483 lines
18 KiB
C++
Executable File
483 lines
18 KiB
C++
Executable File
/******************************************************************************
|
|
*<
|
|
FILE: PhyExp.h
|
|
|
|
DESCRIPTION: Export Interface Functionality for Physique
|
|
|
|
CREATED BY: John Chadwick with a lot of help from Jurie Horneman
|
|
|
|
HISTORY: created July 10, 1997, modified for Version 2.0 March 5, 1998
|
|
|
|
*> Copyright (c) Unreal Pictures, Inc. 1997, 1998 All Rights Reserved.
|
|
*******************************************************************************/
|
|
|
|
// This header file is included in CS3.2.
|
|
|
|
// Plugins compiled with this header are incompatible with CS3.0, CS3.01, CS3.1, and CS3.1.1
|
|
|
|
#ifndef PHYEXP_H
|
|
#define PHYEXP_H
|
|
|
|
#ifdef BLD_PHYSIQUE
|
|
#define PHYExport __declspec( dllexport )
|
|
#else
|
|
#define PHYExport __declspec( dllimport )
|
|
#endif
|
|
|
|
#include "max.h"
|
|
#include "modstack.h"
|
|
|
|
// this is the interface ID for a Physique Modifier Interface
|
|
#define I_PHYINTERFACE 0x00100100
|
|
#define I_PHYEXPORT 0x00100100
|
|
#define I_PHYIMPORT 0x00100101
|
|
|
|
//return values for GetInitNodeTM
|
|
#define MATRIX_RETURNED 0
|
|
#define NODE_NOT_FOUND 1
|
|
#define NO_MATRIX_SAVED 2
|
|
#define INVALID_MOD_POINTER 3
|
|
|
|
// version control
|
|
#define CURRENT_VERSION 313
|
|
|
|
|
|
// these are the Class ID defines for Physique Modifier:
|
|
// Physique Class_ID = ClassID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B);
|
|
#define PHYSIQUE_CLASS_ID_A 0x00100
|
|
#define PHYSIQUE_CLASS_ID_B 0x00000
|
|
|
|
|
|
#define RIGID_TYPE 1
|
|
#define DEFORMABLE_TYPE 2
|
|
#define BLENDED_TYPE 4
|
|
#define FLOATING_TYPE 8
|
|
|
|
#define RIGID_NON_BLENDED_TYPE (RIGID_TYPE)
|
|
#define DEFORMABLE_NON_BLENDED_TYPE (DEFORMABLE_TYPE)
|
|
#define RIGID_BLENDED_TYPE (RIGID_TYPE | BLENDED_TYPE)
|
|
#define DEFORMABLE_BLENDED_TYPE (DEFORMABLE_TYPE | BLENDED_TYPE)
|
|
|
|
// NOTE: for Character Studio 2.1 Deformable Offset Vertices and Vertex Assignment
|
|
// Import has been added. These classes and descriptions follow the standard Rigid
|
|
// Export functionality at the end of this file.
|
|
|
|
|
|
// Using the Physique Export Interface:
|
|
//
|
|
// 1. Find the Physique Modifier you which to export rigid vertex assignments from.
|
|
// (there is a comment at the bottom of this file giving an example of this)
|
|
//
|
|
// 2. Given Physique Modifier Modifier *phyMod get the Physique Export Interface:
|
|
// IPhysiqueExport *phyExport = (IPhysqiueExport *)phyMod->GetInterface(I_PHYINTERFACE);
|
|
//
|
|
// 3. For a given Object's INode get this ModContext Interface from the Physique Export Interface:
|
|
// IPhyContextExport *contextExport = (IPhyContextExport *)phyExport->GetContextInterface(INode* nodePtr);
|
|
//
|
|
// 4. For each vertex of the Object get the Vertex Interface from the ModContext Export Interface:
|
|
// IPhyVertexExport *vtxExport = (IPhyVertexExport *)contextExport->GetVertexInterface(int i);
|
|
// NOTE: only Rigid Vertices are currently supported: (see ConvertToRigid(TRUE) to make all vertices rigid)
|
|
// IPhyRigidVertex *rigidExport = (IPhyRigidVertex *)contextExport->GetVertexInterface(int i);
|
|
//
|
|
// 5. Get the INode for each Rigid Vertex Interface:
|
|
// INode *nodePtr = rigidExport->GetNode();
|
|
//
|
|
// 6. Get the Point3 Offset Vector in INode coordinates for each Rigid Vertex Interface:
|
|
// Point3 offsetVector = rigidExport->GetOffsetVector();
|
|
|
|
|
|
|
|
|
|
|
|
// IPhyVertexExport: this is the base class for Vertex Export Interface
|
|
// NOTE: currently only RIGID_TYPE vertices are supported (IPhyRigidVertex)
|
|
// When a vertex is not assigned Rigid in Physique, the VertexInterface will be NULL
|
|
// Unless you call IPhyContextExport->ConvertToRigid(TRUE) (see IPhyContextExport below)
|
|
// With ConvertToRigid(TRUE) you will always get a IPhyRigidVertex
|
|
// from IPhyContextExport->GetVertexInterface(i)
|
|
|
|
class IPhyFloatingVertex;
|
|
|
|
class IPhyVertexExport
|
|
{
|
|
public:
|
|
|
|
PHYExport virtual ~IPhyVertexExport() {}
|
|
|
|
// NOTE: currently only type RIGID_TYPE | RIGID_BLENDED_TYPE are supported
|
|
PHYExport virtual int GetVertexType() = 0;
|
|
|
|
PHYExport virtual int Execute(int cmd, ULONG arg1=0, ULONG arg2=0, ULONG arg3=0) = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
class IPhyRigidVertex : public IPhyVertexExport
|
|
{
|
|
public:
|
|
|
|
PHYExport virtual ~IPhyRigidVertex() {}
|
|
|
|
// GetNode() will return the INode pointer of the link of the given VertexInterface
|
|
PHYExport virtual INode *GetNode() = 0;
|
|
|
|
// GetOffsetVector() will return the coordinates of the vertex
|
|
// in the local coordinates of associated INode pointer from GetNode
|
|
// this is NOT THE SAME as the .vph file coordinates. (It is simpler)
|
|
// the world coordinates of the vertex have been transformed by the Inverse of the INode pointer.
|
|
PHYExport virtual Point3 GetOffsetVector() = 0;
|
|
|
|
PHYExport virtual int Execute(int cmd, ULONG arg1=0, ULONG arg2=0, ULONG arg3=0) = 0;
|
|
|
|
};
|
|
|
|
class IPhyBlendedRigidVertex : public IPhyVertexExport
|
|
{
|
|
public:
|
|
|
|
PHYExport virtual ~IPhyBlendedRigidVertex() {}
|
|
|
|
// GetNumberNodes() returns the number of nodes assigned to the given VertexInterface
|
|
PHYExport virtual int GetNumberNodes() = 0;
|
|
|
|
// GetNode(i) will return the i'th INode pointer of the link of the given VertexInterface
|
|
PHYExport virtual INode *GetNode(int i) = 0;
|
|
|
|
// GetOffsetVector(i) will return the coordinates of the vertex
|
|
// in the local coordinates of associated i'th INode pointer from GetNode(i)
|
|
// this is NOT THE SAME as the .vph file coordinates. (It is simpler)
|
|
// the world coordinates of the vertex have been transformed by the Inverse of the INode pointer.
|
|
PHYExport virtual Point3 GetOffsetVector(int i) = 0;
|
|
|
|
// GetWeight(i) will return the weight of the vertex associated with the i'th Node
|
|
// pointer from GetNode(i)
|
|
PHYExport virtual float GetWeight(int i) = 0;
|
|
|
|
PHYExport virtual int Execute(int cmd, ULONG arg1=0, ULONG arg2=0, ULONG arg3=0) = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// IPhyContextExport: This class can be returned by :
|
|
// passing the INode pointer of an Object with the given Physique Modifier's IPhysiqueExport::GetContextInterface(node)
|
|
// If this Node does contain the Physique Modifier associated with this interface an interface to this object's
|
|
// interface is returned (several object's may share the same physique modifier), else returns NULL.
|
|
|
|
class IPhyContextExport
|
|
{
|
|
public:
|
|
|
|
PHYExport virtual ~IPhyContextExport() {}
|
|
|
|
// this returns the number of vertices for the given modContext's Object
|
|
PHYExport virtual int GetNumberVertices() = 0;
|
|
|
|
// If ConvertToRigid is set to TRUE, all GetVertexInterface calls will be IPhyRigidVertex OR IPhyBlendedRigidVertex.
|
|
// Vertices which are not Rigid in Physique will be converted to Rigid for the VertexInterface.
|
|
// When ConvertToRigid is set to FALSE, GetVertexInterface for non-Rigid vertices currently returns NULL.
|
|
// By default, if you do not call ConvertToRigid, it is set to FALSE.
|
|
PHYExport virtual void ConvertToRigid(BOOL flag = TRUE) = 0;
|
|
|
|
// If AllowBlending is set to FALSE then GetVertexInterface will return a non-blended subclass.
|
|
// Currently the only valid VertexInterface subclasses are IPhyRigidVertex, and IPhyBlendedRigidVertex.
|
|
// When AllowBlending is FALSE, either IPhyRigidVertex or NULL will be returned.
|
|
// If ConvertToRigid is TRUE and AllowBlending is FALSE, all vertices will return
|
|
// IPhyRigidVertex. By default AllowBlending is set to TRUE.
|
|
PHYExport virtual void AllowBlending(BOOL flag = TRUE) = 0;
|
|
|
|
// GetVertexInterface return's a VertexInterface (IPhyVertexExport *) for the i'th vertex.
|
|
// If ConvertToRigid has been set to TRUE, then all VertexInterfaces will return IPhyRigidVertex OR IPhyBlendedRigidVertex.
|
|
// When ConvertToRigid has been set to FALSE, non-Rigid vertices will return NULL (CURRENTLY).
|
|
PHYExport virtual IPhyVertexExport *GetVertexInterface(int i) = 0;
|
|
|
|
// You must call ReleaseVertexInterface to delete the VertexInterface when finished with it.
|
|
PHYExport virtual void ReleaseVertexInterface(IPhyVertexExport *vertexExport) = 0;
|
|
|
|
PHYExport virtual int Execute(int cmd, ULONG arg1=0, ULONG arg2=0, ULONG arg3=0) = 0;
|
|
|
|
PHYExport virtual IPhyFloatingVertex *GetFloatingVertexInterface(int i) = 0;
|
|
};
|
|
|
|
// IPhysiqueExport: This class can be returned by calling the method GetInterface() for a Physique Modifier
|
|
// given Modifier *mod points to a Physique Modifier, then:
|
|
// IPhysiqueExport *phyInterface = (IPhysiqueExport *)( mod->GetInterface(I_PHYINTERFACE) );
|
|
// will return the interface for this Physique Modifier, else returns NULL.
|
|
|
|
class IPhysiqueExport
|
|
{
|
|
|
|
public:
|
|
|
|
PHYExport virtual ~IPhysiqueExport() {}
|
|
|
|
//GetContextInterface will return a pointer to IPhyContextExport Interface for a given INode.
|
|
// Ff the given INode does not contain the Physique Modifier of this IPhysique Export then NULL is returned.
|
|
PHYExport virtual IPhyContextExport *GetContextInterface(INode* nodePtr) = 0;
|
|
|
|
// You must call ReleaseContextInterface to delete the COntextInterface when finished with it.
|
|
PHYExport virtual void ReleaseContextInterface(IPhyContextExport *contextExport) = 0;
|
|
|
|
PHYExport virtual int GetInitNodeTM(INode *node, Matrix3 &initNodeTM) = 0;
|
|
|
|
PHYExport virtual int Execute(int cmd, ULONG arg1=0, ULONG arg2=0, ULONG arg3=0) = 0;
|
|
|
|
PHYExport virtual int Version(void) = 0;
|
|
|
|
PHYExport virtual void SetInitialPose(bool set) = 0;
|
|
};
|
|
|
|
// example code to find if a given node contains a Physique Modifier
|
|
// DerivedObjectPtr requires you include "modstack.h" from the MAX SDK
|
|
/*
|
|
Modifier* FindPhysiqueModifier (INode* nodePtr)
|
|
{
|
|
Object* ObjectPtr = nodePtr->GetObjectRef();
|
|
|
|
if (!ObjectPtr ) return NULL;
|
|
|
|
while (ObjectPtr->SuperClassID() == GEN_DERIVOB_CLASS_ID && ObjectPtr)
|
|
{
|
|
// Yes -> Cast.
|
|
IDerivedObject* DerivedObjectPtr = (IDerivedObject *)(ObjectPtr);
|
|
|
|
// Iterate over all entries of the modifier stack.
|
|
int ModStackIndex = 0;
|
|
|
|
while (ModStackIndex < DerivedObjectPtr->NumModifiers())
|
|
{
|
|
// Get current modifier.
|
|
Modifier* ModifierPtr = DerivedObjectPtr->GetModifier(ModStackIndex);
|
|
|
|
// Is this Physique ?
|
|
if (ModifierPtr->ClassID() == Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B))
|
|
{
|
|
// is this the correct Physique Modifier based on index?
|
|
SkinMod *phyMod = (SkinMod *)ModifierPtr;
|
|
|
|
if (phyMod == mod)
|
|
{
|
|
ModContext *mc = DerivedObjectPtr->GetModContext(ModStackIndex);
|
|
}
|
|
}
|
|
|
|
ModStackIndex++;
|
|
}
|
|
|
|
ObjectPtr = DerivedObjectPtr->GetObjRef();
|
|
}
|
|
|
|
// Not found.
|
|
return NULL;
|
|
}
|
|
*/
|
|
|
|
|
|
// Deformable Vertex Export via Offset Vectors
|
|
//
|
|
// Character Studio 2.1 allows users to export Deformable Vertices
|
|
// as time frame offsets from a rigid node offset
|
|
// The Rigid Offset Vector is identical to the Rigid Vertex Offset Vector.
|
|
// This represents the vertex in local coordinates from the attached node.
|
|
// Note that since the deformable offset is relative to a single node,
|
|
// Blending between links is handled internal to Physique in determining
|
|
// this offset, so that the export is a single offset for a given time
|
|
// for a single Node.
|
|
// Basically, you export a deformable offset from a single node, while
|
|
// Physique uses blending between several deformable links to determine
|
|
// this offset.
|
|
// NOTE: while the Rigid Vertex and Rigid Blended Vertex Export require
|
|
// a one time export for replicating the deformabion internal to the game engine,
|
|
// the Deformable Offset Vertex Export requires the export of DeformVertexOffset(t)
|
|
// at several (or every) frame.
|
|
|
|
class IPhyDeformableOffsetVertex : public IPhyVertexExport
|
|
{
|
|
public:
|
|
|
|
PHYExport virtual ~IPhyDeformableOffsetVertex() {}
|
|
|
|
// GetNode() will return the INode pointer of the link of the given VertexInterface
|
|
PHYExport virtual INode *GetNode() = 0;
|
|
|
|
// GetOffsetVector() will return the coordinates of the undeformed vertex
|
|
// in the local coordinates of associated INode pointer from GetNode().
|
|
// This is IDENTICAL to the Rigid Non Blended OffsetVector.
|
|
// It represents the Vertex in the local coordinates of the node via GetNode().
|
|
PHYExport virtual Point3 GetOffsetVector() = 0;
|
|
|
|
// GetDeformOffsetVector(t) will return the coorinates of the deformed vertex
|
|
// in the local coordinates of the associated INode pointer from GetNode().
|
|
// Game Developers wishing to store relative offsets can subtract the
|
|
// Deformable Offsets for given frames from the Base Offset Vector.
|
|
PHYExport virtual Point3 GetDeformOffsetVector(TimeValue t) = 0;
|
|
|
|
PHYExport virtual int Execute(int cmd, ULONG arg1=0, ULONG arg2=0, ULONG arg3=0) = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Import Interface Functionality for Physique
|
|
//
|
|
// Character Studio 2.1 allows users to programatically set the Rigid
|
|
// Vertex Assignments (with or without Blending) via Import Interface
|
|
|
|
|
|
// IPhyVertexImport: this is the base class for Vertex Export Interface
|
|
// NOTE: currently only RIGID_TYPE vertices are supported (IPhyRigidVertex)
|
|
// When a vertex is not assigned Rigid in Physique, the VertexInterface will be NULL
|
|
// Unless you call IPhyContextExport->ConvertToRigid(TRUE) (see IPhyContextExport below)
|
|
// With ConvertToRigid(TRUE) you will always get a IPhyRigidVertex
|
|
// from IPhyContextExport->GetVertexInterface(i)
|
|
|
|
class IPhyVertexImport
|
|
{
|
|
public:
|
|
|
|
PHYExport virtual ~IPhyVertexImport() {}
|
|
|
|
// NOTE: currently only type RIGID_TYPE | RIGID_BLENDED_TYPE are supported
|
|
PHYExport virtual int GetVertexType() = 0;
|
|
|
|
// You can lock (TRUE) or unlock (FALSE) vertex assignments
|
|
// To avoid changes to manual vertex assignments locking prevents
|
|
// these vertices from being reinitialized by Physique.
|
|
PHYExport virtual void LockVertex(BOOL lock) = 0;
|
|
|
|
PHYExport virtual int Execute(int cmd, ULONG arg1=0, ULONG arg2=0, ULONG arg3=0) = 0;
|
|
};
|
|
|
|
|
|
|
|
class IPhyRigidVertexImport : public IPhyVertexImport
|
|
{
|
|
public:
|
|
|
|
PHYExport virtual ~IPhyRigidVertexImport() {}
|
|
|
|
// SetNode() will define the INode pointer of the link of the given Rigid Vertex Interface
|
|
// If this INode is a valid Physique Link SetNode returns TRUE, and this vertex is
|
|
// now assigned Rigid (NonBlended) to this INode.
|
|
// If this INode is not a valid Physique Link, then SetNode returns FALSE,
|
|
// and no change to the vertex assignment occurs.
|
|
PHYExport virtual BOOL SetNode(INode *nodePtr) = 0;
|
|
|
|
PHYExport virtual int Execute(int cmd, ULONG arg1=0, ULONG arg2=0, ULONG arg3=0) = 0;
|
|
|
|
};
|
|
|
|
class IPhyBlendedRigidVertexImport : public IPhyVertexImport
|
|
{
|
|
public:
|
|
|
|
PHYExport virtual ~IPhyBlendedRigidVertexImport() {}
|
|
|
|
// SetWeightedNode will assign the given vertex to the nodePtr with the weight specified.
|
|
// When init = TRUE, this will remove all existing asignments and define this nodePtr
|
|
// as the first and only nodePtr assigned to the given vertex. When init = FALSE this
|
|
// nodePtr and weight are appeneded to the current assignments.
|
|
// Always set init = TRUE for the first nodePtr and weight for a given vertex
|
|
// and init = FALSE for all additional 2nd thru Nth nodeptr and weights.
|
|
// SetWeightedNode returns the number of Nodes assigned to the given Vertex
|
|
// when set successfully, or when the given nodePtr is not a valid Physique Link
|
|
// SetWeightedNode returns 0.
|
|
PHYExport virtual int SetWeightedNode(INode *nodePtr, float weight, BOOL init = FALSE) = 0;
|
|
|
|
PHYExport virtual int Execute(int cmd, ULONG arg1=0, ULONG arg2=0, ULONG arg3=0) = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
class IPhyContextImport
|
|
{
|
|
public:
|
|
|
|
PHYExport virtual ~IPhyContextImport() {}
|
|
|
|
// this returns the number of vertices for the given modContext's Object
|
|
PHYExport virtual int GetNumberVertices() = 0;
|
|
|
|
// SetVertexInterface return's a VertexInterface (IPhyVertexImport *) for the i'th vertex.
|
|
// type = RIGID_NON_BLENDED_TYPE | RIGID_BLENDED_TYPE are currently supported.
|
|
// Any other value for type will return NULL.
|
|
|
|
PHYExport virtual IPhyVertexImport *SetVertexInterface(int i, int type) = 0;
|
|
|
|
// You must call ReleaseVertexInterface to delete the VertexInterface when finished with it.
|
|
PHYExport virtual void ReleaseVertexInterface(IPhyVertexImport *vertexImport) = 0;
|
|
|
|
PHYExport virtual int Execute(int cmd, ULONG arg1=0, ULONG arg2=0, ULONG arg3=0) = 0;
|
|
|
|
};
|
|
|
|
|
|
class IPhysiqueImport
|
|
{
|
|
public:
|
|
|
|
PHYExport virtual ~IPhysiqueImport() {}
|
|
|
|
//GetContextInterface will return a pointer to IPhyContextImport Interface for a given INode.
|
|
// if the given INode does not contain the Physique Modifier of this IPhysique Import then NULL is returned.
|
|
PHYExport virtual IPhyContextImport *GetContextInterface(INode* nodePtr) = 0;
|
|
|
|
// You must call ReleaseContextInterface to delete the ContextInterface when finished with it.
|
|
PHYExport virtual void ReleaseContextInterface(IPhyContextImport *contextImport) = 0;
|
|
|
|
// You call AttachRootNode to define the root node of the Physique Modifier
|
|
// This will create default vertex assignments.
|
|
// You MUST call AttachRootNode prior to any Imported Vertex Assignments
|
|
// This method is designed specifically for developers wanting to
|
|
// define Physique fully via import. Predictable results should only be
|
|
// expected when this call is followed by a series of Vertex Import calls
|
|
// for every ModContext and Vertex of the Modifier.
|
|
// If the attach is successful it returns TRUE, otherwise it returns FALSE.
|
|
// TimeValue t specifies the initial skeleton pose, the position of the
|
|
// skeleton relative to the Object Geometry.
|
|
PHYExport virtual BOOL AttachRootNode(INode *nodePtr, TimeValue t) = 0;
|
|
|
|
PHYExport virtual BOOL InitializePhysique(INode *nodePtr, TimeValue t) = 0;
|
|
|
|
PHYExport virtual int Execute(int cmd, ULONG arg1=0, ULONG arg2=0, ULONG arg3=0) = 0;
|
|
|
|
};
|
|
|
|
class IPhyFloatingVertex : public IPhyVertexExport
|
|
{
|
|
public:
|
|
|
|
PHYExport virtual ~IPhyFloatingVertex() {}
|
|
|
|
PHYExport virtual int GetNumberNodes() = 0;
|
|
PHYExport virtual INode *GetNode(int i) = 0;
|
|
PHYExport virtual float GetWeight(int i, float &totalweight) = 0;
|
|
PHYExport virtual Point3 GetOffsetVector(int i) = 0;
|
|
PHYExport virtual int Execute(int cmd, ULONG arg1=0, ULONG arg2=0, ULONG arg3=0) = 0;
|
|
|
|
// GetNumberNodes() returns the number of nodes (bones) assigned to the given Vertex
|
|
|
|
// GetNode(i) will return the INode pointer of the ith node assigned to
|
|
//this Vertex
|
|
|
|
// GetOffsetVector(i) will return the coordinates of the vertex
|
|
// in the local coordinates of associated i'th INode pointer from GetNode(i)
|
|
// this is NOT THE SAME as the .vph file coordinates. (It is simpler)
|
|
// the world coordinates of the vertex have been transformed by the Inverse of the INode pointer.
|
|
|
|
// GetWeight(i) will return the normalized weight of the vertex associated with the i'th Node
|
|
// pointer from GetNode(i)
|
|
|
|
};
|
|
|
|
|
|
#endif
|
|
|
|
|