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