Phyexp.h

Go to the documentation of this file.
00001 /******************************************************************************
00002  *<
00003     FILE: PhyExp.h
00004                   
00005     DESCRIPTION:  Export Interface Functionality for Physique
00006 
00007     CREATED BY: John Chadwick with a lot of help from Jurie Horneman
00008 
00009     HISTORY: created July 10, 1997, modified for Version 2.0 March 5, 1998
00010 
00011  *>     Copyright (c) Unreal Pictures, Inc. 1997, 1998 All Rights Reserved.
00012  *******************************************************************************/
00013 #pragma once
00014 
00015 #include "..\maxheap.h"
00016 #include "..\modstack.h"
00017 
00018 #ifdef BLD_PHYSIQUE
00019 #define PHYExport __declspec( dllexport )
00020 #else
00021 #define PHYExport __declspec( dllimport )
00022 #endif
00023 
00024 // this is the interface ID for a Physique Modifier Interface
00025 #define I_PHYINTERFACE 0x00100100
00026 #define I_PHYEXPORT 0x00100100 
00027 #define I_PHYIMPORT 0x00100101
00028 
00029 //return values for GetInitNodeTM
00030 #define MATRIX_RETURNED     0
00031 #define NODE_NOT_FOUND      1
00032 #define NO_MATRIX_SAVED     2
00033 #define INVALID_MOD_POINTER 3
00034 
00035 // version control 
00036 #define CURRENT_VERSION 313
00037 
00038 
00039 // these are the Class ID defines for Physique Modifier: 
00040 // Physique Class_ID = ClassID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B);
00041 #define PHYSIQUE_CLASS_ID_A 0x00100
00042 #define PHYSIQUE_CLASS_ID_B 0x00000
00043 
00044 
00045 #define RIGID_TYPE      1
00046 #define DEFORMABLE_TYPE 2
00047 #define BLENDED_TYPE    4   
00048 #define FLOATING_TYPE   8   
00049 
00050 #define RIGID_NON_BLENDED_TYPE      (RIGID_TYPE)
00051 #define DEFORMABLE_NON_BLENDED_TYPE (DEFORMABLE_TYPE)
00052 #define RIGID_BLENDED_TYPE          (RIGID_TYPE | BLENDED_TYPE)
00053 #define DEFORMABLE_BLENDED_TYPE     (DEFORMABLE_TYPE | BLENDED_TYPE)
00054 
00055 // NOTE: for Character Studio 2.1 Deformable Offset Vertices and Vertex Assignment 
00056 // Import has been added.  These classes and descriptions follow the standard Rigid
00057 // Export functionality at the end of this file.
00058 
00059 
00060 // Using the Physique Export Interface:
00061 // 
00062 //  1.  Find the Physique Modifier you which to export rigid vertex assignments from.
00063 //      (there is a comment at the bottom of this file giving an example of this)
00064 //
00065 //  2.  Given Physique Modifier Modifier *phyMod get the Physique Export Interface:
00066 //      IPhysiqueExport *phyExport = (IPhysqiueExport *)phyMod->GetInterface(I_PHYINTERFACE);       
00067 //
00068 //  3.  For a given Object's INode get this ModContext Interface from the Physique Export Interface:
00069 //      IPhyContextExport *contextExport = (IPhyContextExport *)phyExport->GetContextInterface(INode* nodePtr);
00070 //
00071 //  4.  For each vertex of the Object get the Vertex Interface from the ModContext Export Interface:
00072 //      IPhyVertexExport *vtxExport = (IPhyVertexExport *)contextExport->GetVertexInterface(int i); 
00073 //      NOTE: only Rigid Vertices are currently supported: (see ConvertToRigid(TRUE) to make all vertices rigid)
00074 //      IPhyRigidVertex *rigidExport = (IPhyRigidVertex *)contextExport->GetVertexInterface(int i);
00075 //
00076 //  5.  Get the INode for each Rigid Vertex Interface:
00077 //      INode *nodePtr = rigidExport->GetNode();
00078 //
00079 //  6.  Get the Point3 Offset Vector in INode coordinates for each Rigid Vertex Interface:
00080 //      Point3 offsetVector = rigidExport->GetOffsetVector();
00081 
00082 
00083 
00084 
00085 
00086 // IPhyVertexExport: this is the base class for Vertex Export Interface
00087 //                   NOTE: currently only RIGID_TYPE vertices are supported (IPhyRigidVertex)
00088 //                   When a vertex is not assigned Rigid in Physique, the VertexInterface will be NULL
00089 //                   Unless you call IPhyContextExport->ConvertToRigid(TRUE) (see IPhyContextExport below)
00090 //                   With ConvertToRigid(TRUE) you will always get a IPhyRigidVertex 
00091 //                   from IPhyContextExport->GetVertexInterface(i) 
00092 
00093 class IPhyFloatingVertex;
00094 
00095 class IPhyVertexExport: public MaxHeapOperators
00096 {
00097     public:
00098 
00099         PHYExport virtual ~IPhyVertexExport() {}
00100 
00101         // NOTE: currently only type RIGID_TYPE | RIGID_BLENDED_TYPE are supported
00102         PHYExport virtual int GetVertexType() = 0;
00103 
00104         PHYExport virtual INT_PTR Execute(int cmd, ULONG_PTR arg1=0, ULONG_PTR arg2=0, ULONG_PTR arg3=0) = 0;
00105         
00106 };
00107 
00108 
00109 
00110 class IPhyRigidVertex : public IPhyVertexExport
00111 {
00112     public:
00113 
00114         PHYExport virtual ~IPhyRigidVertex() {}
00115 
00116         // GetNode() will return the INode pointer of the link of the given VertexInterface
00117         PHYExport virtual INode *GetNode() = 0;
00118 
00119         // GetOffsetVector() will return the coordinates of the vertex 
00120         // in the local coordinates of associated INode pointer from GetNode
00121         // this is NOT THE SAME as the .vph file coordinates. (It is simpler)
00122         // the world coordinates of the vertex have been transformed by the Inverse of the INode pointer.
00123         PHYExport virtual Point3 GetOffsetVector() = 0;
00124 
00125         PHYExport virtual INT_PTR Execute(int cmd, ULONG_PTR arg1=0, ULONG_PTR arg2=0, ULONG_PTR arg3=0) = 0;
00126         
00127 };
00128 
00129 class IPhyBlendedRigidVertex : public IPhyVertexExport
00130 {
00131     public:
00132 
00133         PHYExport virtual ~IPhyBlendedRigidVertex() {}
00134 
00135         // GetNumberNodes() returns the number of nodes assigned to the given VertexInterface
00136         PHYExport virtual int GetNumberNodes() = 0;
00137 
00138         // GetNode(i) will return the i'th INode pointer of the link of the given VertexInterface
00139         PHYExport virtual INode *GetNode(int i) = 0;
00140 
00141         // GetOffsetVector(i) will return the coordinates of the vertex 
00142         // in the local coordinates of associated i'th INode pointer from GetNode(i)
00143         // this is NOT THE SAME as the .vph file coordinates. (It is simpler)
00144         // the world coordinates of the vertex have been transformed by the Inverse of the INode pointer.
00145         PHYExport virtual Point3 GetOffsetVector(int i) = 0;
00146 
00147         // GetWeight(i) will return the weight of the vertex associated with the i'th Node
00148         // pointer from GetNode(i)
00149         PHYExport virtual float GetWeight(int i) = 0;
00150 
00151         PHYExport virtual INT_PTR Execute(int cmd, ULONG_PTR arg1=0, ULONG_PTR arg2=0, ULONG_PTR arg3=0) = 0;
00152 
00153 };
00154 
00155 
00156 
00157 
00158 
00159 // IPhyContextExport: This class can be returned by :
00160 // passing the INode pointer of an Object with the given Physique Modifier's IPhysiqueExport::GetContextInterface(node)
00161 // If this Node does contain the Physique Modifier associated with this interface an interface to this object's
00162 // interface is returned (several object's may share the same physique modifier), else returns NULL.
00163 
00164 class IPhyContextExport: public MaxHeapOperators
00165 {
00166     public:
00167 
00168         PHYExport virtual ~IPhyContextExport() {}
00169         
00170         // this returns the number of vertices for the given modContext's Object
00171         PHYExport virtual int GetNumberVertices() = 0;
00172 
00173         // If ConvertToRigid is set to TRUE, all GetVertexInterface calls will be IPhyRigidVertex OR IPhyBlendedRigidVertex.
00174         // Vertices which are not Rigid in Physique will be converted to Rigid for the VertexInterface.
00175         // When ConvertToRigid is set to FALSE, GetVertexInterface for non-Rigid vertices currently returns NULL.
00176         // By default, if you do not call ConvertToRigid, it is set to FALSE.
00177         PHYExport virtual void ConvertToRigid(BOOL flag = TRUE) = 0;
00178 
00179         // If AllowBlending is set to FALSE then GetVertexInterface will return a non-blended subclass.
00180         // Currently the only valid VertexInterface subclasses are IPhyRigidVertex, and IPhyBlendedRigidVertex.
00181         // When AllowBlending is FALSE, either IPhyRigidVertex or NULL will be returned.
00182         // If ConvertToRigid is TRUE and AllowBlending is FALSE, all vertices will return
00183         // IPhyRigidVertex. By default AllowBlending is set to TRUE.
00184         PHYExport virtual void AllowBlending(BOOL flag = TRUE) = 0;
00185 
00186         // GetVertexInterface return's a VertexInterface (IPhyVertexExport *) for the i'th vertex.
00187         // If ConvertToRigid has been set to TRUE, then all VertexInterfaces will return IPhyRigidVertex OR IPhyBlendedRigidVertex.
00188         // When ConvertToRigid has been set to FALSE, non-Rigid vertices will return NULL (CURRENTLY).
00189         PHYExport virtual IPhyVertexExport *GetVertexInterface(int i) = 0;
00190 
00191         // You must call ReleaseVertexInterface to delete the VertexInterface when finished with it.
00192         PHYExport virtual void ReleaseVertexInterface(IPhyVertexExport *vertexExport) = 0;
00193 
00194         PHYExport virtual INT_PTR Execute(int cmd, ULONG_PTR arg1=0, ULONG_PTR arg2=0, ULONG_PTR arg3=0) = 0;
00195 
00196         PHYExport virtual IPhyFloatingVertex *GetFloatingVertexInterface(int i) = 0;
00197 };
00198 
00199 // IPhysiqueExport: This class can be returned by calling the method GetInterface() for a Physique Modifier
00200 // given Modifier *mod points to a Physique Modifier, then:
00201 // IPhysiqueExport *phyInterface = (IPhysiqueExport *)( mod->GetInterface(I_PHYINTERFACE) );
00202 // will return the interface for this Physique Modifier, else returns NULL.
00203 
00204 class IPhysiqueExport: public MaxHeapOperators
00205 {
00206 
00207     public:
00208 
00209         PHYExport virtual ~IPhysiqueExport() {}
00210 
00211         //GetContextInterface will return a pointer to IPhyContextExport Interface for a given INode.
00212         // Ff the given INode does not contain the Physique Modifier of this IPhysique Export then NULL is returned.
00213         PHYExport virtual IPhyContextExport *GetContextInterface(INode* nodePtr) = 0;
00214 
00215         // You must call ReleaseContextInterface to delete the COntextInterface when finished with it.
00216         PHYExport virtual void ReleaseContextInterface(IPhyContextExport *contextExport) = 0;
00217 
00218         PHYExport virtual int GetInitNodeTM(INode *node, Matrix3 &initNodeTM) = 0;
00219 
00220         PHYExport virtual INT_PTR Execute(int cmd, ULONG_PTR arg1=0, ULONG_PTR arg2=0, ULONG_PTR arg3=0) = 0;
00221 
00222         PHYExport virtual int Version(void) = 0;
00223 
00224         PHYExport virtual void SetInitialPose(bool set) = 0;
00225 };
00226 
00227 // example code to find if a given node contains a Physique Modifier
00228 // DerivedObjectPtr requires you include "modstack.h" from the MAX SDK
00229 /*
00230 Modifier* FindPhysiqueModifier (INode* nodePtr)
00231 {
00232     Object* ObjectPtr = nodePtr->GetObjectRef();
00233 
00234     if (!ObjectPtr ) return NULL;
00235     
00236     while (ObjectPtr->SuperClassID() == GEN_DERIVOB_CLASS_ID && ObjectPtr)
00237     {
00238             // Yes -> Cast.
00239             IDerivedObject* DerivedObjectPtr = (IDerivedObject *)(ObjectPtr);               
00240             
00241         // Iterate over all entries of the modifier stack.
00242         int ModStackIndex = 0;
00243 
00244         while (ModStackIndex < DerivedObjectPtr->NumModifiers())
00245         {
00246             // Get current modifier.
00247             Modifier* ModifierPtr = DerivedObjectPtr->GetModifier(ModStackIndex);
00248 
00249             // Is this Physique ?
00250             if (ModifierPtr->ClassID() == Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B))
00251             {
00252                 // is this the correct Physique Modifier based on index?
00253                 SkinMod *phyMod = (SkinMod *)ModifierPtr;
00254                 
00255                 if (phyMod == mod)
00256                 {
00257                     ModContext *mc = DerivedObjectPtr->GetModContext(ModStackIndex);
00258                 }
00259             }
00260 
00261                 ModStackIndex++;
00262         }
00263 
00264         ObjectPtr = DerivedObjectPtr->GetObjRef();
00265     }
00266 
00267     // Not found.
00268     return NULL;
00269 }
00270 */
00271 
00272 
00273 // Deformable Vertex Export via Offset Vectors
00274 //
00275 // Character Studio 2.1 allows users to export Deformable Vertices
00276 // as time frame offsets from a rigid node offset
00277 // The Rigid Offset Vector is identical to the Rigid Vertex Offset Vector.
00278 // This represents the vertex in local coordinates from the attached node.
00279 // Note that since the deformable offset is relative to a single node,
00280 // Blending between links is handled internal to Physique in determining
00281 // this offset, so that the export is a single offset for a given time
00282 // for a single Node.
00283 // Basically, you export a deformable offset from a single node, while
00284 // Physique uses blending between several deformable links to determine
00285 // this offset.
00286 // NOTE: while the Rigid Vertex and Rigid Blended Vertex Export require
00287 // a one time export for replicating the deformabion internal to the game engine,
00288 // the Deformable Offset Vertex Export requires the export of DeformVertexOffset(t)
00289 // at several (or every) frame.
00290 
00291 class IPhyDeformableOffsetVertex : public IPhyVertexExport
00292 {
00293     public:
00294 
00295         PHYExport virtual ~IPhyDeformableOffsetVertex() {}
00296 
00297         // GetNode() will return the INode pointer of the link of the given VertexInterface
00298         PHYExport virtual INode *GetNode() = 0;
00299 
00300         // GetOffsetVector() will return the coordinates of the undeformed vertex 
00301         // in the local coordinates of associated INode pointer from GetNode().
00302         // This is IDENTICAL to the Rigid Non Blended OffsetVector.
00303         // It represents the Vertex in the local coordinates of the node via GetNode().
00304         PHYExport virtual Point3 GetOffsetVector() = 0;
00305 
00306         // GetDeformOffsetVector(t) will return the coorinates of the deformed vertex
00307         // in the local coordinates of the associated INode pointer from GetNode().
00308         // Game Developers wishing to store relative offsets can subtract the
00309         // Deformable Offsets for given frames from the Base Offset Vector.
00310         PHYExport virtual Point3 GetDeformOffsetVector(TimeValue t) = 0;
00311 
00312         PHYExport virtual INT_PTR Execute(int cmd, ULONG_PTR arg1=0, ULONG_PTR arg2=0, ULONG_PTR arg3=0) = 0;
00313         
00314 };
00315 
00316 
00317 
00318 
00319 
00320 // Import Interface Functionality for Physique
00321 //
00322 // Character Studio 2.1 allows users to programatically set the Rigid
00323 // Vertex Assignments (with or without Blending) via Import Interface
00324 
00325 
00326 // IPhyVertexImport: this is the base class for Vertex Export Interface
00327 //                   NOTE: currently only RIGID_TYPE vertices are supported (IPhyRigidVertex)
00328 //                   When a vertex is not assigned Rigid in Physique, the VertexInterface will be NULL
00329 //                   Unless you call IPhyContextExport->ConvertToRigid(TRUE) (see IPhyContextExport below)
00330 //                   With ConvertToRigid(TRUE) you will always get a IPhyRigidVertex 
00331 //                   from IPhyContextExport->GetVertexInterface(i) 
00332 
00333 class IPhyVertexImport: public MaxHeapOperators
00334 {
00335     public:
00336 
00337         PHYExport virtual ~IPhyVertexImport() {}
00338 
00339         // NOTE: currently only type RIGID_TYPE | RIGID_BLENDED_TYPE are supported
00340         PHYExport virtual int GetVertexType() = 0;
00341 
00342         // You can lock (TRUE) or unlock (FALSE) vertex assignments
00343         // To avoid changes to manual vertex assignments locking prevents
00344         // these vertices from being reinitialized by Physique.
00345         PHYExport virtual void LockVertex(BOOL lock) = 0;
00346 
00347         PHYExport virtual INT_PTR Execute(int cmd, ULONG_PTR arg1=0, ULONG_PTR arg2=0, ULONG_PTR arg3=0) = 0;
00348 };
00349 
00350 
00351 
00352 class IPhyRigidVertexImport : public IPhyVertexImport
00353 {
00354     public:
00355 
00356         PHYExport virtual ~IPhyRigidVertexImport() {}
00357 
00358         // SetNode() will define the INode pointer of the link of the given Rigid Vertex Interface
00359         // If this INode is a valid Physique Link SetNode returns TRUE, and this vertex is
00360         // now assigned Rigid (NonBlended) to this INode.
00361         // If this INode is not a valid Physique Link, then SetNode returns FALSE,
00362         // and no change to the vertex assignment occurs.
00363         PHYExport virtual BOOL SetNode(INode *nodePtr) = 0;
00364 
00365         PHYExport virtual INT_PTR Execute(int cmd, ULONG_PTR arg1=0, ULONG_PTR arg2=0, ULONG_PTR arg3=0) = 0;
00366 
00367 };
00368 
00369 class IPhyBlendedRigidVertexImport : public IPhyVertexImport
00370 {
00371     public:
00372 
00373         PHYExport virtual ~IPhyBlendedRigidVertexImport() {}
00374 
00375         // SetWeightedNode will assign the given vertex to the nodePtr with the weight specified.
00376         // When init = TRUE, this will remove all existing asignments and define this nodePtr
00377         // as the first and only nodePtr assigned to the given vertex.  When init = FALSE this
00378         // nodePtr and weight are appeneded to the current assignments.
00379         // Always set init = TRUE for the first nodePtr and weight for a given vertex
00380         // and init = FALSE for all additional 2nd thru Nth nodeptr and weights.
00381         // SetWeightedNode returns the number of Nodes assigned to the given Vertex
00382         // when set successfully, or when the given nodePtr is not a valid Physique Link
00383         // SetWeightedNode returns 0.
00384         PHYExport virtual int SetWeightedNode(INode *nodePtr, float weight, BOOL init = FALSE) = 0;
00385 
00386         PHYExport virtual INT_PTR Execute(int cmd, ULONG_PTR arg1=0, ULONG_PTR arg2=0, ULONG_PTR arg3=0) = 0;
00387 
00388 };
00389 
00390 
00391 
00392 class IPhyContextImport: public MaxHeapOperators
00393 {
00394     public:
00395 
00396         PHYExport virtual ~IPhyContextImport() {}
00397         
00398         // this returns the number of vertices for the given modContext's Object
00399         PHYExport virtual int GetNumberVertices() = 0;
00400 
00401         // SetVertexInterface return's a VertexInterface (IPhyVertexImport *) for the i'th vertex.
00402         // type = RIGID_NON_BLENDED_TYPE | RIGID_BLENDED_TYPE are currently supported.
00403         // Any other value for type will return NULL.
00404         
00405         PHYExport virtual IPhyVertexImport *SetVertexInterface(int i, int type) = 0;
00406 
00407         // You must call ReleaseVertexInterface to delete the VertexInterface when finished with it.
00408         PHYExport virtual void ReleaseVertexInterface(IPhyVertexImport *vertexImport) = 0;
00409 
00410         PHYExport virtual INT_PTR Execute(int cmd, ULONG_PTR arg1=0, ULONG_PTR arg2=0, ULONG_PTR arg3=0) = 0;
00411 
00412 };
00413 
00414 
00415 class IPhysiqueImport: public MaxHeapOperators
00416 {
00417     public:
00418         
00419         PHYExport virtual ~IPhysiqueImport() {}
00420 
00421         //GetContextInterface will return a pointer to IPhyContextImport Interface for a given INode.
00422         // if the given INode does not contain the Physique Modifier of this IPhysique Import then NULL is returned.
00423         PHYExport virtual IPhyContextImport *GetContextInterface(INode* nodePtr) = 0;
00424 
00425         // You must call ReleaseContextInterface to delete the ContextInterface when finished with it.
00426         PHYExport virtual void ReleaseContextInterface(IPhyContextImport *contextImport) = 0;
00427 
00428         // You call AttachRootNode to define the root node of the Physique Modifier
00429         // This will create default vertex assignments.
00430         // You MUST call AttachRootNode prior to any Imported Vertex Assignments
00431         // This method is designed specifically for developers wanting to 
00432         // define Physique fully via import.  Predictable results should only be
00433         // expected when this call is followed by a series of Vertex Import calls
00434         // for every ModContext and Vertex of the Modifier.
00435         // If the attach is successful it returns TRUE, otherwise it returns FALSE.
00436         // TimeValue t specifies the initial skeleton pose, the position of the
00437         // skeleton relative to the Object Geometry.
00438         PHYExport virtual BOOL AttachRootNode(INode *nodePtr, TimeValue t) = 0;
00439 
00440         PHYExport virtual BOOL InitializePhysique(INode *nodePtr, TimeValue t) = 0;
00441 
00442         PHYExport virtual INT_PTR Execute(int cmd, ULONG_PTR arg1=0, ULONG_PTR arg2=0, ULONG_PTR arg3=0) = 0;
00443         
00444 };
00445 
00446 class IPhyFloatingVertex : public IPhyVertexExport
00447 {
00448     public:
00449 
00450         PHYExport virtual ~IPhyFloatingVertex() {}
00451 
00452         PHYExport virtual int GetNumberNodes() = 0;
00453         PHYExport virtual INode *GetNode(int i) = 0;
00454         PHYExport virtual float GetWeight(int i, float &totalweight) = 0;
00455         PHYExport virtual Point3 GetOffsetVector(int i) = 0;
00456         PHYExport virtual INT_PTR Execute(int cmd, ULONG_PTR arg1=0, ULONG_PTR arg2=0, ULONG_PTR arg3=0) = 0;
00457 
00458         // GetNumberNodes() returns the number of nodes (bones) assigned to the given Vertex
00459         
00460         // GetNode(i) will return the INode pointer of the ith node assigned to
00461         //this Vertex
00462 
00463         // GetOffsetVector(i) will return the coordinates of the vertex 
00464         // in the local coordinates of associated i'th INode pointer from GetNode(i)
00465         // this is NOT THE SAME as the .vph file coordinates. (It is simpler)
00466         // the world coordinates of the vertex have been transformed by the Inverse of the INode pointer.
00467         
00468         // GetWeight(i) will return the normalized weight of the vertex associated with the i'th Node
00469         // pointer from GetNode(i)
00470     
00471 };
00472 
00473 
00474 
00475