void GR2ImportImpl::ImportAnimations() { if (info.Animations.size() == 0 || !enableAnimation) return; ClearAnimation(); //for (int anim=0, nanim=info.Animations.size(); anim<nanim; ++anim) //{ // Animation& anim = (*info.Animations[anim]); //} Interval range; range.SetInstant(0); float time = FrameToTime(0); for (int ianim=0, nanim=info.Animations.size(); ianim<nanim; ++ianim) { Animation& anim = (*info.Animations[ianim]); TimeValue animEnd = TimeToFrame(time + anim.Duration); if (animEnd > range.End()) range.SetEnd(animEnd); // Build Default Time int nkeys = anim.Duration / anim.TimeStep; GR2Array<granny_real32> defaultKeys(nkeys); granny_real32 curtime = 0.0f; for (int ikeys=0; ikeys<nkeys; ++ikeys, curtime += anim.TimeStep) defaultKeys[ikeys] = curtime; for (int grp=0, ngrp=anim.TrackGroups.size(); grp<ngrp; ++grp) { TrackGroup& group = (*anim.TrackGroups[grp]); if (INode *root = o->gi->GetINodeByName(group.Name)) { Point3 s( group.InitialPlacement.Scale.m[0][0] , group.InitialPlacement.Scale.m[1][1] , group.InitialPlacement.Scale.m[2][2] ); for (int itrack=0, ntrack=group.TransformTracks.size(); itrack<ntrack; ++itrack) { TransformTrack& track = group.TransformTracks[itrack]; if (INode *node = o->gi->GetINodeByName(track.Name)) { if (Control *c = node->GetTMController()) { DWORD flags=INHERIT_ALL; c->SetInheritanceFlags(INHERIT_ALL,FALSE); ImportPosition(c, track, time, defaultKeys); ImportRotation(c, track, time, defaultKeys); ImportScale(c, track, time, defaultKeys); } } } Matrix3 rot(true); group.InitialPlacement.Rotation.MakeMatrix(rot); Matrix3 m = TransMatrix(group.InitialPlacement.Origin) * Inverse(rot) * ScaleMatrix( s ); PosRotScaleNode(root, m); // TODO: Move to initial transform } } } o->gi->SetAnimRange(range); }
void Import::SetSceneParameters() { Interval range; range.SetStart(0); range.SetEnd(30); SetFrameRate(30); SetTicksPerFrame(160); range.SetStart(range.Start() * GetTicksPerFrame()); range.SetEnd(range.End() * GetTicksPerFrame()); m_ip->SetAnimRange(range); Point3 bkColor (0.0f, 0.0f, 0.0f); m_impip->SetBackGround(0, bkColor); Point3 amColor (0.3f, 0.3f, 0.3f); m_impip->SetAmbient(0, amColor); }
// 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); } } } }