BOOL AIShapeImport::FinishWorkingShape(BOOL forceFinish, ImpInterface *i) { // If nothing going on, forget the whole thing and return success if(!splShape) return TRUE; if(!shape) { assert(0); return FALSE; } // Otherwise, see if the current spline is closed if(spline) { int knots = spline->KnotCount(); // If not a valid spline, get rid of it! if(knots < 2) { singularity: // DebugPrint("WARN: spline w/%d points\n",knots); shape->UpdateSels(); // Make sure it readies the selection set info shape->DeleteSpline(shape->SplineCount() - 1); spline = NULL; } else { int lastKnot = knots-1; if(spline->GetKnotPoint(0) == spline->GetKnotPoint(lastKnot)) { spline->SetInVec(0, spline->GetInVec(lastKnot)); spline->DeleteKnot(lastKnot); if(spline->KnotCount() < 2) goto singularity; spline->SetClosed(); } // Check to be sure knot types are correct -- The default is for // smooth beziers, but they may be corners for(int k = 0; k < knots; ++k) { Point3 in = spline->GetInVec(k); Point3 out = spline->GetOutVec(k); Point3 knot = spline->GetKnotPoint(k); int type = spline->GetKnotType(k); if(type == KTYPE_BEZIER) { if(in == knot && out == knot) // If both zero length vector, it's a corner spline->SetKnotType(k, KTYPE_CORNER); else // If vectors not collinear, it's a corner! if(in == knot || out == knot) // If zero length vector, it's a bez corner spline->SetKnotType(k, KTYPE_BEZIER_CORNER); else { // If vectors not collinear, it's a corner! Point3 normIn = Normalize(knot - in); Point3 normOut = Normalize(out - knot); Point3 lowtest = normIn * 0.98f; Point3 hightest = normIn * 1.02f; if(!(((normOut.x >= lowtest.x && normOut.x <= hightest.x) || (normOut.x <= lowtest.x && normOut.x >= hightest.x)) && ((normOut.y >= lowtest.y && normOut.y <= hightest.y) || (normOut.y <= lowtest.y && normOut.y >= hightest.y)) && ((normOut.z >= lowtest.z && normOut.z <= hightest.z) || (normOut.z <= lowtest.z && normOut.z >= hightest.z)))) spline->SetKnotType(k, KTYPE_BEZIER_CORNER); } } } spline->ComputeBezPoints(); } } // If necessary, create the object if(importType == MULTIPLE_SHAPES || forceFinish) { if(shape->SplineCount()) { shape->UpdateSels(); // Make sure it readies the selection set info shape->InvalidateGeomCache(); // create shape object ImpNode *node = i->CreateNode(); if(!node) return FALSE; node->Reference(splShape); Matrix3 tm(1); Box3 bbox = shape->GetBoundingBox(); Point3 center = Point3(bbox.Center().x, bbox.Center().y, 0.0f); tm.SetTrans(center); // TH 7/5/96 node->SetPivot(-center); // TH 3/9/99 node->SetTransform(0,tm); i->AddNodeToScene(node); TSTR name; name.printf(GetString(IDS_TH_SHAPE_NUM),theShapeImport->shapeNumber++); node->SetName(name); gotStuff = TRUE; } // Reset the shape stuff splShape = NULL; shape = NULL; spline = NULL; } return TRUE; }
// 2. 加载骨骼数据 void M2Importer::importBoneObject() { // Bone Group Header Node INode* groupHeadNode = createGroupHeaderNode(); groupHeadNode->SetGroupHead(TRUE); groupHeadNode->SetGroupMember(FALSE); if (m_modelHeader->nameLength > 1) { TCHAR* modelName = (TCHAR*)(m_m2FileData + m_modelHeader->nameOfs); TCHAR boneGroupName[256]; sprintf(boneGroupName, "%s_bone", modelName); groupHeadNode->SetName(boneGroupName); } else groupHeadNode->SetName("BoneGroup"); // Bone // 一个Bone构造一个Node, 并且加入到组中 ModelBoneDef* boneData = (ModelBoneDef*)(m_m2FileData + m_modelHeader->ofsBones); m_boneNodeList.reserve(m_modelHeader->nBones); for (unsigned int i = 0; i < m_modelHeader->nBones; ++i) { ModelBoneDef& boneDef = boneData[i]; // create bone node HelperObject* obj = (HelperObject*)CreateInstance(HELPER_CLASS_ID, Class_ID(BONE_CLASS_ID, 0)); ImpNode* node = m_impInterface->CreateNode(); TCHAR boneName[256]; sprintf(boneName, "bone_%02d", i); node->SetName(boneName); node->SetPivot(*(Point3*)&(boneDef.pivot)); node->Reference(obj); m_impInterface->AddNodeToScene(node); // 设置变换矩阵 Matrix3 tm; tm.IdentityMatrix(); tm.SetTrans(*(Point3*)&(boneDef.pivot)); node->SetTransform(0, tm); // 添加到组 INode* realINode = node->GetINode(); realINode->SetGroupHead(FALSE); realINode->SetGroupMember(TRUE); groupHeadNode->AttachChild(realINode); // 设置Bone父子关系 realINode->ShowBone(2); m_boneNodeList.push_back(realINode); if (boneDef.parent != -1) { INode* parentNode = m_boneNodeList[boneDef.parent]; parentNode->AttachChild(realINode); } realINode->EvalWorldState(0); } // 导入每根骨骼的关键桢数据 for (unsigned int i = 0; i < m_modelHeader->nBones; ++i) { ModelBoneDef& boneDef = boneData[i]; INode* realINode = m_boneNodeList[i]; Control* tmControl = realINode->GetTMController(); // Position if (boneDef.translation.nKeys) { // 设置动画控制器为线性控制器 Control* posControl = createPositionController(); tmControl->SetPositionController(posControl); unsigned int* timeData = (unsigned int*)(m_m2FileData + boneDef.translation.ofsTimes); Point3* keyData = (Point3*)(m_m2FileData + boneDef.translation.ofsKeys); // 设置动画时间范围 bool animRangeChanged = false; Interval animRange = m_maxInterface->GetAnimRange(); for (unsigned int j = 0; j < boneDef.translation.nKeys; ++j) { if (timeData[j] < animRange.Start()) { animRange.SetStart(timeData[j]); animRangeChanged = true; } else if (timeData[j] > animRange.End()) { animRange.SetEnd(timeData[j]); animRangeChanged = true; } } if (animRangeChanged) m_maxInterface->SetAnimRange(animRange); // 设置动画关键桢数据 Control* xControl = posControl->GetXController(); IKeyControl* xKeyControl = GetKeyControlInterface(xControl); xKeyControl->SetNumKeys(boneDef.translation.nKeys); Control* yControl = posControl->GetYController(); IKeyControl* yKeyControl = GetKeyControlInterface(yControl); yKeyControl->SetNumKeys(boneDef.translation.nKeys); Control* zControl = posControl->GetZController(); IKeyControl* zKeyControl = GetKeyControlInterface(zControl); zKeyControl->SetNumKeys(boneDef.translation.nKeys); for (unsigned int j = 0; j < boneDef.translation.nKeys; ++j) { // X AnyKey bufX; ILinFloatKey* keyX = reinterpret_cast<ILinFloatKey*>((IKey*)bufX); keyX->time = timeData[j]; keyX->val = keyData[j].x; xKeyControl->AppendKey(keyX); // Y AnyKey bufY; ILinFloatKey* keyY = reinterpret_cast<ILinFloatKey*>((IKey*)bufY); keyY->time = timeData[j]; keyY->val = keyData[j].y; yKeyControl->AppendKey(keyY); // Z AnyKey bufZ; ILinFloatKey* keyZ = reinterpret_cast<ILinFloatKey*>((IKey*)bufZ); keyZ->time = timeData[j]; keyZ->val = keyData[j].z; zKeyControl->AppendKey(keyZ); } } /* // Rotation if (boneDef.rotation.nKeys) { Control* rotControl = createRotationController(); tmControl->SetRotationController(rotControl); unsigned int* timeData = (unsigned int*)(m_m2FileData + boneDef.rotation.ofsTimes); Quat* keyData = (Quat*)(m_m2FileData + boneDef.rotation.ofsKeys); // 设置动画时间范围 bool animRangeChanged = false; Interval animRange = m_maxInterface->GetAnimRange(); for (unsigned int j = 0; j < boneDef.rotation.nKeys; ++j) { if (timeData[j] < animRange.Start()) { animRange.SetStart(timeData[j]); animRangeChanged = true; } else if (timeData[j] > animRange.End()) { animRange.SetEnd(timeData[j]); animRangeChanged = true; } } if (animRangeChanged) m_maxInterface->SetAnimRange(animRange); // 设置动画关键桢数据 IKeyControl* keyControl = GetKeyControlInterface(rotControl); keyControl->SetNumKeys(boneDef.rotation.nKeys); for (unsigned int j = 0; j < boneDef.rotation.nKeys; ++j) { AnyKey buf; ILinRotKey* key = reinterpret_cast<ILinRotKey*>((IKey*)buf); key->time = timeData[j]; key->val = keyData[j]; keyControl->AppendKey(key); } } */ // Scaling if (boneDef.scaling.nKeys) { Control* scaControl = createScaleController(); tmControl->SetScaleController(scaControl); unsigned int* timeData = (unsigned int*)(m_m2FileData + boneDef.scaling.ofsTimes); Point3* keyData = (Point3*)(m_m2FileData + boneDef.scaling.ofsKeys); // 设置动画时间范围 bool animRangeChanged = false; Interval animRange = m_maxInterface->GetAnimRange(); for (unsigned int j = 0; j < boneDef.scaling.nKeys; ++j) { if (timeData[j] < animRange.Start()) { animRange.SetStart(timeData[j]); animRangeChanged = true; } else if (timeData[j] > animRange.End()) { animRange.SetEnd(timeData[j]); animRangeChanged = true; } } if (animRangeChanged) m_maxInterface->SetAnimRange(animRange); // 设置动画关键桢数据 IKeyControl* keyControl = GetKeyControlInterface(scaControl); keyControl->SetNumKeys(boneDef.scaling.nKeys); for (unsigned int j = 0; j < boneDef.scaling.nKeys; ++j) { AnyKey buf; ILinScaleKey* key = reinterpret_cast<ILinScaleKey*>((IKey*)buf); key->time = timeData[j]; key->val = ScaleValue(keyData[j]); keyControl->AppendKey(key); } } } }