945 lines
34 KiB
C++
945 lines
34 KiB
C++
/***************************************************************************
|
|
File: Ge2Virtools.h
|
|
|
|
Author: Romain Sididris - Virtools 2000
|
|
|
|
Class Definition
|
|
|
|
This file defines a set of helper classes that can be use when dealing with
|
|
exporter/importer to Virtools Format.
|
|
|
|
The Export2Virtools class contains methods to help you generate Virtools objects
|
|
and store them in a database. Each created can be assigned a key (void*)
|
|
to retrieve it afterward.
|
|
|
|
+ The Virtools mesh format has some constraints about vertex format :
|
|
one normal,color/uv per vertex and use triangle faces only, so you may also
|
|
find useful the VirtoolsTransitionMesh class which can be used to construct
|
|
a mesh without these limitations (Any number of normals/colors/uv per vertex)
|
|
and polygon face.
|
|
|
|
Virtools SDK
|
|
Copyright (c) Virtools 2000, All Rights Reserved.
|
|
***************************************************************************/
|
|
#ifndef GENERICEXPORT_H
|
|
#define GENERICEXPORT_H
|
|
|
|
// Declare the generic structures for Import/Export.
|
|
#include "CKAll.h"
|
|
#include "GeFileLog.h"
|
|
|
|
#define MAX_UVCHANNEL_COUNT 8
|
|
#define SMALL_FLOAT 0.000001f
|
|
|
|
//------------- Type Definitions ---------------------
|
|
|
|
typedef XArray<int> IntArray;
|
|
class Export2Virtools;
|
|
class VirtoolsCompositeMaterial;
|
|
// Hash table definitions
|
|
|
|
// Hash Tables (Key -> Object )
|
|
typedef XHashTable<CKObject*,void*> XObjectHashTable;
|
|
typedef XHashTable<CKObject*,void*>::Iterator XObjectHashTableIt;
|
|
typedef XHashTable<CKObject*,void*>::Pair XObjectHashTablePair;
|
|
// Hash Tables (Key -> int)
|
|
typedef XHashTable<int,void*> XIntHashTable;
|
|
typedef XHashTable<int,void*>::Iterator XIntHashTableIt;
|
|
typedef XHashTable<int,void*>::Pair XIntHashTablePair;
|
|
// Hash Tables (texture filename -> texture)
|
|
typedef XHashTable<CKTexture*,XString> XTextureHashTable;
|
|
typedef XHashTable<CKTexture*,XString>::Iterator XTextureHashTableIt;
|
|
typedef XHashTable<CKTexture*,XString>::Pair XTextureHashTablePair;
|
|
|
|
// Hash Tables (CKMaterial -> VirtoolsCompositeMaterial )
|
|
typedef XHashTable<int,CKMaterial*> XCmpMatHashTable;
|
|
typedef XHashTable<int,CKMaterial*>::Iterator XCmpMatHashTableIt;
|
|
typedef XHashTable<int,CKMaterial*>::Pair XCmpMatHashTablePair;
|
|
|
|
|
|
|
|
// Triangle indices
|
|
class TriIndices {
|
|
public:
|
|
int idx[3];
|
|
TriIndices() { idx[0]=idx[1]=idx[2]=0; }
|
|
TriIndices(int a,int b,int c) { idx[0]=a; idx[1]=b; idx[2]=c; }
|
|
};
|
|
|
|
// The same with a pointer to the CKMaterial which gives
|
|
// the color/lighting properties of the face
|
|
class TriFace: public TriIndices {
|
|
public:
|
|
CKMaterial* material;
|
|
TriFace():material(NULL) { }
|
|
TriFace(int a,int b,int c,CKMaterial* mat):TriIndices(a,b,c),material(mat){}
|
|
};
|
|
|
|
//CompositeMaterialInfo, used internally by SplitMeshByCompositeMaterial
|
|
class CompositeMtlInfo{
|
|
public:
|
|
VirtoolsCompositeMaterial* c;
|
|
XArray<int> faces;
|
|
XArray<int> usedV;
|
|
XArray<int> remapV;
|
|
};
|
|
|
|
enum EControlPointType
|
|
{
|
|
eBezierCP =0,
|
|
eCatmullRomCP =1,
|
|
eHermiteCP =2,
|
|
eBSplineCP =3
|
|
};
|
|
|
|
enum EAnimType
|
|
{
|
|
ePosition =0,
|
|
eRotation =1,
|
|
eScale =2,
|
|
eScaleAxis =3,
|
|
eMorph =4,
|
|
eBlendShapeWeight =5
|
|
};
|
|
|
|
enum EAxis
|
|
{
|
|
ePositiveX,
|
|
ePositiveY,
|
|
ePositiveZ,
|
|
|
|
eNegativeX,
|
|
eNegativeY,
|
|
eNegativeZ
|
|
};
|
|
|
|
enum ETextureResizeMethod
|
|
{
|
|
eNearestPowerOfTwo =0,
|
|
eLowerPowerOfTwo =1,
|
|
eHigherPowerOfTwo =2
|
|
};
|
|
|
|
//Use to tell ReduceAnimationKeys the method to compute the algorithm's effectivness
|
|
enum EEvalMethod
|
|
{
|
|
eAuto =0,
|
|
eQuality =1,
|
|
eFileSize =2
|
|
};
|
|
|
|
/***************************************************************************
|
|
VirtoolsVertex
|
|
Transition class for constructing vertices.
|
|
This class is used internally by the exporter when generating meshes but
|
|
can be useful when dealing with morph animations.
|
|
***************************************************************************/
|
|
class VirtoolsVertex {
|
|
public:
|
|
VxVector Pos; // Vertex Position
|
|
VxVector Norm; // Vertex Normal
|
|
VxColor Col; // Vertex Color
|
|
VxColor Uvs[MAX_UVCHANNEL_COUNT]; // Vertex Texture coordinates
|
|
|
|
// These are different indices of the position,normal and color in
|
|
// the source format (that is in the m_Vertices,m_Normals,m_VertexColors
|
|
// array sof VirtoolsTransitionMesh class)
|
|
int OriginalPosIndex; // -1 if invalid
|
|
int OriginalNormIndex; // " " "
|
|
int OriginalColIndex; // " " "
|
|
int OriginalUvIndex[MAX_UVCHANNEL_COUNT]; // " " "
|
|
// This is the index of the vertice in NbFace*3 array (used internally)
|
|
int FlatIndex;
|
|
// If this vertex is equal to an existing vertex => Index of the this
|
|
// vertex or -1 (used internally)
|
|
int ReAssign;
|
|
};
|
|
|
|
class VirtoolsFaceDelta
|
|
{
|
|
public:
|
|
int m_Index; // face index
|
|
VxVector m_PosDelta[3];
|
|
VxVector m_NormalDelta[3];
|
|
};
|
|
|
|
|
|
class VirtoolsBlendShapeBase
|
|
{
|
|
public:
|
|
int m_LogicalBlendShape;
|
|
float m_Weight; // weight of the "parent logical blend shape" at which this blend shape has full influence
|
|
float m_InSlope;
|
|
float m_OutSlope;
|
|
};
|
|
|
|
class VirtoolsPerFaceBlendShape : public VirtoolsBlendShapeBase
|
|
{
|
|
public:
|
|
XClassArray<VirtoolsFaceDelta> m_Faces;
|
|
};
|
|
|
|
|
|
|
|
class VirtoolsVertexDelta
|
|
{
|
|
public:
|
|
int m_Index;
|
|
VxVector m_PosDelta;
|
|
VxVector m_NormalDelta;
|
|
};
|
|
|
|
class VirtoolsPerVertexBlendShape : public VirtoolsBlendShapeBase
|
|
{
|
|
public:
|
|
XString m_Name;
|
|
XClassArray<VirtoolsVertexDelta> m_Deltas;
|
|
};
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
VirtoolsTransitionMesh
|
|
Helper class for building geometry mesh. Virtools forces the mesh to have only
|
|
1 texture coordinate and 1 normal or color per vertex and triangle faces.
|
|
This class will help you convert from other formats where a vertex can have
|
|
more than one normal per vertex or polygon faces.
|
|
|
|
Usage :
|
|
- Create a VirtoolsTransitionMesh with a pointer to the Export2Virtools interface
|
|
and specify if it should be prelit (vertex color ) or not (using normals)
|
|
|
|
- Fill information about geometry using the
|
|
AddPosition,AddNormal,AddVertexColor and AddUv methods
|
|
|
|
- Fill face data. A face is a set of 3 or more indices to the previous tables.
|
|
If the incoming format is similar to Virtools and already ensures one
|
|
normal/color/uv per vertex use the same indices for AddFace and AddUVFace/
|
|
AddNormalFace/AddColorFace.
|
|
|
|
- Call GenerateVirtoolsData which will generate the m_VirtoolsVertices and m_VirtoolsFaces
|
|
arrays. In the general cases you won't have to access these arrays.
|
|
|
|
- You can add the generated mesh to the exporter database with the
|
|
Export2Virtools::AddMesh(...) method
|
|
|
|
- When dealing with morph animations you may avoid to regenerate a transition mesh
|
|
for a morph key by only updating the source arrays (m_Vertices,m_Normals)
|
|
and call RefreshVirtoolsVerticesPosition(...) which will update the
|
|
m_VirtoolsVertices array accordingly to the new positions.
|
|
|
|
- When using face materials having channels applied to differents faces
|
|
|
|
/********************************************************************************/
|
|
class VirtoolsTransitionMesh {
|
|
public:
|
|
// Constructor
|
|
VirtoolsTransitionMesh(Export2Virtools* exporter=NULL,BOOL PrelitMesh=FALSE):Exporter(exporter),m_ChannelCount(0),m_PrelitMesh(PrelitMesh),m_HasLightMap(FALSE) {}
|
|
|
|
//-- Reset all datas. Prelit Mode doesn't change
|
|
void Reset();
|
|
|
|
//-- Filling geometry
|
|
void AddPosition(VxVector& p) { m_Vertices.PushBack(p); }
|
|
void AddNormal(VxVector& n) { m_Normals.PushBack(n); }
|
|
void AddVertexColor(VxColor& c) { m_VertexColors.PushBack(c); }
|
|
void AddUv(VxUV& uv,int channel=0) { m_Uvs[channel].PushBack(VxColor(uv.u,uv.v,0.f,0.f)); }
|
|
bool AddChannelComponent(VxColor &pColor, int pChannel){m_Uvs[pChannel].PushBack(pColor);return true;}
|
|
//-- Faces...
|
|
void AddFace(int* indices,int indexcount,CKMaterial* m);
|
|
void AddFace(int index1,int index2,int index3,CKMaterial* m);
|
|
void SetFaceMaterial(int index,CKMaterial* m) { m_Faces[index].material = m; }
|
|
|
|
void AddUVFace(int* indices,int indexcount,int channel=0);
|
|
void AddUVFace(int index1,int index2,int index3,int channel=0);
|
|
void AddColorFace(int* indices,int indexcount);
|
|
void AddColorFace(int index1,int index2,int index3);
|
|
void AddNormalFace(int* indices,int indexcount);
|
|
void AddNormalFace(int index1,int index2,int index3);
|
|
int GetLogicalBlendShapeCount() const { return m_LogicalBlendShapeNames.Size(); }
|
|
void AddLogicalBlendShape(const XString& name);
|
|
void AddPhysicalBlendShape(const VirtoolsPerFaceBlendShape& blendShape);
|
|
void AddDefaultBlendShapeWeight(float weight);
|
|
float GetDefaultBlendShapeWeight(int index);
|
|
|
|
|
|
//-- Additionnal Materials (Multi-texture)
|
|
void AddChannelMaterial(CKMaterial* m) { m_Channels.PushBack(m); m_ExtendedChannelsTypes.PushBack(0); }
|
|
//--Extended Channels
|
|
BOOL AddExtendedChannel(int pNumComponent=1){ if(pNumComponent<1 || pNumComponent>4) return false; m_ExtendedChannelsTypes.PushBack(pNumComponent); m_Channels.PushBack(NULL);return true;}
|
|
|
|
|
|
// Construct arrays of Virtools Faces and Vertices
|
|
BOOL GenerateVirtoolsData( BOOL iOptimizeVertexSharing=TRUE );
|
|
// Only recomputes vertices and normals ( GenerateVirtoolsData must have been called at least once...)
|
|
BOOL RefreshVirtoolsVerticesPosition();
|
|
//
|
|
const IntArray& GetGeneratedIndices(int OriginalVertexIndex) { return m_RemapIndices[OriginalVertexIndex]; }
|
|
|
|
//-- Source Data
|
|
XArray<VxVector> m_Vertices; // List of Vertex positions
|
|
XArray<VxVector> m_Normals; // List of normals
|
|
XArray<VxColor> m_VertexColors; // List of vertex colors
|
|
XArray<VxColor> m_Uvs[MAX_UVCHANNEL_COUNT]; // List of texture coordinates per channel
|
|
|
|
XArray<TriFace> m_Faces; // List of triangle faces
|
|
XArray<TriIndices> m_NormalFaces; // There must be an equal number face for normals,uv and colors or none if not used;
|
|
XArray<TriIndices> m_ColorFaces; // ""
|
|
XArray<TriIndices> m_UVFaces[MAX_UVCHANNEL_COUNT];
|
|
|
|
XArray<CKMaterial*> m_Channels;
|
|
XArray<VirtoolsCompositeMaterial*> m_CompositeMaterials;
|
|
XArray<int> m_ExtendedChannelsTypes; // Type 1,2,3,4 for float1 float2 float3 or float 4
|
|
XClassArray<XString> m_LogicalBlendShapeNames;
|
|
XClassArray<VirtoolsPerFaceBlendShape> m_PerFaceBlendShapes;
|
|
XArray<float> m_DefaultBlendShapeWeights;
|
|
|
|
BOOL m_PrelitMesh;
|
|
|
|
|
|
//-- Generated Data
|
|
|
|
|
|
XClassArray<IntArray> m_RemapIndices; // This array has the size of the given m_Vertices,
|
|
// and contains the list of generated indices for a given
|
|
// original vertex.
|
|
XClassArray<VirtoolsVertex> m_VirtoolsVertices; // Array of vertex as used in Virtools (Pos,Normal,UV)
|
|
XArray<TriFace> m_VirtoolsFaces;
|
|
XClassArray<VirtoolsPerVertexBlendShape> m_PerVertexBlendShapes;
|
|
|
|
|
|
int m_ChannelCount;
|
|
|
|
BOOL m_HasLightMap; // whether the mesh has a lightmap channel
|
|
|
|
protected:
|
|
BOOL CompVtx(const VirtoolsVertex& v1,const VirtoolsVertex& v2);
|
|
Export2Virtools* Exporter;
|
|
};
|
|
|
|
|
|
/*****************************************************************************
|
|
VirtoolsTransitionPatchMesh
|
|
Helper class for building patchmesh geometry. No vertex color.
|
|
|
|
Usage :
|
|
- Create a VirtoolsTransitionPatchMesh with a pointer to the Export2Virtools interface.
|
|
- Set ucount and vcount using SetUVCount(u,v)
|
|
- Set the type of control points you'll be using with SetControlPointsType(p).
|
|
Bezier control points are native while Hermite, BSpline and CatmullRom require conversion
|
|
to the bezier form. This conversion is done internally.
|
|
- Fill information about geometry using:
|
|
|
|
AddControlPoints
|
|
Add all the corner control points. Add them in the following order
|
|
|
|
for(v=0; v<vcount;v++)
|
|
for(u=0; u<vcount;u++)
|
|
{{
|
|
AddControlPoints( evalknotposition( u,v ) );
|
|
}}
|
|
|
|
AddEdgeControlPoint(...)
|
|
Depending of the type of control points, Vecs will represent:
|
|
-Tangents for Hermite
|
|
-Position on surface for Catmul Rom and BSpline
|
|
-Bezier Control Points for Bezier
|
|
//Adding U Vecs
|
|
for(v=0; v< vcount;v++)
|
|
for(u=0; u< ucount-1;u++)
|
|
{{
|
|
AddEdgeControlPoint(...);
|
|
AddEdgeControlPoint(...);
|
|
}}
|
|
|
|
//Adding V Vecs
|
|
for(v=0; v< vcount-1;v++)
|
|
for(u=0; u< ucount;u++)
|
|
{{
|
|
AddEdgeControlPoint(...);
|
|
AddEdgeControlPoint(...);
|
|
}}
|
|
|
|
AddUV(...)
|
|
Add all the UVs per channel in the same order as ControlPoints.
|
|
There should be one UV per corner point .
|
|
Warning:When you skip channels (ie: use 0.... use 5) the skipped channel (ie: 1,2,3,4)
|
|
will still be add!!
|
|
|
|
- Set the iteration level using SetIteration(). default= 3, min= 0, max= 20
|
|
|
|
- You can add the generated mesh to the exporter database with the
|
|
Export2Virtools::AddPatch(...) method
|
|
|
|
/********************************************************************************/
|
|
class VirtoolsTransitionPatchMesh{
|
|
public:
|
|
//-- Constructor
|
|
VirtoolsTransitionPatchMesh(Export2Virtools* exporter=NULL);
|
|
|
|
//-- Control Points
|
|
void AddControlPoint(const VxVector &pControlPoint);
|
|
void AddEdgeControlPoint(const VxVector &pControlPoint);
|
|
|
|
//-- Edge
|
|
void AddEdge(int Vert0, int Vert1, int Vec0, int Vec1);
|
|
|
|
//-- Patch
|
|
void AddPatch(int E0, int E1, int E2, int E3);
|
|
|
|
//-- Texture Coordinates
|
|
bool AddUV(VxUV &pUV, int pChannel);
|
|
bool AddChannelComponent(VxColor &pColor, int pChannel);
|
|
|
|
//-- Iteration Level
|
|
BOOL SetIterationLevel(int pLevel);
|
|
|
|
//-- Additionnal Materials (Multi-texture)
|
|
void AddChannelMaterial(CKMaterial* m) { m_Channels.PushBack(m); m_ExtendedChannelsTypes.PushBack(0); }
|
|
|
|
//-- Extended Channels
|
|
BOOL AddExtendedChannel(int pNumComponent=1){ if(pNumComponent<1 || pNumComponent>4) return false; m_ExtendedChannelsTypes.PushBack(pNumComponent); m_Channels.PushBack(NULL);return true;}
|
|
|
|
//-- Utilities
|
|
bool Generate( bool AutoCalculateVec, bool TransformEvalIntoCP=true );
|
|
void Reset();// Reset will clear everything except m_PatchMesh and m_Exporter
|
|
void SetUVCount(int u, int v) {m_UCount=u; m_VCount=v;}
|
|
void SetControlPointsType(int p) {m_ControlPointsType=p;}
|
|
|
|
//-- Source Data
|
|
XArray<VxVector> m_ControlPoints; // List of all control points
|
|
XArray<VxVector> m_Vecs; // List of all Vecs control points
|
|
XArray<VxColor> m_UVs[MAX_UVCHANNEL_COUNT]; // List corner UVs
|
|
XArray<CKPatch> m_Patches; // List of all temporary patches using indices of m_ControlPoints
|
|
XArray<CKPatchEdge >m_Edges; // List of all temporary edges using indices of m_ControlPoints
|
|
//XArray<int> m_Corners;
|
|
//XArray<int> m_Interior_Edges;
|
|
XArray<CKMaterial*> m_Channels;
|
|
XArray<int> m_ExtendedChannelsTypes; // Type 1,2,3,4 for float1 float2 float3 or float 4
|
|
|
|
//-- Misc Data
|
|
int m_ChannelCount;
|
|
int m_IterationLevel;
|
|
int m_UCount;
|
|
int m_VCount;
|
|
int m_ControlPointsType;
|
|
|
|
|
|
protected:
|
|
Export2Virtools* m_Exporter; //A pointer to a valid Ge2Virtools with a valid CKContext
|
|
bool ComputeBezierCoeff(float t, float B[4]);
|
|
bool ComputeDiffBezierCoeff(float t, float B[4]);
|
|
void TransformEvaluations();
|
|
};
|
|
|
|
/********************************************************************************
|
|
VirtoolsSkin
|
|
VirtoolsSkinVertex
|
|
+ Structure reprensenting a skin.
|
|
+ Use internally as a temporary structure
|
|
+ The current bone matrices must be in the bind pose
|
|
*******************************************************************************/
|
|
class VirtoolsSkinVertex{
|
|
public:
|
|
VirtoolsSkinVertex(){}
|
|
|
|
VirtoolsSkinVertex(const VirtoolsSkinVertex &v){
|
|
m_Bones= v.m_Bones;
|
|
m_Weights= v.m_Weights;
|
|
m_IntialPos= v.m_IntialPos;
|
|
}
|
|
|
|
VirtoolsSkinVertex(CKSkinVertexData* s)
|
|
{
|
|
for(int i=0; i<s->GetBoneCount(); i++){
|
|
m_Bones.PushBack( s->GetBone(i));
|
|
m_Weights.PushBack( s->GetWeight(i));
|
|
}
|
|
|
|
m_IntialPos= s->GetInitialPos();
|
|
}
|
|
|
|
XArray<int> m_Bones;
|
|
XArray<float> m_Weights;
|
|
VxVector m_IntialPos;
|
|
};
|
|
|
|
class VirtoolsSkin{
|
|
public:
|
|
VirtoolsSkin(){}
|
|
VirtoolsSkin(CKSkin* s, CK3dEntity* owner)
|
|
{ int i;
|
|
for(i=0; i<s->GetBoneCount(); i++){
|
|
CK3dEntity* e=s->GetBoneData(i)->GetBone();
|
|
m_Bones.PushBack( e );
|
|
m_BonesIntialMatrix.PushBack( e->GetInverseWorldMatrix() );
|
|
}
|
|
|
|
for(i=0; i<s->GetVertexCount(); i++){
|
|
CKSkinVertexData* svd=s->GetVertexData(i);
|
|
VirtoolsSkinVertex vsv(svd);
|
|
m_Vertex.PushBack( vsv );
|
|
}
|
|
|
|
for(i=0; i<s->GetNormalCount(); i++)
|
|
m_VertexNormals.PushBack( s->GetNormal(i) );
|
|
|
|
m_ObjectInitialMatrix= owner->GetInverseWorldMatrix();
|
|
}
|
|
|
|
XArray<CK3dEntity*> m_Bones;
|
|
XArray<VxMatrix> m_BonesIntialMatrix;
|
|
XClassArray<VirtoolsSkinVertex> m_Vertex;
|
|
XArray<VxVector> m_VertexNormals;
|
|
VxMatrix m_ObjectInitialMatrix;
|
|
};
|
|
|
|
|
|
/********************************************************************************
|
|
VirtoolsTexture
|
|
|
|
+ Structure reprensenting a texture with a separated alpha map.
|
|
There is also an opacity member
|
|
Exporter will create new .tga every time a texture is used with an alpha map.
|
|
*******************************************************************************/
|
|
class VirtoolsTexture {
|
|
public:
|
|
CKTexture* m_Diffuse;
|
|
CKTexture* m_Alpha;
|
|
float m_Opacity;
|
|
|
|
CKTexture* m_RealTexture;
|
|
};
|
|
|
|
/********************************************************************************
|
|
VirtoolsMaterialEffect
|
|
+Structure holding generic information of material effect
|
|
+Parameters are stored as string and the CKParameter String function is used for conversion
|
|
+Textures are considered the same as other parameters and you must use texture names.
|
|
+Use the same parameter and effects names as in the Dev Interface... except for "Bump Textur..." parameter in "FloorDotProduct3 Ligthing" effect where you should use "Bump Texture"
|
|
+This can be used as a basis for shader effects to exposed the variables.
|
|
*******************************************************************************/
|
|
class VirtoolsMaterialEffect {
|
|
public:
|
|
void AddParameter( const char* name, const char* value );
|
|
const char* GetParameter(const char* name);
|
|
|
|
XString m_EffectName;
|
|
XHashTable<XString,XString> m_Parameters;
|
|
};
|
|
|
|
/********************************************************************************
|
|
VirtoolsMaterial
|
|
|
|
+ Structure that hold all the available parameters for a CKMaterial
|
|
Exporter can either use this structure to store all their parameters or
|
|
directly used the appropriate CKMaterial methods. The default constructor
|
|
sets all the members to their default value in Virtools so you can only setup your specific needs.
|
|
*******************************************************************************/
|
|
class VirtoolsMaterial {
|
|
public:
|
|
VxColor m_Diffuse;
|
|
VxColor m_Specular;
|
|
VxColor m_Ambient;
|
|
VxColor m_Emissive;
|
|
float m_SpecularPower;
|
|
|
|
CKTexture* m_Texture;
|
|
VirtoolsMaterialEffect m_Effect;
|
|
|
|
BOOL m_TwoSided;
|
|
|
|
VXFILL_MODE m_FillMode;
|
|
VXSHADE_MODE m_ShadeMode;
|
|
|
|
BOOL m_AlphaBlending;
|
|
VXBLEND_MODE m_SrcBlendFactor;
|
|
VXBLEND_MODE m_DstBlendFactor;
|
|
BOOL m_PerspectiveCorrection;
|
|
|
|
VXTEXTURE_FILTERMODE m_MinFilterMode;
|
|
VXTEXTURE_FILTERMODE m_MagFilterMode;
|
|
VXTEXTURE_BLENDMODE m_TextureBlendMode;
|
|
|
|
VXCMPFUNC m_ZFunc;
|
|
BOOL m_ZWriteEnable;
|
|
|
|
|
|
VirtoolsMaterial();
|
|
|
|
|
|
|
|
bool AddParameter(char* paramName, CKParameter* p)
|
|
{
|
|
if(paramName==NULL || p==NULL) return false;
|
|
char * buf; int c;
|
|
c =p->GetStringValue(NULL);
|
|
|
|
if(c<=0) return false;
|
|
|
|
buf = new char[c];
|
|
p->GetStringValue(buf);
|
|
m_Effect.AddParameter(paramName, buf );
|
|
delete [] buf;
|
|
buf=NULL;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
/********************************************************************************
|
|
VirtoolsChannelMaterial
|
|
+ Specify the properties of a mesh channel.. but linked to a material instead of a mesh
|
|
/*********************************************************************************/
|
|
class VirtoolsChannelMaterial{
|
|
public:
|
|
VirtoolsChannelMaterial(CKMaterial* mat=NULL, BOOL Active=true, BOOL Lit=true, VXBLEND_MODE srcBlend=VXBLEND_SRCALPHA, VXBLEND_MODE dstBlend=VXBLEND_INVSRCALPHA):m_CKMaterial(mat),m_ChannelActive(Active),m_ChannelLit(Lit), m_SrcBlend(srcBlend), m_DstBlend(dstBlend), m_Channel(-1){}
|
|
void SetChannel(int c){m_Channel=c;}
|
|
int GetChannel(){return m_Channel;}
|
|
|
|
CKMaterial* m_CKMaterial;
|
|
BOOL m_ChannelActive;
|
|
BOOL m_ChannelLit;
|
|
VXBLEND_MODE m_SrcBlend;
|
|
VXBLEND_MODE m_DstBlend;
|
|
int m_Channel;
|
|
};
|
|
|
|
/********************************************************************************
|
|
VirtoolsCompositeMaterial
|
|
+ A composite material includes multiple Virtools Material to easily create materials
|
|
channels.
|
|
+ When more than one composite material are applied to faces, the mesh will be splited in
|
|
smaller ones.
|
|
/*********************************************************************************/
|
|
class VirtoolsCompositeMaterial{
|
|
public:
|
|
VirtoolsCompositeMaterial(){};
|
|
|
|
VirtoolsCompositeMaterial(CKMaterial* mat, const XArray<CKMaterial*> &subMaterials){
|
|
m_Material= mat;
|
|
for(int i=0; i< subMaterials.Size(); i++)
|
|
AddSubMaterial( subMaterials[i], true, true );
|
|
}
|
|
|
|
int AddSubMaterial( CKMaterial* mat, BOOL Active, BOOL Lit)
|
|
{
|
|
if(mat==NULL) return -1;
|
|
|
|
m_SubMaterials.PushBack( VirtoolsChannelMaterial(mat, Active, Lit) );
|
|
|
|
return m_SubMaterials.Size()-1;
|
|
|
|
}
|
|
|
|
int GetSubMaterialCount(){ return m_SubMaterials.Size();}
|
|
|
|
CKMaterial* m_Material;
|
|
XArray<VirtoolsChannelMaterial> m_SubMaterials;
|
|
|
|
|
|
};
|
|
|
|
/********************************************************************************
|
|
VirtoolsLevel
|
|
|
|
+ Structure holding temporary Level Settings such as Ambient Lighting and Fog Settings
|
|
*******************************************************************************/
|
|
class VirtoolsLevel{
|
|
public:
|
|
//Default Constructor
|
|
VirtoolsLevel(){
|
|
m_ClrAmbient =VxColor(0.f, 0.f, 0.f);
|
|
|
|
m_ClrBackGround =VxColor(128.f, 128.f, 128.f);
|
|
m_TxtrBackground =NULL;
|
|
|
|
m_ClrFog =VxColor(0.f, 0.f, 0.f);
|
|
m_FogMode =VXFOG_NONE;
|
|
m_FogDensity =1.f;
|
|
m_FogStart =1.f;
|
|
m_FogEnd =100.f;
|
|
|
|
m_StartCamera =NULL;
|
|
|
|
m_GlobalTint =VxColor(1.f, 1.f, 1.f);
|
|
m_TintLevel =1.f;
|
|
};
|
|
|
|
//Member Variables
|
|
VxColor m_ClrAmbient;
|
|
|
|
VxColor m_ClrBackGround;
|
|
CKTexture* m_TxtrBackground;
|
|
|
|
VxColor m_ClrFog;
|
|
VXFOG_MODE m_FogMode;
|
|
float m_FogDensity;
|
|
float m_FogStart;
|
|
float m_FogEnd;
|
|
|
|
CKCamera* m_StartCamera;
|
|
|
|
//Theses values are from Max but you can use them as global values to modulate all the lights colors
|
|
//The modulation is done in ProduceCMO()
|
|
VxColor m_GlobalTint;
|
|
float m_TintLevel;
|
|
|
|
};
|
|
|
|
//-----------------------------------------------//
|
|
#define FINDHASH(list,type)\
|
|
if(list.Size()==0) return NULL;\
|
|
XObjectHashTableIt it=list.Find(Key);\
|
|
return (it==list.End()) ? NULL : (type)*it;\
|
|
|
|
/********************************************************************************
|
|
Export2Virtools
|
|
|
|
This is the main utility class used to generate your data to Virtools format.
|
|
|
|
Usage:
|
|
- Create your mesh,entity,material,etc... using the Add(Object) methods. You
|
|
may assign a key (a void* pointer) to the created object so you can access it later
|
|
using the Get(Object)ByKey methods
|
|
|
|
- You can create a global animation that will contain all the objects animations
|
|
with CreateGlobalAnimation.
|
|
|
|
- Once all the objects have been createdyou can fill a CKObjectArray of objects
|
|
to load/save with the GenerateObjects methods.
|
|
|
|
TODO : Utility functions for PatchMesh & Skin creation.
|
|
********************************************************************************/
|
|
class Export2Virtools {
|
|
friend class VirtoolsTransitionMesh;
|
|
public:
|
|
Export2Virtools(CKContext* context, BOOL createLevel);
|
|
BOOL GenerateObjects(CKObjectArray* array,BOOL AnimationsOnly=FALSE, BOOL ProduceCMO=FALSE);
|
|
|
|
//--- Geometry
|
|
CKMesh* AddMesh(VirtoolsTransitionMesh* mesh,const char* Name=NULL,void* Key=NULL,CKBOOL KeepTM=TRUE);
|
|
//--- TODO A transition Patch (with autosmooth) to avoid giving the Edges and Vec control points
|
|
CKPatchMesh* AddPatchMesh(const char* Name=NULL,void* Key=NULL);
|
|
CKPatchMesh* AddPatchMesh(VirtoolsTransitionPatchMesh* patchmesh, const char* Name=NULL,void* Key=NULL/*, CKBOOL KeepTransitionMesh=TRUE*/);
|
|
|
|
//--- Material & Textures
|
|
CKMaterial* AddMaterial(VirtoolsMaterial* mat,const char* Name=NULL,void* Key=NULL);
|
|
BOOL AddMaterial(CKMaterial* ckmat,VirtoolsMaterial* mat,const char* Name=NULL,void* Key=NULL);
|
|
VirtoolsCompositeMaterial* AddCompositeMaterial( VirtoolsCompositeMaterial cMat);
|
|
CKTexture* AddTexture(const char* TextureFileName,const char* Name=NULL,void* Key=NULL);
|
|
CKTexture* AddTexture(int Width,int Height,const char* Name=NULL,void* Key=NULL);
|
|
CKTexture* AddTextureAlphaMap(CKTexture* colorMap, CKTexture* alphaMap, float alphaMapOpacity);
|
|
int GenerateMaterialEffect(VirtoolsMaterial* vMat, CKMaterial* ckMat);
|
|
int GenerateMaterialShader(VirtoolsMaterial* vMat, CKMaterial* ckMat, void (*TextProcessCallBack) (CKMaterial*) );
|
|
|
|
|
|
//--- 3D Entities
|
|
CK3dEntity* AddDummyObject(const char* Name=NULL,void* Key=NULL);
|
|
CK3dEntity* RegisterDummyObject(CK3dEntity* Dummy, void* Key=NULL);
|
|
CKPlace* AddPlace(const char* Name=NULL,void* Key=NULL);
|
|
CK3dObject* Add3dObject(const char* Name=NULL,void* Key=NULL);
|
|
CKSprite3D* Add3dSprite(const char* Name=NULL,void* Key=NULL);
|
|
CKBodyPart* AddCharacterBodyPart(const char* Name=NULL,void* Key=NULL);
|
|
|
|
CKLight* AddLight(BOOL Target,VXLIGHT_TYPE Type,const char* Name=NULL,void* Key=NULL, BOOL iCreateTarget=TRUE);
|
|
CKCamera* AddCamera(BOOL Target,const char* Name=NULL,void* Key=NULL, BOOL iCreateTarget=TRUE);
|
|
|
|
CKCurve* AddCurve(const char* Name=NULL,void* Key=NULL);
|
|
CKCurvePoint* AddCurvePoint(CKCurve* curve,const char* Name=NULL,void* Key=NULL);
|
|
|
|
//--- Animation
|
|
CKObjectAnimation* AddObjectAnimation(CK3dEntity* AnimatedEntity,const char* Name=NULL,void* Key=NULL);
|
|
void AddObjectAnimation(CKObjectAnimation* anim,void* Key=NULL);
|
|
|
|
|
|
//---- Utilities
|
|
CKGroup* AddGroup(const char* Name=NULL,void* Key=NULL);
|
|
CKKeyedAnimation* CreateGlobalAnimation(const char* Name);
|
|
CKCharacter* CreateCharacter(const char* Name);
|
|
void SetCharacter(CKCharacter* character);
|
|
|
|
//---- Automatic Mesh Spliting and Channel Application with composite material.
|
|
void SetSplitMesh(bool v){m_SplitMesh=v;}
|
|
bool GetSplitMesh(){return m_SplitMesh;}
|
|
|
|
//---- Parameters Utilities
|
|
CKParameter* GetObjParameter( CKObject* v, CK_CLASSID iClassID=CKCID_OBJECT);
|
|
CKParameter* GetFloatParameter( float v);
|
|
CKParameter* GetIntParameter( int v);
|
|
CKParameter* GetStringParameter( char* v);
|
|
|
|
//----PostProcess-- May need to be put elsewhere later on---------------------------------------------------------------------------
|
|
int ForceTextureResize(ETextureResizeMethod Method, bool Square);
|
|
|
|
//Reduce Animation Keys based on a Threshold
|
|
int ReduceAnimKeys( CKKeyedAnimation* pAnim, float pThreshold, int pPrecision, EEvalMethod method= eAuto );
|
|
int ReduceAnimBlendShapesKeys( CKKeyedAnimation* pAnim, float pThreshold, int pPrecision, EEvalMethod method= eAuto );
|
|
int RemoveSingleKeyAnimation( CKKeyedAnimation* pAnim );
|
|
|
|
//ConvertReferential
|
|
int ConvertObjectReferential( CKObject* obj, EAxis XAxisInVirtools, EAxis YAxisInVirtools, EAxis ZAxisInVirtools );
|
|
int ConvertAllReferential( EAxis XAxisInVirtools, EAxis YAxisInVirtools, EAxis ZAxisInVirtools );
|
|
|
|
//Rescale Scene's Units
|
|
int RescaleObject(CKObject* obj, float factor);
|
|
int RescaleScene( float factor);
|
|
|
|
//Detect And Share Identical ...
|
|
int DASIMeshes( CKMesh* p, XObjectPointerArray* s, XArray<CK_ID> &toDelete );
|
|
int DASIMeshesGlobal();
|
|
int DASIAnimations( CKObjectAnimation* p, XObjectPointerArray* s );
|
|
int DASIAnimationsGlobal();
|
|
int DASIMaterials( CKMaterial* p, XObjectPointerArray* s, XArray<CK_ID> &toDelete );
|
|
int DASIMaterialsGlobal();
|
|
int DASITextures(CKTexture* p, XObjectPointerArray* s, XArray<CK_ID> &toDelete );
|
|
int DASITexturesGlobal();
|
|
|
|
//LOD
|
|
int FindNamedLOD( CKMesh* p, XObjectPointerArray* s, CKSTRING suffix, int numOfDigits, XArray<CK_ID> &toDelete );
|
|
int FindNamedLODGlobal( CKSTRING suffix, int numOfDigits );
|
|
|
|
//ReadChannels Settings from file
|
|
int ReadChannels( CKSTRING filename );
|
|
int GetArgsFromString( const XString &s, XClassArray<XString> &Args );
|
|
|
|
//-- Automatic HierarchicalHide on 3DEntity without meshes to speed up culing on characters
|
|
int AutoHideHierarchyGlobal();
|
|
|
|
//Use this to set the level export options
|
|
VirtoolsLevel* GetVirtoolsLevel(){return &m_VirtoolsLevelSettings;}
|
|
|
|
//The log must be started and closed manually
|
|
GeLog* m_FileLog;
|
|
//---------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
//---- Created Object access (GetEntityByKey works for bodyparts,3DObjects,places and dummy)
|
|
CK3dEntity* GetEntityByKey (void* Key) { FINDHASH(m_Entities ,CK3dEntity*) }
|
|
CKMesh* GetMeshByKey (void* Key) { FINDHASH(m_Meshes ,CKMesh*) }
|
|
CKMaterial* GetMaterialByKey(void* Key) { FINDHASH(m_Materials ,CKMaterial*) }
|
|
CKTexture* GetTextureByKey (void* Key) { FINDHASH(m_Textures ,CKTexture*) }
|
|
CKLight* GetLightByKey (void* Key) { FINDHASH(m_Lights ,CKLight*) }
|
|
CKCamera* GetCameraByKey (void* Key) { FINDHASH(m_Cameras ,CKCamera*) }
|
|
CKGroup* GetGroupByKey (void* Key) { FINDHASH(m_Groups ,CKGroup*) }
|
|
CKObjectAnimation* GetObjectAnimByKey(void* Key) { FINDHASH(m_ObjectAnimations ,CKObjectAnimation*) }
|
|
|
|
CKCharacter* GetCharacter() { return m_Character; }
|
|
CKKeyedAnimation* GetGlobalAnimation() { return m_GlobalAnimation; }
|
|
|
|
VirtoolsTransitionMesh* GetTransitionMesh(void* Key){
|
|
XIntHashTableIt it=m_TransitionMeshIndices.Find(Key);
|
|
return (it==m_TransitionMeshIndices.End()) ? NULL : &m_VirtoolsTmpMesh[*it];
|
|
}
|
|
|
|
VirtoolsCompositeMaterial* GetCompositeMaterialByKey(CKMaterial* Key)
|
|
{
|
|
XCmpMatHashTableIt it=m_CompositeMaterials.Find(Key);
|
|
if(it==m_CompositeMaterials.End() ) return NULL;
|
|
|
|
return &(m_VirtoolsTmpComposite[*it]);
|
|
}
|
|
|
|
|
|
//---- If the created animations should be applied to existing objects or
|
|
//---- to a specific character
|
|
void ResolveAnimationsTargets(CKCharacter *carac = NULL);
|
|
|
|
//----- Call this to set specific creation options
|
|
void SetObjectsCreationOptions(CK_OBJECTCREATION_OPTIONS Options) { m_CreationOptions = Options; }
|
|
|
|
//---- Functions used to create scripts, add attributes, and modify local params
|
|
BOOL Load( CKContext *ctx, char *fileName, CKObjectArray *m_GeneratedArray );
|
|
BOOL AttachScript( CKBeObject *beo, char *scriptName );
|
|
BOOL SetParam( CKBeObject *beo, char *paramName, char *strValue );
|
|
BOOL SetAttribute( CKBeObject *beo, char *attributeName, char *strValue, char *strType, char *strCategory );
|
|
|
|
void DestroyObject(CKObject* obj, void* iKey);
|
|
// void DestroyObject(CK_ID id);
|
|
// void DestroyObject(CKObject* obj) {DestroyObject(obj->GetID());};
|
|
|
|
protected:
|
|
//-- Created Objects
|
|
XObjectHashTable m_Entities,m_Meshes,m_Materials,m_Textures,
|
|
m_ObjectAnimations,m_Lights,m_Cameras,m_Groups;
|
|
|
|
XIntHashTable m_TransitionMeshIndices;
|
|
|
|
//-- Hash table by filename
|
|
XTextureHashTable m_TextureByName;
|
|
|
|
//-- Hash table to retreive a composite material with the base material
|
|
XCmpMatHashTable m_CompositeMaterials;
|
|
|
|
//-- Generated character and animation
|
|
CKCharacter* m_Character;
|
|
CKKeyedAnimation* m_GlobalAnimation;
|
|
|
|
//-- Generated List
|
|
XObjectPointerArray m_AllObjects;
|
|
|
|
//--Level Settings for Produce CMO
|
|
VirtoolsLevel m_VirtoolsLevelSettings;
|
|
|
|
//-- Internal Data
|
|
XArray<VirtoolsVertex> m_VerticesPool;
|
|
CKContext* m_Context;
|
|
XObjectPointerArray m_OAnimations;
|
|
XObjectPointerArray m_Bodyparts;
|
|
XClassArray<VirtoolsTransitionMesh> m_VirtoolsTmpMesh;
|
|
XClassArray<VirtoolsCompositeMaterial> m_VirtoolsTmpComposite;
|
|
XArray< VirtoolsTexture > m_VirtoolsTmpTexture;
|
|
|
|
//-- Creation options
|
|
CK_OBJECTCREATION_OPTIONS m_CreationOptions;
|
|
|
|
//-- Utilities
|
|
int ProduceCMO( CKObjectArray* array );
|
|
int GetForceSize(int s, ETextureResizeMethod Method);
|
|
void AppendParents( CK3dEntity* e, XArray<CK3dEntity*> &meshParents, int n=-1);
|
|
|
|
//-- ReduceAnimation
|
|
//4 algorithms to reduce keys of an animation controller
|
|
//Last one is an example for new algorithms
|
|
//The Compute fitting function is used to compute a fitting factor to compare algorithms together
|
|
int ReduceAnimController(CKObjectAnimation* oa, float pThreshold, int pPrecision, EAnimType pAnimType, EEvalMethod method, int bsIndex = 0);
|
|
CKANIMATION_CONTROLLER RemoveKeysThreshold ( CKAnimController* acOriginal, CKAnimController* &acReduce, CKObjectAnimation* oaReduce, float pThreshold );
|
|
CKANIMATION_CONTROLLER ResampleLinear ( CKAnimController* acOriginal, CKAnimController* &acReduce, CKObjectAnimation* oaReduce, float pThreshold );
|
|
CKANIMATION_CONTROLLER ResampleTCB ( CKAnimController* acOriginal, CKAnimController* &acReduce, CKObjectAnimation* oaReduce, float pThreshold );
|
|
CKANIMATION_CONTROLLER ResampleBezier ( CKAnimController* acOriginal, CKAnimController* &acReduce, CKObjectAnimation* oaReduce, float pThreshold );
|
|
CKANIMATION_CONTROLLER ResampleMyNewAlgorithm( CKAnimController* acOriginal, CKAnimController* &acReduce, CKObjectAnimation* oaReduce, float pThreshold );
|
|
float ComputeFitting( CKAnimController* acOriginal, CKAnimController* acNew);
|
|
void WriteExcelAnimController( CKAnimController* ac, const char* file, EAnimType pAnimType, int samplePerKey );
|
|
|
|
//-- SMBCM: SplitMeshByCompositeMaterial
|
|
bool m_SplitMesh;
|
|
int SplitMeshByCompositeMaterial(CKMesh* toSplit, XArray<CKMesh*> &result);
|
|
int SplitMeshByCompositeMaterialGlobal();
|
|
CKMesh* SMBCMExtract(CKMesh* ref, CKMesh* newMesh, CompositeMtlInfo* info);
|
|
CKMesh* SMBCMFlatten(CKMesh* newMesh, VirtoolsCompositeMaterial* cm);
|
|
int SMBCMRelink(XArray<CKMesh*> &result, XArray< CompositeMtlInfo > &infoArray);
|
|
CKSkin* SMBCMRelinkSkin(VirtoolsSkin* old, CK3dEntity* ent, CompositeMtlInfo* info );
|
|
bool SMBCMRelinkSkinChangeRef( CK3dEntity* cur, CK3dEntity*ent);
|
|
CKObjectAnimation* SMBCMRelinkMorph(CKObjectAnimation* old, CK3dEntity* ent, CompositeMtlInfo* info, XArray<CKKeyedAnimation*> &AllAnimations );
|
|
|
|
//-- Component Comparaison utilities
|
|
bool Compare(CKMesh* m1, CKMesh* m2, XString message); //replace CKMesh::Compare( CKMesh* m )
|
|
bool Compare(CKMaterial* m1, CKMaterial* m2, XString message); //replace CKMaterial::Compare( CKMaterial* m )
|
|
bool Compare(CKTexture* t1, CKTexture* t2, XString message); //replace CKTexture::Compare( CKTexture* t )
|
|
|
|
//-- LOD Utilities
|
|
bool ExtractNamedLOD( CKSTRING suffix, int numOfDigits, CKSTRING pName, CKSTRING curName );
|
|
|
|
//-- Cleanup
|
|
CKMaterial* RemoveMaterialIfNotUse(CKMaterial* m);
|
|
void RemoveUnusedMaterials();
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif |