Permalink
Browse files

export instantiated objects only once

  • Loading branch information...
opencollada-sebastian committed Aug 28, 2008
1 parent a3010a9 commit 681d647ba874cb4700f28b4b93d78b3dce0c50c2
View
@@ -3,6 +3,11 @@ COLLADAMax Nextgen: Export - Supported features
Scene graph
- Transform nodes
+ - Instances
+ - Visual scenes
+ - Geometries
+ - Materials
+ - Effects
Geometry
- Mesh:
@@ -15,11 +20,12 @@ Materials / Effects
- Materials Phong and Blinn
Animation
- - Rotation / Transformation
+ - LINEAR, STEP, BEZIER
+ - Rotation / Transformation / Scale
+ - Extra parameters of camera, light, primitives
+
+Camera
+
+Light
-Instances
- - Visual scenes
- - Geometries
- - Materials
- - Effects
@@ -59,7 +59,12 @@ namespace COLLADAMax
virtual ~Controller()
{}
- Object* getInitialPose()const;
+ /** Returns the pose before the application of the controller.*/
+ Object* getPoseBefore()const;
+
+ /** Returns the pose after the application of the controller.*/
+ Object* getPoseAfter()const;
+
/** Returns the controller type*/
ControllerType getControllerType()const{return mControllerType;}
@@ -70,6 +75,12 @@ namespace COLLADAMax
/** Returns the type of the controller*/
ControllerType getType()const { return mControllerType; }
+ /** Returns the modifier index of the controller.*/
+ int getModifierIndex()const { return mModifierIndex; }
+
+ /** Returns the derived object.*/
+ IDerivedObject* getDerivedObject()const{ return mDerivedObject; }
+
protected:
/** Sets the controller type*/
void setControllerType(ControllerType controllerType){mControllerType=controllerType;}
@@ -79,8 +79,11 @@ namespace COLLADAMax
/** Exports @a morphController.*/
void exportMorphController( ExportNode* exportNode, MorphController* morphController, const String& controllerId, const String& morphSource);
- /** Calculates the skeleton roots of. */
- static void calculateSkeletonRoots( const ExportNodeSet &referencedJoints, ControllerList * controllerList);
+ /** Determines the referenced joints. This is required to export the skeleton elements.*/
+ void determineReferencedJoints(ExportNode* exportNode, SkinController* skinController);
+
+ /** Determines the skeleton roots of. */
+ static void determineSkeletonRoots( const ExportNodeSet &referencedJoints, ControllerList * controllerList);
/** Determines if one of the parents of @a joint is in @a jointSet.
@return Returns true if @a joint is in @a jointSet set, otherwise false.*/
@@ -36,8 +36,22 @@ namespace COLLADAMax
class AnimationExporter;
+
+ class ObjectIdentifier
+ {
+ private:
+ void* mObject;
+ int mIdentificationNumber;
+ public:
+ ObjectIdentifier(void* object) : mObject(object),mIdentificationNumber(0){}
+ ObjectIdentifier(void* object, int identificationNumber) :mObject(object),mIdentificationNumber(identificationNumber){}
+ bool operator<(const ObjectIdentifier& other)const;
+ };
+
class DocumentExporter
{
+ private:
+ typedef std::map<ObjectIdentifier, String> ObjectIdMap;
private:
/** The name of the output file.*/
@@ -69,6 +83,9 @@ namespace COLLADAMax
/** The id of the @a \<scene\> element.*/
static const String SCENE_ID;
+ /** A map, that hold all already exported objects with their ids*/
+ ObjectIdMap mExportedObjects;
+
public:
/** Constructor
@param i the max interface
@@ -123,12 +140,21 @@ namespace COLLADAMax
/** Shows the export options dialog.
@param suppressPrompts If set to true, no dialog is shows (for scripting).*/
- bool ShowExportOptions(bool suppressPrompts);
-
+ bool showExportOptions(bool suppressPrompts);
/** Splits the filepath in directory and file name */
static void DocumentExporter::splitFilePath( const String& filePath, String& fileDir, String& fileName );
+ /** Returns if @a object has already been exported*/
+ bool isExportedObject(ObjectIdentifier& object);
+
+ /** Inserts @a object with id @a objectId to the list of exported objects*/
+ void insertExportedObject(ObjectIdentifier& object, const String& objectId);
+
+ /** Returns the id of the the already exported object @a object.
+ If @a object has not been exported, an empty string is returned*/
+ const String& getExportedObjectId(ObjectIdentifier& object);
+
private:
DocumentExporter ( const DocumentExporter & documentExporter );
DocumentExporter & operator= ( const DocumentExporter & documentExporter );
@@ -159,6 +159,15 @@ namespace COLLADAMax
return mINode;
}
+ /** Returns the camera object represented by the export node. This functions returns a non zero pointer
+ only if the node is a camera.*/
+ CameraObject* getCamera()const{ return (CameraObject*)mINode->GetObjectRef(); }
+
+ /** Returns the light object represented by the export node. This functions returns a non zero pointer
+ only if the node is a light.*/
+ LightObject* getLight()const{ return (LightObject*)mINode->GetObjectRef(); }
+
+
/** Returns if the node is in the visual scene, i.e. not hidden or selected if export selection only
is choosen.*/
bool getIsInVisualScene()const {return mIsInVisualScene;}
@@ -207,10 +216,17 @@ namespace COLLADAMax
controllers are assigned.*/
String getLastControllerId()const;
+ /** Returns the the last controller applied to the nodes geometry or 0 if no
+ controllers are assigned.*/
+ Controller* getLastController()const;
+
/** Returns the initial pose of the object, before all controllers that will be exported are applied.*/
Object* getInitialPose()const;
- /** Determines and returns the type of @a INode.*/
+ /** Returns the final pose of the object, after all controllers are applied.*/
+ Object* getFinalPose()const;
+
+ /** Determines and returns the type of @a INode.*/
static Type determineType ( INode * iNode );
/** Adds channel @a channel with corresponding effect id @a effectId. The symbol is marked as unused.*/
@@ -53,6 +53,8 @@ namespace COLLADAMax
typedef std::vector<float> FloatList;
+
+ typedef std::map<Object*, String> ObjectStringMap;
}
@@ -135,6 +135,12 @@ namespace COLLADAMax
if ( camera )
{
+ if ( mDocumentExporter->isExportedObject(ObjectIdentifier(camera)) )
+ return;
+
+ mDocumentExporter->insertExportedObject(ObjectIdentifier(camera), cameraId);
+
+
// Retrieve the camera parameters block
IParamBlock* parameters = (IParamBlock*) camera->GetReference(MaxCamera::PBLOCK_REF);
@@ -136,7 +136,7 @@ namespace COLLADAMax
try
{
DocumentExporter document ( maxInterface, name );
- if (document.ShowExportOptions(suppressPrompts) != false)
+ if (document.showExportOptions(suppressPrompts) != false)
{
/// @todo handle errors here
document.exportCurrentMaxScene();
@@ -38,7 +38,7 @@ namespace COLLADAMax
//---------------------------------------------------------------
- Object* Controller::getInitialPose() const
+ Object* Controller::getPoseBefore() const
{
Object* initialPose = 0;
// Remember that 3dsMax has the modifier stack reversed
@@ -47,7 +47,6 @@ namespace COLLADAMax
if (mModifierIndex < modifierCount - 1)
{
ObjectState state = mDerivedObject->Eval(TIME_INITIAL_POSE, mModifierIndex + 1);
-// ObjectState state = mDerivedObject->Eval(TIME_INITIAL_POSE, mModifierIndex + 1);
initialPose = state.obj;
}
else
@@ -59,6 +58,28 @@ namespace COLLADAMax
}
+ //---------------------------------------------------------------
+ Object* Controller::getPoseAfter() const
+ {
+ Object* initialPose = 0;
+ // Remember that 3dsMax has the modifier stack reversed
+ // So that evaluating the zero'th modifier implies evaluating the whole modifier stack.
+ int modifierCount = mDerivedObject->NumModifiers();
+ if ( mModifierIndex < modifierCount )
+ {
+ ObjectState state = mDerivedObject->Eval(TIME_INITIAL_POSE, mModifierIndex);
+ initialPose = state.obj;
+ }
+ else
+ {
+ initialPose = mDerivedObject->GetObjRef();
+ }
+ return initialPose;
+
+ }
+
+
+
//---------------------------------------------------------------
bool SkinController::isSkinController( Modifier * modifier )
{
@@ -89,15 +89,39 @@ namespace COLLADAMax
return;
size_t controllerCount = controllerList->getControllerCount();
- for ( size_t i = 0; i < controllerCount; ++i)
+ for ( size_t j = 0; j < controllerCount; ++j)
{
- String controllerId = getControllerId(*exportNode, controllerCount - i, controllerList->getController(i)->getType());
+ size_t i = controllerCount - j - 1;
+
+ Controller* controller = controllerList->getController(i);
+
+ ObjectIdentifier poseAfter(controller->getDerivedObject(), (int)i);
+
+ if ( mDocumentExporter->isExportedObject(poseAfter) )
+ {
+ if ( controller->getType() == Controller::SKIN )
+ determineReferencedJoints(exportNode, (SkinController*)controller);
+ continue;
+ }
+
+ String controllerId = getControllerId(*exportNode, controllerCount - i, controller->getType());
String controllerSource;
if ( i < controllerCount - 1)
- controllerSource = '#' + getControllerId(*exportNode, controllerCount - i - 1, controllerList->getController(i+1)->getType());
+ {
+ String previousControllerId = mDocumentExporter->getExportedObjectId(ObjectIdentifier(controllerList->getController(i+1)->getDerivedObject(), (int)i+1));
+ assert( !previousControllerId.empty() );
+ controllerSource = '#' + previousControllerId;
+// controllerSource = '#' + getControllerId(*exportNode, controllerCount - i - 1, controllerList->getController(i+1)->getType());
+ }
else
- controllerSource = '#' + GeometriesExporter::getGeometryId(*exportNode);
- exportController(exportNode, controllerList->getController(i), controllerId, controllerSource);
+ {
+ String geometryId = mDocumentExporter->getExportedObjectId(ObjectIdentifier(exportNode->getInitialPose()));
+ assert( !geometryId.empty() );
+ controllerSource = '#' + geometryId;
+// controllerSource = '#' + GeometriesExporter::getGeometryId(*exportNode);
+ }
+ exportController(exportNode, controller, controllerId, controllerSource);
+ mDocumentExporter->insertExportedObject(poseAfter, controllerId);
}
}
@@ -147,9 +171,6 @@ namespace COLLADAMax
jointSource.setAccessorCount(jointCount);
jointSource.prepareToAppendValues();
-
- ExportNodeSet referencedJoints;
-
for (int i = 0; i < jointCount; ++i)
{
// there should not be any null bone.
@@ -164,16 +185,13 @@ namespace COLLADAMax
if ( !jointExportNode->hasSid() )
jointExportNode->setSid(mExportSceneGraph->createJointSid());
- referencedJoints.insert(jointExportNode);
- //exportNode->getControllerList()->addReferencedJoint(jointExportNode);
jointExportNode->setIsJoint();
jointSource.appendValues(jointExportNode->getSid());
-
}
jointSource.finish();
- calculateSkeletonRoots(referencedJoints, exportNode->getControllerList());
+ determineReferencedJoints(exportNode, skinController);
//export inverse bind matrix source
String inverseBindMatrixId = controllerId + BIND_POSES_SOURCE_ID_SUFFIX;
@@ -341,7 +359,10 @@ namespace COLLADAMax
ExportNode* targetExportNode = mExportSceneGraph->getExportNode(targetINode);
assert(targetExportNode);
- listOfTargetIds.push_back(GeometriesExporter::getGeometryId(*targetExportNode));
+ String geometryId = mDocumentExporter->getExportedObjectId(ObjectIdentifier(targetExportNode->getInitialPose()));
+ assert( !geometryId.empty() );
+ listOfTargetIds.push_back(geometryId);
+// listOfTargetIds.push_back(GeometriesExporter::getGeometryId(*targetExportNode));
}
}
@@ -389,8 +410,34 @@ namespace COLLADAMax
}
+ void ControllerExporter::determineReferencedJoints(ExportNode* exportNode, SkinController* skinController)
+ {
+ ISkin* skin = skinController->getSkin();
+
+ int jointCount = skin->GetNumBones();
+
+ ExportNodeSet referencedJoints;
+
+ for (int i = 0; i < jointCount; ++i)
+ {
+ // there should not be any null bone.
+ // the ISkin::GetBone, not GetBoneFlat, function is called here.
+ INode* boneNode = skin->GetBone(i);
+ assert(boneNode);
+
+ ExportNode* jointExportNode = mExportSceneGraph->getExportNode(boneNode);
+ assert(jointExportNode);
+
+ referencedJoints.insert(jointExportNode);
+ }
+
+ determineSkeletonRoots(referencedJoints, exportNode->getControllerList());
+ }
+
+
+
//---------------------------------------------------------------
- void ControllerExporter::calculateSkeletonRoots( const ExportNodeSet &referencedJoints, ControllerList * controllerList)
+ void ControllerExporter::determineSkeletonRoots( const ExportNodeSet &referencedJoints, ControllerList * controllerList)
{
for ( ExportNodeSet::const_iterator it = referencedJoints.begin(); it!=referencedJoints.end(); ++it)
{
@@ -99,7 +99,7 @@ namespace COLLADAMax
Object* ControllerList::getInitialPose() const
{
if ( !mControllers.empty() )
- return mControllers.back()->getInitialPose();
+ return mControllers.back()->getPoseBefore();
else
return 0;
}
Oops, something went wrong.

0 comments on commit 681d647

Please sign in to comment.