- rough support for multi-part player models.

SceneCombiner
 - added support for cross-attachments of nodes in the whole graph

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@345 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
This commit is contained in:
aramis_acg
2009-02-12 22:14:35 +00:00
parent e6758ce923
commit d70c092b71
6 changed files with 232 additions and 74 deletions

View File

@@ -129,7 +129,6 @@ inline void PrefixString(aiString& string,const char* prefix, unsigned int len)
void SceneCombiner::AddNodePrefixes(aiNode* node, const char* prefix, unsigned int len)
{
ai_assert(NULL != prefix);
PrefixString(node->mName,prefix,len);
// Process all children recursively
@@ -177,8 +176,7 @@ void SceneCombiner::MergeScenes(aiScene** _dest,std::vector<aiScene*>& src,
master->mRootNode->mName.Set("<MergeRoot>");
std::vector<AttachmentInfo> srcList (src.size());
for (unsigned int i = 0; i < srcList.size();++i)
{
for (unsigned int i = 0; i < srcList.size();++i) {
srcList[i] = AttachmentInfo(src[i],master->mRootNode);
}
@@ -190,7 +188,6 @@ void SceneCombiner::MergeScenes(aiScene** _dest,std::vector<aiScene*>& src,
void SceneCombiner::AttachToGraph (aiNode* attach, std::vector<NodeAttachmentInfo>& srcList)
{
unsigned int cnt;
for (cnt = 0; cnt < attach->mNumChildren;++cnt)
AttachToGraph(attach->mChildren[cnt],srcList);
@@ -198,15 +195,13 @@ void SceneCombiner::AttachToGraph (aiNode* attach, std::vector<NodeAttachmentInf
for (std::vector<NodeAttachmentInfo>::iterator it = srcList.begin();
it != srcList.end(); ++it)
{
if ((*it).attachToNode == attach)
if ((*it).attachToNode == attach && !(*it).resolved)
++cnt;
}
if (cnt)
{
if (cnt) {
aiNode** n = new aiNode*[cnt+attach->mNumChildren];
if (attach->mNumChildren)
{
if (attach->mNumChildren) {
::memcpy(n,attach->mChildren,sizeof(void*)*attach->mNumChildren);
delete[] attach->mChildren;
}
@@ -215,14 +210,15 @@ void SceneCombiner::AttachToGraph (aiNode* attach, std::vector<NodeAttachmentInf
n += attach->mNumChildren;
attach->mNumChildren += cnt;
for (unsigned int i = 0; i < srcList.size();++i)
{
for (unsigned int i = 0; i < srcList.size();++i) {
NodeAttachmentInfo& att = srcList[i];
if (att.attachToNode == attach)
{
if (att.attachToNode == attach && !att.resolved) {
*n = att.node;
(**n).mParent = attach;
++n;
// mark this attachment as resolved
att.resolved = true;
}
}
}
@@ -261,8 +257,7 @@ void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
std::vector<SceneHelper> src (srcList.size()+1);
src[0].scene = master;
for (unsigned int i = 0; i < srcList.size();++i)
{
for (unsigned int i = 0; i < srcList.size();++i) {
src[i+1] = SceneHelper( srcList[i].scene );
}
@@ -272,7 +267,6 @@ void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
// this helper array is used as lookup table several times
std::vector<unsigned int> offset(src.size());
// Find duplicate scenes
for (unsigned int i = 0; i < src.size();++i)
{
@@ -316,8 +310,7 @@ void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
{
SceneHelper* cur = &src[n];
if (n == duplicates[n] || flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY)
{
if (n == duplicates[n] || flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY) {
dest->mNumTextures += (*cur)->mNumTextures;
dest->mNumMaterials += (*cur)->mNumMaterials;
dest->mNumMeshes += (*cur)->mNumMeshes;
@@ -378,11 +371,8 @@ void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
if ((*cur)->mNumTextures != dest->mNumTextures)
{
// We need to update all texture indices of the mesh.
// So we need to search for a material property like
// that follows the following pattern: "$tex.file.<s>.<n>"
// where s is the texture type (i.e. diffuse) and n is
// the index of the texture.
// We need to update all texture indices of the mesh. So we need to search for
// a material property called '$tex.file'
for (unsigned int a = 0; a < (*pip)->mNumProperties;++a)
{
@@ -393,8 +383,7 @@ void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
// In this case the property looks like this: *<n>,
// where n is the index of the texture.
aiString& s = *((aiString*)prop->mData);
if ('*' == s.data[0])
{
if ('*' == s.data[0]) {
// Offset the index and write it back ..
const unsigned int idx = strtol10(&s.data[1]) + offset[n];
ASSIMP_itoa10(&s.data[1],sizeof(s.data)-1,idx);
@@ -428,8 +417,7 @@ void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
SceneHelper* cur = &src[n];
for (unsigned int i = 0; i < (*cur)->mNumMeshes;++i)
{
if (n != duplicates[n])
{
if (n != duplicates[n]) {
if ( flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY)
Copy(pip, (*cur)->mMeshes[i]);
@@ -439,7 +427,6 @@ void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
// update the material index of the mesh
(*pip)->mMaterialIndex += offset[n];
++pip;
}
@@ -481,8 +468,7 @@ void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
{
Copy( &node, (*cur)->mRootNode );
if (flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY)
{
if (flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY) {
// (note:) they are already 'offseted' by offset[duplicates[n]]
OffsetNodeMeshIndices(node,offset[n] - offset[duplicates[n]]);
}
@@ -493,7 +479,7 @@ void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
OffsetNodeMeshIndices(node,offset[n]);
}
if (n) // src[0] is the master node
nodes.push_back(NodeAttachmentInfo( node,srcList[n-1].attachToNode ));
nodes.push_back(NodeAttachmentInfo( node,srcList[n-1].attachToNode,n ));
// --------------------------------------------------------------------
// Copy light sources
@@ -508,8 +494,7 @@ void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
// --------------------------------------------------------------------
// Copy cameras
for (unsigned int i = 0; i < (*cur)->mNumCameras;++i,++ppCameras)
{
for (unsigned int i = 0; i < (*cur)->mNumCameras;++i,++ppCameras) {
if (n != duplicates[n]) // duplicate scene?
{
Copy(ppCameras, (*cur)->mCameras[i]);
@@ -519,8 +504,7 @@ void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
// --------------------------------------------------------------------
// Copy animations
for (unsigned int i = 0; i < (*cur)->mNumAnimations;++i,++ppAnims)
{
for (unsigned int i = 0; i < (*cur)->mNumAnimations;++i,++ppAnims) {
if (n != duplicates[n]) // duplicate scene?
{
Copy(ppAnims, (*cur)->mAnimations[i]);
@@ -529,8 +513,7 @@ void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
}
}
for ( unsigned int n = 1; n < src.size();++n )
{
for ( unsigned int n = 1; n < src.size();++n ) {
SceneHelper* cur = &src[n];
// --------------------------------------------------------------------
// Add prefixes
@@ -542,8 +525,7 @@ void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
for (unsigned int i = 0; i < (*cur)->mNumCameras;++i)
PrefixString(dest->mCameras[i]->mName,(*cur).id,(*cur).idlen);
for (unsigned int i = 0; i < (*cur)->mNumAnimations;++i)
{
for (unsigned int i = 0; i < (*cur)->mNumAnimations;++i) {
aiAnimation* anim = dest->mAnimations[i];
PrefixString(anim->mName,(*cur).id,(*cur).idlen);
@@ -551,7 +533,6 @@ void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
for (unsigned int a = 0; a < anim->mNumChannels;++a)
PrefixString(anim->mChannels[a]->mNodeName,(*cur).id,(*cur).idlen);
}
AddNodePrefixes(nodes[n-1].node,(*cur).id,(*cur).idlen);
}
}
@@ -560,10 +541,31 @@ void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
AttachToGraph ( master, nodes);
dest->mRootNode = master->mRootNode;
// Check whether we succeeded at building the output graph
for (std::vector <NodeAttachmentInfo> ::iterator it = nodes.begin();
it != nodes.end(); ++it)
{
if (!(*it).resolved) {
if (flags & AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS) {
// search for this attachment point in all other imported scenes, too.
for ( unsigned int n = 0; n < src.size();++n ) {
if (n != (*it).src_idx) {
AttachToGraph(src[n].scene,nodes);
if ((*it).resolved)
break;
}
}
}
if (!(*it).resolved) {
DefaultLogger::get()->error(std::string("SceneCombiner: Failed to resolve attachment ")
+ (*it).node->mName.data + " " + (*it).attachToNode->mName.data);
}
}
}
// now delete all input scenes. Make sure duplicate scenes aren't
// deleted more than one time
for ( unsigned int n = 0; n < src.size();++n )
{
for ( unsigned int n = 0; n < src.size();++n ) {
if (n != duplicates[n]) // duplicate scene?
continue;