git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@1096 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/3/head^2
parent
052ad0e3de
commit
5957e9996b
|
@ -243,14 +243,13 @@ void AnimResolver::ExtractBindPose(aiMatrix4x4& out)
|
||||||
if (scale_z) scaling.z = scale_z->keys[0].value;
|
if (scale_z) scaling.z = scale_z->keys[0].value;
|
||||||
|
|
||||||
// build the final matrix
|
// build the final matrix
|
||||||
aiMatrix4x4 s,r,t;
|
aiMatrix4x4 s,rx,ry,rz,t;
|
||||||
|
aiMatrix4x4::RotationZ(angles.z, rz);
|
||||||
r.FromEulerAnglesXYZ(angles);
|
aiMatrix4x4::RotationX(angles.y, rx);
|
||||||
//aiMatrix4x4::RotationY(angles.y,r);
|
aiMatrix4x4::RotationY(angles.x, ry);
|
||||||
// fixme: make FromEulerAngles static, too
|
|
||||||
aiMatrix4x4::Translation(translation,t);
|
aiMatrix4x4::Translation(translation,t);
|
||||||
aiMatrix4x4::Scaling(scaling,s);
|
aiMatrix4x4::Scaling(scaling,s);
|
||||||
out = s*r*t;
|
out = t*ry*rx*rz*s;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -567,10 +566,15 @@ void AnimResolver::ExtractAnimChannel(aiNodeAnim** out, unsigned int flags /*= 0
|
||||||
anim->mRotationKeys = new aiQuatKey[ anim->mNumRotationKeys = keys.size() ];
|
anim->mRotationKeys = new aiQuatKey[ anim->mNumRotationKeys = keys.size() ];
|
||||||
|
|
||||||
// convert heading, pitch, bank to quaternion
|
// convert heading, pitch, bank to quaternion
|
||||||
|
// mValue.x=Heading=Rot(Y), mValue.y=Pitch=Rot(X), mValue.z=Bank=Rot(Z)
|
||||||
|
// Lightwave's rotation order is ZXY
|
||||||
|
aiVector3D X(1.0,0.0,0.0);
|
||||||
|
aiVector3D Y(0.0,1.0,0.0);
|
||||||
|
aiVector3D Z(0.0,0.0,1.0);
|
||||||
for (unsigned int i = 0; i < anim->mNumRotationKeys; ++i) {
|
for (unsigned int i = 0; i < anim->mNumRotationKeys; ++i) {
|
||||||
aiQuatKey& qk = anim->mRotationKeys[i];
|
aiQuatKey& qk = anim->mRotationKeys[i];
|
||||||
qk.mTime = keys[i].mTime;
|
qk.mTime = keys[i].mTime;
|
||||||
qk.mValue = aiQuaternion( -keys[i].mValue.x ,-keys[i].mValue.z ,-keys[i].mValue.y );
|
qk.mValue = aiQuaternion(Y,keys[i].mValue.x)*aiQuaternion(X,keys[i].mValue.y)*aiQuaternion(Z,keys[i].mValue.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
@ -180,8 +181,14 @@ void LWOImporter::InternReadFile( const std::string& pFile,
|
||||||
// The newer lightwave format allows the user to configure the
|
// The newer lightwave format allows the user to configure the
|
||||||
// loader that just one layer is used. If this is the case
|
// loader that just one layer is used. If this is the case
|
||||||
// we need to check now whether the requested layer has been found.
|
// we need to check now whether the requested layer has been found.
|
||||||
if (UINT_MAX != configLayerIndex && configLayerIndex > mLayers->size())
|
if (UINT_MAX != configLayerIndex) {
|
||||||
throw DeadlyImportError("LWO2: The requested layer was not found");
|
unsigned int layerCount = 0;
|
||||||
|
for(std::list<LWO::Layer>::iterator itLayers=mLayers->begin(); itLayers!=mLayers->end(); itLayers++)
|
||||||
|
if (!itLayers->skip)
|
||||||
|
layerCount++;
|
||||||
|
if (layerCount!=2)
|
||||||
|
throw DeadlyImportError("LWO2: The requested layer was not found");
|
||||||
|
}
|
||||||
|
|
||||||
if (configLayerName.length() && !hasNamedLayer) {
|
if (configLayerName.length() && !hasNamedLayer) {
|
||||||
throw DeadlyImportError("LWO2: Unable to find the requested layer: "
|
throw DeadlyImportError("LWO2: Unable to find the requested layer: "
|
||||||
|
@ -195,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
|
||||||
|
@ -384,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;
|
||||||
|
@ -523,78 +530,69 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void LWOImporter::AddChildren(aiNode* node, uint16_t parent, std::vector<aiNode*>& apcNodes)
|
void LWOImporter::GenerateNodeGraph(std::map<uint16_t,aiNode*>& apcNodes)
|
||||||
{
|
|
||||||
for (std::vector<aiNode*>::iterator it = apcNodes.begin(); it != apcNodes.end(); ++it) {
|
|
||||||
if (*it) {
|
|
||||||
LWO::Layer* layer = (LWO::Layer*)(*it)->mParent;
|
|
||||||
if (layer->mParent == parent && layer->mIndex != parent)
|
|
||||||
++node->mNumChildren;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node->mNumChildren) {
|
|
||||||
unsigned int p = 0;
|
|
||||||
|
|
||||||
node->mChildren = new aiNode* [ node->mNumChildren ];
|
|
||||||
for (std::vector<aiNode*>::iterator it = apcNodes.begin(); it != apcNodes.end(); ++it) {
|
|
||||||
if (*it) {
|
|
||||||
LWO::Layer* layer = (LWO::Layer*)(*it)->mParent;
|
|
||||||
if (layer->mParent == parent && layer->mIndex != parent) {
|
|
||||||
aiNode* nd = node->mChildren[p++] = *it;
|
|
||||||
nd->mParent = node;
|
|
||||||
|
|
||||||
// fixme: ignore pivot points for the moment
|
|
||||||
//nd->mTransformation.a4 = layer->mPivot.x;
|
|
||||||
//nd->mTransformation.b4 = layer->mPivot.y;
|
|
||||||
//nd->mTransformation.c4 = layer->mPivot.z;
|
|
||||||
|
|
||||||
// recursively add more children
|
|
||||||
(*it) = NULL;
|
|
||||||
AddChildren(nd,layer->mIndex,apcNodes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void LWOImporter::GenerateNodeGraph(std::vector<aiNode*>& apcNodes)
|
|
||||||
{
|
{
|
||||||
// now generate the final nodegraph - generate a root node and attach children
|
// now generate the final nodegraph - generate a root node and attach children
|
||||||
aiNode* root = pScene->mRootNode = new aiNode();
|
aiNode* root = pScene->mRootNode = new aiNode();
|
||||||
root->mName.Set("<LWORoot>");
|
root->mName.Set("<LWORoot>");
|
||||||
AddChildren(root,0,apcNodes);
|
|
||||||
|
|
||||||
// check whether we added all layers with meshes assigned to the output graph.
|
//Set parent of all children, inserting pivots
|
||||||
// if not, add them to the root node
|
std::cout << "Set parent of all children" << std::endl;
|
||||||
unsigned int extra = 0;
|
std::map<uint16_t, aiNode*> mapPivot;
|
||||||
for (std::vector<aiNode*>::iterator it = apcNodes.begin(); it != apcNodes.end(); ++it) {
|
for (std::map<uint16_t,aiNode*>::iterator itapcNodes = apcNodes.begin(); itapcNodes != apcNodes.end(); ++itapcNodes) {
|
||||||
if ((*it) && (*it)->mNumMeshes)
|
|
||||||
++extra;
|
//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;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extra) {
|
//Merge pivot map into node map
|
||||||
const unsigned int newSize = extra + pScene->mRootNode->mNumChildren;
|
std::cout << "Merge pivot map into node map" << std::endl;
|
||||||
aiNode** const apcNewNodes = new aiNode*[newSize];
|
for (std::map<uint16_t, aiNode*>::iterator itMapPivot = mapPivot.begin(); itMapPivot != mapPivot.end(); ++itMapPivot) {
|
||||||
if((extra = root->mNumChildren))
|
apcNodes[itMapPivot->first] = itMapPivot->second;
|
||||||
::memcpy(apcNewNodes,root->mChildren,extra*sizeof(void*));
|
}
|
||||||
|
|
||||||
aiNode** cc = apcNewNodes+extra;
|
//Set children of all parents
|
||||||
for (std::vector<aiNode*>::iterator it = apcNodes.begin(); it != apcNodes.end(); ++it) {
|
apcNodes[-1] = root;
|
||||||
if ((*it) && (*it)->mNumMeshes) {
|
for (std::map<uint16_t,aiNode*>::iterator itMapParentNodes = apcNodes.begin(); itMapParentNodes != apcNodes.end(); ++itMapParentNodes) {
|
||||||
aiNode* nd = *cc++ = *it;
|
for (std::map<uint16_t,aiNode*>::iterator itMapChildNodes = apcNodes.begin(); itMapChildNodes != apcNodes.end(); ++itMapChildNodes) {
|
||||||
nd->mParent = pScene->mRootNode;
|
if ((itMapParentNodes->first != itMapChildNodes->first) && (itMapParentNodes->second == itMapChildNodes->second->mParent)) {
|
||||||
|
++(itMapParentNodes->second->mNumChildren);
|
||||||
// recursively add more children
|
}
|
||||||
(*it) = NULL;
|
}
|
||||||
AddChildren(nd,((LWO::Layer*)nd->mParent)->mIndex,apcNodes);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete[] root->mChildren;
|
|
||||||
root->mChildren = apcNewNodes;
|
|
||||||
root->mNumChildren = newSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pScene->mRootNode->mNumChildren)
|
if (!pScene->mRootNode->mNumChildren)
|
||||||
throw DeadlyImportError("LWO: Unable to build a valid node graph");
|
throw DeadlyImportError("LWO: Unable to build a valid node graph");
|
||||||
|
|
||||||
|
@ -1285,17 +1283,15 @@ void LWOImporter::LoadLWO2File()
|
||||||
|
|
||||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,LAYR,16);
|
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,LAYR,16);
|
||||||
|
|
||||||
|
// layer index.
|
||||||
|
layer.mIndex = GetU2();
|
||||||
|
|
||||||
// Continue loading this layer or ignore it? Check the layer index property
|
// Continue loading this layer or ignore it? Check the layer index property
|
||||||
// NOTE: The first layer is the default layer, so the layer index is one-based now
|
if (UINT_MAX != configLayerIndex && (configLayerIndex-1) != layer.mIndex) {
|
||||||
if (UINT_MAX != configLayerIndex && configLayerIndex != mLayers->size()-1) {
|
|
||||||
skip = true;
|
skip = true;
|
||||||
}
|
}
|
||||||
else skip = false;
|
else skip = false;
|
||||||
|
|
||||||
// layer index. that's just for internal parenting, from the scope of a LWS file
|
|
||||||
// all layers are numbered in the oder in which they appear in the file
|
|
||||||
layer.mIndex = GetU2();
|
|
||||||
|
|
||||||
// pivot point
|
// pivot point
|
||||||
mFileBuffer += 2; /* unknown */
|
mFileBuffer += 2; /* unknown */
|
||||||
mCurLayer->mPivot.x = GetF4();
|
mCurLayer->mPivot.x = GetF4();
|
||||||
|
@ -1319,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
|
||||||
|
|
|
@ -295,8 +295,9 @@ void LWSImporter::SetupNodeName(aiNode* nd, LWS::NodeDesc& src)
|
||||||
if (s == std::string::npos)
|
if (s == std::string::npos)
|
||||||
s = 0;
|
s = 0;
|
||||||
else ++s;
|
else ++s;
|
||||||
|
std::string::size_type t = src.path.substr(s).find_last_of(".");
|
||||||
nd->mName.length = ::sprintf(nd->mName.data,"%s_(%08X)",src.path.substr(s).c_str(),combined);
|
|
||||||
|
nd->mName.length = ::sprintf(nd->mName.data,"%s_(%08X)",src.path.substr(s).substr(0,t).c_str(),combined);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,18 +314,62 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
|
||||||
{
|
{
|
||||||
// Setup a very cryptic name for the node, we want the user to be happy
|
// Setup a very cryptic name for the node, we want the user to be happy
|
||||||
SetupNodeName(nd,src);
|
SetupNodeName(nd,src);
|
||||||
|
aiNode* ndAnim = nd;
|
||||||
|
|
||||||
// If this is an object from an external file - get the scene and setup proper attachment tags
|
// If the node is an object
|
||||||
aiScene* obj = NULL;
|
if (src.type == LWS::NodeDesc::OBJECT) {
|
||||||
if (src.type == LWS::NodeDesc::OBJECT && src.path.length() ) {
|
|
||||||
obj = batch.GetImport(src.id);
|
// If the object is from an external file, get it
|
||||||
if (!obj) {
|
aiScene* obj = NULL;
|
||||||
DefaultLogger::get()->error("LWS: Failed to read external file " + src.path);
|
if (src.path.length() ) {
|
||||||
}
|
obj = batch.GetImport(src.id);
|
||||||
else {
|
if (!obj) {
|
||||||
attach.push_back(AttachmentInfo(obj,nd));
|
DefaultLogger::get()->error("LWS: Failed to read external file " + src.path);
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
if (obj->mRootNode->mNumChildren == 1) {
|
||||||
|
|
||||||
|
//If the pivot is not set for this layer, get it from the external object
|
||||||
|
if (!src.isPivotSet) {
|
||||||
|
src.pivotPos.x = +obj->mRootNode->mTransformation.a4;
|
||||||
|
src.pivotPos.y = +obj->mRootNode->mTransformation.b4;
|
||||||
|
src.pivotPos.z = -obj->mRootNode->mTransformation.c4; //The sign is the RH to LH back conversion
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remove first node from obj (the old pivot), reset transform of second node (the mesh node)
|
||||||
|
aiNode* newRootNode = obj->mRootNode->mChildren[0];
|
||||||
|
free(obj->mRootNode->mChildren);
|
||||||
|
free(obj->mRootNode);
|
||||||
|
obj->mRootNode = newRootNode;
|
||||||
|
obj->mRootNode->mTransformation.a4 = 0.0;
|
||||||
|
obj->mRootNode->mTransformation.b4 = 0.0;
|
||||||
|
obj->mRootNode->mTransformation.c4 = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup the pivot node (also the animation node), the one we received
|
||||||
|
nd->mName = std::string("Pivot:") + nd->mName.data;
|
||||||
|
ndAnim = nd;
|
||||||
|
|
||||||
|
//Add the attachment node to it
|
||||||
|
nd->mNumChildren = 1;
|
||||||
|
nd->mChildren = new aiNode*[1];
|
||||||
|
nd->mChildren[0] = new aiNode();
|
||||||
|
nd->mChildren[0]->mParent = nd;
|
||||||
|
nd->mChildren[0]->mTransformation.a4 = -src.pivotPos.x;
|
||||||
|
nd->mChildren[0]->mTransformation.b4 = -src.pivotPos.y;
|
||||||
|
nd->mChildren[0]->mTransformation.c4 = -src.pivotPos.z;
|
||||||
|
SetupNodeName(nd->mChildren[0], src);
|
||||||
|
|
||||||
|
//Update the attachment node
|
||||||
|
nd = nd->mChildren[0];
|
||||||
|
|
||||||
|
//Push attachment, if the object came from an external file
|
||||||
|
if (obj) {
|
||||||
|
attach.push_back(AttachmentInfo(obj,nd));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If object is a light source - setup a corresponding ai structure
|
// If object is a light source - setup a corresponding ai structure
|
||||||
else if (src.type == LWS::NodeDesc::LIGHT) {
|
else if (src.type == LWS::NodeDesc::LIGHT) {
|
||||||
|
@ -368,7 +413,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
|
||||||
|
|
||||||
// Get the node transformation from the LWO key
|
// Get the node transformation from the LWO key
|
||||||
LWO::AnimResolver resolver(src.channels,fps);
|
LWO::AnimResolver resolver(src.channels,fps);
|
||||||
resolver.ExtractBindPose(nd->mTransformation);
|
resolver.ExtractBindPose(ndAnim->mTransformation);
|
||||||
|
|
||||||
// .. and construct animation channels
|
// .. and construct animation channels
|
||||||
aiNodeAnim* anim = NULL;
|
aiNodeAnim* anim = NULL;
|
||||||
|
@ -377,44 +422,11 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
|
||||||
resolver.SetAnimationRange(first,last);
|
resolver.SetAnimationRange(first,last);
|
||||||
resolver.ExtractAnimChannel(&anim,AI_LWO_ANIM_FLAG_SAMPLE_ANIMS|AI_LWO_ANIM_FLAG_START_AT_ZERO);
|
resolver.ExtractAnimChannel(&anim,AI_LWO_ANIM_FLAG_SAMPLE_ANIMS|AI_LWO_ANIM_FLAG_START_AT_ZERO);
|
||||||
if (anim) {
|
if (anim) {
|
||||||
anim->mNodeName = nd->mName;
|
anim->mNodeName = ndAnim->mName;
|
||||||
animOut.push_back(anim);
|
animOut.push_back(anim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// process pivot point, if any
|
|
||||||
if (src.pivotPos != aiVector3D()) {
|
|
||||||
aiMatrix4x4 tmp;
|
|
||||||
aiMatrix4x4::Translation(-src.pivotPos,tmp);
|
|
||||||
|
|
||||||
if (anim) {
|
|
||||||
|
|
||||||
// We have an animation channel for this node. Problem: to combine the pivot
|
|
||||||
// point with the node anims, we'd need to interpolate *all* keys, get
|
|
||||||
// transformation matrices from them, apply the translation and decompose
|
|
||||||
// the resulting matrices again in order to reconstruct the keys. This
|
|
||||||
// solution here is *much* easier ... we're just inserting an extra node
|
|
||||||
// in the hierarchy.
|
|
||||||
// Maybe the final optimization here will be done during postprocessing.
|
|
||||||
|
|
||||||
aiNode* pivot = new aiNode();
|
|
||||||
pivot->mName.length = sprintf( pivot->mName.data, "$Pivot_%s",nd->mName.data);
|
|
||||||
pivot->mTransformation = tmp;
|
|
||||||
|
|
||||||
pivot->mChildren = new aiNode*[pivot->mNumChildren = 1];
|
|
||||||
pivot->mChildren[0] = nd;
|
|
||||||
|
|
||||||
pivot->mParent = nd->mParent;
|
|
||||||
nd->mParent = pivot;
|
|
||||||
|
|
||||||
// swap children and hope the parents wont see a huge difference
|
|
||||||
pivot->mParent->mChildren[pivot->mParent->mNumChildren-1] = pivot;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nd->mTransformation = tmp*nd->mTransformation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add children
|
// Add children
|
||||||
if (src.children.size()) {
|
if (src.children.size()) {
|
||||||
nd->mChildren = new aiNode*[src.children.size()];
|
nd->mChildren = new aiNode*[src.children.size()];
|
||||||
|
@ -585,11 +597,12 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
// add node to list
|
// add node to list
|
||||||
LWS::NodeDesc d;
|
LWS::NodeDesc d;
|
||||||
d.type = LWS::NodeDesc::OBJECT;
|
d.type = LWS::NodeDesc::OBJECT;
|
||||||
d.name = c;
|
|
||||||
if (version >= 4) { // handle LWSC 4 explicit ID
|
if (version >= 4) { // handle LWSC 4 explicit ID
|
||||||
d.number = strtoul16(c,&c) & AI_LWS_MASK;
|
d.number = strtoul16(c,&c) & AI_LWS_MASK;
|
||||||
|
SkipSpaces(&c);
|
||||||
}
|
}
|
||||||
else d.number = cur_object++;
|
else d.number = cur_object++;
|
||||||
|
d.name = c;
|
||||||
nodes.push_back(d);
|
nodes.push_back(d);
|
||||||
|
|
||||||
num_object++;
|
num_object++;
|
||||||
|
@ -780,6 +793,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
c = fast_atof_move(c, (float&) nodes.back().pivotPos.y );
|
c = fast_atof_move(c, (float&) nodes.back().pivotPos.y );
|
||||||
SkipSpaces(&c);
|
SkipSpaces(&c);
|
||||||
c = fast_atof_move(c, (float&) nodes.back().pivotPos.z );
|
c = fast_atof_move(c, (float&) nodes.back().pivotPos.z );
|
||||||
|
// Mark pivotPos as set
|
||||||
|
nodes.back().isPivotSet = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -866,7 +881,7 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
|
|
||||||
// .. ccw
|
// .. ccw
|
||||||
FlipWindingOrderProcess flipper;
|
FlipWindingOrderProcess flipper;
|
||||||
flipper.Execute(pScene);
|
flipper.Execute(master);
|
||||||
|
|
||||||
// OK ... finally build the output graph
|
// OK ... finally build the output graph
|
||||||
SceneCombiner::MergeScenes(&pScene,master,attach,
|
SceneCombiner::MergeScenes(&pScene,master,attach,
|
||||||
|
|
|
@ -81,6 +81,7 @@ struct NodeDesc
|
||||||
: number (0)
|
: number (0)
|
||||||
, parent (0)
|
, parent (0)
|
||||||
, name ("")
|
, name ("")
|
||||||
|
, isPivotSet (false)
|
||||||
, lightColor (1.f,1.f,1.f)
|
, lightColor (1.f,1.f,1.f)
|
||||||
, lightIntensity (1.f)
|
, lightIntensity (1.f)
|
||||||
, lightType (0)
|
, lightType (0)
|
||||||
|
@ -115,6 +116,7 @@ struct NodeDesc
|
||||||
|
|
||||||
// position of pivot point
|
// position of pivot point
|
||||||
aiVector3D pivotPos;
|
aiVector3D pivotPos;
|
||||||
|
bool isPivotSet;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue