Skip to content

Commit

Permalink
export instantiated objects only once
Browse files Browse the repository at this point in the history
  • Loading branch information
opencollada-sebastian committed Aug 28, 2008
1 parent a3010a9 commit 681d647
Show file tree
Hide file tree
Showing 17 changed files with 264 additions and 39 deletions.
18 changes: 12 additions & 6 deletions COLLADAMax/FEATURES
Expand Up @@ -3,6 +3,11 @@ COLLADAMax Nextgen: Export - Supported features

Scene graph
- Transform nodes
- Instances
- Visual scenes
- Geometries
- Materials
- Effects

Geometry
- Mesh:
Expand All @@ -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

13 changes: 12 additions & 1 deletion COLLADAMax/include/COLLADAMaxController.h
Expand Up @@ -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;}
Expand All @@ -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;}
Expand Down
7 changes: 5 additions & 2 deletions COLLADAMax/include/COLLADAMaxControllerExporter.h
Expand Up @@ -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.*/
Expand Down
30 changes: 28 additions & 2 deletions COLLADAMax/include/COLLADAMaxDocumentExporter.h
Expand Up @@ -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.*/
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 );
Expand Down
18 changes: 17 additions & 1 deletion COLLADAMax/include/COLLADAMaxExportNode.h
Expand Up @@ -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;}
Expand Down Expand Up @@ -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.*/
Expand Down
2 changes: 2 additions & 0 deletions COLLADAMax/include/COLLADAMaxTypes.h
Expand Up @@ -53,6 +53,8 @@ namespace COLLADAMax

typedef std::vector<float> FloatList;


typedef std::map<Object*, String> ObjectStringMap;
}


Expand Down
6 changes: 6 additions & 0 deletions COLLADAMax/src/COLLADAMaxCameraExporter.cpp
Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion COLLADAMax/src/COLLADAMaxColladaExporter.cpp
Expand Up @@ -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();
Expand Down
25 changes: 23 additions & 2 deletions COLLADAMax/src/COLLADAMaxController.cpp
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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 )
{
Expand Down
75 changes: 61 additions & 14 deletions COLLADAMax/src/COLLADAMaxControllerExporter.cpp
Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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.
Expand All @@ -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;
Expand Down Expand Up @@ -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));
}
}

Expand Down Expand Up @@ -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)
{
Expand Down
2 changes: 1 addition & 1 deletion COLLADAMax/src/COLLADAMaxControllerList.cpp
Expand Up @@ -99,7 +99,7 @@ namespace COLLADAMax
Object* ControllerList::getInitialPose() const
{
if ( !mControllers.empty() )
return mControllers.back()->getInitialPose();
return mControllers.back()->getPoseBefore();
else
return 0;
}
Expand Down

0 comments on commit 681d647

Please sign in to comment.