deekpyro
10-04-2004, 09:05 PM
Hey all,
I'm a C4D advocate and a PC (mac/linux/windows...in that order) game developer. On my latest project I've decide to put a good deal of emphasis on animation, using C4D to animate the models for the game. To get the animation information in a format that satisfies me I've written my own format and plugin (thanks to the COFFEE plugin base I could find here (http://www.tinrocket.com/content/code/000037.html)), unfortunately I've run into a complete snag at properly exporting the markers from the time line and keyframe information (object pos, rotation matrix, and scale).
Anyways, I've come to you guys as I've spent the last month working on this thing and in the past few weeks my progress has slowed. Here's the file of greatest importance that should give you an idea where I'm at now. Hopefully someone will know how I can clean/fix this so I can start exporting the animation information to my custom format (and soon). Currently if I comment out the SaveAnimation() function I can export just the object information (at frame 0), but if I uncomment it C4D just hangs while it exports the thing.
Thanks again!
Derek Arndt
include "tinrocketXML.coh"
class tinrocketXMLExport
{
public:
tinrocketXMLExport();
SaveStart(doc,op,file);
private:
var xml;
SaveObjects(doc,op,file);
SaveAnimation(file,doc,op);
}
tinrocketXMLExport:: tinrocketXMLExport()
{
xml = new(tinrocketXML);
}
tinrocketXMLExport:: SaveStart(doc,op,file)
{
var ok;
xml->WriteXMLHeader(file);
//var str = stradd("<XMLSidekick version=","\"","1.0","\"","?>",GeGetLineEnd())
//file->WriteString(str);
ok = SaveObjects(doc,op,file);
//you could save material data here, for example
}
//write out the object hierarchy
tinrocketXMLExport:: SaveObjects(doc,op,file)
{
var attributes = new(tinrocketXMLAttribute);
var vec;
var objectType;
var rotMat;
var markerCount;
var keyCount;
while (op)
{
switch (tostring(getclass(op)))
{
case "[Class-NullObject]":
objectType = "Object";
break;
case "[Class-BoneObject]":
objectType = "Bone";
break;
case "[Class-CameraObject]":
objectType = "Camera";
break;
default:
objectType = "Object";
}
// objectType
attributes->Clear(); //clean out the attributes object for reuse
attributes->AppendAttribute("name",op->GetName());
attributes->AppendAttribute("editorMode",op->GetEditorMode());
//attributes->AppendAttribute("container",op->GetContainer());
//attributes->AppendAttribute("renderMode",op->GetRenderMode());
if(objectType == "Bone")
{
var container = op->GetContainer();
attributes->AppendAttribute("length",container->GetData(BONEOBJECT_LENGTH));
}
xml->WriteTagStart(file,objectType,attributes);
//trasformation data
attributes->Clear();
xml->WriteTagStart(file,"Orientation",attributes);
//position
attributes->Clear();
attributes->AppendAttribute("name","translation");
vec = op->GetPosition();
attributes->AppendAttribute("x",vec.x);
attributes->AppendAttribute("y",vec.y);
attributes->AppendAttribute("z",vec.z);
xml->WriteTag(file,"Vector",attributes,nil);
//
//rotation
attributes->Clear();
attributes->AppendAttribute("name","rotation");
rotMat = op->GetMln();
vec = rotMat->GetV1();
attributes->AppendAttribute("x1",vec.x);
attributes->AppendAttribute("y1",vec.y);
attributes->AppendAttribute("z1",vec.z);
vec = rotMat->GetV2();
attributes->AppendAttribute("x2",vec.x);
attributes->AppendAttribute("y2",vec.y);
attributes->AppendAttribute("z2",vec.z);
vec = rotMat->GetV3();
attributes->AppendAttribute("x3",vec.x);
attributes->AppendAttribute("y3",vec.y);
attributes->AppendAttribute("z3",vec.z);
xml->WriteTag(file,"Matrix",attributes,nil);
//
//scale
attributes->Clear();
attributes->AppendAttribute("name","scale");
vec = op->GetScale();
attributes->AppendAttribute("x",vec.x);
attributes->AppendAttribute("y",vec.y);
attributes->AppendAttribute("z",vec.z);
xml->WriteTag(file,"Vector",attributes,nil);
//
xml->WriteTagEnd(file); //end Orientation
if(objectType == "Bone")
{
SaveAnimation(file,doc,op);
}
if (!SaveObjects(doc,op->GetDown(),file)) return FALSE;
op = op->GetNext();
xml->WriteTagEnd(file); //end Object
}
return TRUE;
}
tinrocketXMLExport:: SaveAnimation(file,doc,op)
{
var attributes = new(tinrocketXMLAttribute);
var track = op->GetFirstTrack();
var sequence = track->GetFirstSequence();
var key = sequence->GetFirstKey();
var keycontainer;
var vec;
var rotMat;
attributes->Clear();
xml->WriteTagStart(file,"Animation",attributes);
while(key)
{
switch (tostring(getclass(key)))
{
case "[Class-MarkerKey]":
keycontainer = key->GetContainer();
attributes->Clear(); //clean out the attributes object for reuse
//attributes->AppendAttribute("name", keycontainer->GetData(MARKERKEY_NAME));
attributes->AppendAttribute("startTime", key->GetTime());
//attributes->AppendAttribute("endFrame", );
xml->WriteTagStart(file,"Marker",attributes);
break;
case "[Class-PSRKey]":
attributes->Clear(); //clean out the attributes object for reuse
attributes->AppendAttribute("time", key->GetTime());
xml->WriteTagStart(file,"Frame",attributes);
doc->SetTime(key->GetTime());
//trasformation data
attributes->Clear();
xml->WriteTagStart(file,"Orientation",attributes);
//position
attributes->Clear();
attributes->AppendAttribute("name","translation");
vec = op->GetPosition();
attributes->AppendAttribute("x",vec.x);
attributes->AppendAttribute("y",vec.y);
attributes->AppendAttribute("z",vec.z);
xml->WriteTag(file,"Vector",attributes,nil);
//
//rotation
attributes->Clear();
attributes->AppendAttribute("name","rotation");
rotMat = op->GetMln();
vec = rotMat->GetV1();
attributes->AppendAttribute("x1",vec.x);
attributes->AppendAttribute("y1",vec.y);
attributes->AppendAttribute("z1",vec.z);
vec = rotMat->GetV2();
attributes->AppendAttribute("x2",vec.x);
attributes->AppendAttribute("y2",vec.y);
attributes->AppendAttribute("z2",vec.z);
vec = rotMat->GetV3();
attributes->AppendAttribute("x3",vec.x);
attributes->AppendAttribute("y3",vec.y);
attributes->AppendAttribute("z3",vec.z);
xml->WriteTag(file,"Matrix",attributes,nil);
//
//scale
attributes->Clear();
attributes->AppendAttribute("name","scale");
vec = op->GetScale();
attributes->AppendAttribute("x",vec.x);
attributes->AppendAttribute("y",vec.y);
attributes->AppendAttribute("z",vec.z);
xml->WriteTag(file,"Vector",attributes,nil);
//
xml->WriteTagEnd(file); //end Orientation
xml->WriteTagEnd(file);
break;
default:
break;
}
key->GetNext();
}
// Go back to the first key
//key = sequence->GetFirstKey();
xml->WriteTagEnd(file);
xml->WriteTagEnd(file);
}
I'm a C4D advocate and a PC (mac/linux/windows...in that order) game developer. On my latest project I've decide to put a good deal of emphasis on animation, using C4D to animate the models for the game. To get the animation information in a format that satisfies me I've written my own format and plugin (thanks to the COFFEE plugin base I could find here (http://www.tinrocket.com/content/code/000037.html)), unfortunately I've run into a complete snag at properly exporting the markers from the time line and keyframe information (object pos, rotation matrix, and scale).
Anyways, I've come to you guys as I've spent the last month working on this thing and in the past few weeks my progress has slowed. Here's the file of greatest importance that should give you an idea where I'm at now. Hopefully someone will know how I can clean/fix this so I can start exporting the animation information to my custom format (and soon). Currently if I comment out the SaveAnimation() function I can export just the object information (at frame 0), but if I uncomment it C4D just hangs while it exports the thing.
Thanks again!
Derek Arndt
include "tinrocketXML.coh"
class tinrocketXMLExport
{
public:
tinrocketXMLExport();
SaveStart(doc,op,file);
private:
var xml;
SaveObjects(doc,op,file);
SaveAnimation(file,doc,op);
}
tinrocketXMLExport:: tinrocketXMLExport()
{
xml = new(tinrocketXML);
}
tinrocketXMLExport:: SaveStart(doc,op,file)
{
var ok;
xml->WriteXMLHeader(file);
//var str = stradd("<XMLSidekick version=","\"","1.0","\"","?>",GeGetLineEnd())
//file->WriteString(str);
ok = SaveObjects(doc,op,file);
//you could save material data here, for example
}
//write out the object hierarchy
tinrocketXMLExport:: SaveObjects(doc,op,file)
{
var attributes = new(tinrocketXMLAttribute);
var vec;
var objectType;
var rotMat;
var markerCount;
var keyCount;
while (op)
{
switch (tostring(getclass(op)))
{
case "[Class-NullObject]":
objectType = "Object";
break;
case "[Class-BoneObject]":
objectType = "Bone";
break;
case "[Class-CameraObject]":
objectType = "Camera";
break;
default:
objectType = "Object";
}
// objectType
attributes->Clear(); //clean out the attributes object for reuse
attributes->AppendAttribute("name",op->GetName());
attributes->AppendAttribute("editorMode",op->GetEditorMode());
//attributes->AppendAttribute("container",op->GetContainer());
//attributes->AppendAttribute("renderMode",op->GetRenderMode());
if(objectType == "Bone")
{
var container = op->GetContainer();
attributes->AppendAttribute("length",container->GetData(BONEOBJECT_LENGTH));
}
xml->WriteTagStart(file,objectType,attributes);
//trasformation data
attributes->Clear();
xml->WriteTagStart(file,"Orientation",attributes);
//position
attributes->Clear();
attributes->AppendAttribute("name","translation");
vec = op->GetPosition();
attributes->AppendAttribute("x",vec.x);
attributes->AppendAttribute("y",vec.y);
attributes->AppendAttribute("z",vec.z);
xml->WriteTag(file,"Vector",attributes,nil);
//
//rotation
attributes->Clear();
attributes->AppendAttribute("name","rotation");
rotMat = op->GetMln();
vec = rotMat->GetV1();
attributes->AppendAttribute("x1",vec.x);
attributes->AppendAttribute("y1",vec.y);
attributes->AppendAttribute("z1",vec.z);
vec = rotMat->GetV2();
attributes->AppendAttribute("x2",vec.x);
attributes->AppendAttribute("y2",vec.y);
attributes->AppendAttribute("z2",vec.z);
vec = rotMat->GetV3();
attributes->AppendAttribute("x3",vec.x);
attributes->AppendAttribute("y3",vec.y);
attributes->AppendAttribute("z3",vec.z);
xml->WriteTag(file,"Matrix",attributes,nil);
//
//scale
attributes->Clear();
attributes->AppendAttribute("name","scale");
vec = op->GetScale();
attributes->AppendAttribute("x",vec.x);
attributes->AppendAttribute("y",vec.y);
attributes->AppendAttribute("z",vec.z);
xml->WriteTag(file,"Vector",attributes,nil);
//
xml->WriteTagEnd(file); //end Orientation
if(objectType == "Bone")
{
SaveAnimation(file,doc,op);
}
if (!SaveObjects(doc,op->GetDown(),file)) return FALSE;
op = op->GetNext();
xml->WriteTagEnd(file); //end Object
}
return TRUE;
}
tinrocketXMLExport:: SaveAnimation(file,doc,op)
{
var attributes = new(tinrocketXMLAttribute);
var track = op->GetFirstTrack();
var sequence = track->GetFirstSequence();
var key = sequence->GetFirstKey();
var keycontainer;
var vec;
var rotMat;
attributes->Clear();
xml->WriteTagStart(file,"Animation",attributes);
while(key)
{
switch (tostring(getclass(key)))
{
case "[Class-MarkerKey]":
keycontainer = key->GetContainer();
attributes->Clear(); //clean out the attributes object for reuse
//attributes->AppendAttribute("name", keycontainer->GetData(MARKERKEY_NAME));
attributes->AppendAttribute("startTime", key->GetTime());
//attributes->AppendAttribute("endFrame", );
xml->WriteTagStart(file,"Marker",attributes);
break;
case "[Class-PSRKey]":
attributes->Clear(); //clean out the attributes object for reuse
attributes->AppendAttribute("time", key->GetTime());
xml->WriteTagStart(file,"Frame",attributes);
doc->SetTime(key->GetTime());
//trasformation data
attributes->Clear();
xml->WriteTagStart(file,"Orientation",attributes);
//position
attributes->Clear();
attributes->AppendAttribute("name","translation");
vec = op->GetPosition();
attributes->AppendAttribute("x",vec.x);
attributes->AppendAttribute("y",vec.y);
attributes->AppendAttribute("z",vec.z);
xml->WriteTag(file,"Vector",attributes,nil);
//
//rotation
attributes->Clear();
attributes->AppendAttribute("name","rotation");
rotMat = op->GetMln();
vec = rotMat->GetV1();
attributes->AppendAttribute("x1",vec.x);
attributes->AppendAttribute("y1",vec.y);
attributes->AppendAttribute("z1",vec.z);
vec = rotMat->GetV2();
attributes->AppendAttribute("x2",vec.x);
attributes->AppendAttribute("y2",vec.y);
attributes->AppendAttribute("z2",vec.z);
vec = rotMat->GetV3();
attributes->AppendAttribute("x3",vec.x);
attributes->AppendAttribute("y3",vec.y);
attributes->AppendAttribute("z3",vec.z);
xml->WriteTag(file,"Matrix",attributes,nil);
//
//scale
attributes->Clear();
attributes->AppendAttribute("name","scale");
vec = op->GetScale();
attributes->AppendAttribute("x",vec.x);
attributes->AppendAttribute("y",vec.y);
attributes->AppendAttribute("z",vec.z);
xml->WriteTag(file,"Vector",attributes,nil);
//
xml->WriteTagEnd(file); //end Orientation
xml->WriteTagEnd(file);
break;
default:
break;
}
key->GetNext();
}
// Go back to the first key
//key = sequence->GetFirstKey();
xml->WriteTagEnd(file);
xml->WriteTagEnd(file);
}
