ok. my changes follow.
I’ve just realised that the original problem was to import into Max. My changes are for export from Max, so I haven’t helped your problem here.
However, I have fixed the export from Max plugin which did have issues for us and previously we couldn’t export animation from max at all but now we can.
We don’t have any problems importing animation into Max, because the animators will probably use fbx which comes with Maya and Max.
Please enable ‘KEVT_MATRICES’ by activating the #define. Exporting as matrices works fine and is not really slow. You will get both skeleton and skeletal animation exporting ok, and you’ll get <matrix> under <node> and matrix data in the animation arrays - same as maya collada exporter generates.
Exporting as seperate translate,rotate,scale is very slow , by disabling ‘KEVT_MATRICES’ and needs a lot of optimisation to make it useable; for example if a transform is driving the position, rotation and scale, it will actually sample this 3 times. I haven’t changed this yet.
But, it works much better than it used to and actually generates more reasonable data.
I have tested the export with matrices with some of our animations.
Following is a unified diff.
— orig.cpp 2005-08-22 14:36:00.312244600 +0100
+++ shared/ColladaExporter.cpp 2005-08-19 14:58:46.000000000 +0100
@@ -18,8 +18,8 @@
#include “IGameModifier.h”
#include “IConversionManager.h”
#include “IGameError.h”
-//#define KEVT_MATRICES
+
+//#define KEVT_MATRICES
// exporter’s class ID
#define COALLADAEXPORTER_CLASS_ID Class_ID(0x18466e01, 0x17b5275b)
@@ -86,11 +86,11 @@
PropMapper mapper; // value mapper if not NULL
Tab<TSTR*> targets; // channel targets
Tab<TSTR*> subanims; // subanim IDs
-
Tab<TSTR*> params;
-
IGameNode *n;
@@ -103,7 +103,7 @@
TSTR& getTarget(int i) { return i < 0 ? paramID : *targets[i]; }
TSTR& getSubanimID(int i) { return i < 0 ? animID : *subanims[i]; }
@@ -150,9 +150,9 @@
}
void setSubanims(TCHAR* sx, TCHAR* sy, TCHAR* sz) {
-
TSTR * ps[3] = { new TSTR(sx), new TSTR(sy), new TSTR(sz) };
-
params.Append(3, (TSTR**)&ps);
-
-
TSTR * ps[3] = { new TSTR(sx), new TSTR(sy), new TSTR(sz) };
-
params.Append(3, (TSTR**)&ps);
-
clearSubanims();
TSTR prefix = objectID + TSTR(_T("-")) + paramID + TSTR(_T("-"));
TSTR* ns[3] = { new TSTR(prefix), new TSTR(prefix), new TSTR(prefix) };
@@ -258,7 +258,7 @@
pt_string,
pt_name,
pt_bool,
-
pt_matrix,
};
static TCHAR* typeNames[];
@@ -274,7 +274,8 @@
_T(“int”),
_T(“string”),
_T(“Name”),
- _T(“bool”),
- _T(“matrix”),
};
class ColladaExporterClassDesc:public ClassDesc2
@@ -669,7 +670,9 @@
// create COLLADA node and its attribs
CreateXMLNode(pXMLDoc, pRoot, _T(“COLLADA”), &colladaNode);
AddXMLAttribute(colladaNode, _T(“xmlns”), _T(“http://www.collada.org/2005/COLLADASchema”));
- AddXMLAttribute(colladaNode, _T(“version”), _T(“1.2.3”));
+// kevt
- AddXMLAttribute(colladaNode, _T(“version”), _T(“1.3.2”));
- // add <asset> node
CComPtr<IXMLDOMNode> assetNode;
CComPtr<IXMLDOMNode> tempNode;
@@ -694,14 +697,14 @@
tempNode = NULL;
CreateXMLNode(pXMLDoc, assetNode, _T(“up_axis”), &tempNode);
AddXMLText(pXMLDoc, tempNode, _T(“Z_UP”));
-
- // kevt
- CComPtr<IXMLDOMNode> unitNode;
- CreateXMLNode(pXMLDoc, assetNode, _T(“unit”), &unitNode);
- AddXMLAttribute(unitNode, _T(“name”), _T(“generic”));
- // get internal units in terms of meters
- buf.printf(“%g”,GetMasterScale(UNITS_METERS));
- AddXMLAttribute(unitNode, _T(“meter”), buf);
-
- // kevt
- CComPtr<IXMLDOMNode> unitNode;
- CreateXMLNode(pXMLDoc, assetNode, _T(“unit”), &unitNode);
- AddXMLAttribute(unitNode, _T(“name”), _T(“generic”));
- // get internal units in terms of meters
- buf.printf(“%g”,GetMasterScale(UNITS_METERS));
- AddXMLAttribute(unitNode, _T(“meter”), buf);
}
void
@@ -856,36 +859,37 @@
void
ColladaExporter::AddSceneNodes(CComPtr<IXMLDOMNode>& rootNode, IGameNode* node)
{
- // kevt: if hidden then don’t export!
- if (node->IsNodeHidden())
-
return;
-
- // kevt: if hidden then don’t export!
- if (node->IsNodeHidden())
-
return;
- // add <node> nodes for this node and its children
TSTR buf, nodeID, nodeName = node->GetName(); cleanID(nodeName);
makeNodeID(node, nodeID);
-
// optional insert node for pivot if objectOffsetTM is non-ident
-
CComPtr<IXMLDOMNode> parentNode = AddPivotNode(rootNode, node, nodeName);
// add <node>
CComPtr<IXMLDOMNode> nodeNode, instNode, transNode, rotNode, scaleNode;
-
CreateXMLNode(pXMLDoc, parentNode, _T(“node”), &nodeNode); // <node>
- CreateXMLNode(pXMLDoc, rootNode, _T(“node”), &nodeNode); // <node>
AddXMLAttribute(nodeNode, _T(“id”), nodeID);
AddXMLAttribute(nodeNode, _T(“name”), nodeName);
- // kevt:
- // optional insert node for pivot if objectOffsetTM is non-ident
- // this is not inherited!
- CComPtr<IXMLDOMNode> pivotNode = AddPivotNode(nodeNode, node, nodeName);
-
-
-
// kevt:
-
// optional insert node for pivot if objectOffsetTM is non-ident
-
// this is not inherited!
-
CComPtr<IXMLDOMNode> pivotNode = AddPivotNode(nodeNode, node, nodeName);
-
-
// add <instance> based on class
IGameObject* obj = node->GetIGameObject();
TSTR objID; makeObjectID(obj, objID, node);
switch (obj->GetIGameType()) {
case IGameObject::IGAME_MESH:
-
{
-
// kevt:
-
// put mesh under pivot node, or parent node if pivot is ident
-
CreateXMLNode(pXMLDoc, pivotNode, _T("instance"), &instNode); // <instance>
if (obj->IsObjectXRef()) {
// xref, url is external file
// construct valid xref file URI with .dae suffix
@@ -899,10 +903,11 @@
else
// url is baseObj id
AddXMLAttribute(instNode, _T(“url”), TSTR(_T(“#”)) + (IsSkinned(obj, node) ? TSTR(_T(“skin-”)) : TSTR()) + objID);
-
CreateXMLNode(pXMLDoc, pivotNode, _T("instance"), &instNode); // <instance>
AddXMLAttribute(instNode, _T("url"), TSTR(_T("#")) + objID);
break;
@@ -910,19 +915,23 @@
break;
case IGameObject::IGAME_CAMERA:
-
CreateXMLNode(pXMLDoc, pivotNode, _T("instance"), &instNode); // <instance>
AddXMLAttribute(instNode, _T("url"), TSTR(_T("#")) + objID);
break;
case IGameObject::IGAME_HELPER:
-// kevt; both of these work now
-#ifdef KEVT_MATRICES
-
// world space transformation of the node at the current time
-
Matrix3 tm = node->GetMaxNode()->GetNodeTM(0);
-
Matrix3 iParentTM(1);
-
-
// world space transformation of the node's parent at the current time
-
IGameNode *parent = node->GetNodeParent();
-
if (parent != NULL) iParentTM = parent->GetMaxNode()->GetNodeTM(0);
-
iParentTM.Invert();
-
-
// local matrix relative to parent
-
tm = tm * iParentTM;
-
-
CComPtr<IXMLDOMNode> matrixNode;
-
CreateXMLNode(pXMLDoc, nodeNode, _T("matrix"), &matrixNode); // <scale>
-
-
// if any channel is animated then matrix is animated
-
IGameControl* c = node->GetIGameControl();
-
-
if (
-
// biped controlls can say they are not animated yet they have keys
-
(c->GetIGameKeyCount(IGAME_POS)!=0) ||
-
(c->GetIGameKeyCount(IGAME_ROT)!=0) ||
-
(c->GetIGameKeyCount(IGAME_SCALE)!=0) ||
-
c->IsAnimated(IGAME_POS) ||
-
c->IsAnimated(IGAME_ROT) ||
-
c->IsAnimated(IGAME_SCALE)
-
)
-
{
-
AddXMLAttribute(matrixNode, _T("sid"), _T("transform"));
-
}
-
-
// this code converts from max matrix to collada matrix and outputs it in the collada form
-
float matrix[4][4];
-
-
Point3 row = tm.GetRow(0);
-
-
matrix[0][0] = row.x;
-
matrix[1][0] = row.y;
-
matrix[2][0] = row.z;
-
-
row = tm.GetRow(1);
-
-
matrix[0][1] = row.x;
-
matrix[1][1] = row.y;
-
matrix[2][1] = row.z;
-
-
row = tm.GetRow(2);
-
-
matrix[0][2] = row.x;
-
matrix[1][2] = row.y;
-
matrix[2][2] = row.z;
-
-
Point3 t = tm.GetRow(3);
-
-
matrix[0][3] = t.x;
-
matrix[1][3] = t.y;
-
matrix[2][3] = t.z;
-
matrix[3][3] = 1.0f;
-
-
// fill unused elements
-
matrix[3][0] = 0.0f;
-
matrix[3][1] = 0.0f;
-
matrix[3][2] = 0.0f;
-
-
-
buf.printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g",
-
matrix[0][0],
-
matrix[0][1],
-
matrix[0][2],
-
matrix[0][3],
-
matrix[1][0],
-
matrix[1][1],
-
matrix[1][2],
-
matrix[1][3],
-
matrix[2][0],
-
matrix[2][1],
-
matrix[2][2],
-
matrix[2][3],
-
matrix[3][0],
-
matrix[3][1],
-
matrix[3][2],
-
matrix[3][3]);
-
-
AddXMLText(pXMLDoc, matrixNode, buf);
-
-
-#else
+// kevt; both of these work now
+#ifdef KEVT_MATRICES
-
// world space transformation of the node at the current time
-
Matrix3 tm = node->GetMaxNode()->GetNodeTM(0);
-
Matrix3 iParentTM(1);
-
-
// world space transformation of the node's parent at the current time
-
IGameNode *parent = node->GetNodeParent();
-
if (parent != NULL) iParentTM = parent->GetMaxNode()->GetNodeTM(0);
-
iParentTM.Invert();
-
-
// local matrix relative to parent
-
tm = tm * iParentTM;
-
-
CComPtr<IXMLDOMNode> matrixNode;
-
CreateXMLNode(pXMLDoc, nodeNode, _T("matrix"), &matrixNode); // <scale>
-
-
// if any channel is animated then matrix is animated
-
IGameControl* c = node->GetIGameControl();
-
-
if (
-
// biped controlls can say they are not animated yet they have keys
-
(c->GetIGameKeyCount(IGAME_POS)!=0) ||
-
(c->GetIGameKeyCount(IGAME_ROT)!=0) ||
-
(c->GetIGameKeyCount(IGAME_SCALE)!=0) ||
-
c->IsAnimated(IGAME_POS) ||
-
c->IsAnimated(IGAME_ROT) ||
-
c->IsAnimated(IGAME_SCALE)
-
)
-
{
-
AddXMLAttribute(matrixNode, _T("sid"), _T("transform"));
-
}
-
-
// this code converts from max matrix to collada matrix and outputs it in the collada form
-
float matrix[4][4];
-
-
Point3 row = tm.GetRow(0);
-
-
matrix[0][0] = row.x;
-
matrix[1][0] = row.y;
-
matrix[2][0] = row.z;
-
-
row = tm.GetRow(1);
-
-
matrix[0][1] = row.x;
-
matrix[1][1] = row.y;
-
matrix[2][1] = row.z;
-
-
row = tm.GetRow(2);
-
-
matrix[0][2] = row.x;
-
matrix[1][2] = row.y;
-
matrix[2][2] = row.z;
-
-
Point3 t = tm.GetRow(3);
-
-
matrix[0][3] = t.x;
-
matrix[1][3] = t.y;
-
matrix[2][3] = t.z;
-
matrix[3][3] = 1.0f;
-
-
// fill unused elements
-
matrix[3][0] = 0.0f;
-
matrix[3][1] = 0.0f;
-
matrix[3][2] = 0.0f;
-
-
-
buf.printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g",
-
matrix[0][0],
-
matrix[0][1],
-
matrix[0][2],
-
matrix[0][3],
-
matrix[1][0],
-
matrix[1][1],
-
matrix[1][2],
-
matrix[1][3],
-
matrix[2][0],
-
matrix[2][1],
-
matrix[2][2],
-
matrix[2][3],
-
matrix[3][0],
-
matrix[3][1],
-
matrix[3][2],
-
matrix[3][3]);
-
-
AddXMLText(pXMLDoc, matrixNode, buf);
-
-
+#else
// set up various transforms and decompose node TM into affine parts
Matrix3 tm = node->GetMaxNode()->GetNodeTM(0);
Matrix3 iparentTM(1);
IGameNode* parent = node->GetNodeParent();
if (parent != NULL) iparentTM = parent->GetMaxNode()->GetNodeTM(0);
iparentTM.Invert();
-
tm = tm * iparentTM;
-
-
Point3 row1 = tm.GetRow(0);
-
Point3 row2 = tm.GetRow(1);
-
Point3 row3 = tm.GetRow(2);
-
Point3 row4 = tm.GetRow(3);
-
-
Matrix3 TransposedTM;
-
-
Point4 column1;
-
Point4 column2;
-
Point4 column3;
-
-
column1.x = row1.x;
-
column1.y = row1.y;
-
column1.z = row1.z;
-
column1.w = row4.x;
-
-
column2.x = row2.x;
-
column2.y = row2.y;
-
column2.z = row2.z;
-
column2.w = row4.y;
-
-
column3.x = row3.x;
-
column3.y = row3.y;
-
column3.z = row3.z;
-
column3.w = row4.z;
-
-
TransposedTM.SetColumn(0, column1);
-
TransposedTM.SetColumn(1, column2);
-
TransposedTM.SetColumn(2, column3);
-
-
-
tm = tm * iparentTM;
-
-
Point3 row1 = tm.GetRow(0);
-
Point3 row2 = tm.GetRow(1);
-
Point3 row3 = tm.GetRow(2);
-
Point3 row4 = tm.GetRow(3);
-
-
Matrix3 TransposedTM;
-
-
Point4 column1;
-
Point4 column2;
-
Point4 column3;
-
-
column1.x = row1.x;
-
column1.y = row1.y;
-
column1.z = row1.z;
-
column1.w = row4.x;
-
-
column2.x = row2.x;
-
column2.y = row2.y;
-
column2.z = row2.z;
-
column2.w = row4.y;
-
-
column3.x = row3.x;
-
column3.y = row3.y;
-
column3.z = row3.z;
-
column3.w = row4.z;
-
-
TransposedTM.SetColumn(0, column1);
-
TransposedTM.SetColumn(1, column2);
-
TransposedTM.SetColumn(2, column3);
-
AffineParts ap;
// translation
CComPtr<IXMLDOMNode> transNode;
CreateXMLNode(pXMLDoc, nodeNode, _T("translate"), &transNode); // <translate>
// check for animation, add sid attrib if so
IGameControl* c = node->GetIGameControl();
-
Point3 p = ap.t;
buf.printf("%g %g %g ", p.x, p.y, p.z);
AddXMLText(pXMLDoc, transNode, buf);
// rotation
CComPtr<IXMLDOMNode> rotNode;
// check for animation, add sid attrib if so
-
bool hasAnim = c->IsAnimated(IGAME_ROT);
-
Point3 mp; Quat mq; Point3 ms;
-
DecomposeMatrix(iparentTM, mp, mq, ms);
-
ap.q = ap.q + mq;
-
// as eulerangles for output
-
float angles[3];
-
Matrix3 qtm;
-
ap.q.MakeMatrix(qtm);
-
MatrixToEuler(qtm, angles, EULERTYPE_XYZ);
-
float angles[3];
-
-
QuatToEuler(ap.q, angles);
-
-
angles[0] = -angles[0];
-
angles[1] = -angles[1];
-
angles[2] = -angles[2];
-
-
CreateXMLNode(pXMLDoc, nodeNode, _T("rotate"), &rotNode); // <rotate> x
if (hasAnim) AddXMLAttribute(rotNode, _T("sid"), _T("RotX"));
buf.printf("1 0 0 %g", RadToDeg(angles[0]));
@@ -1140,25 +1143,16 @@
buf.printf(“0 0 1 %g”, RadToDeg(angles[2]));
AddXMLText(pXMLDoc, rotNode, buf);
-
// scale
-
// get scale in parent coordsys
-
ScaleValue s(ap.k, ap.u);
-
Matrix3 m (1);
-
Matrix3 sm (1);
-
ApplyScaling(sm, s);
-
AffineParts sap;
-
sm = sm * iparentTM;
-
decomp_affine(sm, &sap);
-
Point3 scale = sap.k * sap.f;
-
Point3 scale = ap.k * ap.f;
CComPtr<IXMLDOMNode> scaleNode;
CreateXMLNode(pXMLDoc, nodeNode, _T("scale"), &scaleNode); // <scale>
buf.printf("%g %g %g ", scale.x, scale.y, scale.z);
AddXMLText(pXMLDoc, scaleNode, buf);
-#endif
+
+#endif
}
node->ReleaseIGameObject();
@@ -1179,83 +1173,83 @@
if (opos == Point3::Origin && orot == Quat() && oscale == Point3(1,1,1))
return parentNode; // no need for pivot
- // insert pivot node for objectOffsetTM
- CComPtr<IXMLDOMNode> nodeNode, transNode, rotNode, scaleNode;
-// kevt
-#ifdef KEVT_MATRICES
-
// world space transformation of the node at the current time
-
Matrix3 tm(1);
-
tm.PreTranslate(opos);
-
PreRotateMatrix(tm, orot);
-
ScaleValue scaleValue = maxNode->GetObjOffsetScale();
-
ApplyScaling(tm, scaleValue);
-
-
CComPtr<IXMLDOMNode> matrixNode;
-
CreateXMLNode(pXMLDoc, nodeNode, _T("matrix"), &matrixNode); // <matrix>
-
-
// this code converts from max matrix to collada matrix and outputs it in the collada form
-
float matrix[4][4];
-
-
Point3 row = tm.GetRow(0);
-
-
matrix[0][0] = row.x;
-
matrix[1][0] = row.y;
-
matrix[2][0] = row.z;
-
-
row = tm.GetRow(1);
-
-
matrix[0][1] = row.x;
-
matrix[1][1] = row.y;
-
matrix[2][1] = row.z;
-
-
row = tm.GetRow(2);
-
-
matrix[0][2] = row.x;
-
matrix[1][2] = row.y;
-
matrix[2][2] = row.z;
-
-
Point3 t = tm.GetRow(3);
-
-
matrix[0][3] = t.x;
-
matrix[1][3] = t.y;
-
matrix[2][3] = t.z;
-
matrix[3][3] = 1.0f;
-
-
// fill unused elements
-
matrix[3][0] = 0.0f;
-
matrix[3][1] = 0.0f;
-
matrix[3][2] = 0.0f;
-
-
-
buf.printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g",
-
matrix[0][0],
-
matrix[0][1],
-
matrix[0][2],
-
matrix[0][3],
-
matrix[1][0],
-
matrix[1][1],
-
matrix[1][2],
-
matrix[1][3],
-
matrix[2][0],
-
matrix[2][1],
-
matrix[2][2],
-
matrix[2][3],
-
matrix[3][0],
-
matrix[3][1],
-
matrix[3][2],
-
matrix[3][3]);
-
-
AddXMLText(pXMLDoc, matrixNode, buf);
-
-
-#else
- // insert pivot node for objectOffsetTM
+// kevt
+#ifdef KEVT_MATRICES
-
// world space transformation of the node at the current time
-
Matrix3 tm(1);
-
tm.PreTranslate(opos);
-
PreRotateMatrix(tm, orot);
-
ScaleValue scaleValue = maxNode->GetObjOffsetScale();
-
ApplyScaling(tm, scaleValue);
-
-
CComPtr<IXMLDOMNode> matrixNode;
-
CreateXMLNode(pXMLDoc, nodeNode, _T("matrix"), &matrixNode); // <matrix>
-
-
// this code converts from max matrix to collada matrix and outputs it in the collada form
-
float matrix[4][4];
-
-
Point3 row = tm.GetRow(0);
-
-
matrix[0][0] = row.x;
-
matrix[1][0] = row.y;
-
matrix[2][0] = row.z;
-
-
row = tm.GetRow(1);
-
-
matrix[0][1] = row.x;
-
matrix[1][1] = row.y;
-
matrix[2][1] = row.z;
-
-
row = tm.GetRow(2);
-
-
matrix[0][2] = row.x;
-
matrix[1][2] = row.y;
-
matrix[2][2] = row.z;
-
-
Point3 t = tm.GetRow(3);
-
-
matrix[0][3] = t.x;
-
matrix[1][3] = t.y;
-
matrix[2][3] = t.z;
-
matrix[3][3] = 1.0f;
-
-
// fill unused elements
-
matrix[3][0] = 0.0f;
-
matrix[3][1] = 0.0f;
-
matrix[3][2] = 0.0f;
-
-
-
buf.printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g",
-
matrix[0][0],
-
matrix[0][1],
-
matrix[0][2],
-
matrix[0][3],
-
matrix[1][0],
-
matrix[1][1],
-
matrix[1][2],
-
matrix[1][3],
-
matrix[2][0],
-
matrix[2][1],
-
matrix[2][2],
-
matrix[2][3],
-
matrix[3][0],
-
matrix[3][1],
-
matrix[3][2],
-
matrix[3][3]);
-
-
AddXMLText(pXMLDoc, matrixNode, buf);
-
-
+#else
- // insert pivot node for objectOffsetTM
CreateXMLNode(pXMLDoc, nodeNode, _T(“translate”), &transNode); // <translate>
- TSTR buf; buf.printf(“%g %g %g”, opos.x, opos.y, opos.z);
-
buf.printf(“%g %g %g”, opos.x, opos.y, opos.z);
AddXMLText(pXMLDoc, transNode, buf);
float rx, ry, rz;
orot.GetEuler(&rx, &ry, &rz) ;
@@ -1273,7 +1267,7 @@
CreateXMLNode(pXMLDoc, nodeNode, _T(“scale”), &scaleNode); // <scale>
buf.printf(“%g %g %g”, oscale.x, oscale.y, oscale.z);
AddXMLText(pXMLDoc, scaleNode, buf);
-#endif
+#endif
return nodeNode;
}
@@ -1283,44 +1277,22 @@
void
ColladaExporter::AddCameraNodes(CComPtr<IXMLDOMNode>& libNode, IGameNode* node)
{
- // add <camera> library node for nodes that are cameras
- IGameObject* obj = node->GetIGameObject();
- if (obj->GetIGameType() == IGameObject::IGAME_CAMERA) {
-
TSTR objID; makeObjectID(obj, objID, node);
-
IGameCamera* cam = (IGameCamera*)obj;
-
CameraObject* camObj = (CameraObject*)cam->GetMaxObject();
-
if (obj->GetIGameType() == IGameObject::IGAME_CAMERA) {
-
TSTR objID; makeObjectID(obj, objID, node);
-
IGameCamera* cam = (IGameCamera*)obj;
-
CameraObject* camObj = (CameraObject*)cam->GetMaxObject();
-
CComPtr<IXMLDOMNode> camNode, techNode, optNode, progNode, paramNode;
-
CreateXMLNode(pXMLDoc, libNode, _T("camera"), &camNode); // <camera>
-
AddXMLAttribute(camNode, _T("id"), objID);
-
AddXMLAttribute(camNode, _T("name"), objID);
-
CreateXMLNode(pXMLDoc, camNode, _T("technique"), &techNode); // <technique>
-
AddXMLAttribute(techNode, _T("profile"), _T("COMMON"));
-
CreateXMLNode(pXMLDoc, techNode, _T("optics"), &optNode); // <optics>
-
CreateXMLNode(pXMLDoc, optNode, _T("program"), &progNode); // <program>
-
// add perspective or ortho attribs & props
-
if (camObj->IsOrtho()) {
-
AddXMLAttribute(progNode, _T("url"), _T("ORTHOGRAPHIC"));
-
AddXMLAttribute(progNode, _T("name"), _T("ORTHOGRAPHIC"));
-
}
-
else {
-
AddXMLAttribute(progNode, _T("url"), _T("PERSPECTIVE"));
-
AddXMLAttribute(progNode, _T("name"), _T("PERSPECTIVE"));
-
float fov; cam->GetCameraFOV()->GetPropertyValue(fov);
-
AddParamValNode(progNode, _T("YFOV"), pt_float, _T("IN"), RadToDeg(fov), (cam->GetCameraFOV()->IsPropAnimated() ? _T("FOV") : NULL));
-
}
-
// add common props
-
float n; cam->GetCameraNearClip()->GetPropertyValue(n);
-
AddParamValNode(progNode, _T("ZNEAR"), pt_float, _T("IN"), n, (cam->GetCameraNearClip()->IsPropAnimated() ? _T("NearClip") : NULL));
-
float f; cam->GetCameraFarClip()->GetPropertyValue(f);
-
AddParamValNode(progNode, _T("ZFAR"), pt_float, _T("IN"), f, (cam->GetCameraFarClip()->IsPropAnimated() ? _T("FarClip") : NULL));
-
// if target, add 3DSMAX technique
-
INode* target = node->GetMaxNode()->GetTarget();
-
if (target != NULL) {
-
techNode = NULL; optNode = NULL; progNode = NULL;
-
CComPtr<IXMLDOMNode> camNode, techNode, optNode, progNode, paramNode;
-
CreateXMLNode(pXMLDoc, libNode, _T("camera"), &camNode); // <camera>
-
AddXMLAttribute(camNode, _T("id"), objID);
-
AddXMLAttribute(camNode, _T("name"), objID);
CreateXMLNode(pXMLDoc, camNode, _T("technique"), &techNode); // <technique>
-
AddXMLAttribute(techNode, _T("profile"), _T("COMMON"));
CreateXMLNode(pXMLDoc, techNode, _T("optics"), &optNode); // <optics>
CreateXMLNode(pXMLDoc, optNode, _T("program"), &progNode); // <program>
// add perspective or ortho attribs & props
@@ -1339,17 +1311,40 @@
AddParamValNode(progNode, _T(“ZNEAR”), pt_float, _T(“IN”), n, (cam->GetCameraNearClip()->IsPropAnimated() ? _T(“NearClip”) : NULL));
float f; cam->GetCameraFarClip()->GetPropertyValue(f);
AddParamValNode(progNode, _T(“ZFAR”), pt_float, _T(“IN”), f, (cam->GetCameraFarClip()->IsPropAnimated() ? _T(“FarClip”) : NULL));
-
// add target ref
-
AddParamNode(progNode, _T("TARGET"), pt_name, _T("IN"), paramNode);
-
IGameNode* targNode = pIgame->GetIGameNode(target);
-
TSTR targID; makeNodeID(targNode, targID);
-
AddXMLText(pXMLDoc, paramNode, targID);
-
}
-
// if target, add 3DSMAX technique
-
INode* target = node->GetMaxNode()->GetTarget();
-
if (target != NULL) {
-
techNode = NULL; optNode = NULL; progNode = NULL;
-
CreateXMLNode(pXMLDoc, camNode, _T("technique"), &techNode); // <technique>
-
AddXMLAttribute(techNode, _T("profile"), _T("MAX3D"));
-
CreateXMLNode(pXMLDoc, techNode, _T("optics"), &optNode); // <optics>
-
CreateXMLNode(pXMLDoc, optNode, _T("program"), &progNode); // <program>
-
// add perspective or ortho attribs & props
-
if (camObj->IsOrtho()) {
-
AddXMLAttribute(progNode, _T("url"), _T("ORTHOGRAPHIC"));
-
AddXMLAttribute(progNode, _T("name"), _T("ORTHOGRAPHIC"));
-
}
-
else {
-
AddXMLAttribute(progNode, _T("url"), _T("PERSPECTIVE"));
-
AddXMLAttribute(progNode, _T("name"), _T("PERSPECTIVE"));
-
float fov; cam->GetCameraFOV()->GetPropertyValue(fov);
-
AddParamValNode(progNode, _T("YFOV"), pt_float, _T("IN"), RadToDeg(fov), (cam->GetCameraFOV()->IsPropAnimated() ? _T("FOV") : NULL));
-
}
-
// add common props
-
float n; cam->GetCameraNearClip()->GetPropertyValue(n);
-
AddParamValNode(progNode, _T("ZNEAR"), pt_float, _T("IN"), n, (cam->GetCameraNearClip()->IsPropAnimated() ? _T("NearClip") : NULL));
-
float f; cam->GetCameraFarClip()->GetPropertyValue(f);
-
AddParamValNode(progNode, _T("ZFAR"), pt_float, _T("IN"), f, (cam->GetCameraFarClip()->IsPropAnimated() ? _T("FarClip") : NULL));
-
// add target ref
-
AddParamNode(progNode, _T("TARGET"), pt_name, _T("IN"), paramNode);
-
IGameNode* targNode = pIgame->GetIGameNode(target);
-
TSTR targID; makeNodeID(targNode, targID);
-
AddXMLText(pXMLDoc, paramNode, targID);
-
}
-
node->ReleaseIGameObject();
// recurse through children nodes
for (int i = 0; i < node->GetChildCount(); i++)
@@ -1361,64 +1356,68 @@
void
ColladaExporter::AddAnimationNodes(CComPtr<IXMLDOMNode>& libNode, IGameNode* node)
{
-
// add <animation> library elements for scene nodes
-
AnimParam ap(node);
-
IGameObject* obj = node->GetIGameObject();
- // export selected animation based on object type
- switch (obj->GetIGameType()) {
-
case IGameObject::IGAME_MESH:
-
AddPRSAnimationNodes(libNode, node, ap);
-
AddMtlAnimationNodes(libNode, node, ap);
-
break;
-
case IGameObject::IGAME_LIGHT: {
-
AddPRSAnimationNodes(libNode, node, ap);
-
// light props
-
IGameLight* lt = (IGameLight*)obj;
-
TSTR ltID; makeObjectID(obj, ltID, node); ap.setObjectID(ltID);
-
ap.setSubanims(_T("R"), _T("G"), _T("B"));
-
ap.setTargets(_T("R"), _T("G"), _T("B"));
-
-
AddPropAnimationNodes2(libNode, ap, lt, _T("Color"), _T("COLOR"), IGAME_POINT3);
-
AddPropAnimationNodes2(libNode, ap, lt, _T("Multiplier"), _T("INTENSITY"), IGAME_FLOAT);
-
if (lt->GetLightType() != IGameLight::IGAME_OMNI) {
-
AddPropAnimationNodes2(libNode, ap, lt, _T("AspectRatio"), _T("ASPECTRATIO"), IGAME_FLOAT);
-
AddPropAnimationNodes2(libNode, ap, lt, _T("Hotspot"), _T("INNERCONE"), IGAME_FLOAT);
-
AddPropAnimationNodes2(libNode, ap, lt, _T("Falloff"), _T("OUTERCONE"), IGAME_FLOAT);
-
case IGameObject::IGAME_MESH:
-
AddPRSAnimationNodes(libNode, node, ap);
-
AddMtlAnimationNodes(libNode, node, ap);
-
break;
-
-
case IGameObject::IGAME_LIGHT: {
-
AddPRSAnimationNodes(libNode, node, ap);
-
// light props
-
IGameLight* lt = (IGameLight*)obj;
-
TSTR ltID; makeObjectID(obj, ltID, node); ap.setObjectID(ltID);
-
ap.setSubanims(_T("R"), _T("G"), _T("B"));
-
ap.setTargets(_T("R"), _T("G"), _T("B"));
-
-
AddPropAnimationNodes2(libNode, ap, lt, _T("Color"), _T("COLOR"), IGAME_POINT3);
-
AddPropAnimationNodes2(libNode, ap, lt, _T("Multiplier"), _T("INTENSITY"), IGAME_FLOAT);
-
if (lt->GetLightType() != IGameLight::IGAME_OMNI) {
-
AddPropAnimationNodes2(libNode, ap, lt, _T("AspectRatio"), _T("ASPECTRATIO"), IGAME_FLOAT);
-
AddPropAnimationNodes2(libNode, ap, lt, _T("Hotspot"), _T("INNERCONE"), IGAME_FLOAT);
-
AddPropAnimationNodes2(libNode, ap, lt, _T("Falloff"), _T("OUTERCONE"), IGAME_FLOAT);
-
}
-
break;
}
-
case IGameObject::IGAME_CAMERA: {
-
AddPRSAnimationNodes(libNode, node, ap);
-
// camera props
-
IGameCamera* cam = (IGameCamera*)obj;
-
CameraObject* camObj = (CameraObject*)cam->GetMaxObject();
-
TSTR camID; makeObjectID(obj, camID, node); ap.setObjectID(camID);
-
if (!camObj->IsOrtho())
-
AddPropAnimationNodes(libNode, ap, cam, _T("FOV"), _T("YFOV"), IGAME_FLOAT, toDegrees);
-
AddPropAnimationNodes(libNode, ap, cam, _T("NearClip"), _T("ZNEAR"), IGAME_FLOAT, toDegrees);
-
AddPropAnimationNodes(libNode, ap, cam, _T("FarClip"), _T("ZFAR"), IGAME_FLOAT, toDegrees);
-
break;
-
}
-
case IGameObject::IGAME_CAMERA: {
-
AddPRSAnimationNodes(libNode, node, ap);
-
// camera props
-
IGameCamera* cam = (IGameCamera*)obj;
-
CameraObject* camObj = (CameraObject*)cam->GetMaxObject();
-
TSTR camID; makeObjectID(obj, camID, node); ap.setObjectID(camID);
-
if (!camObj->IsOrtho())
-
AddPropAnimationNodes(libNode, ap, cam, _T("FOV"), _T("YFOV"), IGAME_FLOAT, toDegrees);
-
AddPropAnimationNodes(libNode, ap, cam, _T("NearClip"), _T("ZNEAR"), IGAME_FLOAT, toDegrees);
-
AddPropAnimationNodes(libNode, ap, cam, _T("FarClip"), _T("ZFAR"), IGAME_FLOAT, toDegrees);
-
break;
-
}
-
case IGameObject::IGAME_BONE:
-
AddPRSAnimationNodes(libNode, node, ap);
-
break;
-
case IGameObject::IGAME_BONE:
-
AddPRSAnimationNodes(libNode, node, ap);
-
break;
- node->ReleaseIGameObject();
-
node->ReleaseIGameObject();
-
}
// recurse through children nodes
for (int i = 0; i < node->GetChildCount(); i++)
@@ -1432,31 +1431,31 @@
IGameControl* c = node->GetIGameControl();
if (c != NULL)
{
-#ifdef KEVT_MATRICES
-
// if any of these are animated then matrix will be animated
-
if (
-
// biped controlls can say they are not animated yet they have keys
-
(c->GetIGameKeyCount(IGAME_POS)!=0) ||
-
(c->GetIGameKeyCount(IGAME_ROT)!=0) ||
-
(c->GetIGameKeyCount(IGAME_SCALE)!=0) ||
-
c->IsAnimated(IGAME_POS) ||
-
c->IsAnimated(IGAME_ROT) ||
-
c->IsAnimated(IGAME_SCALE)
-
)
-
{
-
ap.setAnim(_T("transform"), c, IGAME_TM);
-
AddAnimationNode(libNode, ap);
-
}
-#else
+#ifdef KEVT_MATRICES
-
// if any of these are animated then matrix will be animated
-
if (
-
// biped controlls can say they are not animated yet they have keys
-
(c->GetIGameKeyCount(IGAME_POS)!=0) ||
-
(c->GetIGameKeyCount(IGAME_ROT)!=0) ||
-
(c->GetIGameKeyCount(IGAME_SCALE)!=0) ||
-
c->IsAnimated(IGAME_POS) ||
-
c->IsAnimated(IGAME_ROT) ||
-
c->IsAnimated(IGAME_SCALE)
-
)
-
{
-
ap.setAnim(_T("transform"), c, IGAME_TM);
-
AddAnimationNode(libNode, ap);
-
}
+#else
// pos
Control* pc = c->GetMaxControl(IGAME_POS);
-
if ((pc != NULL && pc->IsAnimated()) || (c->GetIGameKeyCount(IGAME_POS)!=0)) {
ap.setAnim(_T("Translate"), c, IGAME_POS, _T("X"), _T("Y"), _T("Z"), _T("Trans.X"), _T("Trans.Y"), _T("Trans.Z"));
AddAnimationNode(libNode, ap);
}
// rotation
pc = c->GetMaxControl(IGAME_ROT);
-
if ((pc != NULL && pc->IsAnimated()) || (c->GetIGameKeyCount(IGAME_ROT)!=0)) {
ap.setAnim(_T("Rotate"), c, IGAME_ROT, _T("X"), _T("Y"), _T("Z"), _T("RotX.ANGLE"), _T("RotY.ANGLE"), _T("RotZ.ANGLE"));
ap.setMapper(toRotDegrees);
AddAnimationNode(libNode, ap);
@@ -1464,12 +1463,12 @@
}
// scale
pc = c->GetMaxControl(IGAME_SCALE);
-
if ((pc != NULL && pc->IsAnimated()) || (c->GetIGameKeyCount(IGAME_ROT)!=0)) {
ap.setAnim(_T("Scale"), c, IGAME_SCALE, _T("X"), _T("Y"), _T("Z"), _T("Scale.X"), _T("Scale.Y"), _T("Scale.Z"));
AddAnimationNode(libNode, ap);
}
-#endif
+#endif
+
}
}
@@ -1549,7 +1548,7 @@
AddSamplerNode(animNode, ap);
AddChannelNode(animNode, ap);
}
-
}
}
}
@@ -1564,14 +1563,14 @@
// add <source> nodes based on controller type
try {
switch (ap.type) {
-
case IGAME_TM:
-
{
-
AddAnimationSourceNodes(animNode, ap);
-
AddSamplerNode(animNode, ap);
-
AddChannelNode(animNode, ap);
-
}
-
break;
-
-
case IGAME_TM:
-
{
-
AddAnimationSourceNodes(animNode, ap);
-
AddSamplerNode(animNode, ap);
-
AddChannelNode(animNode, ap);
-
}
-
break;
-
case IGAME_FLOAT:
AddAnimationSourceNodes(animNode, ap);
AddSamplerNode(animNode, ap);
@@ -1664,7 +1663,7 @@
CreateXMLNode(pXMLDoc, animNode, _T(“source”), &tsourceNode); // <source> for time
CreateXMLNode(pXMLDoc, animNode, _T(“source”), &vsourceNode); // <source> for values
CreateXMLNode(pXMLDoc, animNode, _T(“source”), &isourceNode); // <source> for interps
- AddXMLAttribute(vsourceNode, _T(“id”), ap.animID);
-
AddXMLAttribute(vsourceNode, _T(“id”), ap.animID + TSTR(_T(“-values”)));
AddXMLAttribute(tsourceNode, _T(“id”), ap.animID + TSTR(_T(“-time”)));
AddXMLAttribute(isourceNode, _T(“id”), ap.animID + TSTR(_T(“-interp”)));
CComPtr<IXMLDOMNode> tarrayNode, varrayNode, iarrayNode, itarrayNode, otarrayNode;
@@ -1675,7 +1674,7 @@
AddXMLAttribute(tarrayNode, _T(“type”), _T(“float”));
CreateXMLNode(pXMLDoc, vsourceNode, _T(“array”), &varrayNode); // <array> for values
- AddXMLAttribute(varrayNode, _T(“id”), ap.animID + TSTR(_T(“-array”)));
-
AddXMLAttribute(varrayNode, _T(“id”), ap.animID + TSTR(_T(“-values-array”)));
AddXMLAttribute(varrayNode, _T(“type”), _T(“float”));
CreateXMLNode(pXMLDoc, isourceNode, _T(“array”), &iarrayNode); // <array> for interps
@@ -1692,7 +1691,7 @@
end = animEnd * pIgame->GetSceneTicks();
numKeys = animEnd - animStart + 1;
-
buf.printf("%d", keys.Count());
AddXMLAttribute(tarrayNode, _T("count"), buf);
AddXMLAttribute(varrayNode, _T("count"), buf);
AddXMLAttribute(iarrayNode, _T("count"), buf);
@@ -1809,7 +1808,7 @@
AddXMLAttribute(techNode, _T(“profile”), _T(“COMMON”));
CreateXMLNode(pXMLDoc, techNode, _T("accessor"), &accessNode); // <accessor>
- AddXMLAttribute(accessNode, _T(“source”), TSTR(_T(“#”)) + ap.animID + TSTR(_T(“-array”)));
- AddXMLAttribute(accessNode, _T(“source”), TSTR(_T(“#”)) + ap.animID + TSTR(_T(“-values-array”)));
buf.printf(“%d”, numKeys);
AddXMLAttribute(accessNode, _T(“count”), buf);
AddXMLAttribute(accessNode, _T(“stride”), _T(“1”));
@@ -1930,162 +1929,162 @@
return;
}
- if (ap.type == IGAME_TM)
- {
-
TSTR buf;
-
-
CComPtr<IXMLDOMNode> tsourceNode, vsourceNode, isourceNode;
-
CreateXMLNode(pXMLDoc, animNode, _T("source"), &tsourceNode); // <source> for time
-
CreateXMLNode(pXMLDoc, animNode, _T("source"), &vsourceNode); // <source> for values
-
AddXMLAttribute(vsourceNode, _T("id"), ap.getSubanimID(subanim) + TSTR(_T("-values")));
-
AddXMLAttribute(tsourceNode, _T("id"), ap.getSubanimID(subanim) + TSTR(_T("-time")));
-
CComPtr<IXMLDOMNode> tarrayNode, varrayNode;
-
CreateXMLNode(pXMLDoc, tsourceNode, _T("array"), &tarrayNode); // <array> for time
-
CreateXMLNode(pXMLDoc, vsourceNode, _T("array"), &varrayNode); // <array> for values
-
-
AddXMLAttribute(tarrayNode, _T("id"), ap.getSubanimID(subanim) + TSTR(_T("-time-array")));
-
AddXMLAttribute(tarrayNode, _T("type"), _T("float"));
-
-
AddXMLAttribute(varrayNode, _T("id"), ap.getSubanimID(subanim) + TSTR(_T("-values-array")));
-
AddXMLAttribute(varrayNode, _T("type"), _T("float"));
-
-
int numKeys;
-
-
numKeys = animEnd - animStart + 1;
-
-
-
buf.printf("%d", numKeys);
-
-
AddXMLAttribute(tarrayNode, _T("count"), buf);
-
-
buf.printf("%d", numKeys*16);
-
-
AddXMLAttribute(varrayNode, _T("count"), buf);
-
-
-
// add <technique> nodes
-
CComPtr<IXMLDOMNode> techNode, accessNode, paramNode;
-
CreateXMLNode(pXMLDoc, tsourceNode, _T("technique"), &techNode); // <technique> for time
-
AddXMLAttribute(techNode, _T("profile"), _T("COMMON"));
-
-
CreateXMLNode(pXMLDoc, techNode, _T("accessor"), &accessNode); // <accessor>
-
AddXMLAttribute(accessNode, _T("source"), TSTR(_T("#")) + ap.getSubanimID(subanim) + TSTR(_T("-time-array")));
-
buf.printf("%d", numKeys);
-
AddXMLAttribute(accessNode, _T("count"), buf);
-
AddXMLAttribute(accessNode, _T("stride"), _T("1"));
-
-
CreateXMLNode(pXMLDoc, accessNode, _T("param"), ¶mNode); // <param>
-
AddXMLAttribute(paramNode, _T("name"), _T("time"));
-
AddXMLAttribute(paramNode, _T("type"), _T("float"));
-
AddXMLAttribute(paramNode, _T("flow"), _T("OUT"));
-
techNode = NULL; accessNode = NULL; paramNode = NULL;
-
-
CreateXMLNode(pXMLDoc, vsourceNode, _T("technique"), &techNode); // <technique> for values
-
AddXMLAttribute(techNode, _T("profile"), _T("COMMON"));
-
-
CreateXMLNode(pXMLDoc, techNode, _T("accessor"), &accessNode); // <accessor>
-
AddXMLAttribute(accessNode, _T("source"), TSTR(_T("#")) + ap.getSubanimID(subanim) + TSTR(_T("-values-array")));
-
buf.printf("%d", numKeys*16);
-
AddXMLAttribute(accessNode, _T("count"), buf);
-
-
CreateXMLNode(pXMLDoc, accessNode, _T("param"), ¶mNode); // <param>
-
AddXMLAttribute(paramNode, _T("type"), _T("float"));
-
AddXMLAttribute(paramNode, _T("flow"), _T("OUT"));
-
techNode = NULL; accessNode = NULL; paramNode = NULL;
-
-
-
TimeValue current = animStart * pIgame->GetSceneTicks();
-
-
INode *node = ap.n->GetMaxNode();
-
INode *parent = node->GetParentNode();
-
-
TSTR timeBuf;
-
TSTR valuesBuf;
-
-
while (current<=(animEnd*pIgame->GetSceneTicks()))
-
{
-
buf.printf(" %g", current / (float)(pIgame->GetSceneTicks() * GetFrameRate())); // time in secs
-
-
timeBuf += buf;
-
-
// AddXMLText(pXMLDoc, tarrayNode, buf);
-
-
Matrix3 tm = node->GetNodeTM(current);
-
if (parent)
-
{
-
Matrix3 parentNodeTM = parent->GetNodeTM(current);
-
parentNodeTM.Invert();
-
tm = tm * parentNodeTM;
-
}
-
-
// this code converts from max matrix to collada matrix and outputs it in the collada form
-
float matrix[4][4];
-
-
Point3 row = tm.GetRow(0);
-
-
matrix[0][0] = row.x;
-
matrix[1][0] = row.y;
-
matrix[2][0] = row.z;
-
-
row = tm.GetRow(1);
-
-
matrix[0][1] = row.x;
-
matrix[1][1] = row.y;
-
matrix[2][1] = row.z;
-
-
row = tm.GetRow(2);
-
-
matrix[0][2] = row.x;
-
matrix[1][2] = row.y;
-
matrix[2][2] = row.z;
-
-
Point3 t = tm.GetRow(3);
-
-
matrix[0][3] = t.x;
-
matrix[1][3] = t.y;
-
matrix[2][3] = t.z;
-
matrix[3][3] = 1.0f;
-
-
// fill unused elements
-
matrix[3][0] = 0.0f;
-
matrix[3][1] = 0.0f;
-
matrix[3][2] = 0.0f;
-
-
buf.printf(" %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g",
-
matrix[0][0],
-
matrix[0][1],
-
matrix[0][2],
-
matrix[0][3],
-
matrix[1][0],
-
matrix[1][1],
-
matrix[1][2],
-
matrix[1][3],
-
matrix[2][0],
-
matrix[2][1],
-
matrix[2][2],
-
matrix[2][3],
-
matrix[3][0],
-
matrix[3][1],
-
matrix[3][2],
-
matrix[3][3]);
-
-
valuesBuf+=buf;
-
- // AddXMLText(pXMLDoc, varrayNode, buf);
-
-
current+=pIgame->GetSceneTicks();
-
}
-
-
AddXMLText(pXMLDoc, tarrayNode, timeBuf);
-
AddXMLText(pXMLDoc, varrayNode, valuesBuf);
-
-
-
return;
- }
-
- if (ap.type == IGAME_TM)
- {
-
TSTR buf;
-
-
CComPtr<IXMLDOMNode> tsourceNode, vsourceNode, isourceNode;
-
CreateXMLNode(pXMLDoc, animNode, _T("source"), &tsourceNode); // <source> for time
-
CreateXMLNode(pXMLDoc, animNode, _T("source"), &vsourceNode); // <source> for values
-
AddXMLAttribute(vsourceNode, _T("id"), ap.getSubanimID(subanim) + TSTR(_T("-values")));
-
AddXMLAttribute(tsourceNode, _T("id"), ap.getSubanimID(subanim) + TSTR(_T("-time")));
-
CComPtr<IXMLDOMNode> tarrayNode, varrayNode;
-
CreateXMLNode(pXMLDoc, tsourceNode, _T("array"), &tarrayNode); // <array> for time
-
CreateXMLNode(pXMLDoc, vsourceNode, _T("array"), &varrayNode); // <array> for values
-
-
AddXMLAttribute(tarrayNode, _T("id"), ap.getSubanimID(subanim) + TSTR(_T("-time-array")));
-
AddXMLAttribute(tarrayNode, _T("type"), _T("float"));
-
-
AddXMLAttribute(varrayNode, _T("id"), ap.getSubanimID(subanim) + TSTR(_T("-values-array")));
-
AddXMLAttribute(varrayNode, _T("type"), _T("float"));
-
-
int numKeys;
-
-
numKeys = animEnd - animStart + 1;
-
-
-
buf.printf("%d", numKeys);
-
-
AddXMLAttribute(tarrayNode, _T("count"), buf);
-
-
buf.printf("%d", numKeys*16);
-
-
AddXMLAttribute(varrayNode, _T("count"), buf);
-
-
-
// add <technique> nodes
-
CComPtr<IXMLDOMNode> techNode, accessNode, paramNode;
-
CreateXMLNode(pXMLDoc, tsourceNode, _T("technique"), &techNode); // <technique> for time
-
AddXMLAttribute(techNode, _T("profile"), _T("COMMON"));
-
-
CreateXMLNode(pXMLDoc, techNode, _T("accessor"), &accessNode); // <accessor>
-
AddXMLAttribute(accessNode, _T("source"), TSTR(_T("#")) + ap.getSubanimID(subanim) + TSTR(_T("-time-array")));
-
buf.printf("%d", numKeys);
-
AddXMLAttribute(accessNode, _T("count"), buf);
-
AddXMLAttribute(accessNode, _T("stride"), _T("1"));
-
-
CreateXMLNode(pXMLDoc, accessNode, _T("param"), ¶mNode); // <param>
-
AddXMLAttribute(paramNode, _T("name"), _T("time"));
-
AddXMLAttribute(paramNode, _T("type"), _T("float"));
-
AddXMLAttribute(paramNode, _T("flow"), _T("OUT"));
-
techNode = NULL; accessNode = NULL; paramNode = NULL;
-
-
CreateXMLNode(pXMLDoc, vsourceNode, _T("technique"), &techNode); // <technique> for values
-
AddXMLAttribute(techNode, _T("profile"), _T("COMMON"));
-
-
CreateXMLNode(pXMLDoc, techNode, _T("accessor"), &accessNode); // <accessor>
-
AddXMLAttribute(accessNode, _T("source"), TSTR(_T("#")) + ap.getSubanimID(subanim) + TSTR(_T("-values-array")));
-
buf.printf("%d", numKeys*16);
-
AddXMLAttribute(accessNode, _T("count"), buf);
-
-
CreateXMLNode(pXMLDoc, accessNode, _T("param"), ¶mNode); // <param>
-
AddXMLAttribute(paramNode, _T("type"), _T("float"));
-
AddXMLAttribute(paramNode, _T("flow"), _T("OUT"));
-
techNode = NULL; accessNode = NULL; paramNode = NULL;
-
-
-
TimeValue current = animStart * pIgame->GetSceneTicks();
-
-
INode *node = ap.n->GetMaxNode();
-
INode *parent = node->GetParentNode();
-
-
TSTR timeBuf;
-
TSTR valuesBuf;
-
-
while (current<=(animEnd*pIgame->GetSceneTicks()))
-
{
-
buf.printf(" %g", current / (float)(pIgame->GetSceneTicks() * GetFrameRate())); // time in secs
-
-
timeBuf += buf;
-
-
// AddXMLText(pXMLDoc, tarrayNode, buf);
-
-
Matrix3 tm = node->GetNodeTM(current);
-
if (parent)
-
{
-
Matrix3 parentNodeTM = parent->GetNodeTM(current);
-
parentNodeTM.Invert();
-
tm = tm * parentNodeTM;
-
}
-
-
// this code converts from max matrix to collada matrix and outputs it in the collada form
-
float matrix[4][4];
-
-
Point3 row = tm.GetRow(0);
-
-
matrix[0][0] = row.x;
-
matrix[1][0] = row.y;
-
matrix[2][0] = row.z;
-
-
row = tm.GetRow(1);
-
-
matrix[0][1] = row.x;
-
matrix[1][1] = row.y;
-
matrix[2][1] = row.z;
-
-
row = tm.GetRow(2);
-
-
matrix[0][2] = row.x;
-
matrix[1][2] = row.y;
-
matrix[2][2] = row.z;
-
-
Point3 t = tm.GetRow(3);
-
-
matrix[0][3] = t.x;
-
matrix[1][3] = t.y;
-
matrix[2][3] = t.z;
-
matrix[3][3] = 1.0f;
-
-
// fill unused elements
-
matrix[3][0] = 0.0f;
-
matrix[3][1] = 0.0f;
-
matrix[3][2] = 0.0f;
-
-
buf.printf(" %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g",
-
matrix[0][0],
-
matrix[0][1],
-
matrix[0][2],
-
matrix[0][3],
-
matrix[1][0],
-
matrix[1][1],
-
matrix[1][2],
-
matrix[1][3],
-
matrix[2][0],
-
matrix[2][1],
-
matrix[2][2],
-
matrix[2][3],
-
matrix[3][0],
-
matrix[3][1],
-
matrix[3][2],
-
matrix[3][3]);
-
-
valuesBuf+=buf;
-
- // AddXMLText(pXMLDoc, varrayNode, buf);
-
-
current+=pIgame->GetSceneTicks();
-
}
-
-
AddXMLText(pXMLDoc, tarrayNode, timeBuf);
-
AddXMLText(pXMLDoc, varrayNode, valuesBuf);
-
-
-
return;
- }
- // add time & value <source> elements for this controller
Control* maxc = ap.c->GetMaxControl(ap.type);
- if (maxc != NULL && maxc->IsAnimated())
- if (maxc != NULL && (maxc->IsAnimated() || (ap.c->GetIGameKeyCount(ap.type)!=0)))
{
TSTR buf;
bool hasTangents = false, sampleController = sampleAnim != 0;
@@ -2094,7 +2093,7 @@
CreateXMLNode(pXMLDoc, animNode, _T(“source”), &tsourceNode); // <source> for time
CreateXMLNode(pXMLDoc, animNode, _T(“source”), &vsourceNode); // <source> for values
CreateXMLNode(pXMLDoc, animNode, _T(“source”), &isourceNode); // <source> for interps
-
AddXMLAttribute(vsourceNode, _T("id"), ap.getSubanimID(subanim) + TSTR(_T("-values")));
AddXMLAttribute(tsourceNode, _T("id"), ap.getSubanimID(subanim) + TSTR(_T("-time")));
AddXMLAttribute(isourceNode, _T("id"), ap.getSubanimID(subanim) + TSTR(_T("-interp")));
CComPtr<IXMLDOMNode> tarrayNode, varrayNode, iarrayNode, itarrayNode, otarrayNode;
@@ -2106,7 +2105,7 @@
AddXMLAttribute(tarrayNode, _T(“id”), ap.getSubanimID(subanim) + TSTR(_T(“-time-array”)));
AddXMLAttribute(tarrayNode, _T(“type”), _T(“float”));
-
AddXMLAttribute(varrayNode, _T("id"), ap.getSubanimID(subanim) + TSTR(_T("-values-array")));
AddXMLAttribute(varrayNode, _T("type"), _T("float"));
AddXMLAttribute(iarrayNode, _T("id"), ap.getSubanimID(subanim) + TSTR(_T("-interp-array")));
@@ -2117,31 +2116,37 @@
{
// sample controller value at each frame in the selected range
IGameKeyTab keys;
-
-
if (ap.c->GetFullSampledKeys(keys, 1, IGAME_TM, false)) {
TimeValue start = animStart * pIgame->GetSceneTicks(),
end = animEnd * pIgame->GetSceneTicks();
numKeys = animEnd - animStart + 1;
-
buf.printf("%d", keys.Count());
AddXMLAttribute(tarrayNode, _T("count"), buf);
AddXMLAttribute(iarrayNode, _T("count"), buf);
-
if (subanim == SUBANIM_NONE) buf.printf("%d", keys.Count()*3);
AddXMLAttribute(varrayNode, _T("count"), buf);
// loop over sampled keys
if (subanim == SUBANIM_NONE)
{
-
TSTR timeBuf;
-
TSTR valuesBuf;
-
TSTR interpBuf;
-
-
AddXMLText(pXMLDoc, tarrayNode, buf);
-
AddXMLText(pXMLDoc, iarrayNode, _T(" LINEAR"));
+// AddXMLText(pXMLDoc, tarrayNode, buf);
+// AddXMLText(pXMLDoc, iarrayNode, _T(" LINEAR"));
+
+
// export key value based on controller ap.type and value component specifier
if (ap.type==IGAME_POS || ap.type==IGAME_POINT3) {
Point3 k = keys[i].sampleKey.pval;
@@ -2156,28 +2161,34 @@
Point3 s = keys[i].sampleKey.sval.s;
buf.printf(" %g %g %g", ap.mapper(s.x), ap.mapper(s.y), ap.mapper(s.z));
}
-
AddXMLText(pXMLDoc, iarrayNode, interpBuf);
-
AddXMLText(pXMLDoc, tarrayNode, timeBuf);
-
AddXMLText(pXMLDoc, varrayNode, valuesBuf);
-
AddXMLText(pXMLDoc, iarrayNode, interpBuf);
-
AddXMLText(pXMLDoc, tarrayNode, timeBuf);
-
AddXMLText(pXMLDoc, varrayNode, valuesBuf);
}
else
{
-
TSTR timeBuf;
-
TSTR valuesBuf;
-
TSTR interpBuf;
-
-
-
AddXMLText(pXMLDoc, tarrayNode, buf);
-
AddXMLText(pXMLDoc, iarrayNode, _T(" LINEAR"));
+// AddXMLText(pXMLDoc, tarrayNode, buf);
+// AddXMLText(pXMLDoc, iarrayNode, _T(" LINEAR"));
+
+
// export key value based on controller ap.type and value component specifier
if (ap.type==IGAME_POS || ap.type==IGAME_POINT3) {
Point3 k = keys[i].sampleKey.pval;
@@ -2196,14 +2207,15 @@
Point3 s = keys[i].sampleKey.sval.s;
buf.printf(" %g", ap.mapper(getSubanimVal(subanim,s)));
}
-
-
AddXMLText(pXMLDoc, iarrayNode, interpBuf);
-
AddXMLText(pXMLDoc, tarrayNode, timeBuf);
-
AddXMLText(pXMLDoc, varrayNode, valuesBuf);
-
-
-
AddXMLText(pXMLDoc, iarrayNode, interpBuf);
-
AddXMLText(pXMLDoc, tarrayNode, timeBuf);
-
AddXMLText(pXMLDoc, varrayNode, valuesBuf);
-
}
}
}
@@ -2340,7 +2352,7 @@
AddXMLAttribute(techNode, _T(“profile”), _T(“COMMON”));
CreateXMLNode(pXMLDoc, techNode, _T("accessor"), &accessNode); // <accessor>
-
AddXMLAttribute(accessNode, _T("source"), TSTR(_T("#")) + ap.getSubanimID(subanim) + TSTR(_T("-values-array")));
buf.printf("%d", numKeys);
AddXMLAttribute(accessNode, _T("count"), buf);
@@ -2348,7 +2360,9 @@
{
AddXMLAttribute(accessNode, _T(“stride”), _T(“1”));
CreateXMLNode(pXMLDoc, accessNode, _T(“param”), ¶mNode); // <param>
-
// kevt
-
AddXMLAttribute(paramNode, _T("name"), ap.getParam(subanim));
-
AddXMLAttribute(paramNode, _T("type"), _T("float"));
AddXMLAttribute(paramNode, _T("flow"), _T("OUT"));
}
@@ -2453,7 +2467,8 @@
inputNode = NULL;
CreateXMLNode(pXMLDoc, samplerNode, _T(“input”), &inputNode); // <input> for OUTPUT
AddXMLAttribute(inputNode, _T(“semantic”), _T(“OUTPUT”));
}
void
@@ -2475,45 +2490,48 @@
// add <light> library node for nodes that are lights
IGameObject* obj = node->GetIGameObject();
- if (obj->GetIGameType() == IGameObject::IGAME_LIGHT) {
-
TSTR objID; makeObjectID(obj, objID, node);
-
IGameLight* light = (IGameLight*)obj;
-
CComPtr<IXMLDOMNode> lightNode, paramNode;
-
CreateXMLNode(pXMLDoc, libNode, _T("light"), &lightNode); // <camera>
-
AddXMLAttribute(lightNode, _T("id"), objID);
-
AddXMLAttribute(lightNode, _T("name"), objID);
-
int type = light->GetLightType();
-
TCHAR* typeStr = type == IGameLight::IGAME_OMNI ? _T("POINT") :
-
type == IGameLight::IGAME_TSPOT ? _T("SPOT") :
-
type == IGameLight::IGAME_DIR ? _T("DIRECTIONAL") :
-
type == IGameLight::IGAME_FSPOT ? _T("SPOT") :
-
type == IGameLight::IGAME_TDIR ? _T("DIRECTIONAL") : _T("POINT");
-
AddXMLAttribute(lightNode, _T("type"), typeStr);
-
if (light->GetLightColor() != NULL)
-
{
-
// common params
-
Point3 rgb; light->GetLightColor()->GetPropertyValue(rgb);
-
Point4 rgba (rgb, 1);
-
AddParamValNode(lightNode, _T("COLOR"), pt_float4, _T("IN"), rgba, (light->GetLightColor()->IsPropAnimated() ? _T("Color") : NULL));
-
float mult; light->GetLightMultiplier()->GetPropertyValue(mult);
-
AddParamValNode(lightNode, _T("INTENSITY"), pt_float, _T("IN"), mult, (light->GetLightMultiplier()->IsPropAnimated() ? _T("Multiplier") : NULL));
-
// non-point params
-
if (type != IGameLight::IGAME_OMNI) {
-
float aspect; light->GetLightAspectRatio()->GetPropertyValue(aspect);
-
AddParamValNode(lightNode, _T("ASPECTRATIO"), pt_float, _T("IN"), aspect, (light->GetLightAspectRatio()->IsPropAnimated() ? _T("AspectRatio") : NULL));
-
float falloff; light->GetLightFallOff()->GetPropertyValue(falloff);
-
AddParamValNode(lightNode, _T("OUTERCONE"), pt_float, _T("IN"), falloff, (light->GetLightFallOff()->IsPropAnimated() ? _T("Falloff") : NULL));
-
float hotspot; light->GetLightHotSpot()->GetPropertyValue(hotspot);
-
AddParamValNode(lightNode, _T("INNERCONE"), pt_float, _T("IN"), hotspot, (light->GetLightHotSpot()->IsPropAnimated() ? _T("Hotspot") : NULL));
-
}
-
}
-
// target param
-
IGameNode* target = light->GetLightTarget();
-
if (target != NULL) {
-
// add target ref
-
AddParamNode(lightNode, _T("TARGET"), pt_name, _T("IN"), paramNode);
-
TSTR targID; makeNodeID(target, targID);
-
AddXMLText(pXMLDoc, paramNode, targID);
- if (!node->IsNodeHidden())
- {
-
if (obj->GetIGameType() == IGameObject::IGAME_LIGHT) {
-
TSTR objID; makeObjectID(obj, objID, node);
-
IGameLight* light = (IGameLight*)obj;
-
CComPtr<IXMLDOMNode> lightNode, paramNode;
-
CreateXMLNode(pXMLDoc, libNode, _T("light"), &lightNode); // <camera>
-
AddXMLAttribute(lightNode, _T("id"), objID);
-
AddXMLAttribute(lightNode, _T("name"), objID);
-
int type = light->GetLightType();
-
TCHAR* typeStr = type == IGameLight::IGAME_OMNI ? _T("POINT") :
-
type == IGameLight::IGAME_TSPOT ? _T("SPOT") :
-
type == IGameLight::IGAME_DIR ? _T("DIRECTIONAL") :
-
type == IGameLight::IGAME_FSPOT ? _T("SPOT") :
-
type == IGameLight::IGAME_TDIR ? _T("DIRECTIONAL") : _T("POINT");
-
AddXMLAttribute(lightNode, _T("type"), typeStr);
-
if (light->GetLightColor() != NULL)
-
{
-
// common params
-
Point3 rgb; light->GetLightColor()->GetPropertyValue(rgb);
-
Point4 rgba (rgb, 1);
-
AddParamValNode(lightNode, _T("COLOR"), pt_float4, _T("IN"), rgba, (light->GetLightColor()->IsPropAnimated() ? _T("Color") : NULL));
-
float mult; light->GetLightMultiplier()->GetPropertyValue(mult);
-
AddParamValNode(lightNode, _T("INTENSITY"), pt_float, _T("IN"), mult, (light->GetLightMultiplier()->IsPropAnimated() ? _T("Multiplier") : NULL));
-
// non-point params
-
if (type != IGameLight::IGAME_OMNI) {
-
float aspect; light->GetLightAspectRatio()->GetPropertyValue(aspect);
-
AddParamValNode(lightNode, _T("ASPECTRATIO"), pt_float, _T("IN"), aspect, (light->GetLightAspectRatio()->IsPropAnimated() ? _T("AspectRatio") : NULL));
-
float falloff; light->GetLightFallOff()->GetPropertyValue(falloff);
-
AddParamValNode(lightNode, _T("OUTERCONE"), pt_float, _T("IN"), falloff, (light->GetLightFallOff()->IsPropAnimated() ? _T("Falloff") : NULL));
-
float hotspot; light->GetLightHotSpot()->GetPropertyValue(hotspot);
-
AddParamValNode(lightNode, _T("INNERCONE"), pt_float, _T("IN"), hotspot, (light->GetLightHotSpot()->IsPropAnimated() ? _T("Hotspot") : NULL));
-
}
-
}
-
// target param
-
IGameNode* target = light->GetLightTarget();
-
if (target != NULL) {
-
// add target ref
-
AddParamNode(lightNode, _T("TARGET"), pt_name, _T("IN"), paramNode);
-
TSTR targID; makeNodeID(target, targID);
-
AddXMLText(pXMLDoc, paramNode, targID);
-
}
}
}
node->ReleaseIGameObject();
@@ -2691,7 +2709,11 @@
AddXMLAttribute(imgNode, _T(“id”), id);
AddXMLAttribute(imgNode, _T(“name”), id);
// make valid sourcefile URI
-
-
TSTR src = c;
-
// kevt
-
makeValidURIFilename(src, false);
-
src = TSTR(_T("file://")) + src;
AddXMLAttribute(imgNode, _T("source"), src);
}
}
@@ -2750,23 +2772,25 @@
void
ColladaExporter::AddGeometryNodes(CComPtr<IXMLDOMNode>& libNode, IGameNode* node, Tab<Object*>& objects)
{
- // add <geometry> nodes for this node and its children
- IGameObject* obj = node->GetIGameObject();
- if (obj->GetIGameType() == IGameObject::IGAME_MESH)
- if (!node->IsNodeHidden())
{
-
if (!obj->IsObjectXRef()) { // but not xrefs, they just have scene nodes, no geom
-
// only first instance of object, so search in accumulating Object* table
-
Object* maxobj = obj->GetMaxObject();
-
for (int i = 0; i < objects.Count(); i++)
-
if (objects[i] == maxobj) break;
-
if (i == objects.Count()) { // not found, so 1st inst, add <geometry> node for it
-
objects.Append(1, &maxobj);
-
AddGeometryNode(libNode, (IGameMesh*)obj, node);
-
// add <geometry> nodes for this node and its children
-
IGameObject* obj = node->GetIGameObject();
-
if (obj->GetIGameType() == IGameObject::IGAME_MESH)
-
{
-
if (!obj->IsObjectXRef()) { // but not xrefs, they just have scene nodes, no geom
-
// only first instance of object, so search in accumulating Object* table
-
Object* maxobj = obj->GetMaxObject();
-
for (int i = 0; i < objects.Count(); i++)
-
if (objects[i] == maxobj) break;
-
if (i == objects.Count()) { // not found, so 1st inst, add <geometry> node for it
-
objects.Append(1, &maxobj);
-
AddGeometryNode(libNode, (IGameMesh*)obj, node);
-
}
}
}
-
node->ReleaseIGameObject();
// recurse through any children
for (int j = 0; j < node->GetChildCount(); j++) {
@@ -3067,16 +3091,16 @@
AddXMLAttribute(arrayNode, _T(“type”), _T(“float”));
TSTR buf; buf.printf(“%d”, numVerts * 3);
AddXMLAttribute(arrayNode, _T(“count”), buf);
-
-
TSTR vertsBuf;
-
-
TSTR vertsBuf;
// mesh vertex positions
for (int i = 0; i < numVerts; i++) {
Point3 vert;
mesh->GetVertex(i, vert, true);
buf.printf("%g %g %g ", vert.x, vert.y, vert.z);
-
AddXMLText(pXMLDoc, arrayNode, vertsBuf);
// accessor technique node
TCHAR* pnames[3] = { "X", "Y", "Z" };
AddNTupleTechniqueNode(sourceNode, arrayID, numVerts, 3, pnames);
@@ -3103,20 +3127,24 @@
AddXMLAttribute(arrayNode, _T(“count”), buf);
// mesh normals
Point3 n(0,0,0);
- TSTR normalsBuf;
- for (int i = 0; i < numNormals; i++) {
if(mesh->GetNormal(i,n))
{
buf.printf("%g %g %g ",n.x,n.y,n.z);
-
normalsBuf+=buf;
- // AddXMLText(pXMLDoc,arrayNode,buf.data());
}
else
-
{
-
normalsBuf+=_T("0 0 1");
- // AddXMLText(pXMLDoc,arrayNode,_T(“0 0 1”));
-
}
}
-
- AddXMLText(pXMLDoc,arrayNode,normalsBuf);
-
-
-
AddXMLText(pXMLDoc,arrayNode,normalsBuf);
-
// accessor technique node
TCHAR* pnames[3] = { “X”, “Y”, “Z” };
AddNTupleTechniqueNode(sourceNode, arrayID, numNormals, 3, pnames);
@@ -3437,7 +3465,7 @@
// map funny chars
for (int i = 0; i < fn.length(); i++) {
end