Commit 229ff7da authored by hybrid's avatar hybrid

Add support for large meshes in .irrmesh format. Patch submitted by pc0de.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2261 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 12e3d08e
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "IReadFile.h" #include "IReadFile.h"
#include "IAttributes.h" #include "IAttributes.h"
#include "IMeshSceneNode.h" #include "IMeshSceneNode.h"
#include "CDynamicMeshBuffer.h"
#include "SMeshBufferLightMap.h" #include "SMeshBufferLightMap.h"
namespace irr namespace irr
...@@ -138,10 +139,7 @@ IAnimatedMesh* CIrrMeshFileLoader::readMesh(io::IXMLReader* reader) ...@@ -138,10 +139,7 @@ IAnimatedMesh* CIrrMeshFileLoader::readMesh(io::IXMLReader* reader)
//! reads a mesh sections and creates a mesh buffer from it //! reads a mesh sections and creates a mesh buffer from it
IMeshBuffer* CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader) IMeshBuffer* CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader)
{ {
IMeshBuffer* buffer = 0; CDynamicMeshBuffer* buffer = 0;
SMeshBuffer* sbuffer1 = 0;
SMeshBufferLightMap* sbuffer2 = 0;
SMeshBufferTangents* sbuffer3 = 0;
core::stringc verticesSectionName = "vertices"; core::stringc verticesSectionName = "vertices";
core::stringc bbSectionName = "boundingBox"; core::stringc bbSectionName = "boundingBox";
...@@ -184,38 +182,33 @@ IMeshBuffer* CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader) ...@@ -184,38 +182,33 @@ IMeshBuffer* CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader)
{ {
// vertices section // vertices section
core::stringc vertexTypeName1 = "standard"; const core::stringc vertexTypeName1 = "standard";
core::stringc vertexTypeName2 = "2tcoords"; const core::stringc vertexTypeName2 = "2tcoords";
core::stringc vertexTypeName3 = "tangents"; const core::stringc vertexTypeName3 = "tangents";
const wchar_t* vertexType = reader->getAttributeValue(L"type"); const wchar_t* vertexType = reader->getAttributeValue(L"type");
vertexCount = reader->getAttributeValueAsInt(L"vertexCount"); vertexCount = reader->getAttributeValueAsInt(L"vertexCount");
insideVertexSection = true; insideVertexSection = true;
video::E_INDEX_TYPE itype = (vertexCount > 65536)?irr::video::EIT_32BIT:irr::video::EIT_16BIT;
if (vertexTypeName1 == vertexType) if (vertexTypeName1 == vertexType)
{ {
sbuffer1 = new SMeshBuffer(); buffer = new CDynamicMeshBuffer(irr::video::EVT_STANDARD, itype);
sbuffer1->Vertices.reallocate(vertexCount);
sbuffer1->Material = material;
buffer = sbuffer1;
} }
else else
if (vertexTypeName2 == vertexType) if (vertexTypeName2 == vertexType)
{ {
sbuffer2 = new SMeshBufferLightMap(); buffer = new CDynamicMeshBuffer(irr::video::EVT_2TCOORDS, itype);
sbuffer2->Vertices.reallocate(vertexCount);
sbuffer2->Material = material;
buffer = sbuffer2;
} }
else else
if (vertexTypeName3 == vertexType) if (vertexTypeName3 == vertexType)
{ {
sbuffer3 = new SMeshBufferTangents(); buffer = new CDynamicMeshBuffer(irr::video::EVT_TANGENTS, itype);
sbuffer3->Vertices.reallocate(vertexCount);
sbuffer3->Material = material;
buffer = sbuffer3;
} }
buffer->getVertexBuffer().reallocate(vertexCount);
buffer->Material = material;
} }
else else
if (indicesSectionName == nodeName) if (indicesSectionName == nodeName)
...@@ -233,30 +226,14 @@ IMeshBuffer* CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader) ...@@ -233,30 +226,14 @@ IMeshBuffer* CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader)
// read vertex data // read vertex data
if (insideVertexSection) if (insideVertexSection)
{ {
if (sbuffer1) readMeshBuffer(reader, vertexCount, buffer);
readMeshBuffer(reader, vertexCount, sbuffer1);
else
if (sbuffer2)
readMeshBuffer(reader, vertexCount, sbuffer2);
else
if (sbuffer3)
readMeshBuffer(reader, vertexCount, sbuffer3);
insideVertexSection = false; insideVertexSection = false;
} // end reading vertex array } // end reading vertex array
else else
if (insideIndexSection) if (insideIndexSection)
{ {
if (sbuffer1) readIndices(reader, indexCount, buffer->getIndexBuffer());
readIndices(reader, indexCount, sbuffer1->Indices);
else
if (sbuffer2)
readIndices(reader, indexCount, sbuffer2->Indices);
else
if (sbuffer3)
readIndices(reader, indexCount, sbuffer3->Indices);
insideIndexSection = false; insideIndexSection = false;
} }
...@@ -280,7 +257,7 @@ IMeshBuffer* CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader) ...@@ -280,7 +257,7 @@ IMeshBuffer* CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader)
//! read indices //! read indices
void CIrrMeshFileLoader::readIndices(io::IXMLReader* reader, int indexCount, core::array<u16>& indices) void CIrrMeshFileLoader::readIndices(io::IXMLReader* reader, int indexCount, IIndexBuffer& indices)
{ {
indices.reallocate(indexCount); indices.reallocate(indexCount);
...@@ -290,175 +267,163 @@ void CIrrMeshFileLoader::readIndices(io::IXMLReader* reader, int indexCount, cor ...@@ -290,175 +267,163 @@ void CIrrMeshFileLoader::readIndices(io::IXMLReader* reader, int indexCount, cor
for (int i=0; i<indexCount && *p; ++i) for (int i=0; i<indexCount && *p; ++i)
{ {
findNextNoneWhiteSpace(&p); findNextNoneWhiteSpace(&p);
indices.push_back((u16)readInt(&p)); indices.push_back(readInt(&p));
} }
} }
void CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader, int vertexCount, SMeshBuffer* sbuffer) void CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader, int vertexCount, CDynamicMeshBuffer* sbuffer)
{ {
core::stringc data = reader->getNodeData(); core::stringc data = reader->getNodeData();
const c8* p = &data[0]; const c8* p = &data[0];
scene::IVertexBuffer& Vertices = sbuffer->getVertexBuffer();
video::E_VERTEX_TYPE vType = Vertices.getType();
if (sbuffer) if (sbuffer)
{ {
video::S3DVertex vtx;
for (int i=0; i<vertexCount && *p; ++i) for (int i=0; i<vertexCount && *p; ++i)
{ {
// position switch(vType)
{
findNextNoneWhiteSpace(&p); case video::EVT_STANDARD:
vtx.Pos.X = readFloat(&p); {
findNextNoneWhiteSpace(&p); video::S3DVertex vtx;
vtx.Pos.Y = readFloat(&p); // position
findNextNoneWhiteSpace(&p);
vtx.Pos.Z = readFloat(&p);
// normal
findNextNoneWhiteSpace(&p);
vtx.Normal.X = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Normal.Y = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Normal.Z = readFloat(&p);
// color
findNextNoneWhiteSpace(&p);
sscanf(p, "%08x", &vtx.Color.color);
skipCurrentNoneWhiteSpace(&p);
// tcoord1
findNextNoneWhiteSpace(&p); findNextNoneWhiteSpace(&p);
vtx.TCoords.X = readFloat(&p); vtx.Pos.X = readFloat(&p);
findNextNoneWhiteSpace(&p); findNextNoneWhiteSpace(&p);
vtx.TCoords.Y = readFloat(&p); vtx.Pos.Y = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Pos.Z = readFloat(&p);
sbuffer->Vertices.push_back(vtx); // normal
}
}
}
findNextNoneWhiteSpace(&p);
vtx.Normal.X = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Normal.Y = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Normal.Z = readFloat(&p);
void CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader, int vertexCount, SMeshBufferLightMap* sbuffer) // color
{
core::stringc data = reader->getNodeData();
const c8* p = &data[0];
if (sbuffer) findNextNoneWhiteSpace(&p);
{ sscanf(p, "%08x", &vtx.Color.color);
video::S3DVertex2TCoords vtx; skipCurrentNoneWhiteSpace(&p);
for (int i=0; i<vertexCount && *p; ++i) // tcoord1
{
// position
findNextNoneWhiteSpace(&p); findNextNoneWhiteSpace(&p);
vtx.Pos.X = readFloat(&p); vtx.TCoords.X = readFloat(&p);
findNextNoneWhiteSpace(&p); findNextNoneWhiteSpace(&p);
vtx.Pos.Y = readFloat(&p); vtx.TCoords.Y = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Pos.Z = readFloat(&p);
// normal Vertices.push_back(vtx);
}
break;
case video::EVT_2TCOORDS:
{
video::S3DVertex2TCoords vtx;
// position
findNextNoneWhiteSpace(&p); findNextNoneWhiteSpace(&p);
vtx.Normal.X = readFloat(&p); vtx.Pos.X = readFloat(&p);
findNextNoneWhiteSpace(&p); findNextNoneWhiteSpace(&p);
vtx.Normal.Y = readFloat(&p); vtx.Pos.Y = readFloat(&p);
findNextNoneWhiteSpace(&p); findNextNoneWhiteSpace(&p);
vtx.Normal.Z = readFloat(&p); vtx.Pos.Z = readFloat(&p);
// color // normal
findNextNoneWhiteSpace(&p); findNextNoneWhiteSpace(&p);
sscanf(p, "%08x", &vtx.Color.color); vtx.Normal.X = readFloat(&p);
skipCurrentNoneWhiteSpace(&p); findNextNoneWhiteSpace(&p);
vtx.Normal.Y = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Normal.Z = readFloat(&p);
// tcoord1 // color
findNextNoneWhiteSpace(&p); findNextNoneWhiteSpace(&p);
vtx.TCoords.X = readFloat(&p); sscanf(p, "%08x", &vtx.Color.color);
findNextNoneWhiteSpace(&p); skipCurrentNoneWhiteSpace(&p);
vtx.TCoords.Y = readFloat(&p);
// tcoord2 // tcoord1
findNextNoneWhiteSpace(&p); findNextNoneWhiteSpace(&p);
vtx.TCoords2.X = readFloat(&p); vtx.TCoords.X = readFloat(&p);
findNextNoneWhiteSpace(&p); findNextNoneWhiteSpace(&p);
vtx.TCoords2.Y = readFloat(&p); vtx.TCoords.Y = readFloat(&p);
sbuffer->Vertices.push_back(vtx); // tcoord2
}
}
}
findNextNoneWhiteSpace(&p);
vtx.TCoords2.X = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.TCoords2.Y = readFloat(&p);
void CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader, int vertexCount, SMeshBufferTangents* sbuffer) Vertices.push_back(vtx);
{ }
core::stringc data = reader->getNodeData(); break;
const c8* p = &data[0];
if (sbuffer) case video::EVT_TANGENTS:
{ {
video::S3DVertexTangents vtx; video::S3DVertexTangents vtx;
// position
for (int i=0; i<vertexCount && *p; ++i) findNextNoneWhiteSpace(&p);
{ vtx.Pos.X = readFloat(&p);
// position findNextNoneWhiteSpace(&p);
vtx.Pos.Y = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Pos.Z = readFloat(&p);
findNextNoneWhiteSpace(&p); // normal
vtx.Pos.X = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Pos.Y = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Pos.Z = readFloat(&p);
// normal findNextNoneWhiteSpace(&p);
vtx.Normal.X = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Normal.Y = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Normal.Z = readFloat(&p);
findNextNoneWhiteSpace(&p); // color
vtx.Normal.X = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Normal.Y = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Normal.Z = readFloat(&p);
// color findNextNoneWhiteSpace(&p);
sscanf(p, "%08x", &vtx.Color.color);
skipCurrentNoneWhiteSpace(&p);
findNextNoneWhiteSpace(&p); // tcoord1
sscanf(p, "%08x", &vtx.Color.color);
skipCurrentNoneWhiteSpace(&p);
// tcoord1 findNextNoneWhiteSpace(&p);
vtx.TCoords.X = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.TCoords.Y = readFloat(&p);
findNextNoneWhiteSpace(&p); // tangent
vtx.TCoords.X = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.TCoords.Y = readFloat(&p);
// tangent findNextNoneWhiteSpace(&p);
vtx.Tangent.X = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Tangent.Y = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Tangent.Z = readFloat(&p);
findNextNoneWhiteSpace(&p); // binormal
vtx.Tangent.X = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Tangent.Y = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Tangent.Z = readFloat(&p);
// binormal findNextNoneWhiteSpace(&p);
vtx.Binormal.X = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Binormal.Y = readFloat(&p);
findNextNoneWhiteSpace(&p);
vtx.Binormal.Z = readFloat(&p);
findNextNoneWhiteSpace(&p); Vertices.push_back(vtx);
vtx.Binormal.X = readFloat(&p); }
findNextNoneWhiteSpace(&p); break;
vtx.Binormal.Y = readFloat(&p); };
findNextNoneWhiteSpace(&p);
vtx.Binormal.Z = readFloat(&p);
sbuffer->Vertices.push_back(vtx);
} }
} }
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "irrString.h" #include "irrString.h"
#include "SMesh.h" #include "SMesh.h"
#include "SMeshBuffer.h" #include "SMeshBuffer.h"
#include "CDynamicMeshBuffer.h"
#include "ISceneManager.h" #include "ISceneManager.h"
namespace irr namespace irr
...@@ -68,13 +69,11 @@ private: ...@@ -68,13 +69,11 @@ private:
//! reads floats from inside of xml element until end of xml element //! reads floats from inside of xml element until end of xml element
void readFloatsInsideElement(io::IXMLReader* reader, f32* floats, u32 count); void readFloatsInsideElement(io::IXMLReader* reader, f32* floats, u32 count);
//! read all 3 types of mesh buffers //! read the mesh buffers
void readMeshBuffer(io::IXMLReader* reader, int vertexCount, SMeshBuffer* sbuffer); void readMeshBuffer(io::IXMLReader* reader, int vertexCount, CDynamicMeshBuffer* sbuffer);
void readMeshBuffer(io::IXMLReader* reader, int vertexCount, SMeshBufferLightMap* sbuffer);
void readMeshBuffer(io::IXMLReader* reader, int vertexCount, SMeshBufferTangents* sbuffer);
//! read indices //! read indices
void readIndices(io::IXMLReader* reader, int indexCount, core::array<u16>& indices); void readIndices(io::IXMLReader* reader, int indexCount, IIndexBuffer& indices);
// member variables // member variables
......
...@@ -252,13 +252,25 @@ void CIrrMeshWriter::writeMeshBuffer(const scene::IMeshBuffer* buffer) ...@@ -252,13 +252,25 @@ void CIrrMeshWriter::writeMeshBuffer(const scene::IMeshBuffer* buffer)
Writer->writeLineBreak(); Writer->writeLineBreak();
int indexCount = (int)buffer->getIndexCount(); int indexCount = (int)buffer->getIndexCount();
const u16* idx = buffer->getIndices();
video::E_INDEX_TYPE iType = buffer->getIndexType();
const u16* idx16 = buffer->getIndices();
const u32* idx32 = (u32*) buffer->getIndices();
const int maxIndicesPerLine = 25; const int maxIndicesPerLine = 25;
for (int i=0; i<indexCount; ++i) for (int i=0; i<indexCount; ++i)
{ {
core::stringw str((int)idx[i]); if(iType == video::EIT_16BIT)
Writer->writeText(str.c_str()); {
core::stringw str((int)idx16[i]);
Writer->writeText(str.c_str());
}
else
{
core::stringw str((int)idx32[i]);
Writer->writeText(str.c_str());
}
if (i % maxIndicesPerLine != maxIndicesPerLine) if (i % maxIndicesPerLine != maxIndicesPerLine)
{ {
......
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