Commit be0a677b authored by hybrid's avatar hybrid

Fixed multi-mesh animations in .x and added face color in case vertex color is missing.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@974 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 8ed622b6
...@@ -736,9 +736,10 @@ void CSkinnedMesh::checkForAnimation() ...@@ -736,9 +736,10 @@ void CSkinnedMesh::checkForAnimation()
SJoint *Joint = AllJoints[i]; SJoint *Joint = AllJoints[i];
for (j=0; j<Joint->Weights.size(); ++j) for (j=0; j<Joint->Weights.size(); ++j)
{ {
u16 buffer_id=Joint->Weights[j].buffer_id; const u16 buffer_id=Joint->Weights[j].buffer_id;
u32 vertex_id=Joint->Weights[j].vertex_id; const u32 vertex_id=Joint->Weights[j].vertex_id;
assert(vertex_id<LocalBuffers[buffer_id]->getVertexCount());
//check for invalid ids //check for invalid ids
if (buffer_id>=LocalBuffers.size()) if (buffer_id>=LocalBuffers.size())
{ {
...@@ -766,8 +767,8 @@ void CSkinnedMesh::checkForAnimation() ...@@ -766,8 +767,8 @@ void CSkinnedMesh::checkForAnimation()
SJoint *Joint = AllJoints[i]; SJoint *Joint = AllJoints[i];
for (j=0; j<Joint->Weights.size(); ++j) for (j=0; j<Joint->Weights.size(); ++j)
{ {
u32 vertex_id=Joint->Weights[j].vertex_id; const u16 buffer_id=Joint->Weights[j].buffer_id;
u32 buffer_id=Joint->Weights[j].buffer_id; const u32 vertex_id=Joint->Weights[j].vertex_id;
Joint->Weights[j].Moved = &Vertices_Moved[buffer_id] [vertex_id]; Joint->Weights[j].Moved = &Vertices_Moved[buffer_id] [vertex_id];
Joint->Weights[j].StaticPos = LocalBuffers[buffer_id]->getVertex(vertex_id)->Pos; Joint->Weights[j].StaticPos = LocalBuffers[buffer_id]->getVertex(vertex_id)->Pos;
...@@ -805,9 +806,9 @@ void CSkinnedMesh::finalize() ...@@ -805,9 +806,9 @@ void CSkinnedMesh::finalize()
else else
{ {
BoundingBox.reset(LocalBuffers[0]->BoundingBox.MaxEdge); BoundingBox.reset(LocalBuffers[0]->BoundingBox.MaxEdge);
for (u32 i=0; i<LocalBuffers.size(); ++i) for (u32 j=0; j<LocalBuffers.size(); ++j)
{ {
BoundingBox.addInternalBox(LocalBuffers[i]->BoundingBox); BoundingBox.addInternalBox(LocalBuffers[j]->BoundingBox);
} }
} }
......
...@@ -114,6 +114,7 @@ bool CXMeshFileLoader::load(io::IReadFile* file) ...@@ -114,6 +114,7 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
u32 i; u32 i;
mesh->Buffers.reallocate(mesh->Materials.size()); mesh->Buffers.reallocate(mesh->Materials.size());
const u32 bufferOffset = AnimatedMesh->getMeshBufferCount();
for (i=0; i<mesh->Materials.size(); ++i) for (i=0; i<mesh->Materials.size(); ++i)
{ {
mesh->Buffers.push_back( AnimatedMesh->createBuffer() ); mesh->Buffers.push_back( AnimatedMesh->createBuffer() );
...@@ -130,19 +131,30 @@ bool CXMeshFileLoader::load(io::IReadFile* file) ...@@ -130,19 +131,30 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
} }
if (!mesh->HasVertexColors)
{
for (u32 j=0;j<mesh->FaceMaterialIndices.size();++j)
{
for (u32 id=j*3+0;id<=j*3+2;++id)
{
mesh->Vertices[ mesh->Indices[id] ].Color = mesh->Buffers[mesh->FaceMaterialIndices[j]]->Material.DiffuseColor;
}
}
}
#ifdef BETTER_MESHBUFFER_SPLITTING_FOR_X #ifdef BETTER_MESHBUFFER_SPLITTING_FOR_X
{ {
//the same vertex can be used in many different meshbuffers, but it's slow to work out //the same vertex can be used in many different meshbuffers, but it's slow to work out
core::array< core::array< u32 > > verticesLink; core::array< core::array< u32 > > verticesLinkIndex;
verticesLink.reallocate(mesh->Vertices.size()); verticesLinkIndex.reallocate(mesh->Vertices.size());
core::array< core::array< u32 > > verticesLinkBuffer; core::array< core::array< u16 > > verticesLinkBuffer;
verticesLinkBuffer.reallocate(mesh->Vertices.size()); verticesLinkBuffer.reallocate(mesh->Vertices.size());
for (i=0;i<mesh->Vertices.size();++i) for (i=0;i<mesh->Vertices.size();++i)
{ {
verticesLink.push_back( core::array< u32 >() ); verticesLinkIndex.push_back( core::array< u32 >() );
verticesLinkBuffer.push_back( core::array< u32 >() ); verticesLinkBuffer.push_back( core::array< u16 >() );
} }
for (i=0;i<mesh->FaceMaterialIndices.size();++i) for (i=0;i<mesh->FaceMaterialIndices.size();++i)
...@@ -174,12 +186,12 @@ bool CXMeshFileLoader::load(io::IReadFile* file) ...@@ -174,12 +186,12 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
for (i=0;i<mesh->Vertices.size();++i) for (i=0;i<mesh->Vertices.size();++i)
{ {
core::array< u32 > &Array = verticesLinkBuffer[i]; core::array< u16 > &Array = verticesLinkBuffer[i];
verticesLink[i].reallocate(Array.size()); verticesLinkIndex[i].reallocate(Array.size());
for (u32 j=0; j < Array.size(); ++j) for (u32 j=0; j < Array.size(); ++j)
{ {
scene::SSkinMeshBuffer *buffer = mesh->Buffers[ Array[j] ]; scene::SSkinMeshBuffer *buffer = mesh->Buffers[ Array[j] ];
verticesLink[i].push_back( buffer->Vertices_Standard.size() ); verticesLinkIndex[i].push_back( buffer->Vertices_Standard.size() );
buffer->Vertices_Standard.push_back( mesh->Vertices[i] ); buffer->Vertices_Standard.push_back( mesh->Vertices[i] );
} }
} }
...@@ -190,12 +202,12 @@ bool CXMeshFileLoader::load(io::IReadFile* file) ...@@ -190,12 +202,12 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
for (u32 id=i*3+0;id<=i*3+2;++id) for (u32 id=i*3+0;id<=i*3+2;++id)
{ {
core::array< u32 > &Array=verticesLinkBuffer[ mesh->Indices[id] ]; core::array< u16 > &Array=verticesLinkBuffer[ mesh->Indices[id] ];
for (u32 j=0;j< Array.size() ;++j) for (u32 j=0;j< Array.size() ;++j)
{ {
if ( Array[j]== mesh->FaceMaterialIndices[i] ) if ( Array[j]== mesh->FaceMaterialIndices[i] )
buffer->Indices.push_back( verticesLink[ mesh->Indices[id] ][j] ); buffer->Indices.push_back( verticesLinkIndex[ mesh->Indices[id] ][j] );
} }
} }
} }
...@@ -206,7 +218,7 @@ bool CXMeshFileLoader::load(io::IReadFile* file) ...@@ -206,7 +218,7 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
u32 id = Weight.vertex_id; u32 id = Weight.vertex_id;
if (id>=verticesLink.size()) if (id>=verticesLinkIndex.size())
{ {
os::Printer::log("X loader: Weight id out of range", ELL_WARNING); os::Printer::log("X loader: Weight id out of range", ELL_WARNING);
id=0; id=0;
...@@ -214,7 +226,7 @@ bool CXMeshFileLoader::load(io::IReadFile* file) ...@@ -214,7 +226,7 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
if (verticesLinkBuffer[id].size()==1) if (verticesLinkBuffer[id].size()==1)
{ {
Weight.vertex_id=verticesLink[id][0]; Weight.vertex_id=verticesLinkIndex[id][0];
Weight.buffer_id=verticesLinkBuffer[id][0]; Weight.buffer_id=verticesLinkBuffer[id][0];
} }
else if (verticesLinkBuffer[id].size() != 0) else if (verticesLinkBuffer[id].size() != 0)
...@@ -223,25 +235,24 @@ bool CXMeshFileLoader::load(io::IReadFile* file) ...@@ -223,25 +235,24 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
{ {
ISkinnedMesh::SWeight* WeightClone = AnimatedMesh->createWeight(Joint); ISkinnedMesh::SWeight* WeightClone = AnimatedMesh->createWeight(Joint);
WeightClone->strength = Weight.strength; WeightClone->strength = Weight.strength;
WeightClone->vertex_id = verticesLink[id][k]; WeightClone->vertex_id = verticesLinkIndex[id][k];
WeightClone->buffer_id = verticesLinkBuffer[id][k]; WeightClone->buffer_id = verticesLinkBuffer[id][k];
} }
} }
} }
} }
#else #else
{ {
core::array< u32 > verticesLink; core::array< u32 > verticesLinkIndex;
core::array< u32 > verticesLinkBuffer; core::array< u16 > verticesLinkBuffer;
verticesLinkBuffer.set_used(mesh->Vertices.size()); verticesLinkBuffer.set_used(mesh->Vertices.size());
verticesLink.set_used(mesh->Vertices.size()); verticesLinkIndex.set_used(mesh->Vertices.size());
// init with 0 // init with 0
for (i=0;i<mesh->Vertices.size();++i) for (i=0;i<mesh->Vertices.size();++i)
{ {
verticesLinkBuffer[i]=0; verticesLinkBuffer[i]=0;
verticesLink[i]=0; verticesLinkIndex[i]=0;
} }
// store meshbuffer number per vertex // store meshbuffer number per vertex
...@@ -253,7 +264,7 @@ bool CXMeshFileLoader::load(io::IReadFile* file) ...@@ -253,7 +264,7 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
} }
} }
// store vertices in buffers and remember relation in verticesLink // store vertices in buffers and remember relation in verticesLinkIndex
u32* vCountArray = new u32[mesh->Buffers.size()]; u32* vCountArray = new u32[mesh->Buffers.size()];
memset(vCountArray, 0, mesh->Buffers.size()*sizeof(u32)); memset(vCountArray, 0, mesh->Buffers.size()*sizeof(u32));
// count vertices in each buffer and reallocate // count vertices in each buffer and reallocate
...@@ -261,12 +272,13 @@ bool CXMeshFileLoader::load(io::IReadFile* file) ...@@ -261,12 +272,13 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
++vCountArray[verticesLinkBuffer[i]]; ++vCountArray[verticesLinkBuffer[i]];
for (i=0; i!=mesh->Buffers.size(); ++i) for (i=0; i!=mesh->Buffers.size(); ++i)
mesh->Buffers[i]->Vertices_Standard.reallocate(vCountArray[i]); mesh->Buffers[i]->Vertices_Standard.reallocate(vCountArray[i]);
// actually store vertices // actually store vertices
for (i=0;i<mesh->Vertices.size();++i) for (i=0;i<mesh->Vertices.size();++i)
{ {
scene::SSkinMeshBuffer *buffer = mesh->Buffers[ verticesLinkBuffer[i] ]; scene::SSkinMeshBuffer *buffer = mesh->Buffers[ verticesLinkBuffer[i] ];
verticesLink[i] = buffer->Vertices_Standard.size(); verticesLinkIndex[i] = buffer->Vertices_Standard.size();
buffer->Vertices_Standard.push_back( mesh->Vertices[i] ); buffer->Vertices_Standard.push_back( mesh->Vertices[i] );
} }
...@@ -282,37 +294,28 @@ bool CXMeshFileLoader::load(io::IReadFile* file) ...@@ -282,37 +294,28 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
{ {
scene::SSkinMeshBuffer *buffer = mesh->Buffers[ mesh->FaceMaterialIndices[i] ]; scene::SSkinMeshBuffer *buffer = mesh->Buffers[ mesh->FaceMaterialIndices[i] ];
for (u32 id=i*3+0;id!=i*3+3;++id) for (u32 id=i*3+0;id!=i*3+3;++id)
buffer->Indices.push_back( verticesLink[ mesh->Indices[id] ] ); buffer->Indices.push_back( verticesLinkIndex[ mesh->Indices[id] ] );
} }
for (u32 j=0;j<mesh->Weights.size();++j) for (u32 j=0;j<mesh->Weights.size();++j)
{ {
ISkinnedMesh::SWeight& Weight = (*mesh->Weights[j]); ISkinnedMesh::SWeight* weight = mesh->Weights[j];
u32 id = Weight.vertex_id; u32 id = weight->vertex_id;
if (id>=verticesLink.size()) if (id>=verticesLinkIndex.size())
{ {
os::Printer::log("X loader: Weight id out of range", ELL_WARNING); os::Printer::log("X loader: Weight id out of range", ELL_WARNING);
id=0; id=0;
} }
Weight.vertex_id=verticesLink[id]; weight->vertex_id=verticesLinkIndex[id];
Weight.buffer_id=verticesLinkBuffer[id]; weight->buffer_id=verticesLinkBuffer[id] + bufferOffset;;
} }
} }
#endif #endif
} }
return true; return true;
...@@ -1071,8 +1074,6 @@ bool CXMeshFileLoader::parseDataObjectMeshTextureCoords(SXMesh &mesh) ...@@ -1071,8 +1074,6 @@ bool CXMeshFileLoader::parseDataObjectMeshTextureCoords(SXMesh &mesh)
} }
bool CXMeshFileLoader::parseDataObjectMeshVertexColors(SXMesh &mesh) bool CXMeshFileLoader::parseDataObjectMeshVertexColors(SXMesh &mesh)
{ {
#ifdef _XREADER_DEBUG #ifdef _XREADER_DEBUG
...@@ -1085,16 +1086,17 @@ bool CXMeshFileLoader::parseDataObjectMeshVertexColors(SXMesh &mesh) ...@@ -1085,16 +1086,17 @@ bool CXMeshFileLoader::parseDataObjectMeshVertexColors(SXMesh &mesh)
return false; return false;
} }
mesh.HasVertexColors=true;
const u32 nColors = readInt(); const u32 nColors = readInt();
for (u32 i=0; i<nColors; ++i) for (u32 i=0; i<nColors; ++i)
{ {
const u32 Index=readInt(); const u32 Index=readInt();
if (Index>=mesh.Vertices.size() ) if (Index>=mesh.Vertices.size())
{ {
os::Printer::log("index value in parseDataObjectMeshVertexColors out of bounds", ELL_WARNING); os::Printer::log("index value in parseDataObjectMeshVertexColors out of bounds", ELL_WARNING);
return false; return false;
} }
readRGBA(mesh.Vertices[i].Color); readRGBA(mesh.Vertices[Index].Color);
checkForOneFollowingSemicolons(); checkForOneFollowingSemicolons();
} }
...@@ -1206,7 +1208,6 @@ bool CXMeshFileLoader::parseDataObjectMeshMaterialList(SXMesh &mesh) ...@@ -1206,7 +1208,6 @@ bool CXMeshFileLoader::parseDataObjectMeshMaterialList(SXMesh &mesh)
} }
bool CXMeshFileLoader::parseDataObjectMaterial(video::SMaterial& material) bool CXMeshFileLoader::parseDataObjectMaterial(video::SMaterial& material)
{ {
#ifdef _XREADER_DEBUG #ifdef _XREADER_DEBUG
...@@ -1272,7 +1273,6 @@ bool CXMeshFileLoader::parseDataObjectMaterial(video::SMaterial& material) ...@@ -1272,7 +1273,6 @@ bool CXMeshFileLoader::parseDataObjectMaterial(video::SMaterial& material)
if (!parseUnknownDataObject()) if (!parseUnknownDataObject())
return false; return false;
} }
} }
return true; return true;
......
...@@ -46,7 +46,7 @@ public: ...@@ -46,7 +46,7 @@ public:
struct SXMesh struct SXMesh
{ {
SXMesh() : MaxSkinWeightsPerVertex(0), MaxSkinWeightsPerFace(0), BoneCount(0),AttachedJointID(-1),HasSkinning(false){} SXMesh() : MaxSkinWeightsPerVertex(0), MaxSkinWeightsPerFace(0), BoneCount(0),AttachedJointID(-1),HasSkinning(false), HasVertexColors(false) {}
// this mesh contains triangulated texture data. // this mesh contains triangulated texture data.
// because in an .x file, faces can be made of more than 3 // because in an .x file, faces can be made of more than 3
// vertices, the indices data structure is triangulated during the // vertices, the indices data structure is triangulated during the
...@@ -76,6 +76,7 @@ public: ...@@ -76,6 +76,7 @@ public:
s32 AttachedJointID; s32 AttachedJointID;
bool HasSkinning; bool HasSkinning;
bool HasVertexColors;
core::array<ISkinnedMesh::SWeight*> Weights; core::array<ISkinnedMesh::SWeight*> Weights;
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment