wData.vertIdx=i; wData.weight=vtxBlendedInt->GetWeight(j); //check vertex existence for this bone bool notfound = true; for(int v=0;notfound&&v<BD[boneIdx].weightVect.size();v++) { if(BD[boneIdx].weightVect[v].vertIdx==wData.vertIdx&&BD[boneIdx].weightVect[v].meshIdx==wData.meshIdx) { BD[boneIdx].weightVect[v].weight += wData.weight; notfound = false; } } if(notfound) { BD[boneIdx].weightVect.push_back(wData); BD[boneIdx].boneHdr.vertexCnt=BD[boneIdx].weightVect.size(); } } } } } phyInterface->ReleaseContextInterface(modContextInt); } pMod->ReleaseInterface(I_PHYINTERFACE, phyInterface); } return FALSE; } //=========================================== Matrix3 GetBoneTM(INode *pNode, TimeValue t) { Matrix3 tm(1);
tm = pNode->GetNodeTM(t);
tm.NoScale(); return tm; } // ============================================================================ // Recursive iterator to get a bone index, used with GetBoneIndex int RecursiveGetBoneIndex(INode *pRoot, INode *pNodeTest, int &boneCount) { int boneIdx = -1;
if(IsBone(pRoot)) { boneIdx = boneCount; boneCount++;
if(pRoot == pNodeTest) return boneIdx; }
// recurse child nodes for(int i = 0; i < pRoot->NumberOfChildren(); i++) { int boneIdx = RecursiveGetBoneIndex(pRoot->GetChildNode(i), pNodeTest, boneCount); if(boneIdx >= 0) return boneIdx; }
return -1; } // Get the number of direct child bones of a node int GetChildBoneCount(INode *pNode) { int count = 0;
for(int i = 0; i < pNode->NumberOfChildren(); i++) { if(IsBone(pNode->GetChildNode(i))) count++; } return count; } int ProcessBoneStruct(INode *pNode, INode *pRoot,int parentIdx, BoneData* BD) { if(IsBone(pNode)) { int currIdx=GetBoneIndex(pRoot,pNode); assert(-1!=currIdx); Bone_hdr &boneHdr=BD[currIdx].boneHdr; // get the bones inverse base matrix at time 0 Matrix3 tm=GetBoneTM(pNode,0); tm.Invert(); MAXtoGL(tm,boneHdr.inverseOrientationTM); boneHdr.parentIdx=parentIdx; boneHdr.childCnt=GetChildBoneCount(pNode); if(boneHdr.childCnt>0) { BD[currIdx].childIdxVect.reserve(boneHdr.childCnt); for(int i=0;i<pNode->NumberOfChildren();i++) { int cIdx=ProcessBoneStruct(pNode->GetChildNode(i),pRoot,currIdx,BD); if(cIdx>=0) BD[currIdx].childIdxVect.push_back(cIdx); } } assert(BD[currIdx].childIdxVect.size()==BD[currIdx].boneHdr.childCnt); return currIdx; } else { for (int i=0; i<pNode->NumberOfChildren(); ++i) ProcessBoneStruct(pNode->GetChildNode(i),pRoot,-1, BD); return -1; } } // used by GetBoneByIndex static bool BuildIter(INode* pnode, INode** const Iterator, int& currIdx) { if(IsBone(pnode)){ Iterator[currIdx++] = pnode; }
for(int i = 0; i < pnode->NumberOfChildren(); i++) { BuildIter(pnode->GetChildNode(i),Iterator,currIdx); }
return true; } // Get bone pointer from an index, this should get passed the root node INode* GetBoneByIndex(INode* const pRoot, int index) { INode* bone = NULL; const int bone_cnt = CountBones(pRoot); if (index>=bone_cnt) return NULL;
INode** const Iterator = new INode* [bone_cnt]; int currIdx=0; BuildIter(pRoot,Iterator,currIdx); assert(currIdx==bone_cnt);
bone = Iterator[index]; assert (GetBoneIndex(pRoot,bone)==index);
delete [] Iterator; assert (IsBone(bone)); return bone; }
int ProcessBoneAnim (INode *pRoot, Interval range, ULONG sampleD, BoneData* BD) { int keycnt=0; int totalbones=CountBones(pRoot); const ULONG start = TicksToMilliSec(range.Start()); const ULONG end = TicksToMilliSec(range.End()); if(!totalbones) return 0; for(int idx=0;idx<totalbones;idx++) { INode *pBone=GetBoneByIndex(pRoot,idx); assert(IsBone(pBone)); ULONG msec=0; for(msec=start;msec<end+sampleD;msec+=sampleD) { BoneKey_hdr keyHdr; memset(&keyHdr,0,sizeof(BoneKey_hdr)); if(msec>end) keyHdr.time=end; else keyHdr.time=msec; Matrix3 tm; TimeValue t; t=MilliSecToTicks(msec); tm=GetBoneTM(pBone,t); MAXtoGL(tm);
Point3 pt=tm.GetTrans(); keyHdr.pos[0]=pt.x; keyHdr.pos[1]=pt.y; keyHdr.pos[2]=pt.z;
Quat quat(tm); quat.Normalize(); keyHdr.quat[0] = quat.x; keyHdr.quat[1] = quat.y; keyHdr.quat[2] = quat.z; keyHdr.quat[3] = quat.w; BD[idx].keyVect.push_back(keyHdr); } } keycnt = BD[0].keyVect.size(); return keycnt; }
上一页 [1] [2] |