3DS Max Exporter ------ Skin Bone Animation

xiaoxiao2021-03-06  21

// Frist processing bone weightsBOOL ProcessingBoneWeights (INode * pNode, INode * pRoot, BoneData * BD) {if ((pNode) || (IsMesh (pNode))!!) Return FALSE; Modifier * pmf = GetPhysiqueMod (pNode); if (PMF) GetPhysiqueWeights (PNODE, ProT, PMF, BD); Else {PMF = GetskinMod (PNODE); IF (PMF) GetskinWeights (PNode, Pmeshidx, ProT, PMF, BD);} int Num = pnode-> Numberofchildren () For (int N = 0; n getchildnode (n), proot, bd);} return true;} // Here Just Take with Physique and Skin Modify .... static Modifier * GetPhysiqueMod (INode * pNode) {Object * pObj = pNode-> GetObjectRef (); if (! pObj) return NULL; while (pObj-> SuperClassID () == GEN_DERIVOB_CLASS_ID) {IDerivedObject * pDerivedObj = static_cast (pObj); int modStackIndex = 0; while (modStackIndex NumModifiers ()) {Modifier * mod = pDerivedObj-> GetModifier (modStackIndex); if (mod-> ClassID () == class_ID (PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B)) Return mod; ModstackIndex ;} POBJ = PderiveDobj -> getobjref ();} return null;} static modifier * getskinmod (inode * pnode) {Object * pobj = pnode-> getObjectRef (); if (! Pobj) return null; while (pobj-> superclassid () == GEN_DERIVOB_CLASS_ID) {IDerivedObject * pDerivedObj = static_cast (pObj); int modStackIndex = 0; while (modStackIndex NumModifiers ()) {Modifier * mod = pDerivedObj-> GetModifier (modStackIndex); if (mod-> ClassID () == Skin_ClassID) Return MOD; ModstackIndex ;} POBJ = PderiveDobj-> getobjref ();} return null;

} // Get An Index from a Node Pointerint GetBoneIndex (Inode * ProT, Inode * Pnode) {if (! Isbone (pnode)) Return -1;

int boneCount = 0; return RecursiveGetBoneIndex (pRoot, pNode, boneCount);} // if there is more than one mesh, we will use pMeshIdx BOOL GetSkinWeights (INode * pNode, int * pMeshIdx, INode * pRoot, Modifier * pMod, BoneData * BD) {iSkin * skin = (iSkin *) pMod-> GetInterface (I_SKIN); if (skin) {ISkinContextData * skincontext = skin-> GetContextInterface (pNode); if {int numVert = skincontext- (skincontext)> GetNumPoints ( ); For (int i = 0; i getNumassignedBones (i); for (int J = 0; j getBone SkinconText-> GetAssignedBone (i, j)); // do not use j, but use getassignedbone (i, j) int boneidx; if (bone) {boneidx = getBoneIndex (ProT, Bone); if (boneidx == - 1 ) continue;} else continue; BoneWeight_hdr wData; wData.meshIdx = * pMeshIdx; wData.vertIdx = i; wData.weight = skincontext-> GetBoneWeight (i, j); bool notfound = true; for (int v = 0; notfound && v ReleaseInterface (I_SKIN, skin);} return TRUE;} BOOL GetPhysiqueWeights (INode * pNode, int * pMeshIdx, INode * pRoot, Modifier * pMod, BoneData * BD) {IPhysiqueExport * phyInterface =

(IPhysiqueExport *) pMod-> GetInterface (I_PHYINTERFACE); if (phyInterface) {// create a ModContext Export Interface for the specific node of the Physique Modifier IPhyContextExport * modContextInt = (IPhyContextExport *) phyInterface-> GetContextInterface (pNode); // needed by vertex interface (only Rigid one supported for now) modContextInt-> ConvertToRigid (TRUE); // more than a single bone per vertex modContextInt-> AllowBlending (TRUE); if (modContextInt) {int totalVtx = modContextInt-> GetNumberVertices ( ); for (int i = 0; i GetVertexInterface (i); if (vtxInterface) {int vertType = vtxInterface-> GetVertexType (); if (vertType == RIGID_TYPE) {INode * boneNode = ((IPhyRigidVertex *) vtxInterface) -> getNode (); int boneIdx = GetBoneIndex (pRoot, boneNode); BoneWeight_hdr wData; wData.meshIdx = * pMeshIdx; wData.vertIdx = i; wData. Weight = 1.0f; bd [boneidx] .weightvect.push_back wData); BD [boneIdx] .boneHdr.vertexCnt = BD [boneIdx] .weightVect.size ();} else if (vertType == RIGID_BLENDED_TYPE) {IPhyBlendedRigidVertex * vtxBlendedInt = (IPhyBlendedRigidVertex *) vtxInterface; for (int j = 0; j GetNumberNodes (); j ) {INode * boneNode = vtxBlendedInt-> getNode (j); int boneIdx = GetBoneIndex (pRoot, boneNode); BoneWeight_hdr wData; wData.meshIdx = * pMeshIdx; wData.vertIdx = i; WDATA.WEIGHT = vtxblendedint-> getWeight (j); // check vertex existence for this bone bool notfound = true; for (int V = 0;

Notfound && V releaseContextinterface (Modcontextint);} PMOD-> ReleaseInterface (i_phyinterface, phyinterface);} return false;} // ======== =============================================================================================================================== (TM = pnode-> getnodetm (t);

TM.NOSCALE (); returnTM;} // ======================================= ======================================================= // Recursive iterator to get a bone index, used with GetBoneIndexint RecursivegetBoneIndex (Inode * Proot, Inode * PNodeTest, Int & bonecount) {int boneidx = -1;

IF (ISBONE (PROOT) {Boneidx = Bonecount; Bonecount ;

IF (ProT == PNodeTest) Return Boneidx;}

// recurse child nodes for (int i = 0; i numberofchildren (); i ) {int boneidx = RecursivegetBoneIndex (ProT-> getChildNode (i), pnodetest, bonecount); if (boneidx> = 0) Return Boneidx;} Return -1;} // get the number of direct child bones of a nodeint getChildBonECount (Inode * pnode) {int count = 0;

For (int i = 0; i numberofchildren (); i ) {if (isbone (pnode-> getchildnode (i))))))))))))))) - ;} return count;} int processtruct (Inode * pnode, inode * proot, INT PARENTIDX, BONEDATA * BD) {IF (ISBONE (PNODE)) {Int Curridx = getBoneIndex (ProT, 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 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 numberofchildren (); i) ProcessBonestruct (pnode-> getChildNode (i), proot, -1 , BD); RETURN-1;}} // buy by getBonebyindexStatic Bool Builditer (Inode * pnode, inode ** const itrator, int & curridx) {i (isbone (pnode)) {iterator [curridx ] = pnode;}

For (int i = 0; i numberofchildren (); i ) {builditer (pnode-> getchildnode (i), itrator, curridx);} return true;} // Get Bone Pointer from an index, this stay Get Passed the root nodeinode * getBoneByindex (Inode * const proot, int index) {inode * bone = null; const INT bone_cnt = countbones (proot); if (index> = bone_cnt) Return NULL;

Inode ** const itrator = new inode * [bone_cnt]; int curridx = 0; Builditer (ProT, Iterator, Curridx); assert (curridx == bone_cnt);

Bone = iterator [index]; assert (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 end) keyhdr.time = end; Else KeyHDR. Time = msec; Matrix3 Tm; TimeValue T; T = MilliseCTICKS (MSEC); TM = GetBonEtM (Pbone, T); MaxTogl (TM);

Point3 pt = tm.gettrans (); keydr.pos [0] = pt.x; keyhdr.pos [1] = pt.y; keydr.pos [2] = Pt.z;

转载请注明原文地址:https://www.9cbs.com/read-60431.html

New Post(0)