From eee27834d1c2a389cfc2d1e0ecaf51568e1319a0 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Wed, 15 Dec 2010 22:52:59 +0000 Subject: [PATCH] Fixed line endings. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@7030 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/CBatchingMesh.cpp | 1016 ++++++++++++++++---------------- src/graphics/CBatchingMesh.hpp | 348 +++++------ 2 files changed, 682 insertions(+), 682 deletions(-) diff --git a/src/graphics/CBatchingMesh.cpp b/src/graphics/CBatchingMesh.cpp index 014001b71..6a51fe338 100644 --- a/src/graphics/CBatchingMesh.cpp +++ b/src/graphics/CBatchingMesh.cpp @@ -1,508 +1,508 @@ - -#include "graphics/CBatchingMesh.hpp" - -namespace irr -{ -namespace scene -{ - -CBatchingMesh::CBatchingMesh() - : Box(core::vector3df(0,0,0)), IsDirty(false), IsFinal(false) -{ - -} - -CBatchingMesh::~CBatchingMesh() -{ - u32 i; - for (i=0; i < DestBuffers.size(); ++i) - DestBuffers[i].Buffer->drop(); - - for (i=0; i < SourceBuffers.size(); ++i) - SourceBuffers[i]->drop(); -} - -bool CBatchingMesh::isDirty(s32 id) -{ - if ((u32)id > DestBuffers.size()) - return IsDirty; - else - return DestBuffers[id].IsDirty; -} - -//! refreshes the internal buffers from source -void CBatchingMesh::update() -{ - // allocate the index and vertex arrays - u32 i; - for (i=0; igetIndexCount() || - DestBuffers[i].VertexCount != DestBuffers[i].Buffer->getVertexCount()) - { - DestBuffers[i].IsDirty = true; - - switch (DestBuffers[i].VertexType) - { - case video::EVT_STANDARD: - { - SMeshBuffer* mb = (SMeshBuffer*)DestBuffers[i].Buffer; - mb->Vertices.set_used(DestBuffers[i].VertexCount); - mb->Indices.set_used(DestBuffers[i].IndexCount); - break; - } - case video::EVT_2TCOORDS: - { - SMeshBufferLightMap* mb = (SMeshBufferLightMap*)DestBuffers[i].Buffer; - mb->Vertices.set_used(DestBuffers[i].VertexCount); - mb->Indices.set_used(DestBuffers[i].IndexCount); - break; - } - case video::EVT_TANGENTS: - { - SMeshBufferTangents* mb = (SMeshBufferTangents*)DestBuffers[i].Buffer; - mb->Vertices.set_used(DestBuffers[i].VertexCount); - mb->Indices.set_used(DestBuffers[i].IndexCount); - break; - } - default: // shouldn't ever happen - continue; - } - } - } - - // refresh dirty buffers from source - for (i=0; i CBatchingMesh::addMesh(IMesh* mesh, core::vector3df pos, core::vector3df rot, core::vector3df scale) -{ - core::matrix4 m; - m.setRotationDegrees(rot); - m.setTranslation(pos); - - core::matrix4 scalem; - scalem.setScale(scale); - m *= scalem; - - return addMesh(mesh, m); -} - -//! adds a mesh with the given transformation -core::array CBatchingMesh::addMesh(IMesh* mesh, const core::matrix4 &transform) -{ - core::array bufferNos; - - if (!mesh) - return bufferNos; - - u32 i; - for (i=0; igetMeshBufferCount(); ++i) - bufferNos.push_back(addMeshBuffer(mesh->getMeshBuffer(i), transform)); - - return bufferNos; -} - -//! adds a mesh buffer with the given transformation -/** \Return Returns the ID of this mesh buffer */ -s32 CBatchingMesh::addMeshBuffer(IMeshBuffer* buffer, core::vector3df pos, core::vector3df rot, core::vector3df scale) -{ - core::matrix4 m; - m.setRotationDegrees(rot); - m.setTranslation(pos); - - core::matrix4 scalem; - scalem.setScale(scale); - m *= scalem; - - return addMeshBuffer(buffer, m); -} - -//! adds a mesh with the given transformation -/** \Return Returns the ID of this mesh buffer */ -s32 CBatchingMesh::addMeshBuffer(IMeshBuffer* buffer, const core::matrix4 &transform) -{ - if (!buffer || IsFinal) - return -1; - - u32 i; - video::SMaterial m = buffer->getMaterial(); - - // find material - bool found=false; - video::E_VERTEX_TYPE vt = buffer->getVertexType(); - for (i=0; igetIndexCount() + DestBuffers[ MaterialReferences[i].BufferIndex ].IndexCount; - u32 newTotalV = buffer->getVertexCount() + DestBuffers[ MaterialReferences[i].BufferIndex ].VertexCount; - - if ( newTotalI < 65536*3 && newTotalV < 65536) - { - found = true; - DestBuffers[ MaterialReferences[i].BufferIndex ].IndexCount = newTotalI; - DestBuffers[ MaterialReferences[i].BufferIndex ].VertexCount = newTotalV; - break; - } - } - } - - if (!found) - { - // we need a new destination buffer and material reference - IMeshBuffer *mb=0; - - SMaterialReference r; - r.Material = m; - r.VertexType = vt; - r.BufferIndex = DestBuffers.size(); - switch (vt) - { - case video::EVT_STANDARD: - mb = (IMeshBuffer*)new SMeshBuffer(); - mb->getMaterial() = m; - break; - case video::EVT_2TCOORDS: - mb = (IMeshBuffer*)new SMeshBufferLightMap(); - mb->getMaterial() = m; - break; - case video::EVT_TANGENTS: - mb = (IMeshBuffer*)new SMeshBufferTangents(); - mb->getMaterial() = m; - break; - default: // unknown vertex type - return -1; - } - i = MaterialReferences.size(); - MaterialReferences.push_back(r); - - SDestBufferReference db; - db.Buffer = mb; - db.IndexCount = buffer->getIndexCount(); - db.VertexCount = buffer->getVertexCount(); - db.IsDirty = true; - db.VertexType = vt; - - DestBuffers.push_back(db); - } - // now we add the mesh reference - SBufferReference r; - r.DestReference = i; - r.SourceBuffer = buffer; - r.Transform = transform; - r.IndexCount = buffer->getIndexCount(); - r.VertexCount = buffer->getVertexCount(); - r.FirstIndex = DestBuffers[ MaterialReferences[i].BufferIndex ].IndexCount - r.IndexCount; - r.FirstVertex = DestBuffers[ MaterialReferences[i].BufferIndex ].VertexCount - r.VertexCount; - r.Initialized = false; - BufferReferences.push_back(r); - addSourceBuffer(buffer); - - IsDirty = true; - return BufferReferences.size()-1; -} - -//! updates bouding box from internal buffers -void CBatchingMesh::recalculateBoundingBox() -{ - if (DestBuffers.size() == 0) - Box.reset(0,0,0); - else - { - Box.reset(DestBuffers[0].Buffer->getBoundingBox().MinEdge); - - u32 i; - for (i=0; i < DestBuffers.size(); ++i) - Box.addInternalBox(DestBuffers[i].Buffer->getBoundingBox()); - } -} - - -/* Standard IMesh functions */ - -//! Returns the amount of mesh buffers. -/** \return Returns the amount of mesh buffers (IMeshBuffer) in this mesh. */ -u32 CBatchingMesh::getMeshBufferCount() const -{ - return DestBuffers.size(); -} - -//! Returns pointer to a mesh buffer. -/** \param nr: Zero based index of the mesh buffer. The maximum value is -getMeshBufferCount() - 1; -\return Returns the pointer to the mesh buffer or -NULL if there is no such mesh buffer. */ -IMeshBuffer* CBatchingMesh::getMeshBuffer(u32 nr) const -{ - if (nr < DestBuffers.size()) - return DestBuffers[nr].Buffer; - else - return 0; -} - -//! Returns pointer to a mesh buffer which fits a material -IMeshBuffer* CBatchingMesh::getMeshBuffer( const video::SMaterial &material) const -{ - return 0; -} - -//! Returns an axis aligned bounding box of the mesh. -/** \return A bounding box of this mesh is returned. */ -const core::aabbox3d& CBatchingMesh::getBoundingBox() const -{ - return Box; -} - -//! set user axis aligned bounding box -void CBatchingMesh::setBoundingBox( const core::aabbox3df& box) -{ - Box = box; -} - -//! Sets a flag of all contained materials to a new value. -/** \param flag: Flag to set in all materials. - \param newvalue: New value to set in all materials. */ -void CBatchingMesh::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) -{ - for (u32 i=0; igetMaterial().setFlag(flag, newvalue); -} - -//! drops all buffers and clears internal states -void CBatchingMesh::clear() -{ - u32 i; - for (i=0; i < DestBuffers.size(); ++i) - DestBuffers[i].Buffer->drop(); - - for (i=0; i < SourceBuffers.size(); ++i) - SourceBuffers[i]->drop(); - - BufferReferences.clear(); - MaterialReferences.clear(); - DestBuffers.clear(); - SourceBuffers.clear(); - - IsDirty = false; - IsFinal = false; -} - -//! first updates the mesh, then drops all source buffers. -/** once this mesh has been finalized, it cannot be changed again! */ -void CBatchingMesh::finalize() -{ - update(); - - for (u32 i=0; i < SourceBuffers.size(); ++i) - SourceBuffers[i]->drop(); - - SourceBuffers.clear(); - - IsFinal = true; -} - -//! Moves a mesh -core::array CBatchingMesh::moveMesh(const core::array& bufferIDs, const core::matrix4 &newMatrix) -{ - core::array result; - result.reallocate(bufferIDs.size()); - for (u32 i=0; i BufferReferences.size() || IsFinal ) - return false; - - BufferReferences[id].Transform = newMatrix; - - // is the source buffer dirty? - if (!DestBuffers[BufferReferences[id].DestReference].IsDirty) - { - // transform each vertex and normal - updateDestFromSourceBuffer(id); - recalculateDestBufferBoundingBox(BufferReferences[id].DestReference); - } - return true; -} - - -//! returns the source buffer, if available -IMeshBuffer* CBatchingMesh::getSourceBuffer(s32 id) -{ - if ((u32)id > BufferReferences.size() || IsFinal) - return 0; - else - return BufferReferences[id].SourceBuffer; -} - -//! returns the matrix of the source buffer -core::matrix4 CBatchingMesh::getSourceBufferMatrix(s32 id) -{ - core::matrix4 ret; - if ((u32)id > BufferReferences.size() || IsFinal) - ret.makeIdentity(); - else - ret = BufferReferences[id].Transform; - - return ret; -} - - -//! returns the number of source buffers -u32 CBatchingMesh::getSourceBufferCount() const -{ - return BufferReferences.size(); -} - -// private functions - -void CBatchingMesh::recalculateDestBufferBoundingBox(u32 i) -{ - switch (DestBuffers[i].VertexType) - { - case video::EVT_STANDARD: - ((SMeshBuffer*)DestBuffers[i].Buffer)->recalculateBoundingBox(); - break; - case video::EVT_2TCOORDS: - ((SMeshBufferLightMap*)DestBuffers[i].Buffer)->recalculateBoundingBox(); - break; - case video::EVT_TANGENTS: - ((SMeshBufferTangents*)DestBuffers[i].Buffer)->recalculateBoundingBox(); - break; - } -} - -void CBatchingMesh::updateDestFromSourceBuffer(u32 i) -{ - u16* ind = BufferReferences[i].SourceBuffer->getIndices(); - void*ver = BufferReferences[i].SourceBuffer->getVertices(); - core::matrix4 m = BufferReferences[i].Transform; - u32 fi = BufferReferences[i].FirstIndex; - u32 fv = BufferReferences[i].FirstVertex; - u32 ic = BufferReferences[i].IndexCount; - u32 vc = BufferReferences[i].VertexCount; - u32 x; - video::E_VERTEX_TYPE vt = DestBuffers[BufferReferences[i].DestReference].VertexType; - switch (vt) - { - case video::EVT_STANDARD: - { - SMeshBuffer* dest = (SMeshBuffer*) DestBuffers[BufferReferences[i].DestReference].Buffer; - - for (x=fi; x < fi+ic; ++x) - dest->Indices[x] = ind[x-fi]+fv; - - video::S3DVertex* vertices= (video::S3DVertex*) ver; - - for (x=fv; x < fv+vc; ++x) - { - dest->Vertices[x] = vertices[x-fv]; - m.transformVect(dest->Vertices[x].Pos); - m.rotateVect(dest->Vertices[x].Normal); - } - break; - } - case video::EVT_2TCOORDS: - { - SMeshBufferLightMap* dest = (SMeshBufferLightMap*) DestBuffers[BufferReferences[i].DestReference].Buffer; - - for (x=fi; x < fi+ic; ++x) - dest->Indices[x] = ind[x-fi]+fv; - - video::S3DVertex2TCoords* vertices= (video::S3DVertex2TCoords*) ver; - - for (x=fv; x < fv+vc; ++x) - { - dest->Vertices[x] = vertices[x-fv]; - m.transformVect(dest->Vertices[x].Pos); - m.rotateVect(dest->Vertices[x].Normal); - } - break; - } - case video::EVT_TANGENTS: - { - SMeshBufferTangents* dest = (SMeshBufferTangents*) DestBuffers[BufferReferences[i].DestReference].Buffer; - - for (x=fi; x < fi+ic; ++x) - dest->Indices[x] = ind[x-fi]+fv; - - video::S3DVertexTangents* vertices= (video::S3DVertexTangents*) ver; - - for (x=fv; x < fv+vc; ++x) - { - dest->Vertices[x] = vertices[x-fv]; - m.transformVect(dest->Vertices[x].Pos); - m.rotateVect(dest->Vertices[x].Normal); // are tangents/binormals in face space? - } - break; - } - default: - break; - } -} - -void CBatchingMesh::addSourceBuffer(IMeshBuffer *source) -{ - bool found = false; - for (u32 i=0; igrab(); - SourceBuffers.push_back(source); - } -} - -void CBatchingMesh::setHardwareMappingHint(E_HARDWARE_MAPPING mapping, E_BUFFER_TYPE type) -{ - for (u32 i=0; i < DestBuffers.size(); ++i) - DestBuffers[i].Buffer->setHardwareMappingHint(mapping, type); -} - - -void CBatchingMesh::setDirty(E_BUFFER_TYPE type) -{ - for (u32 i=0; i < DestBuffers.size(); ++i) - DestBuffers[i].Buffer->setDirty(type); -} - -} // namespace scene -} // namespace irr - + +#include "graphics/CBatchingMesh.hpp" + +namespace irr +{ +namespace scene +{ + +CBatchingMesh::CBatchingMesh() + : Box(core::vector3df(0,0,0)), IsDirty(false), IsFinal(false) +{ + +} + +CBatchingMesh::~CBatchingMesh() +{ + u32 i; + for (i=0; i < DestBuffers.size(); ++i) + DestBuffers[i].Buffer->drop(); + + for (i=0; i < SourceBuffers.size(); ++i) + SourceBuffers[i]->drop(); +} + +bool CBatchingMesh::isDirty(s32 id) +{ + if ((u32)id > DestBuffers.size()) + return IsDirty; + else + return DestBuffers[id].IsDirty; +} + +//! refreshes the internal buffers from source +void CBatchingMesh::update() +{ + // allocate the index and vertex arrays + u32 i; + for (i=0; igetIndexCount() || + DestBuffers[i].VertexCount != DestBuffers[i].Buffer->getVertexCount()) + { + DestBuffers[i].IsDirty = true; + + switch (DestBuffers[i].VertexType) + { + case video::EVT_STANDARD: + { + SMeshBuffer* mb = (SMeshBuffer*)DestBuffers[i].Buffer; + mb->Vertices.set_used(DestBuffers[i].VertexCount); + mb->Indices.set_used(DestBuffers[i].IndexCount); + break; + } + case video::EVT_2TCOORDS: + { + SMeshBufferLightMap* mb = (SMeshBufferLightMap*)DestBuffers[i].Buffer; + mb->Vertices.set_used(DestBuffers[i].VertexCount); + mb->Indices.set_used(DestBuffers[i].IndexCount); + break; + } + case video::EVT_TANGENTS: + { + SMeshBufferTangents* mb = (SMeshBufferTangents*)DestBuffers[i].Buffer; + mb->Vertices.set_used(DestBuffers[i].VertexCount); + mb->Indices.set_used(DestBuffers[i].IndexCount); + break; + } + default: // shouldn't ever happen + continue; + } + } + } + + // refresh dirty buffers from source + for (i=0; i CBatchingMesh::addMesh(IMesh* mesh, core::vector3df pos, core::vector3df rot, core::vector3df scale) +{ + core::matrix4 m; + m.setRotationDegrees(rot); + m.setTranslation(pos); + + core::matrix4 scalem; + scalem.setScale(scale); + m *= scalem; + + return addMesh(mesh, m); +} + +//! adds a mesh with the given transformation +core::array CBatchingMesh::addMesh(IMesh* mesh, const core::matrix4 &transform) +{ + core::array bufferNos; + + if (!mesh) + return bufferNos; + + u32 i; + for (i=0; igetMeshBufferCount(); ++i) + bufferNos.push_back(addMeshBuffer(mesh->getMeshBuffer(i), transform)); + + return bufferNos; +} + +//! adds a mesh buffer with the given transformation +/** \Return Returns the ID of this mesh buffer */ +s32 CBatchingMesh::addMeshBuffer(IMeshBuffer* buffer, core::vector3df pos, core::vector3df rot, core::vector3df scale) +{ + core::matrix4 m; + m.setRotationDegrees(rot); + m.setTranslation(pos); + + core::matrix4 scalem; + scalem.setScale(scale); + m *= scalem; + + return addMeshBuffer(buffer, m); +} + +//! adds a mesh with the given transformation +/** \Return Returns the ID of this mesh buffer */ +s32 CBatchingMesh::addMeshBuffer(IMeshBuffer* buffer, const core::matrix4 &transform) +{ + if (!buffer || IsFinal) + return -1; + + u32 i; + video::SMaterial m = buffer->getMaterial(); + + // find material + bool found=false; + video::E_VERTEX_TYPE vt = buffer->getVertexType(); + for (i=0; igetIndexCount() + DestBuffers[ MaterialReferences[i].BufferIndex ].IndexCount; + u32 newTotalV = buffer->getVertexCount() + DestBuffers[ MaterialReferences[i].BufferIndex ].VertexCount; + + if ( newTotalI < 65536*3 && newTotalV < 65536) + { + found = true; + DestBuffers[ MaterialReferences[i].BufferIndex ].IndexCount = newTotalI; + DestBuffers[ MaterialReferences[i].BufferIndex ].VertexCount = newTotalV; + break; + } + } + } + + if (!found) + { + // we need a new destination buffer and material reference + IMeshBuffer *mb=0; + + SMaterialReference r; + r.Material = m; + r.VertexType = vt; + r.BufferIndex = DestBuffers.size(); + switch (vt) + { + case video::EVT_STANDARD: + mb = (IMeshBuffer*)new SMeshBuffer(); + mb->getMaterial() = m; + break; + case video::EVT_2TCOORDS: + mb = (IMeshBuffer*)new SMeshBufferLightMap(); + mb->getMaterial() = m; + break; + case video::EVT_TANGENTS: + mb = (IMeshBuffer*)new SMeshBufferTangents(); + mb->getMaterial() = m; + break; + default: // unknown vertex type + return -1; + } + i = MaterialReferences.size(); + MaterialReferences.push_back(r); + + SDestBufferReference db; + db.Buffer = mb; + db.IndexCount = buffer->getIndexCount(); + db.VertexCount = buffer->getVertexCount(); + db.IsDirty = true; + db.VertexType = vt; + + DestBuffers.push_back(db); + } + // now we add the mesh reference + SBufferReference r; + r.DestReference = i; + r.SourceBuffer = buffer; + r.Transform = transform; + r.IndexCount = buffer->getIndexCount(); + r.VertexCount = buffer->getVertexCount(); + r.FirstIndex = DestBuffers[ MaterialReferences[i].BufferIndex ].IndexCount - r.IndexCount; + r.FirstVertex = DestBuffers[ MaterialReferences[i].BufferIndex ].VertexCount - r.VertexCount; + r.Initialized = false; + BufferReferences.push_back(r); + addSourceBuffer(buffer); + + IsDirty = true; + return BufferReferences.size()-1; +} + +//! updates bouding box from internal buffers +void CBatchingMesh::recalculateBoundingBox() +{ + if (DestBuffers.size() == 0) + Box.reset(0,0,0); + else + { + Box.reset(DestBuffers[0].Buffer->getBoundingBox().MinEdge); + + u32 i; + for (i=0; i < DestBuffers.size(); ++i) + Box.addInternalBox(DestBuffers[i].Buffer->getBoundingBox()); + } +} + + +/* Standard IMesh functions */ + +//! Returns the amount of mesh buffers. +/** \return Returns the amount of mesh buffers (IMeshBuffer) in this mesh. */ +u32 CBatchingMesh::getMeshBufferCount() const +{ + return DestBuffers.size(); +} + +//! Returns pointer to a mesh buffer. +/** \param nr: Zero based index of the mesh buffer. The maximum value is +getMeshBufferCount() - 1; +\return Returns the pointer to the mesh buffer or +NULL if there is no such mesh buffer. */ +IMeshBuffer* CBatchingMesh::getMeshBuffer(u32 nr) const +{ + if (nr < DestBuffers.size()) + return DestBuffers[nr].Buffer; + else + return 0; +} + +//! Returns pointer to a mesh buffer which fits a material +IMeshBuffer* CBatchingMesh::getMeshBuffer( const video::SMaterial &material) const +{ + return 0; +} + +//! Returns an axis aligned bounding box of the mesh. +/** \return A bounding box of this mesh is returned. */ +const core::aabbox3d& CBatchingMesh::getBoundingBox() const +{ + return Box; +} + +//! set user axis aligned bounding box +void CBatchingMesh::setBoundingBox( const core::aabbox3df& box) +{ + Box = box; +} + +//! Sets a flag of all contained materials to a new value. +/** \param flag: Flag to set in all materials. + \param newvalue: New value to set in all materials. */ +void CBatchingMesh::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) +{ + for (u32 i=0; igetMaterial().setFlag(flag, newvalue); +} + +//! drops all buffers and clears internal states +void CBatchingMesh::clear() +{ + u32 i; + for (i=0; i < DestBuffers.size(); ++i) + DestBuffers[i].Buffer->drop(); + + for (i=0; i < SourceBuffers.size(); ++i) + SourceBuffers[i]->drop(); + + BufferReferences.clear(); + MaterialReferences.clear(); + DestBuffers.clear(); + SourceBuffers.clear(); + + IsDirty = false; + IsFinal = false; +} + +//! first updates the mesh, then drops all source buffers. +/** once this mesh has been finalized, it cannot be changed again! */ +void CBatchingMesh::finalize() +{ + update(); + + for (u32 i=0; i < SourceBuffers.size(); ++i) + SourceBuffers[i]->drop(); + + SourceBuffers.clear(); + + IsFinal = true; +} + +//! Moves a mesh +core::array CBatchingMesh::moveMesh(const core::array& bufferIDs, const core::matrix4 &newMatrix) +{ + core::array result; + result.reallocate(bufferIDs.size()); + for (u32 i=0; i BufferReferences.size() || IsFinal ) + return false; + + BufferReferences[id].Transform = newMatrix; + + // is the source buffer dirty? + if (!DestBuffers[BufferReferences[id].DestReference].IsDirty) + { + // transform each vertex and normal + updateDestFromSourceBuffer(id); + recalculateDestBufferBoundingBox(BufferReferences[id].DestReference); + } + return true; +} + + +//! returns the source buffer, if available +IMeshBuffer* CBatchingMesh::getSourceBuffer(s32 id) +{ + if ((u32)id > BufferReferences.size() || IsFinal) + return 0; + else + return BufferReferences[id].SourceBuffer; +} + +//! returns the matrix of the source buffer +core::matrix4 CBatchingMesh::getSourceBufferMatrix(s32 id) +{ + core::matrix4 ret; + if ((u32)id > BufferReferences.size() || IsFinal) + ret.makeIdentity(); + else + ret = BufferReferences[id].Transform; + + return ret; +} + + +//! returns the number of source buffers +u32 CBatchingMesh::getSourceBufferCount() const +{ + return BufferReferences.size(); +} + +// private functions + +void CBatchingMesh::recalculateDestBufferBoundingBox(u32 i) +{ + switch (DestBuffers[i].VertexType) + { + case video::EVT_STANDARD: + ((SMeshBuffer*)DestBuffers[i].Buffer)->recalculateBoundingBox(); + break; + case video::EVT_2TCOORDS: + ((SMeshBufferLightMap*)DestBuffers[i].Buffer)->recalculateBoundingBox(); + break; + case video::EVT_TANGENTS: + ((SMeshBufferTangents*)DestBuffers[i].Buffer)->recalculateBoundingBox(); + break; + } +} + +void CBatchingMesh::updateDestFromSourceBuffer(u32 i) +{ + u16* ind = BufferReferences[i].SourceBuffer->getIndices(); + void*ver = BufferReferences[i].SourceBuffer->getVertices(); + core::matrix4 m = BufferReferences[i].Transform; + u32 fi = BufferReferences[i].FirstIndex; + u32 fv = BufferReferences[i].FirstVertex; + u32 ic = BufferReferences[i].IndexCount; + u32 vc = BufferReferences[i].VertexCount; + u32 x; + video::E_VERTEX_TYPE vt = DestBuffers[BufferReferences[i].DestReference].VertexType; + switch (vt) + { + case video::EVT_STANDARD: + { + SMeshBuffer* dest = (SMeshBuffer*) DestBuffers[BufferReferences[i].DestReference].Buffer; + + for (x=fi; x < fi+ic; ++x) + dest->Indices[x] = ind[x-fi]+fv; + + video::S3DVertex* vertices= (video::S3DVertex*) ver; + + for (x=fv; x < fv+vc; ++x) + { + dest->Vertices[x] = vertices[x-fv]; + m.transformVect(dest->Vertices[x].Pos); + m.rotateVect(dest->Vertices[x].Normal); + } + break; + } + case video::EVT_2TCOORDS: + { + SMeshBufferLightMap* dest = (SMeshBufferLightMap*) DestBuffers[BufferReferences[i].DestReference].Buffer; + + for (x=fi; x < fi+ic; ++x) + dest->Indices[x] = ind[x-fi]+fv; + + video::S3DVertex2TCoords* vertices= (video::S3DVertex2TCoords*) ver; + + for (x=fv; x < fv+vc; ++x) + { + dest->Vertices[x] = vertices[x-fv]; + m.transformVect(dest->Vertices[x].Pos); + m.rotateVect(dest->Vertices[x].Normal); + } + break; + } + case video::EVT_TANGENTS: + { + SMeshBufferTangents* dest = (SMeshBufferTangents*) DestBuffers[BufferReferences[i].DestReference].Buffer; + + for (x=fi; x < fi+ic; ++x) + dest->Indices[x] = ind[x-fi]+fv; + + video::S3DVertexTangents* vertices= (video::S3DVertexTangents*) ver; + + for (x=fv; x < fv+vc; ++x) + { + dest->Vertices[x] = vertices[x-fv]; + m.transformVect(dest->Vertices[x].Pos); + m.rotateVect(dest->Vertices[x].Normal); // are tangents/binormals in face space? + } + break; + } + default: + break; + } +} + +void CBatchingMesh::addSourceBuffer(IMeshBuffer *source) +{ + bool found = false; + for (u32 i=0; igrab(); + SourceBuffers.push_back(source); + } +} + +void CBatchingMesh::setHardwareMappingHint(E_HARDWARE_MAPPING mapping, E_BUFFER_TYPE type) +{ + for (u32 i=0; i < DestBuffers.size(); ++i) + DestBuffers[i].Buffer->setHardwareMappingHint(mapping, type); +} + + +void CBatchingMesh::setDirty(E_BUFFER_TYPE type) +{ + for (u32 i=0; i < DestBuffers.size(); ++i) + DestBuffers[i].Buffer->setDirty(type); +} + +} // namespace scene +} // namespace irr + diff --git a/src/graphics/CBatchingMesh.hpp b/src/graphics/CBatchingMesh.hpp index 19c2ada01..54613d1ea 100644 --- a/src/graphics/CBatchingMesh.hpp +++ b/src/graphics/CBatchingMesh.hpp @@ -1,174 +1,174 @@ -// A mesh used for batching many other meshes together, to reduce the number -// of draw calls. Simply add meshes into this one, with given transformations -// or positions, and then call update - -// TODO: Adapt the VBO interface and integrate setDirty with the current VBO updates. - -#include "IMesh.h" -#include "SMeshBuffer.h" - -namespace irr -{ -namespace scene -{ - -class CBatchingMesh : public IMesh -{ -public: - CBatchingMesh(); - - virtual ~CBatchingMesh(); - - //! returns true if new buffers have been added without updating the internal buffers - bool isDirty(s32 id=-1); - - //! refreshes the internal buffers from source - void update(); - - //! drops all buffers and clears internal states - void clear(); - - //! first updates the mesh, then drops all source buffers. - /** once this mesh has been finalized, it cannot be changed again! */ - void finalize(); - - //! adds a mesh to the buffers with the given offset - /** \Return: Returns an array of ID numbers */ - core::array addMesh(IMesh* mesh, - core::vector3df pos = core::vector3df(0,0,0), - core::vector3df rot = core::vector3df(0,0,0), - core::vector3df scale = core::vector3df(1,1,1)); - - //! adds a mesh with the given transformation - /** \Return: Returns an array of ID numbers */ - core::array addMesh(IMesh* mesh, const core::matrix4 &transform); - - //! adds a mesh buffer with the given transformation - /** \Return: Returns the ID of this mesh buffer */ - s32 addMeshBuffer(IMeshBuffer* buffer, - core::vector3df pos = core::vector3df(0,0,0), - core::vector3df rot = core::vector3df(0,0,0), - core::vector3df scale = core::vector3df(1,1,1)); - - //! adds a mesh with the given transformation - /** \Return Returns the ID of this mesh buffer */ - s32 addMeshBuffer(IMeshBuffer* buffer, const core::matrix4 &transform); - - //! updates bouding box from internal buffers - void recalculateBoundingBox(); - - //! Moves a mesh, - /** mesh buffers in clean destination buffers will be moved immediately, - ones in dirty buffers will be left until the next update */ - core::array moveMesh(const core::array& bufferIDs, const core::matrix4 &newMatrix); - - //! Moves a mesh buffer - /** if the destination buffer is clean it will be moved immediately, - if a member of a dirty buffer, it will be left until the next update */ - bool moveMeshBuffer(const s32 id, const core::matrix4 &newMatrix); - - //! returns the source buffer, if available - IMeshBuffer* getSourceBuffer(s32 id); - - //! returns the matrix of the source buffer - core::matrix4 getSourceBufferMatrix(s32 id); - - //! returns the number of source buffers - u32 getSourceBufferCount() const; - - /* Standard IMesh functions */ - - //! Returns the amount of mesh buffers. - /** \return Returns the amount of mesh buffers (IMeshBuffer) in this mesh. */ - virtual u32 getMeshBufferCount() const; - - //! Returns pointer to a mesh buffer. - /** \param nr: Zero based index of the mesh buffer. The maximum value is - getMeshBufferCount() - 1; - \return Returns the pointer to the mesh buffer or - NULL if there is no such mesh buffer. */ - virtual IMeshBuffer* getMeshBuffer(u32 nr) const; - - //! Returns pointer to a mesh buffer which fits a material - /** \param material: material to search for - \return Returns the pointer to the mesh buffer or - NULL if there is no such mesh buffer. */ - virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const; - - //! Returns an axis aligned bounding box of the mesh. - /** \return A bounding box of this mesh is returned. */ - virtual const core::aabbox3d& getBoundingBox() const; - - //! set user axis aligned bounding box - virtual void setBoundingBox( const core::aabbox3df& box); - - //! Sets a flag of all contained materials to a new value. - /** \param flag: Flag to set in all materials. - \param newvalue: New value to set in all materials. */ - virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue); - - virtual void setHardwareMappingHint(E_HARDWARE_MAPPING mapping, E_BUFFER_TYPE type); - - virtual void setDirty(E_BUFFER_TYPE type); - -private: - - // add a buffer to the source buffers array if it doesn't already exist - void addSourceBuffer(IMeshBuffer* source); - - // updates the vertices in dest buffer from the source one - void updateDestFromSourceBuffer(u32 id); - - // recalculates the bounding box for the given dest buffer - void recalculateDestBufferBoundingBox(u32 i); - - struct SBufferReference - { - SBufferReference() - : SourceBuffer(0), DestReference(0), FirstVertex(0), VertexCount(0), - FirstIndex(0), IndexCount(0), Initialized(false) { } - - IMeshBuffer* SourceBuffer; - u32 DestReference; - u32 FirstVertex, VertexCount, FirstIndex, IndexCount; - core::matrix4 Transform; - bool Initialized; - }; - - struct SMaterialReference - { - video::SMaterial Material; - video::E_VERTEX_TYPE VertexType; - u32 BufferIndex; - }; - - struct SDestBufferReference - { - IMeshBuffer* Buffer; - video::E_VERTEX_TYPE VertexType; - u32 VertexCount; - u32 IndexCount; - bool IsDirty; - }; - - //! Source mesh buffers, these are locked - core::array SourceBuffers; - - core::array BufferReferences; - core::array MaterialReferences; - core::array DestBuffers; - - //! bounding containing all destination buffers - core::aabbox3d Box; - - //! does it require an update? - bool IsDirty; - - //! can it be changed? - bool IsFinal; -}; - -} // namespace scene -} // namespace irr - -// #endif +// A mesh used for batching many other meshes together, to reduce the number +// of draw calls. Simply add meshes into this one, with given transformations +// or positions, and then call update + +// TODO: Adapt the VBO interface and integrate setDirty with the current VBO updates. + +#include "IMesh.h" +#include "SMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + +class CBatchingMesh : public IMesh +{ +public: + CBatchingMesh(); + + virtual ~CBatchingMesh(); + + //! returns true if new buffers have been added without updating the internal buffers + bool isDirty(s32 id=-1); + + //! refreshes the internal buffers from source + void update(); + + //! drops all buffers and clears internal states + void clear(); + + //! first updates the mesh, then drops all source buffers. + /** once this mesh has been finalized, it cannot be changed again! */ + void finalize(); + + //! adds a mesh to the buffers with the given offset + /** \Return: Returns an array of ID numbers */ + core::array addMesh(IMesh* mesh, + core::vector3df pos = core::vector3df(0,0,0), + core::vector3df rot = core::vector3df(0,0,0), + core::vector3df scale = core::vector3df(1,1,1)); + + //! adds a mesh with the given transformation + /** \Return: Returns an array of ID numbers */ + core::array addMesh(IMesh* mesh, const core::matrix4 &transform); + + //! adds a mesh buffer with the given transformation + /** \Return: Returns the ID of this mesh buffer */ + s32 addMeshBuffer(IMeshBuffer* buffer, + core::vector3df pos = core::vector3df(0,0,0), + core::vector3df rot = core::vector3df(0,0,0), + core::vector3df scale = core::vector3df(1,1,1)); + + //! adds a mesh with the given transformation + /** \Return Returns the ID of this mesh buffer */ + s32 addMeshBuffer(IMeshBuffer* buffer, const core::matrix4 &transform); + + //! updates bouding box from internal buffers + void recalculateBoundingBox(); + + //! Moves a mesh, + /** mesh buffers in clean destination buffers will be moved immediately, + ones in dirty buffers will be left until the next update */ + core::array moveMesh(const core::array& bufferIDs, const core::matrix4 &newMatrix); + + //! Moves a mesh buffer + /** if the destination buffer is clean it will be moved immediately, + if a member of a dirty buffer, it will be left until the next update */ + bool moveMeshBuffer(const s32 id, const core::matrix4 &newMatrix); + + //! returns the source buffer, if available + IMeshBuffer* getSourceBuffer(s32 id); + + //! returns the matrix of the source buffer + core::matrix4 getSourceBufferMatrix(s32 id); + + //! returns the number of source buffers + u32 getSourceBufferCount() const; + + /* Standard IMesh functions */ + + //! Returns the amount of mesh buffers. + /** \return Returns the amount of mesh buffers (IMeshBuffer) in this mesh. */ + virtual u32 getMeshBufferCount() const; + + //! Returns pointer to a mesh buffer. + /** \param nr: Zero based index of the mesh buffer. The maximum value is + getMeshBufferCount() - 1; + \return Returns the pointer to the mesh buffer or + NULL if there is no such mesh buffer. */ + virtual IMeshBuffer* getMeshBuffer(u32 nr) const; + + //! Returns pointer to a mesh buffer which fits a material + /** \param material: material to search for + \return Returns the pointer to the mesh buffer or + NULL if there is no such mesh buffer. */ + virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const; + + //! Returns an axis aligned bounding box of the mesh. + /** \return A bounding box of this mesh is returned. */ + virtual const core::aabbox3d& getBoundingBox() const; + + //! set user axis aligned bounding box + virtual void setBoundingBox( const core::aabbox3df& box); + + //! Sets a flag of all contained materials to a new value. + /** \param flag: Flag to set in all materials. + \param newvalue: New value to set in all materials. */ + virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue); + + virtual void setHardwareMappingHint(E_HARDWARE_MAPPING mapping, E_BUFFER_TYPE type); + + virtual void setDirty(E_BUFFER_TYPE type); + +private: + + // add a buffer to the source buffers array if it doesn't already exist + void addSourceBuffer(IMeshBuffer* source); + + // updates the vertices in dest buffer from the source one + void updateDestFromSourceBuffer(u32 id); + + // recalculates the bounding box for the given dest buffer + void recalculateDestBufferBoundingBox(u32 i); + + struct SBufferReference + { + SBufferReference() + : SourceBuffer(0), DestReference(0), FirstVertex(0), VertexCount(0), + FirstIndex(0), IndexCount(0), Initialized(false) { } + + IMeshBuffer* SourceBuffer; + u32 DestReference; + u32 FirstVertex, VertexCount, FirstIndex, IndexCount; + core::matrix4 Transform; + bool Initialized; + }; + + struct SMaterialReference + { + video::SMaterial Material; + video::E_VERTEX_TYPE VertexType; + u32 BufferIndex; + }; + + struct SDestBufferReference + { + IMeshBuffer* Buffer; + video::E_VERTEX_TYPE VertexType; + u32 VertexCount; + u32 IndexCount; + bool IsDirty; + }; + + //! Source mesh buffers, these are locked + core::array SourceBuffers; + + core::array BufferReferences; + core::array MaterialReferences; + core::array DestBuffers; + + //! bounding containing all destination buffers + core::aabbox3d Box; + + //! does it require an update? + bool IsDirty; + + //! can it be changed? + bool IsFinal; +}; + +} // namespace scene +} // namespace irr + +// #endif