source: OGRE/trunk/ogrenew/Tools/3dsmaxExport/plugins/PhysiqueInterface_sources/PublishedInterface.cpp @ 657

Revision 657, 32.7 KB checked in by mattausch, 18 years ago (diff)

added ogre dependencies and patched ogre sources

Line 
1
2#include "PublishedInterface.h"
3#include "modstack.h"
4
5#define VIEW_DEFAULT_WIDTH ((float)400.0)
6
7// FP interface descriptor - FnPub-published methods & properties
8//****************************************************************
9static IPhysiqueInterface iPhysiqueInterface (IPHYSIQUEINTERFACE, _T("physiqueOps"), 0, NULL, FP_CORE + FP_STATIC_METHODS,
10        //methods
11        IPhysiqueInterface::checkMatrix, _T("checkMatrix"), 0, TYPE_BOOL, 0, 2,
12                _T("physiqued_Node"), 0, TYPE_INODE,
13                _T("modifier"), 0, TYPE_REFTARG,f_keyArgDefault, NULL,
14
15        IPhysiqueInterface::getPhysique, _T("getPhysiqueModifier"), 0, TYPE_REFTARG, 0, 2,
16                _T("physiqued_Node"), 0, TYPE_INODE,
17                _T("index"), 0, TYPE_INDEX, f_keyArgDefault, 0,
18        IPhysiqueInterface::getAPIVersion, _T("getAPIVersion"), 0, TYPE_INT, 0, 2,
19                _T("physiqued_Node"), 0, TYPE_INODE,
20                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
21
22        IPhysiqueInterface::getBoneList, _T("getBones"), 0, TYPE_INODE_TAB_BV, 0, 2,
23                _T("physiqued_Node"), 0, TYPE_INODE,
24                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
25        IPhysiqueInterface::getBoneCount, _T("getBoneCount"), 0, TYPE_INT, 0, 2,
26                _T("physiqued_Node"), 0, TYPE_INODE,
27                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
28        IPhysiqueInterface::getVertexCount, _T("getVertexCount"), 0, TYPE_INT, 0, 2,
29                _T("physiqued_Node"), 0, TYPE_INODE,
30                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
31
32        IPhysiqueInterface::getInitialNodeTM, _T("getInitialNodeTM"), 0, TYPE_MATRIX3_BV, 0, 2,
33                _T("physiqued_Node"), 0, TYPE_INODE,
34                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
35        IPhysiqueInterface::getInitialBoneTM, _T("getInitialBoneTM"), 0, TYPE_MATRIX3_BV, 0, 3,
36                _T("physiqued_Node"), 0, TYPE_INODE,
37                _T("boneIndex"), 0, TYPE_INDEX,
38                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
39       
40        IPhysiqueInterface::getVertexType, _T("getVertexType"), 0, TYPE_ENUM, IPhysiqueInterface::blendingTypeEnum, 0, 3,
41                _T("physiqued_Node"), 0, TYPE_INODE,
42                _T("vertexIndex"), 0, TYPE_INDEX,
43                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
44        IPhysiqueInterface::getVertexBones, _T("getVertexBones"), 0, TYPE_INODE_TAB_BV, 0, 5,
45                _T("physiqued_Node"), 0, TYPE_INODE,
46                _T("vertexIndex"), 0, TYPE_INDEX,
47                _T("rigid"), 0, TYPE_bool, f_keyArgDefault, true,
48                _T("blending"), 0, TYPE_bool, f_keyArgDefault, true,
49                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
50        IPhysiqueInterface::getVertexBoneCount, _T("getVertexBoneCount"), 0, TYPE_INT, 0, 4,
51                _T("physiquedNode"), 0, TYPE_INODE,
52                _T("vertexIndex"), 0, TYPE_INDEX,
53                _T("rigid"), 0, TYPE_bool, f_keyArgDefault, true,
54                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
55        IPhysiqueInterface::getVertexBone, _T("getVertexBone"), 0, TYPE_INODE, 0, 6,
56                _T("physiqued_Node"), 0, TYPE_INODE,
57                _T("vertexIndex"), 0, TYPE_INDEX,
58                _T("boneIndex"), 0, TYPE_INDEX,
59                _T("rigid"), 0, TYPE_bool, f_keyArgDefault, true,
60                _T("blending"), 0, TYPE_bool, f_keyArgDefault, true,
61                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
62        IPhysiqueInterface::getVertexOffset, _T("getVertexOffset"), 0, TYPE_POINT3_BV, 0, 6,
63                _T("physiqued_Node"), 0, TYPE_INODE,
64                _T("vertexIndex"), 0, TYPE_INDEX,
65                _T("boneIndex"), 0, TYPE_INDEX,
66                _T("rigid"), 0, TYPE_bool, f_keyArgDefault, true,
67                _T("blending"), 0, TYPE_bool, f_keyArgDefault, true,
68                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
69        IPhysiqueInterface::getVertexDeformableOffset, _T("getVertexDeformableOffset"), 0, TYPE_POINT3_BV, 0, 3,
70                _T("physiqued_Node"), 0, TYPE_INODE,
71                _T("vertexIndex"), 0, TYPE_INDEX,
72                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
73        IPhysiqueInterface::getVertexWeight, _T("getVertexWeight"), 0, TYPE_FLOAT, 0, 6,
74                _T("physiqued_Node"), 0, TYPE_INODE,
75                _T("vertexIndex"), 0, TYPE_INDEX,
76                _T("boneIndex"), 0, TYPE_INDEX,
77                _T("rigid"), 0, TYPE_bool, f_keyArgDefault, true,
78                _T("blending"), 0, TYPE_bool, f_keyArgDefault, true,
79                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
80
81        IPhysiqueInterface::setInitialPose, _T("setInitialPose"), 0, TYPE_VOID, 0, 3,
82                _T("physiqued_Node"), 0, TYPE_INODE,
83                _T("state"), 0, TYPE_bool,
84                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
85        IPhysiqueInterface::setFigureMode, _T("setFigureMode"), 0, TYPE_bool, 0, 3,
86                _T("physiqued_Node"), 0, TYPE_INODE,
87                _T("state"), 0, TYPE_bool,
88                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
89
90        IPhysiqueInterface::attachToNode, _T("attachToNode"), 0, TYPE_bool, 0, 3,
91                _T("physiqued_Node"), 0, TYPE_INODE,
92                _T("rootNode"), 0, TYPE_INODE,
93                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
94        IPhysiqueInterface::initialize, _T("initialize"), 0, TYPE_bool, 0, 3,
95                _T("physiqued_Node"), 0, TYPE_INODE,
96                _T("rootNode"), 0, TYPE_INODE,
97                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
98       
99        IPhysiqueInterface::lockVertex, _T("lockVertex"), 0, TYPE_VOID, 0, 3,
100                _T("physiqued_Node"), 0, TYPE_INODE,
101                _T("vertexIndex"), 0, TYPE_INDEX,
102                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
103        IPhysiqueInterface::unlockVertex, _T("unlockVertex"), 0, TYPE_VOID, 0, 3,
104                _T("physiqued_Node"), 0, TYPE_INODE,
105                _T("vertexIndex"), 0, TYPE_INDEX,
106                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
107        IPhysiqueInterface::setVertexBone, _T("setVertexBone"), 0, TYPE_VOID, 0, 6,
108                _T("physiqued_Node"), 0, TYPE_INODE,
109                _T("vertexIndex"), 0, TYPE_INDEX,
110                _T("bone"), 0, TYPE_INODE,
111                _T("weight"), 0, TYPE_FLOAT, f_keyArgDefault, 1.0f,
112                _T("clear"), 0, TYPE_bool, f_keyArgDefault, false,
113                _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL,
114
115//      properties,
116//      ICoreTestInterface::iobjectInterfaceServer, FP_NO_FUNCTION, _T("interfaceServer"), 0, TYPE_IOBJECT,
117        enums,
118        IPhysiqueInterface::blendingTypeEnum, 8,
119                                        _T("rigid_type"), RIGID_TYPE,
120                                        _T("deformable_type"), DEFORMABLE_TYPE,
121                                        _T("blended_type"), BLENDED_TYPE,
122                                        _T("floating_type"), FLOATING_TYPE,
123                                        _T("rigid_non_blended_type"), RIGID_NON_BLENDED_TYPE,
124                                        _T("deformable_non_blended_type"), DEFORMABLE_NON_BLENDED_TYPE,
125                                        _T("rigid_blended_type"), RIGID_BLENDED_TYPE,
126                                        _T("deformable_blended_type"), DEFORMABLE_BLENDED_TYPE,
127        IPhysiqueInterface::interfaceTypeEnum, 1,
128                                        _T("floatingInterface"), FLOATING_TYPE,
129
130        end
131        );
132
133//SDK level methods
134//****************************************************************
135Modifier* IPhysiqueInterface::FindPhysiqueModifier (INode* nodePtr, int modIndex)
136{
137        // Get object from node. Abort if no object.
138        if (!nodePtr) return NULL;
139
140        Object* ObjectPtr = nodePtr->GetObjectRef();
141
142        if (!ObjectPtr ) return NULL;
143       
144        while (ObjectPtr->SuperClassID() == GEN_DERIVOB_CLASS_ID && ObjectPtr)
145        {
146                // Yes -> Cast.
147                IDerivedObject* DerivedObjectPtr = (IDerivedObject *)(ObjectPtr);                               
148                       
149                // Iterate over all entries of the modifier stack.
150                int modStackIndex = 0, phyModIndex = 0;
151               
152                while (modStackIndex < DerivedObjectPtr->NumModifiers())
153                {
154                        // Get current modifier.
155                        Modifier* ModifierPtr = DerivedObjectPtr->GetModifier(modStackIndex);
156
157                        // Is this Physique ?
158                        if (ModifierPtr->ClassID() == Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B))
159                        {
160                                if (phyModIndex >= modIndex)
161                                {
162                                        return ModifierPtr;
163                                }
164                                phyModIndex++;
165                        }
166                        modStackIndex++;
167                }
168                ObjectPtr = DerivedObjectPtr->GetObjRef();
169        }
170
171        // Not found.
172        throw MAXException("No physique modifier found");
173        return NULL;
174}
175
176BOOL IPhysiqueInterface::CheckMatrix(INode* node, ReferenceTarget* mod)
177{
178        if (!mod) mod = FindPhysiqueModifier(node, 0);
179        if (!mod) throw MAXException("No Physique modifier was found on this node");
180       
181        //get a pointer to the export interface
182        IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE);
183
184
185        int version = phyExport->Version();
186       
187        if(version == 30)
188        {
189        //get the node's initial transformation matrix and store it in a matrix3
190                Matrix3 initTM = Matrix3(TRUE);
191                int msg = phyExport->GetInitNodeTM(node, initTM);
192
193                //Release the physique interface
194
195
196                if (msg == NO_MATRIX_SAVED)
197                        return false;
198        }
199
200        mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
201        return true;
202
203
204}
205
206Matrix3 IPhysiqueInterface::GetInitialNodeTM(INode* node, ReferenceTarget* mod)
207{
208
209        if (!mod) mod = FindPhysiqueModifier(node, 0);
210        if (!mod) throw MAXException("No Physique modifier was found on this node");
211       
212        //get a pointer to the export interface
213        IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE);
214
215        //get the node's initial transformation matrix and store it in a matrix3
216        Matrix3 initTM = Matrix3(TRUE);
217        int msg = phyExport->GetInitNodeTM(node, initTM);
218
219        //Release the physique interface
220        mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
221        if (msg != MATRIX_RETURNED)
222        {
223                switch (msg)
224                {
225                        case NODE_NOT_FOUND:
226                                throw MAXException ("Node not found");
227                        case NO_MATRIX_SAVED:
228                                throw MAXException("No matrix saved");
229                        case INVALID_MOD_POINTER:
230                                throw MAXException("Invalid modifier pointer");
231                        default:
232                                break;
233                }
234        }
235
236
237        return initTM;
238}
239
240Matrix3 IPhysiqueInterface::GetInitialBoneTM(INode* node, int index, ReferenceTarget* mod)
241{
242
243        if (!mod) mod = FindPhysiqueModifier(node, 0);
244        if (!mod) throw MAXException("No Physique modifier was found on this node");
245       
246        //get a pointer to the export interface
247        IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE);
248
249        //get the list of bones
250        Tab<INode*> bones = GetBoneList(node);
251        if (index <0 || index >= bones.Count()) throw MAXException("The Bone index is not in the valid range");
252
253        //get the node's initial transformation matrix and store it in a matrix3
254        Matrix3 initTM = Matrix3(TRUE);
255        int msg = phyExport->GetInitNodeTM(bones[index], initTM);
256        //Release the physique interface
257        mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
258       
259        if (msg != MATRIX_RETURNED)
260        {
261                switch (msg)
262                {
263                        case NODE_NOT_FOUND:
264                                throw MAXException ("Node not found");
265                        case NO_MATRIX_SAVED:
266                                throw MAXException("No matrix saved");
267                        case INVALID_MOD_POINTER:
268                                throw MAXException("Invalid modifier pointer");
269                        default:
270                                break;
271                }
272        }
273        return initTM;
274}
275
276int IPhysiqueInterface::GetBoneCount(INode* node, ReferenceTarget* mod)
277{
278        //get the list of bones
279        Tab<INode*> bones = GetBoneList(node, mod);
280        return bones.Count();
281}
282
283
284
285// This function can be used to gather the list of bones used by the modifier
286//****************************************************************************
287Tab<INode*> IPhysiqueInterface::GetBoneList(INode* node, ReferenceTarget* mod)
288{
289        int i = 0, x = 0;
290        Tab<INode*> bones;
291        INode* bone;
292
293        if (!mod) mod = FindPhysiqueModifier(node, 0);
294        if (!mod) throw MAXException("No Physique modifier was found on this node");
295
296        //get a pointer to the export interface
297        IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE);
298
299        //get a pointer to the export context interface
300        IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node);
301
302        //convert to rigid for time independent vertex assignment
303        mcExport->ConvertToRigid(true);
304
305        //allow blending to export multi-link assignments
306        mcExport->AllowBlending(true);
307
308        //These are the different types of vertex classes
309        IPhyBlendedRigidVertex *rb_vtx;
310        IPhyRigidVertex *r_vtx;
311        IPhyFloatingVertex *f_vtx;
312
313        //get the vertex count from the export interface
314        int numverts = mcExport->GetNumberVertices();
315       
316        //iterate through all vertices and gather the bone list
317        for (i = 0; i<numverts; i++)
318        {
319                BOOL exists = false;
320               
321                //get the hierarchial vertex interface
322                IPhyVertexExport* vi = mcExport->GetVertexInterface(i);
323                if (vi) {
324
325                        //check the vertex type and process accordingly
326                        int type = vi->GetVertexType();
327                        switch (type)
328                        {
329                                //The vertex is rigid, blended vertex.  It's assigned to multiple links
330                                case RIGID_BLENDED_TYPE:
331                                        //type-cast the node to the proper class               
332                                        rb_vtx = (IPhyBlendedRigidVertex*)vi;
333                                       
334                                        //iterate through the bones assigned to this vertex
335                                        for (x = 0; x<rb_vtx->GetNumberNodes(); x++)
336                                        {
337                                                exists = false;
338                                                //get the node by index
339                                                bone = rb_vtx->GetNode(x);
340                                               
341                                                //check to see if we already have this bone
342                                                for (int z=0;z<bones.Count();z++)
343                                                        if (bone == bones[z]) exists = true;
344
345                                                //if you didn't find a match add it to the list
346                                                if (!exists) bones.Append(1, &bone);
347                                        }
348                                        break;
349                                //The vertex is a rigid vertex and only assigned to one link
350                                case RIGID_TYPE:
351                                        //type-cast the node to the proper calss
352                                        r_vtx = (IPhyRigidVertex*)vi;
353                                       
354                                        //get the node
355                                        bone = r_vtx->GetNode();
356
357                                        //check to see if the bone is already in the list
358                                        for (x = 0;x<bones.Count();x++)
359                                        {
360                                                if (bone == bones[x]) exists = true;
361                                        }
362                                        //if you didn't find a match add it to the list
363                                        if (!exists) bones.Append(1, &bone);
364                                        break;
365
366                                case FLOATING_TYPE:
367                                        f_vtx = (IPhyFloatingVertex*)mcExport->GetVertexInterface(i);
368                                        for (x = 0; x<f_vtx->GetNumberNodes(); x++)
369                                        {
370                                                exists = false;
371
372                                                 //get the node by index
373                                                bone = f_vtx->GetNode(x);
374                                               
375                                                //check to see if we already have this bone
376                                                for (int z=0;z<bones.Count();z++)
377                                                        if (bone == bones[z]) exists = true;
378
379                                                //if you didn't find a match add it to the list
380                                                if (!exists) bones.Append(1, &bone);
381                                        }
382                                        break;
383       
384                                // Shouldn't make it here because we converted to rigid earlier. 
385                                // It should be one of the above two types
386                                default: break; 
387                        }
388                }
389                 
390        }
391
392        //release the context interface
393        phyExport->ReleaseContextInterface(mcExport);
394
395        //Release the physique interface
396        mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
397
398        return bones;
399}
400
401int IPhysiqueInterface::GetAPIVersion(INode* node, ReferenceTarget* mod)
402{
403        if (!mod) mod = FindPhysiqueModifier(node, 0);
404        if (!mod) throw MAXException("No Physique modifier was found on this node");
405
406        //get a pointer to the export interface
407        IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE);
408        int version = phyExport->Version();
409        mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
410
411        return version;
412}
413
414void IPhysiqueInterface::SetInitialPose(INode* node, bool set, ReferenceTarget* mod)
415{
416        if (!mod) mod = FindPhysiqueModifier(node, 0);
417        if (!mod) throw MAXException("No Physique modifier was found on this node");
418
419        //get a pointer to the export interface
420        IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE);
421
422        phyExport->SetInitialPose(set);
423        ((ReferenceTarget*)mod)->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
424        mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
425}
426
427int IPhysiqueInterface::GetVertexCount(INode* node, ReferenceTarget* mod)
428{
429        if (!mod) mod = FindPhysiqueModifier(node, 0);
430        if (!mod) throw MAXException("No Physique modifier was found on this node");
431
432        //get a pointer to the export interface
433        IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE);
434
435        //get a pointer to the export context interface
436        IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node);
437
438        int vertCount = mcExport->GetNumberVertices();
439
440        phyExport->ReleaseContextInterface(mcExport);
441        mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
442
443        return vertCount;
444}
445
446int IPhysiqueInterface::GetVertexType(INode* node, int vertIndex, ReferenceTarget* mod)
447{
448        if (!mod) mod = FindPhysiqueModifier(node, 0);
449        if (!mod) throw MAXException("No Physique modifier was found on this node");
450
451        //get a pointer to the export interface
452        IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE);
453
454        //get a pointer to the export context interface
455        IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node);
456       
457        IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex);
458        if (!vi)
459        {
460                phyExport->ReleaseContextInterface(mcExport);
461                mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
462                throw MAXException("No vertex interface found");
463        }
464
465        int type = vi->GetVertexType();
466
467        mcExport->ReleaseVertexInterface(vi);
468        phyExport->ReleaseContextInterface(mcExport);
469        mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
470
471        return type;
472}
473
474int IPhysiqueInterface::GetVertexBoneCount(INode* node, int vertIndex, bool rigid, ReferenceTarget* mod)
475{
476        if (!mod) mod = FindPhysiqueModifier(node, 0);
477        if (!mod) throw MAXException("No Physique modifier was found on this node");
478
479        //get a pointer to the export interface
480        IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE);
481
482        //get a pointer to the export context interface
483        IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node);
484
485        if (vertIndex < 0 || vertIndex >= mcExport->GetNumberVertices())
486                throw MAXException("The vertex index is not in the valid range");
487
488        mcExport->ConvertToRigid(rigid);
489        int count = 0;
490
491        IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex);
492        if (vi)
493        {
494                int type = vi->GetVertexType();
495                switch (type)
496                {
497                        case RIGID_NON_BLENDED_TYPE:
498                        case DEFORMABLE_NON_BLENDED_TYPE:
499                                count += 1;
500                                break;
501                        case RIGID_BLENDED_TYPE:
502                                count += ((IPhyBlendedRigidVertex*)vi)->GetNumberNodes();
503                                break;
504                        case DEFORMABLE_BLENDED_TYPE:
505                                throw MAXException("Not a currently supported type");
506                                break;
507                        case FLOATING_TYPE:
508                                count += ((IPhyFloatingVertex*)vi)->GetNumberNodes();
509                                break;
510                }
511
512                mcExport->ReleaseVertexInterface(vi);
513
514        }
515
516        phyExport->ReleaseContextInterface(mcExport);
517        mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
518
519        return count;
520}
521
522Tab<INode*> IPhysiqueInterface::GetVertexBones(INode* node, int vertIndex, bool rigid, bool blending, ReferenceTarget* mod)
523{
524        if (!mod) mod = FindPhysiqueModifier(node, 0);
525        if (!mod) throw MAXException("No Physique modifier was found on this node");
526
527        //get a pointer to the export interface
528        IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE);
529
530        //get a pointer to the export context interface
531        IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node);
532        mcExport->ConvertToRigid(rigid);
533        mcExport->AllowBlending(blending);
534       
535        if (vertIndex < 0 || vertIndex >= mcExport->GetNumberVertices())
536                throw MAXException("The vertex index is not in the valid range");
537
538        INode* bone = NULL;
539        Tab<INode*> bones;
540        bones.ZeroCount();
541        int count = 0, i = 0;
542
543        IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex);
544        if (vi)
545        {
546                int type = vi->GetVertexType();
547                switch (type)
548                {
549                        case RIGID_NON_BLENDED_TYPE:
550                                bone = ((IPhyRigidVertex*)vi)->GetNode();
551                                bones.Append(1, &bone);
552                                break;
553                        case RIGID_BLENDED_TYPE:
554                                count = ((IPhyBlendedRigidVertex*)vi)->GetNumberNodes();
555                                for (i=0;i<count;i++)
556                                {
557                                        bone = ((IPhyBlendedRigidVertex*)vi)->GetNode(i);
558                                        bones.Append(1, &bone);
559                                }
560                                break;
561                        case DEFORMABLE_NON_BLENDED_TYPE:
562                                bone = ((IPhyDeformableOffsetVertex*)vi)->GetNode();
563                                bones.Append(1, &bone);
564                                break;
565                        case DEFORMABLE_BLENDED_TYPE:
566                                throw MAXException("Not a currently supported type");
567                                break;
568                        case FLOATING_TYPE:
569                                count += ((IPhyFloatingVertex*)vi)->GetNumberNodes();
570                                for (i=0;i<count;i++)
571                                {
572                                        bone = ((IPhyFloatingVertex*)vi)->GetNode(i);
573                                        bones.Append(1, &bone);
574                                }
575                                break;
576                }
577
578                mcExport->ReleaseVertexInterface(vi);
579        }
580
581        phyExport->ReleaseContextInterface(mcExport);
582        mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
583       
584        return bones;
585}
586
587INode* IPhysiqueInterface::GetVertexBone(INode* node, int vertIndex, int boneIndex, bool rigid, bool blending, ReferenceTarget* mod)
588{
589        Tab<INode*> bones = GetVertexBones(node, vertIndex, rigid, blending, mod);
590        if (boneIndex < 0 || boneIndex >= bones.Count())
591                throw MAXException("The bone index is not in the valid range");
592
593        return bones[boneIndex];
594}
595
596Point3 IPhysiqueInterface::GetVertexOffset(INode* node, int vertIndex, int boneIndex, bool rigid, bool blending, ReferenceTarget* mod)
597{
598        if (!mod) mod = FindPhysiqueModifier(node, 0);
599        if (!mod) throw MAXException("No Physique modifier was found on this node");
600
601        //get a pointer to the export interface
602        IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE);
603
604        //get a pointer to the export context interface
605        IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node);
606        mcExport->ConvertToRigid(rigid);
607        mcExport->AllowBlending(blending);
608       
609        if (vertIndex < 0 || vertIndex >= mcExport->GetNumberVertices())
610                throw MAXException("The vertex index is not in the valid range");
611
612        Point3 offset = Point3(0,0,0);
613        Tab<Point3> offsetTab;
614        offsetTab.ZeroCount();
615        int count = 0, i = 0;
616
617        IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex);
618        if (vi)
619        {
620                int type = vi->GetVertexType();
621                switch (type)
622                {
623                        case RIGID_NON_BLENDED_TYPE:
624                                offset = ((IPhyRigidVertex*)vi)->GetOffsetVector();
625                                offsetTab.Append(1, &offset);
626                                break;
627                        case RIGID_BLENDED_TYPE:
628                                count = ((IPhyBlendedRigidVertex*)vi)->GetNumberNodes();
629                                for (i=0;i<count;i++)
630                                {
631                                        offset = ((IPhyBlendedRigidVertex*)vi)->GetOffsetVector(i);
632                                        offsetTab.Append(1, &offset);
633                                }
634                                break;
635                        case DEFORMABLE_NON_BLENDED_TYPE:
636                                offset = ((IPhyDeformableOffsetVertex*)vi)->GetOffsetVector();
637                                offsetTab.Append(1, &offset);
638                                break;
639                        case DEFORMABLE_BLENDED_TYPE:
640                                throw MAXException("Not a currently supported type");
641                                break;
642                        case FLOATING_TYPE:
643                                count += ((IPhyFloatingVertex*)vi)->GetNumberNodes();
644                                for (i=0;i<count;i++)
645                                {
646                                        offset = ((IPhyFloatingVertex*)vi)->GetOffsetVector(i);
647                                        offsetTab.Append(1, &offset);
648                                }
649                                break;
650                }
651
652                mcExport->ReleaseVertexInterface(vi);
653
654        }
655
656        phyExport->ReleaseContextInterface(mcExport);
657        mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
658
659        if (boneIndex < 0 || boneIndex >= offsetTab.Count())
660                throw MAXException("The bone index is not in the valid range");
661       
662        return offsetTab[boneIndex];
663}
664
665Point3 IPhysiqueInterface::GetVertexDeformableOffset(INode* node, int vertIndex, ReferenceTarget* mod, TimeValue t)
666{
667        if (!mod) mod = FindPhysiqueModifier(node, 0);
668        if (!mod) throw MAXException("No Physique modifier was found on this node");
669
670        //get a pointer to the export interface
671        IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE);
672
673        //get a pointer to the export context interface
674        IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node);
675       
676        if (vertIndex < 0 || vertIndex >= mcExport->GetNumberVertices())
677                throw MAXException("The vertex index is not in the valid range");
678
679        Point3 offset = Point3(0,0,0);
680
681        IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex);
682        if (vi)
683        {
684                int type = vi->GetVertexType();
685                switch (type)
686                {
687                        case RIGID_NON_BLENDED_TYPE:
688                        case RIGID_BLENDED_TYPE:
689                        case FLOATING_TYPE:
690                                break;
691                        case DEFORMABLE_NON_BLENDED_TYPE:
692                                offset = ((IPhyDeformableOffsetVertex*)vi)->GetDeformOffsetVector(t);
693                                break;
694                        case DEFORMABLE_BLENDED_TYPE:
695                                throw MAXException("Not a currently supported type");
696                                break;
697                }
698                mcExport->ReleaseVertexInterface(vi);
699        }
700
701        phyExport->ReleaseContextInterface(mcExport);
702        mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
703        return offset;
704}
705
706float IPhysiqueInterface::GetVertexWeight(INode* node, int vertIndex, int boneIndex, bool rigid, bool blending, ReferenceTarget* mod)
707{
708        if (!mod) mod = FindPhysiqueModifier(node, 0);
709        if (!mod) throw MAXException("No Physique modifier was found on this node");
710
711        //get a pointer to the export interface
712        IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE);
713
714        //get a pointer to the export context interface
715        IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node);
716        mcExport->ConvertToRigid(rigid);
717        mcExport->AllowBlending(blending);
718       
719        if (vertIndex < 0 || vertIndex >= mcExport->GetNumberVertices())
720                throw MAXException("The vertex index is not in the valid range");
721
722        //Point3 offset = Point3(0,0,0);
723        //Tab<Point3> offsetTab;
724        //offsetTab.ZeroCount();
725        int count = 0, i = 0;
726        float normalizedWeight = 0.0f, totalWeight = 0.0f, weight = 0.0f;
727        float tempFloat;
728
729        IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex);
730        if (vi)
731        {
732                int type = vi->GetVertexType();
733                switch (type)
734                {
735                        case RIGID_NON_BLENDED_TYPE:
736                        case DEFORMABLE_NON_BLENDED_TYPE:
737                                count = 1;
738                                normalizedWeight = 1.0f;
739                                break;
740                        case RIGID_BLENDED_TYPE:
741                                count = ((IPhyBlendedRigidVertex*)vi)->GetNumberNodes();
742                                for (i=0;i<count;i++)
743                                {
744                                        tempFloat = ((IPhyBlendedRigidVertex*)vi)->GetWeight(i);
745                                        if (i == boneIndex) normalizedWeight = tempFloat;
746                                }
747                                break;
748                        case DEFORMABLE_BLENDED_TYPE:
749                                throw MAXException("Not a currently supported type");
750                                break;
751                        case FLOATING_TYPE:
752                                normalizedWeight = 0.0f;
753                                for (i=0;i<((IPhyFloatingVertex*)vi)->GetNumberNodes();i++)
754                                {
755                                        tempFloat = ((IPhyFloatingVertex*)vi)->GetWeight(i, weight);
756                                        if (count + i == boneIndex) normalizedWeight = tempFloat;
757                                        totalWeight += weight;
758                                }
759                                count = count+i;
760
761                                if (totalWeight != 0)
762                                        normalizedWeight = normalizedWeight/totalWeight;
763                                break;
764                }
765
766                mcExport->ReleaseVertexInterface(vi);
767        }
768
769        phyExport->ReleaseContextInterface(mcExport);
770        mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
771
772        if (boneIndex < 0 || boneIndex >= count)
773                throw MAXException("The bone index is not in the valid range");
774       
775        return normalizedWeight;
776}
777
778bool IPhysiqueInterface::SetFigureMode(INode* node, bool state, ReferenceTarget* mod)
779{
780        int i = 0, x = 0;
781        INode* bone;
782
783        if (!mod) mod = FindPhysiqueModifier(node, 0);
784        if (!mod) throw MAXException("No Physique modifier was found on this node");
785
786        IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE);
787        IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node);
788        int numverts = mcExport->GetNumberVertices();
789       
790        for (i = 0; i<numverts; i++)
791        {
792                IPhyVertexExport* vi = mcExport->GetVertexInterface(i);
793                if (vi) {
794                        int type = vi->GetVertexType();
795                        switch (type)
796                        {
797                                case RIGID_BLENDED_TYPE:
798                                        for (x = 0; x<((IPhyBlendedRigidVertex*)vi)->GetNumberNodes(); x++)
799                                        {
800                                                bone = ((IPhyBlendedRigidVertex*)vi)->GetNode(x);
801                                                if (BipedFigureMode(bone, state))
802                                                {
803                                                        mcExport->ReleaseVertexInterface(vi);
804                                                        phyExport->ReleaseContextInterface(mcExport);
805                                                        mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
806                                                        return true;
807                                                }
808
809                                        }
810                                        break;
811                                case RIGID_TYPE:
812                                        bone = ((IPhyRigidVertex*)vi)->GetNode();
813                                        if (BipedFigureMode(bone, state))
814                                        {
815                                                mcExport->ReleaseVertexInterface(vi);
816                                                phyExport->ReleaseContextInterface(mcExport);
817                                                mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
818                                                return true;
819                                        }
820                                        break;
821                                case DEFORMABLE_TYPE:
822                                        bone = ((IPhyDeformableOffsetVertex*)vi)->GetNode();
823                                        if (BipedFigureMode(bone, state))
824                                        {
825                                                mcExport->ReleaseVertexInterface(vi);
826                                                phyExport->ReleaseContextInterface(mcExport);
827                                                mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
828                                                return true;
829                                        }
830                                        break;
831                                case FLOATING_TYPE:
832                                        for (x = 0; x<((IPhyFloatingVertex*)vi)->GetNumberNodes(); x++)
833                                        {
834                                                bone = ((IPhyFloatingVertex*)vi)->GetNode(x);
835                                                if (BipedFigureMode(bone, state))
836                                                {
837                                                        mcExport->ReleaseVertexInterface(vi);
838                                                        phyExport->ReleaseContextInterface(mcExport);
839                                                        mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
840                                                        return true;
841                                                }
842                                        }
843                                        break;
844                                default: break; 
845                        }
846                }
847                mcExport->ReleaseVertexInterface(vi);
848
849        }
850
851        phyExport->ReleaseContextInterface(mcExport);
852        mod->ReleaseInterface(I_PHYINTERFACE, phyExport);
853
854        return false;
855}
856
857bool IPhysiqueInterface::BipedFigureMode(INode* node, bool state)
858{
859        if (node->IsRootNode()) return false;
860
861        Control* c = node->GetTMController();
862    if ((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) ||
863         (c->ClassID() == BIPBODY_CONTROL_CLASS_ID) ||
864         (c->ClassID() == FOOTPRINT_CLASS_ID))
865    {
866        IBipedExport *iBiped = (IBipedExport *) c->GetInterface(I_BIPINTERFACE);
867        if (iBiped)
868                {
869                        //iBiped->RemoveNonUniformScale((BOOL)state);
870                        if (state) iBiped->BeginFigureMode(0);
871                        else iBiped->EndFigureMode(0);
872
873                        Control* iMaster = (Control *) c->GetInterface(I_MASTER);
874                        iMaster->NotifyDependents(FOREVER, PART_TM, REFMSG_CHANGE);
875                       
876                        c->ReleaseInterface(I_MASTER,iMaster);
877                        c->ReleaseInterface(I_BIPINTERFACE,iBiped);
878                        return true;
879                }
880        }
881        return false;
882}
883
884bool IPhysiqueInterface::AttachToNode(INode* node, INode* rootNode, ReferenceTarget* mod, TimeValue t)
885{
886        if (!mod) mod = FindPhysiqueModifier(node, 0);
887        if (!mod) throw MAXException("No Physique modifier was found on this node");
888
889        IPhysiqueImport *phyImport = (IPhysiqueImport *)mod->GetInterface(I_PHYIMPORT);
890        bool val = false;
891        if (phyImport->AttachRootNode(rootNode, t))
892                val = true;
893        mod->ReleaseInterface(I_PHYIMPORT, phyImport);
894        return val;
895}
896
897
898bool IPhysiqueInterface::Initialize(INode* node, INode* rootNode, ReferenceTarget* mod, TimeValue t)
899{
900        if (!mod) mod = FindPhysiqueModifier(node, 0);
901        if (!mod) throw MAXException("No Physique modifier was found on this node");
902
903        IPhysiqueImport *phyImport = (IPhysiqueImport *)mod->GetInterface(I_PHYIMPORT);
904        bool val = false;
905        if (phyImport->InitializePhysique(rootNode, t))
906                val = true;
907        mod->ReleaseInterface(I_PHYIMPORT, phyImport);
908        return val;
909}
910
911void IPhysiqueInterface::LockVertex(INode* node, int vertexIndex, ReferenceTarget* mod)
912{
913        if (!mod) mod = FindPhysiqueModifier(node, 0);
914        if (!mod) throw MAXException("No Physique modifier was found on this node");
915
916        IPhysiqueImport *phyImport = (IPhysiqueImport *)mod->GetInterface(I_PHYIMPORT);
917        IPhyContextImport *mcImport = (IPhyContextImport *)phyImport->GetContextInterface(node);
918        IPhyVertexImport *vi = mcImport->SetVertexInterface(vertexIndex, RIGID_BLENDED_TYPE);
919       
920        vi->LockVertex(TRUE);
921        mcImport->ReleaseVertexInterface(vi);
922        phyImport->ReleaseContextInterface(mcImport);
923        mod->ReleaseInterface(I_PHYIMPORT, phyImport);
924}
925
926void IPhysiqueInterface::UnLockVertex(INode* node, int vertexIndex, ReferenceTarget* mod)
927{
928        if (!mod) mod = FindPhysiqueModifier(node, 0);
929        if (!mod) throw MAXException("No Physique modifier was found on this node");
930
931        IPhysiqueImport *phyImport = (IPhysiqueImport *)mod->GetInterface(I_PHYIMPORT);
932        IPhyContextImport *mcImport = (IPhyContextImport *)phyImport->GetContextInterface(node);
933        IPhyVertexImport *vi = mcImport->SetVertexInterface(vertexIndex, RIGID_BLENDED_TYPE);
934       
935        vi->LockVertex(FALSE);
936        mcImport->ReleaseVertexInterface(vi);
937        phyImport->ReleaseContextInterface(mcImport);
938        mod->ReleaseInterface(I_PHYIMPORT, phyImport);
939}
940
941void IPhysiqueInterface::SetVertexBone(INode* node, int vertexIndex, INode* bone, float weight, bool clear, ReferenceTarget* mod)
942{
943        if (!mod) mod = FindPhysiqueModifier(node, 0);
944        if (!mod) throw MAXException("No Physique modifier was found on this node");
945
946        IPhysiqueImport *phyImport = (IPhysiqueImport *)mod->GetInterface(I_PHYIMPORT);
947        IPhyContextImport *mcImport = (IPhyContextImport *)phyImport->GetContextInterface(node);
948        IPhyVertexImport *viImport = mcImport->SetVertexInterface(vertexIndex, RIGID_BLENDED_TYPE);
949       
950        int numverts = mcImport->GetNumberVertices();
951       
952        if (!clear)  //if you don't clear it check to see if it already exists
953        {
954                Tab<INode*> bones = GetVertexBones(node, vertexIndex, true, true, mod);
955                Tab<float> weights;
956                weights.ZeroCount();
957                bool exists = false;
958                int i;
959
960                for(i=0;i<bones.Count();i++)
961                {
962                        if (bone == bones[i])
963                        {
964                                exists = true;
965                                break;
966                        }
967                }
968                if (exists)
969                {
970                        //store the weights
971                        for(i=0;i<bones.Count();i++)
972                        {
973                                float curWeight = GetVertexWeight(node, vertexIndex, i, true, true, mod);
974                                weights.Append(1, &weight);
975                        }
976                        for(i=0;i<bones.Count();i++)
977                        {
978                                bool tempClear = false;
979                                if (i==0)
980                                        tempClear = true; //clear the first time through
981                                float curWeight;
982                                if (bone == bones[i])
983                                        curWeight = weight;
984                                else curWeight = weights[i];
985
986                                //int type = viImport->GetVertexType();
987                                ((IPhyBlendedRigidVertexImport*)viImport)->SetWeightedNode(bone, curWeight, tempClear);
988                        }
989                }
990                else
991                {
992                        ((IPhyBlendedRigidVertexImport*)viImport)->SetWeightedNode(bone, weight, FALSE);
993                }
994        }
995        else ((IPhyBlendedRigidVertexImport*)viImport)->SetWeightedNode(bone, weight, TRUE);
996       
997        mcImport->ReleaseVertexInterface(viImport);
998        phyImport->ReleaseContextInterface(mcImport);
999        mod->ReleaseInterface(I_PHYIMPORT, phyImport);
1000}
1001
Note: See TracBrowser for help on using the repository browser.