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/TranslationCharacterModel.h"
00027 #include "Translator/Model/TranslationBone.h"
00028 #include "Translator/Mesh/TranslationMeshManager.h"
00029 #include "Graphics/Scene/Scene.h"
00030 #include "Graphics/Model/ModelManager.h"
00031 #include "Graphics/Mesh/MeshManager.h"
00032 #include "Animation/System/AnimationManager.h"
00033 #include "Animation/System/AnimationSet.h"
00034 #include "Animation/Model/CharacterModelAnimation.h"
00035 #include "Animation/VectorInterpolator/VectorArrayInterpolator.h"
00036 #include "Animation/RotationInterpolator/EulerArrayInterpolator.h"
00037
00038 namespace LampForMaya{
00039
00040
00041
00042 TranslationCharacterModel::TranslationCharacterModel(
00043 const MObject& initializeObject, const String& initializeName,
00044 const MObject& skinClusterObject) :
00045 TranslationModel(initializeObject, initializeName),
00046 skinClusterObject_(skinClusterObject),
00047 transBones_(NULL), transBoneCount_(0), transMeshes_(NULL){
00048 MayaStatusCheck(skinCluster_.setObject(skinClusterObject_));
00049 }
00050
00051
00052 TranslationCharacterModel::~TranslationCharacterModel(){
00053 SafeArrayDelete(transBones_);
00054 SafeArrayDelete(transMeshes_);
00055 }
00056
00057
00058 bool TranslationCharacterModel::analyze(TranslationMeshManager* meshManager){
00059
00060 if(!analyzeModel()){ return false; }
00061
00062 if(skinCluster_.numOutputConnections() != 1){
00063 MayaErrorOut(String("TranslationCharacterModel::analyze() ") +
00064 name_ + "に複数のモデルが接続されています");
00065 return false;
00066 }
00067
00068 if(!analyzeBone()){ return false; }
00069
00070 if(!analyzeMesh(meshManager)){ return false; }
00071
00072 if(!analyzeWeight()){ return false; }
00073
00074 for(int i = 0; i < meshes_.getCount(); i++){
00075 if(!meshes_.get(i)->logicalCheck()){ return false; }
00076 }
00077 return true;
00078 }
00079
00080
00081 bool TranslationCharacterModel::analyzeBone(){
00082 MStatus result;
00083 String errorMessage;
00084
00085 MDagPathArray bonePathArray;
00086 transBoneCount_ = skinCluster_.influenceObjects(bonePathArray, &result);
00087 MayaStatusCheck(result);
00088 if(transBoneCount_ > CharacterModel::maxBoneCount){
00089 errorMessage.format("TranslationCharacterModel::analyzeBone() "
00090 "%sのボーン数が多すぎます ( %d / %d )",
00091 name_.getBytes(), transBoneCount_, CharacterModel::maxBoneCount);
00092 MayaErrorOut(errorMessage);
00093 return false;
00094 }else if(transBoneCount_ == 0){
00095 MayaErrorOut(String("TranslationCharacterModel::analyzeBone() ") +
00096 name_ + "にボーンがありません");
00097 return false;
00098 }
00099
00100 transBones_ = new TranslationBone[transBoneCount_];
00101 for(int i = 0; i < transBoneCount_; i++){
00102 transBones_[i].analyze(bonePathArray[i]);
00103 }
00104
00105 transBones_[0].buildModelMatrix(this, Matrix34::unit);
00106 return true;
00107 }
00108
00109
00110 TranslationBone* TranslationCharacterModel::searchBone(const String& boneName){
00111
00112 for(int i = 0; i < transBoneCount_; i++){
00113 if(transBones_[i].getName().equals(boneName)){
00114 return &transBones_[i];
00115 }
00116 }
00117 return NULL;
00118 }
00119
00120
00121 bool TranslationCharacterModel::analyzeMesh(TranslationMeshManager* meshManager){
00122 MStatus result;
00123 String errorString;
00124 MFnMesh fnMesh(object_, &result);
00125 MayaStatusCheck(result);
00126
00127
00128 MStringArray uvSetNames;
00129 MayaStatusCheck(fnMesh.getUVSetNames(uvSetNames));
00130 int uvSetCount = uvSetNames.length();
00131
00132
00133 MObjectArray shaders;
00134 MIntArray shaderIndices;
00135
00136 result = fnMesh.getConnectedShaders(0, shaders, shaderIndices);
00137 MayaStatusCheck(result);
00138
00139
00140 for(u_int i = 0; i < shaderIndices.length(); i++){
00141 if(shaderIndices[i] == -1){
00142 MIntArray vertexIndex;
00143 MayaStatusCheck(fnMesh.getPolygonVertices(i, vertexIndex));
00144 int vertexCount = vertexIndex.length();
00145 errorString.format("TranslationCharacterModel::analyze() "
00146 "%sにシェーダの割り当てられいないポリゴンがあります ",
00147 name_.getBytes());
00148 for(int i = 0; i < vertexCount; i++){
00149 MPoint position;
00150 MayaStatusCheck(fnMesh.getPoint(vertexIndex[i], position));
00151 String temp;
00152 temp.format(" ( %.3f , %.3f , %.3f)",
00153 position.x, position.y, position.z);
00154 errorString += temp;
00155 }
00156 MayaErrorOut(errorString);
00157 return false;
00158 }
00159 }
00160
00161
00162 transMeshCount_ = shaders.length();
00163 int nameCount = 0;
00164 transMeshes_ = new TranslationCharacterMesh*[transMeshCount_];
00165 for(int i = 0; i < transMeshCount_; i++){
00166
00167 String meshName;
00168 while(true){
00169 meshName.format("%sM%d", name_.getBytes(), nameCount);
00170 nameCount++;
00171 TranslationMesh* exist = meshManager->search(meshName);
00172 if(exist == NULL){ break; }
00173 }
00174 transMeshes_[i] = meshManager->createCharacterMesh(meshName);
00175
00176 meshes_.add(transMeshes_[i]);
00177
00178 transMeshes_[i]->setUVSetCount(uvSetCount);
00179
00180 transMeshes_[i]->setMaterialName(getShaderName(shaders[i]));
00181 }
00182
00183
00184 MObject inputShapeObject = skinCluster_.inputShapeAtIndex(0, &result);
00185 MayaStatusCheck(result);
00186
00187 MItMeshPolygon polygonIterator(inputShapeObject, &result);
00188 MayaStatusCheck(result);
00189 int polygonCount = 0;
00190 for( ; !polygonIterator.isDone(); polygonIterator.next()){
00191 int shaderIndex = shaderIndices[polygonCount];
00192 TranslationCharacterMesh* mesh = transMeshes_[shaderIndex];
00193 polygonCount++;
00194
00195 MPointArray positions;
00196 polygonIterator.getPoints(positions, MSpace::kObject, &result);
00197 MayaStatusCheck(result);
00198
00199
00200
00201 if(positions.length() != 3){
00202 errorString.format("TranslationStandardModel::analyze() "
00203
00204 "%sが三角以外のポリゴン(%d角形)を持っています\n",
00205 name_.getBytes(), positions.length());
00206 for(u_int i = 0; i < positions.length(); i++){
00207 String temp;
00208 temp.format(" %d ( %.3f , %.3f , %.3f)",
00209 i, positions[i].x, positions[i].y, positions[i].z);
00210 errorString += temp;
00211 }
00212 MayaErrorOut(errorString);
00213 return false;
00214 }
00215 mesh->addPosition(Vector3((float)positions[0].x,
00216 (float)positions[0].y, (float)positions[0].z));
00217 mesh->addPosition(Vector3((float)positions[1].x,
00218 (float)positions[1].y, (float)positions[1].z));
00219 mesh->addPosition(Vector3((float)positions[2].x,
00220 (float)positions[2].y, (float)positions[2].z));
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 MVectorArray normals;
00234 result = polygonIterator.getNormals(normals, MSpace::kObject);
00235 MayaStatusCheck(result);
00236 mesh->addNormal(Vector3(
00237 (float)normals[0].x, (float)normals[0].y, (float)normals[0].z));
00238 mesh->addNormal(Vector3(
00239 (float)normals[1].x, (float)normals[1].y, (float)normals[1].z));
00240 mesh->addNormal(Vector3(
00241 (float)normals[2].x, (float)normals[2].y, (float)normals[2].z));
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 bool hasColor = polygonIterator.hasColor(&result);
00255 MayaStatusCheck(result);
00256 if(hasColor){
00257 MColorArray colors;
00258 result = polygonIterator.getColors(colors);
00259 MayaStatusCheck(result);
00260 mesh->addColor(Color4f(
00261 colors[0].r, colors[0].g, colors[0].b, colors[0].a));
00262 mesh->addColor(Color4f(
00263 colors[1].r, colors[1].g, colors[1].b, colors[1].a));
00264 mesh->addColor(Color4f(
00265 colors[2].r, colors[2].g, colors[2].b, colors[2].a));
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 }
00277
00278
00279 MFloatArray uArray, vArray;
00280 for(int i = 0; i < uvSetCount; i++){
00281 MayaStatusCheck(polygonIterator.getUVs(
00282 uArray, vArray, &uvSetNames[i]));
00283
00284 mesh->addUV(TexCoord2(uArray[0], (vArray[0] - 1.f) * -1.f));
00285 mesh->addUV(TexCoord2(uArray[1], (vArray[1] - 1.f) * -1.f));
00286 mesh->addUV(TexCoord2(uArray[2], (vArray[2] - 1.f) * -1.f));
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 u_int index0 = polygonIterator.vertexIndex(0, &result);
00303 u_int index1 = polygonIterator.vertexIndex(1, &result);
00304 u_int index2 = polygonIterator.vertexIndex(2, &result);
00305 mesh->addIndex(index0);
00306 mesh->addIndex(index1);
00307 mesh->addIndex(index2);
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 }
00320 return true;
00321 }
00322
00323
00324 bool TranslationCharacterModel::analyzeWeight(){
00325 MStatus result;
00326 String errorMessage;
00327 bool returnValue = true;
00328
00329 u_int index = skinCluster_.indexForOutputConnection(0, &result);
00330 MayaStatusCheck(result);
00331 MDagPath skinPath;
00332 MayaStatusCheck(skinCluster_.getPathAtIndex(index, skinPath));
00333 MItGeometry geometries(skinPath);
00334
00335 int vertexCount = geometries.count();
00336 float* weights = new float[transBoneCount_ * vertexCount];
00337 int * weightCounts = new int[vertexCount];
00338 u_int vertexCounter = 0;
00339 for( ; !geometries.isDone(); geometries.next(), vertexCounter++){
00340 MObject component = geometries.component(&result);
00341 MayaStatusCheck(result);
00342 MFloatArray weightArray;
00343 u_int boneCount;
00344 MayaStatusCheck(skinCluster_.getWeights(
00345 skinPath, component, weightArray, boneCount));
00346 if(transBoneCount_ != boneCount){
00347 MayaErrorOut(String("TranslationCharacterModel::analyzeWeight() ") +
00348 name_ + "の頂点ボーン数と出力ボーン数に違いがあります");
00349 returnValue = false;
00350 break;
00351 }
00352 int offset = vertexCounter * transBoneCount_;
00353 weightCounts[vertexCounter] = 0;
00354 float totalWeight = 0.f;
00355 for(int i = 0; i < transBoneCount_; i++){
00356 weights[offset + i] = weightArray[i];
00357
00358 if(weights[offset + i] < 0.001f){ weights[offset + i] = 0.f; }
00359 if(weights[offset + i] != 0.f){ weightCounts[vertexCounter]++; }
00360 totalWeight += weights[offset + i];
00361 }
00362
00363 if((weightCounts[vertexCounter] > CharacterMesh::maxWeightPerVertex) ||
00364 (weightCounts[vertexCounter] <= 0)){
00365 errorMessage.format("TranslationCharacterModel::analyzeWeight() "
00366 "%sの%d番目の頂点に%d個のウェイトが割り付けられています",
00367 name_.getBytes(), vertexCounter, weightCounts[vertexCounter]);
00368 MayaErrorOut(errorMessage);
00369 returnValue = false;
00370 break;
00371 }
00372
00373 if(Math::abs(totalWeight - 1.f) > 0.001f){
00374 errorMessage.format("TranslationCharacterModel::analyzeWeight() "
00375 "%sの%d番目の頂点のウェイト合計が1でありません",
00376 name_.getBytes(), vertexCounter, totalWeight);
00377 MayaErrorOut(errorMessage);
00378 returnValue = false;
00379 break;
00380 }
00381 }
00382 if(!returnValue){
00383 delete[] weights;
00384 delete[] weightCounts;
00385 return returnValue;
00386 }
00387
00388 MFnDependencyNode node(object_, &result);
00389 MayaStatusCheck(result);
00390 MObject stitchingAttribute = node.attribute("LampStitching", &result);
00391 bool stitchingFlag = false;
00392 if(result){
00393 MayaStatusCheck(result);
00394 MPlug stitchingPlug(object_, stitchingAttribute);
00395 result = stitchingPlug.getValue(stitchingFlag);
00396 MayaStatusCheck(result);
00397 }
00398
00399 if(stitchingFlag){
00400 for(int i = 0; i < vertexCount; i++){
00401 int offset = i * transBoneCount_;
00402 int maxWeightIndex = 0;
00403 float maxWeight = weights[offset];
00404 weights[offset] = 0.f;
00405 for(int j = 1; j < transBoneCount_; j++){
00406 if(weights[offset + j] > maxWeight){
00407 maxWeight = weights[offset + j];
00408 maxWeightIndex = j;
00409 }
00410 weights[offset + j] = 0.f;
00411 }
00412
00413 weights[offset + maxWeightIndex] = 1.f;
00414 weightCounts[i] = 1;
00415 }
00416 }
00417
00418 if(returnValue){
00419 for(int i = 0; i < transMeshCount_; i++){
00420 if(!transMeshes_[i]->setWeights(
00421 transBoneCount_, weights, weightCounts)){
00422 returnValue = false;
00423 break;
00424 }
00425 }
00426 }
00427 delete[] weights;
00428 delete[] weightCounts;
00429 return returnValue;
00430 }
00431
00432
00433 bool TranslationCharacterModel::analyzeAnimation(){
00434
00435 if(!sequence_.analyze(object_)){ return true; }
00436 int startTime = sequence_.getStartTime(0);
00437 int endTime = sequence_.getEndTime(sequence_.getSequenceCount() - 1);
00438 for(int i = 0; i < transBoneCount_; i++){
00439 transBones_[i].analyzeAnimation(startTime, endTime);
00440 }
00441 return true;
00442 }
00443
00444
00445 bool TranslationCharacterModel::convertToLamp(Scene* scene){
00446 ModelManager* modelManager = scene->getModelManager();
00447 CharacterModel* model = modelManager->createCharacterModel(name_);
00448
00449 model->setEnabled(visibility_);
00450
00451 MeshManager* meshManager = scene->getMeshManager();
00452 int meshCount = meshes_.getCount();
00453 for(int i = 0; i < meshCount; i++){
00454 String meshName = meshes_.get(i)->getName();
00455 Mesh* mesh = meshManager->search(meshName);
00456 if(mesh == NULL){
00457 MayaErrorOut(String("TranslationCharacterModel::convertToLamp() "
00458 "メッシュが見つかりません ") + meshName);
00459 return false;
00460 }
00461 model->addMesh(mesh);
00462 }
00463
00464 for(int i = 0; i < transBoneCount_; i++){
00465 if(!transBones_[i].convertToLamp(model)){ return false; }
00466 }
00467
00468 for(int i = 0; i < transBoneCount_; i++){
00469 if(!transBones_[i].boneLink(model, i)){ return false; }
00470 }
00471 return true;
00472 }
00473
00474
00475 bool TranslationCharacterModel::convertAnimation(
00476 AnimationManager* animationManager, AnimationSet* animationSet){
00477
00478 if(!sequence_.hasSequence()){ return true; }
00479 CharacterModelAnimation* animation =
00480 animationManager->createCharacterModel(name_);
00481 if(animation->getName() != name_){
00482 MayaErrorOut("TranslationCharacterModel::convertAnimation() " +
00483 name_ + "の名前が重複しています ");
00484 return false;
00485 }
00486 CharacterModelAnimationData* data =
00487 animationManager->createCharacterModelData(name_);
00488 if(data->getName() != name_){
00489 MayaErrorOut("TranslationCharacterModel::convertAnimation() " +
00490 name_ + "の名前が重複しています ");
00491 return false;
00492 }
00493
00494 animation->setTargetName(name_);
00495 animation->setCharacterModelAnimationData(data);
00496 animation->setBoneCount(transBoneCount_);
00497 for(int i = 0; i < transBoneCount_; i++){
00498 animation->setBoneName(i, transBones_[i].getName());
00499 }
00500 animationSet->addAnimation(animation);
00501
00502 data->setBoneCount(transBoneCount_);
00503 int sequenceCount = sequence_.getSequenceCount();
00504 data->setSequenceCount(sequenceCount);
00505 for(int i = 0; i < sequenceCount; i++){
00506 int startTime = sequence_.getStartTime(i);
00507 int endTime = sequence_.getEndTime(i);
00508 for(int j = 0; j < transBoneCount_; j++){
00509 TranslationBone& bone = transBones_[j];
00510
00511 VectorInterpolator* scale =
00512 bone.getScaleAnimation(startTime, endTime);
00513 if(scale != NULL){ data->setScale(i, j, scale); }
00514
00515 RotationInterpolator* rotation =
00516 bone.getRotationAnimation(startTime, endTime);
00517 if(rotation != NULL){ data->setRotation(i, j, rotation); }
00518
00519 VectorInterpolator* translation =
00520 bone.getTranslationAnimation(startTime, endTime);
00521 if(translation != NULL){ data->setTranslation(i, j, translation); }
00522 }
00523 data->setLooped(i, sequence_.isLooped(i));
00524 }
00525 return true;
00526 }
00527
00528 }
00529