00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "System/stdafx.h"
00026 #include "Translator/Model/TranslationBone.h"
00027 #include "Translator/Model/TranslationCharacterModel.h"
00028 #include "Graphics/Model/CharacterModel.h"
00029 #include "Translator/Animation/TranslationAnimationUtility.h"
00030 #include "Animation/VectorInterpolator/VectorArrayInterpolator.h"
00031 #include "Animation/RotationInterpolator/EulerArrayInterpolator.h"
00032
00033 namespace LampForMaya{
00034
00035
00036
00037 TranslationBone::TranslationBone() :
00038 scaleAnimation_(NULL), rotationAnimation_(NULL),
00039 translationAnimation_(NULL){
00040 }
00041
00042
00043 TranslationBone::~TranslationBone(){
00044 SafeDelete(translationAnimation_);
00045 SafeDelete(rotationAnimation_);
00046 SafeDelete(scaleAnimation_);
00047 }
00048
00049
00050 bool TranslationBone::analyze(const MDagPath& dagPath){
00051 MStatus result;
00052
00053 dagPath_ = dagPath;
00054 MFnDagNode dagNode(dagPath, &result);
00055 MayaStatusCheck(result);
00056 object_ = dagPath_.node(&result);
00057 MayaStatusCheck(result);
00058 MFnIkJoint joint(object_, &result);
00059 MayaStatusCheck(result);
00060
00061 name_ = dagNode.name(&result).asChar();
00062 MayaStatusCheck(result);
00063
00064
00065 u_int length = dagPath_.length(&result);
00066 MayaStatusCheck(result);
00067 MItDag childIterator(MItDag::kBreadthFirst, MFn::kInvalid, &result);
00068 MayaStatusCheck(result);
00069 result = childIterator.reset(
00070 dagPath_, MItDag::kBreadthFirst, MFn::kInvalid);
00071 MayaStatusCheck(result);
00072
00073 childIterator.next();
00074 MDagPath childPath;
00075 for( ; !childIterator.isDone(); childIterator.next()){
00076 result = childIterator.getPath(childPath);
00077 MayaStatusCheck(result);
00078
00079 u_int childLength = childPath.length(&result);
00080 MayaStatusCheck(result);
00081 if(childLength > length + 1){ break; }
00082
00083 if(childPath.node().apiType() != MFn::kJoint){
00084
00085 continue;
00086 }
00087
00088 MFnDagNode childNode(childPath, &result);
00089 MayaStatusCheck(result);
00090 String childName(childNode.name(&result).asChar());
00091 MayaStatusCheck(result);
00092 bones_.add(childName);
00093 }
00094
00095
00096 MObject bindPoseAttribute = dagNode.attribute("bindPose", &result);
00097 MayaStatusCheck(result);
00098 MPlug bindPosePlug(object_, bindPoseAttribute);
00099 MPlugArray bindPosePlugArray;
00100 bindPosePlug.connectedTo(bindPosePlugArray, false, true);
00101 u_int bindPosePlugCount = bindPosePlugArray.length();
00102 if(bindPosePlugCount != 1){
00103 MayaErrorOut(String("TranslationBone::analyze() ") +
00104 name_ + "に複数のポーズがバインドされています");
00105 return false;
00106 }
00107 u_int logicalIndex = bindPosePlugArray[0].logicalIndex(&result);
00108 MayaStatusCheck(result);
00109 MObject bindPoseObject = bindPosePlugArray[0].node(&result);
00110 MayaStatusCheck(result);
00111 MFnDependencyNode bindPose(bindPoseObject, &result);
00112 MayaStatusCheck(result);
00113
00114 MPlug xformPlug = bindPose.findPlug("xformMatrix", &result);
00115 MayaStatusCheck(result);
00116 xformPlug.selectAncestorLogicalIndex(logicalIndex);
00117 MObject xformObject;
00118 MayaStatusCheck(xformPlug.getValue(xformObject));
00119 MFnMatrixData xformData(xformObject);
00120 MMatrix xform = xformData.matrix();
00121 Matrix44 bindPoseMatrix;
00122 for(int i = 0; i < 4; i++){
00123 for(int j = 0; j < 4; j++){
00124
00125 bindPoseMatrix.m[j][i] = (float)xform(i, j);
00126 }
00127 }
00128 bindPoseMatrix.invert();
00129 inversePoseMatrix_.set(bindPoseMatrix);
00130
00131
00132 MEulerRotation jointRotation;
00133 result = joint.getOrientation(jointRotation);
00134 MayaStatusCheck(result);
00135 if(jointRotation.order != MEulerRotation::kXYZ){
00136 MayaErrorOut(String("TranslationBone::analyze() "
00137 "ジョイント回転順序はXYZしかサポートしていません ") + name_);
00138 return false;
00139 }
00140 jointRotation_.set(
00141 (float)jointRotation.x, (float)jointRotation.y, (float)jointRotation.z);
00142
00143
00144 double scale[3];
00145 result = joint.getScale(scale);
00146 MayaStatusCheck(result);
00147 scale_.set((float)scale[0], (float)scale[1], (float)scale[2]);
00148
00149
00150 MEulerRotation rotation;
00151 result = joint.getRotation(rotation);
00152 MayaStatusCheck(result);
00153 if(rotation.order != MEulerRotation::kXYZ){
00154 MayaErrorOut(String("TranslationBone::analyze() "
00155 "回転順序はXYZしかサポートしていません ") + name_);
00156 return false;
00157 }
00158 rotation_.set((float)rotation.x, (float)rotation.y, (float)rotation.z);
00159 originalRotation_ = rotation_;
00160
00161
00162 Matrix33 rotationMatrix;
00163 rotationMatrix.setRotationXYZ(originalRotation_);
00164 rotationMatrix.addRotationXYZ(jointRotation_);
00165 if(!rotationMatrix.getRotationXYZ(&rotation_)){
00166 MayaMessageOut(String("TranslationBone::convertToLamp() "
00167 "ジョイント回転補正の解が一つでは有りません") + name_);
00168 }
00169
00170
00171 MVector translation = joint.translation(MSpace::kTransform, &result);
00172 MayaStatusCheck(result);
00173 translation_.set(
00174 (float)translation.x, (float)translation.y, (float)translation.z);
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 return true;
00190 }
00191
00192
00193 void TranslationBone::buildModelMatrix(
00194 TranslationCharacterModel* characterModel, const Matrix34& parentMatrix){
00195 inversePoseMatrix_ = inversePoseMatrix_ * parentMatrix;
00196 for(int i = 0; i < bones_.getCount(); i++){
00197 TranslationBone* bone = characterModel->searchBone(bones_.get(i));
00198 bone->buildModelMatrix(characterModel, inversePoseMatrix_);
00199 }
00200 }
00201
00202
00203 bool TranslationBone::analyzeAnimation(int startTime, int endTime){
00204
00205 scaleAnimation_ =
00206 TranslationAnimationUtility::analyzeVectorAnimation(
00207 object_, "scale", scale_, startTime, endTime);
00208
00209 rotationAnimation_ =
00210 TranslationAnimationUtility::analyzeRotationAnimation(
00211 object_, "rotate", originalRotation_, startTime, endTime);
00212
00213 if(rotationAnimation_ != NULL){
00214 int size = rotationAnimation_->getSize();
00215 for(int i = 0; i < size; i++){
00216 Vector3 rotation = rotationAnimation_->getValue(i);
00217 Matrix33 rotationMatrix;
00218 rotationMatrix.setRotationXYZ(rotation);
00219 rotationMatrix.addRotationXYZ(jointRotation_);
00220 if(!rotationMatrix.getRotationXYZ(&rotation)){
00221 MayaMessageOut(String("TranslationBone::analyzeAnimation() "
00222 "ジョイント回転補正の解が一つでは有りません") + name_);
00223 }
00224 rotationAnimation_->setValue(i, rotation);
00225 }
00226 }
00227
00228 translationAnimation_ =
00229 TranslationAnimationUtility::analyzeVectorAnimation(
00230 object_, "translate", translation_, startTime, endTime);
00231 return true;
00232 }
00233
00234
00235 bool TranslationBone::convertToLamp(CharacterModel* model){
00236
00237 Bone* bone = model->createBone(name_);
00238 bone->setInversePoseMatrix(inversePoseMatrix_);
00239 bone->setScale(scale_);
00240 bone->setRotationXYZ(rotation_);
00241 bone->setTranslation(translation_);
00242 return true;
00243 }
00244
00245
00246 bool TranslationBone::boneLink(CharacterModel* model, int index){
00247 Bone* bone = model->getBone(index);
00248 for(int i = 0; i < bones_.getCount(); i++){
00249 Bone* child = model->searchBone(bones_.get(i));
00250 if(child == NULL){
00251 MayaErrorOut(String("TranslationBone::boneLink() "
00252 "ボーンが見つかりません ") + bones_.get(i));
00253 return false;
00254 }
00255 bone->addBone(child);
00256 }
00257 return true;
00258 }
00259
00260
00261 VectorInterpolator* TranslationBone::getScaleAnimation(
00262 int startTime, int endTime){
00263 if(scaleAnimation_ == NULL){ return NULL; }
00264 int size = endTime - startTime + 1;
00265 VectorArrayInterpolator* array = new VectorArrayInterpolator();
00266 array->setSize(size);
00267 for(int i = 0; i < size; i++){
00268 array->setValue(i, scaleAnimation_->getValue(startTime + i));
00269 }
00270 return array;
00271 }
00272
00273
00274 RotationInterpolator* TranslationBone::getRotationAnimation(
00275 int startTime, int endTime){
00276 if(rotationAnimation_ == NULL){ return NULL; }
00277 int size = endTime - startTime + 1;
00278 EulerArrayInterpolator* array = new EulerArrayInterpolator();
00279 array->setSize(size);
00280 for(int i = 0; i < size; i++){
00281 array->setValue(i, rotationAnimation_->getValue(startTime + i));
00282 }
00283 return array;
00284 }
00285
00286
00287 VectorInterpolator* TranslationBone::getTranslationAnimation(
00288 int startTime, int endTime){
00289 if(translationAnimation_ == NULL){ return NULL; }
00290 int size = endTime - startTime + 1;
00291 VectorArrayInterpolator* array = new VectorArrayInterpolator();
00292 array->setSize(size);
00293 for(int i = 0; i < size; i++){
00294 array->setValue(i, translationAnimation_->getValue(startTime + i));
00295 }
00296 return array;
00297 }
00298
00299 }
00300