Improve Node Graph generation, adding pivot node.
- The default layer index is set to -1. - Layers without parents are set to have a parent index of -1. - apcNodes type is changed from std::vector<aiNode*> to std::map<uint16_t, aiNode*>, in order to match layer and layer index.pull/3/head
parent
058be9323d
commit
90427fdcba
|
@ -142,6 +142,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
mLayers->push_back(Layer());
|
mLayers->push_back(Layer());
|
||||||
mCurLayer = &mLayers->back();
|
mCurLayer = &mLayers->back();
|
||||||
mCurLayer->mName = "<LWODefault>";
|
mCurLayer->mName = "<LWODefault>";
|
||||||
|
mCurLayer->mIndex = -1;
|
||||||
|
|
||||||
// old lightwave file format (prior to v6)
|
// old lightwave file format (prior to v6)
|
||||||
if (AI_LWO_FOURCC_LWOB == fileType) {
|
if (AI_LWO_FOURCC_LWOB == fileType) {
|
||||||
|
@ -201,8 +202,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
// now process all layers and build meshes and nodes
|
// now process all layers and build meshes and nodes
|
||||||
std::vector<aiMesh*> apcMeshes;
|
std::vector<aiMesh*> apcMeshes;
|
||||||
std::vector<aiNode*> apcNodes;
|
std::map<uint16_t, aiNode*> apcNodes;
|
||||||
apcNodes. reserve(mLayers->size());
|
|
||||||
apcMeshes.reserve(mLayers->size()*std::min(((unsigned int)mSurfaces->size()/2u), 1u));
|
apcMeshes.reserve(mLayers->size()*std::min(((unsigned int)mSurfaces->size()/2u), 1u));
|
||||||
|
|
||||||
unsigned int iDefaultSurface = UINT_MAX; // index of the default surface
|
unsigned int iDefaultSurface = UINT_MAX; // index of the default surface
|
||||||
|
@ -390,7 +391,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
unsigned int num = apcMeshes.size() - meshStart;
|
unsigned int num = apcMeshes.size() - meshStart;
|
||||||
if (layer.mName != "<LWODefault>" || num > 0) {
|
if (layer.mName != "<LWODefault>" || num > 0) {
|
||||||
aiNode* pcNode = new aiNode();
|
aiNode* pcNode = new aiNode();
|
||||||
apcNodes.push_back(pcNode);
|
apcNodes[layer.mIndex] = pcNode;
|
||||||
pcNode->mName.Set(layer.mName);
|
pcNode->mName.Set(layer.mName);
|
||||||
pcNode->mParent = (aiNode*)&layer;
|
pcNode->mParent = (aiNode*)&layer;
|
||||||
pcNode->mNumMeshes = num;
|
pcNode->mNumMeshes = num;
|
||||||
|
@ -528,6 +529,89 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void LWOImporter::GenerateNodeGraph(std::map<uint16_t,aiNode*>& apcNodes)
|
||||||
|
{
|
||||||
|
// now generate the final nodegraph - generate a root node and attach children
|
||||||
|
aiNode* root = pScene->mRootNode = new aiNode();
|
||||||
|
root->mName.Set("<LWORoot>");
|
||||||
|
|
||||||
|
//Set parent of all children, inserting pivots
|
||||||
|
std::cout << "Set parent of all children" << std::endl;
|
||||||
|
std::map<uint16_t, aiNode*> mapPivot;
|
||||||
|
for (std::map<uint16_t,aiNode*>::iterator itapcNodes = apcNodes.begin(); itapcNodes != apcNodes.end(); ++itapcNodes) {
|
||||||
|
|
||||||
|
//Get the parent index
|
||||||
|
LWO::Layer* nodeLayer = (LWO::Layer*)(itapcNodes->second->mParent);
|
||||||
|
uint16_t parentIndex = nodeLayer->mParent;
|
||||||
|
|
||||||
|
//Create pivot node, store it into the pivot map, and set the parent as the pivot
|
||||||
|
aiNode* pivotNode = new aiNode();
|
||||||
|
pivotNode->mName.Set("Pivot-"+std::string(itapcNodes->second->mName.data));
|
||||||
|
mapPivot[-(itapcNodes->first+2)] = pivotNode;
|
||||||
|
itapcNodes->second->mParent = pivotNode;
|
||||||
|
|
||||||
|
//Look for the parent node to attach the pivot to
|
||||||
|
if (apcNodes.find(parentIndex) != apcNodes.end()) {
|
||||||
|
pivotNode->mParent = apcNodes[parentIndex];
|
||||||
|
} else {
|
||||||
|
//If not, attach to the root node
|
||||||
|
pivotNode->mParent = root;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the node and the pivot node transformation
|
||||||
|
itapcNodes->second->mTransformation.a4 = -nodeLayer->mPivot.x;
|
||||||
|
itapcNodes->second->mTransformation.b4 = -nodeLayer->mPivot.y;
|
||||||
|
itapcNodes->second->mTransformation.c4 = -nodeLayer->mPivot.z;
|
||||||
|
pivotNode->mTransformation.a4 = nodeLayer->mPivot.x;
|
||||||
|
pivotNode->mTransformation.b4 = nodeLayer->mPivot.y;
|
||||||
|
pivotNode->mTransformation.c4 = nodeLayer->mPivot.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Merge pivot map into node map
|
||||||
|
std::cout << "Merge pivot map into node map" << std::endl;
|
||||||
|
for (std::map<uint16_t, aiNode*>::iterator itMapPivot = mapPivot.begin(); itMapPivot != mapPivot.end(); ++itMapPivot) {
|
||||||
|
apcNodes[itMapPivot->first] = itMapPivot->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set children of all parents
|
||||||
|
apcNodes[-1] = root;
|
||||||
|
for (std::map<uint16_t,aiNode*>::iterator itMapParentNodes = apcNodes.begin(); itMapParentNodes != apcNodes.end(); ++itMapParentNodes) {
|
||||||
|
for (std::map<uint16_t,aiNode*>::iterator itMapChildNodes = apcNodes.begin(); itMapChildNodes != apcNodes.end(); ++itMapChildNodes) {
|
||||||
|
if ((itMapParentNodes->first != itMapChildNodes->first) && (itMapParentNodes->second == itMapChildNodes->second->mParent)) {
|
||||||
|
++(itMapParentNodes->second->mNumChildren);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (itMapParentNodes->second->mNumChildren) {
|
||||||
|
itMapParentNodes->second->mChildren = new aiNode* [ itMapParentNodes->second->mNumChildren ];
|
||||||
|
uint16_t p = 0;
|
||||||
|
for (std::map<uint16_t,aiNode*>::iterator itMapChildNodes = apcNodes.begin(); itMapChildNodes != apcNodes.end(); ++itMapChildNodes) {
|
||||||
|
if ((itMapParentNodes->first != itMapChildNodes->first) && (itMapParentNodes->second == itMapChildNodes->second->mParent)) {
|
||||||
|
itMapParentNodes->second->mChildren[p++] = itMapChildNodes->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pScene->mRootNode->mNumChildren)
|
||||||
|
throw DeadlyImportError("LWO: Unable to build a valid node graph");
|
||||||
|
|
||||||
|
// Remove a single root node with no meshes assigned to it ...
|
||||||
|
if (1 == pScene->mRootNode->mNumChildren) {
|
||||||
|
aiNode* pc = pScene->mRootNode->mChildren[0];
|
||||||
|
pc->mParent = pScene->mRootNode->mChildren[0] = NULL;
|
||||||
|
delete pScene->mRootNode;
|
||||||
|
pScene->mRootNode = pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert the whole stuff to RH with CCW winding
|
||||||
|
MakeLeftHandedProcess maker;
|
||||||
|
maker.Execute(pScene);
|
||||||
|
|
||||||
|
FlipWindingOrderProcess flipper;
|
||||||
|
flipper.Execute(pScene);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void LWOImporter::ResolveTags()
|
void LWOImporter::ResolveTags()
|
||||||
{
|
{
|
||||||
|
@ -1231,6 +1315,7 @@ void LWOImporter::LoadLWO2File()
|
||||||
// optional: parent of this layer
|
// optional: parent of this layer
|
||||||
if (mFileBuffer + 2 <= next)
|
if (mFileBuffer + 2 <= next)
|
||||||
layer.mParent = GetU2();
|
layer.mParent = GetU2();
|
||||||
|
else layer.mParent = -1;
|
||||||
|
|
||||||
// Set layer skip parameter
|
// Set layer skip parameter
|
||||||
layer.skip = skip;
|
layer.skip = skip;
|
||||||
|
|
|
@ -303,7 +303,7 @@ private:
|
||||||
* Unused nodes are deleted.
|
* Unused nodes are deleted.
|
||||||
* @param apcNodes Flat list of nodes
|
* @param apcNodes Flat list of nodes
|
||||||
*/
|
*/
|
||||||
void GenerateNodeGraph(std::vector<aiNode*>& apcNodes);
|
void GenerateNodeGraph(std::map<uint16_t,aiNode*>& apcNodes);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Add children to a node
|
/** Add children to a node
|
||||||
|
|
Loading…
Reference in New Issue