From b849f8666374b6cc7af3ec6b066d476b4d7abb25 Mon Sep 17 00:00:00 2001 From: cutealien Date: Wed, 4 May 2022 21:26:18 +0000 Subject: [PATCH] Merging r6337 through r6363 from trunk to ogl-es branch git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@6379 dfc29bdd-3216-0410-991c-e03cc46cb475 --- changes.txt | 21 +++- include/CDynamicMeshBuffer.h | 20 ++++ include/CIndexBuffer.h | 41 ++++---- include/CVertexBuffer.h | 102 +++++++++++++++--- include/IAnimatedMeshMD3.h | 33 ------ include/IDynamicMeshBuffer.h | 44 +------- include/IIndexBuffer.h | 32 ++++-- include/IMeshBuffer.h | 6 +- include/IMeshLoader.h | 35 +++++-- include/IQ3Shader.h | 2 - include/IVertexBuffer.h | 30 ++++-- include/S3DVertex.h | 7 +- include/SMaterial.h | 62 +---------- include/irrMap.h | 20 +--- include/vector2d.h | 4 - include/vector3d.h | 4 - source/Irrlicht/CB3DMeshFileLoader.cpp | 13 ++- source/Irrlicht/CB3DMeshWriter.cpp | 36 +++++-- source/Irrlicht/CGUITable.cpp | 4 +- source/Irrlicht/CMemoryFile.cpp | 8 +- source/Irrlicht/COBJMeshFileLoader.cpp | 20 ++-- source/Irrlicht/COBJMeshFileLoader.h | 4 +- source/Irrlicht/CSTLMeshFileLoader.cpp | 137 +++++++++++++++---------- source/Irrlicht/CSTLMeshFileLoader.h | 7 +- source/Irrlicht/CSTLMeshWriter.cpp | 65 +++++++++--- source/Irrlicht/CXMeshFileLoader.cpp | 6 +- tests/tests-last-passed-at.txt | 2 +- 27 files changed, 437 insertions(+), 328 deletions(-) diff --git a/changes.txt b/changes.txt index e1d71be7..d165ba97 100644 --- a/changes.txt +++ b/changes.txt @@ -9,11 +9,28 @@ Changes in ogl-es (not yet released - will be merged with trunk at some point) -------------------------- Changes in 1.9 (not yet released) + +- Fix CVertexBuffer::setType switching types for non-empty arrays. Before we had some bad casts which could result in random initializing of some vertex data. +- IVertexBuffer interface changes: pointer() now returns void*. Adding a const version of getData(). Some set functions have now overload for all vertex types. +- S3DVertex now always initializes color to 0xffffff. That was previously the only uninitialized variable in there. Also both derived classes have now a constructor taking a const S3DVertex&. +- Fix deserialization in CGUITable. Use now getAttributeAsStringW instead of getAttributeAsString. + Thanks @chronologicaldot for report and patch: https://irrlicht.sourceforge.io/forum/viewtopic.php?f=7&t=52821 +- IIndexBuffer interface changes: Adding a const version of getData(). Some set functions now copy by value instead of per reference, which shouldn't be slower for this and is safer to use. +- Fix CIndexBuffer::setType going from 16 to 32 bit. This had some casts which simply could mess up the results. +- Fix OSX nor resizing properly. Thanks @torleif, Jordach and sfan5 for patch and report: https://irrlicht.sourceforge.io/forum/viewtopic.php?f=2&t=52819 +- X meshloader fixes bug with uninitialized normals. Thanks @sfan5 for patch: https://irrlicht.sourceforge.io/forum/viewtopic.php?f=2&t=52819 +- stl meshloader now faster, especially with text format +- CMemoryReadFile::seek CMemoryWriteFile::seek and no longer allowed to go _before_ start. + Thanks @sfan5 for patch: https://irrlicht.sourceforge.io/forum/viewtopic.php?f=2&t=52819 +- stl meshloader can now load 32 bit buffers. + Thanks @Foaly for the patch: https://irrlicht.sourceforge.io/forum/viewtopic.php?f=9&t=51441 - Add IMeshBufffer::clone function to create buffer copies. CMeshManipulator::createMeshCopy uses that now and works now with all types of meshbuffers. - obj writer can now write 32 bit buffers -- obj meshloader can now load 32 bit buffers when setPreferredIndexType is set to EIT_32BIT. +- obj meshloader can now load 32 bit buffers when setIndexTypeHint is set correspondingly It's 16 bit meshes use now also an IDynamicMeshbuffer instead of an SMeshBuffer. -- Add IMeshLoader::setPreferredIndexType and getPreferredIndexType to allow setting hints for the loaders if users prefer 16 or 32 bit meshbuffers. + Thanks @Wol101 for original patch proposal: https://irrlicht.sourceforge.io/forum/viewtopic.php?f=9&t=51441 +- Add IMeshLoader::setIndexTypeHint and getIndexTypeHint to allow setting hints for the loaders if users prefer 16 or 32 bit meshbuffers. + Default is now to use optimal meshbuffer depending on number of vertices (if the loader supports it). - Add IMeshBuffer::getType to allow finding out which class type a meshbuffer has (similar to ISceneNode::getType). - Add IGUIImage::flip to flip/mirror images - IBillboardSceneNode got functions to access meshbuffers. So uv-coordinates can now be modified directly (previously only possible via texture matrix). diff --git a/include/CDynamicMeshBuffer.h b/include/CDynamicMeshBuffer.h index 2eed836a..4a707285 100644 --- a/include/CDynamicMeshBuffer.h +++ b/include/CDynamicMeshBuffer.h @@ -102,6 +102,26 @@ namespace scene } } + //! Append the vertices and indices to the current buffer + /** Only works for compatible vertex types. + \param vertices Pointer to a vertex array. + \param numVertices Number of vertices in the array. + \param indices Pointer to index array. + \param numIndices Number of indices in array. */ + virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) IRR_OVERRIDE + { + // TODO + } + + //! Append the meshbuffer to the current buffer + /** Only works for compatible vertex types + \param other Buffer to append to this one. */ + virtual void append(const IMeshBuffer* const other) IRR_OVERRIDE + { + // TODO + } + + //! Describe what kind of primitive geometry is used by the meshbuffer virtual void setPrimitiveType(E_PRIMITIVE_TYPE type) IRR_OVERRIDE { diff --git a/include/CIndexBuffer.h b/include/CIndexBuffer.h index 152fb040..a29d1379 100644 --- a/include/CIndexBuffer.h +++ b/include/CIndexBuffer.h @@ -14,7 +14,7 @@ namespace scene class CIndexBuffer : public IIndexBuffer { - + // Virtual function wrapper around irr::core::array class IIndexList { public: @@ -22,14 +22,15 @@ namespace scene virtual u32 stride() const =0; virtual u32 size() const =0; - virtual void push_back(const u32 &element) =0; + virtual void push_back(u32 value) =0; virtual u32 operator [](u32 index) const =0; virtual u32 getLast() =0; virtual void setValue(u32 index, u32 value) =0; virtual void set_used(u32 usedNow) =0; - virtual void reallocate(u32 new_size) =0; + virtual void reallocate(u32 new_size, bool canShrink=true) =0; virtual u32 allocated_size() const =0; virtual void* pointer() =0; + virtual const void* const_pointer() const =0; virtual video::E_INDEX_TYPE getType() const =0; }; @@ -43,10 +44,9 @@ namespace scene virtual u32 size() const IRR_OVERRIDE {return Indices.size();} - virtual void push_back(const u32 &element) IRR_OVERRIDE + virtual void push_back(u32 value) IRR_OVERRIDE { - // push const ref due to compiler problem with gcc 4.6, big endian - Indices.push_back((const T&)element); + Indices.push_back((T)value); } virtual u32 operator [](u32 index) const IRR_OVERRIDE @@ -66,9 +66,9 @@ namespace scene Indices.set_used(usedNow); } - virtual void reallocate(u32 new_size) IRR_OVERRIDE + virtual void reallocate(u32 new_size, bool canShrink) IRR_OVERRIDE { - Indices.reallocate(new_size); + Indices.reallocate(new_size, canShrink); } virtual u32 allocated_size() const IRR_OVERRIDE @@ -76,7 +76,8 @@ namespace scene return Indices.allocated_size(); } - virtual void* pointer() IRR_OVERRIDE {return Indices.pointer();} + virtual void* pointer() IRR_OVERRIDE { return Indices.pointer(); } + virtual const void* const_pointer() const IRR_OVERRIDE { return Indices.const_pointer(); } virtual video::E_INDEX_TYPE getType() const IRR_OVERRIDE { @@ -109,12 +110,14 @@ namespace scene delete Indices; } - //virtual void setType(video::E_INDEX_TYPE IndexType); - virtual void setType(video::E_INDEX_TYPE IndexType) IRR_OVERRIDE + virtual void setType(video::E_INDEX_TYPE indexType) IRR_OVERRIDE { + if ( Indices && Indices->getType() == indexType ) + return; + IIndexList *NewIndices=0; - switch (IndexType) + switch (indexType) { case video::EIT_16BIT: { @@ -142,6 +145,7 @@ namespace scene } virtual void* getData() IRR_OVERRIDE {return Indices->pointer();} + virtual const void* getData() const IRR_OVERRIDE { return Indices->const_pointer(); } virtual video::E_INDEX_TYPE getType() const IRR_OVERRIDE {return Indices->getType();} @@ -152,9 +156,9 @@ namespace scene return Indices->size(); } - virtual void push_back(const u32 &element) IRR_OVERRIDE + virtual void push_back(u32 value) IRR_OVERRIDE { - Indices->push_back(element); + Indices->push_back(value); } virtual u32 operator [](u32 index) const IRR_OVERRIDE @@ -177,9 +181,9 @@ namespace scene Indices->set_used(usedNow); } - virtual void reallocate(u32 new_size) IRR_OVERRIDE + virtual void reallocate(u32 new_size, bool canShrink=true) IRR_OVERRIDE { - Indices->reallocate(new_size); + Indices->reallocate(new_size, canShrink); } virtual u32 allocated_size() const IRR_OVERRIDE @@ -187,11 +191,6 @@ namespace scene return Indices->allocated_size(); } - virtual void* pointer() IRR_OVERRIDE - { - return Indices->pointer(); - } - //! get the current hardware mapping hint virtual E_HARDWARE_MAPPING getHardwareMappingHint() const IRR_OVERRIDE { diff --git a/include/CVertexBuffer.h b/include/CVertexBuffer.h index 2a984268..5494b974 100644 --- a/include/CVertexBuffer.h +++ b/include/CVertexBuffer.h @@ -25,12 +25,20 @@ namespace scene virtual u32 size() const =0; virtual void push_back (const video::S3DVertex &element) =0; + virtual void push_back(const video::S3DVertex2TCoords &element) =0; + virtual void push_back(const video::S3DVertexTangents &element) =0; + virtual void setValue(u32 index, const video::S3DVertex &value) =0; + virtual void setValue(u32 index, const video::S3DVertex2TCoords &value) =0; + virtual void setValue(u32 index, const video::S3DVertexTangents &value) =0; + + virtual video::S3DVertex& operator [](u32 index) = 0; virtual video::S3DVertex& operator [](const u32 index) const =0; virtual video::S3DVertex& getLast() =0; virtual void set_used(u32 usedNow) =0; - virtual void reallocate(u32 new_size) =0; + virtual void reallocate(u32 new_size, bool canShrink=true) =0; virtual u32 allocated_size() const =0; - virtual video::S3DVertex* pointer() =0; + virtual void* pointer() =0; + virtual const void* const_pointer() const =0; virtual video::E_VERTEX_TYPE getType() const =0; }; @@ -45,7 +53,21 @@ namespace scene virtual u32 size() const IRR_OVERRIDE {return Vertices.size();} virtual void push_back (const video::S3DVertex &element) IRR_OVERRIDE - {Vertices.push_back((T&)element);} + {Vertices.push_back(element);} + virtual void push_back(const video::S3DVertex2TCoords &element) IRR_OVERRIDE + {Vertices.push_back(element);} + virtual void push_back(const video::S3DVertexTangents &element) IRR_OVERRIDE + {Vertices.push_back(element);} + + virtual void setValue(u32 index, const video::S3DVertex &value) IRR_OVERRIDE + {Vertices[index] = value;} + virtual void setValue(u32 index, const video::S3DVertex2TCoords &value) IRR_OVERRIDE + {Vertices[index] = value;} + virtual void setValue(u32 index, const video::S3DVertexTangents &value) IRR_OVERRIDE + {Vertices[index] = value;} + + virtual video::S3DVertex& operator [](u32 index) IRR_OVERRIDE + {return (video::S3DVertex&)Vertices[index];} virtual video::S3DVertex& operator [](const u32 index) const IRR_OVERRIDE {return (video::S3DVertex&)Vertices[index];} @@ -56,15 +78,16 @@ namespace scene virtual void set_used(u32 usedNow) IRR_OVERRIDE {Vertices.set_used(usedNow);} - virtual void reallocate(u32 new_size) IRR_OVERRIDE - {Vertices.reallocate(new_size);} + virtual void reallocate(u32 new_size, bool canShrink) IRR_OVERRIDE + {Vertices.reallocate(new_size, canShrink);} virtual u32 allocated_size() const IRR_OVERRIDE { return Vertices.allocated_size(); } - virtual video::S3DVertex* pointer() IRR_OVERRIDE {return Vertices.pointer();} + virtual void* pointer() IRR_OVERRIDE {return Vertices.pointer();} + virtual const void* const_pointer() const IRR_OVERRIDE {return Vertices.const_pointer();} virtual video::E_VERTEX_TYPE getType() const IRR_OVERRIDE {return T::getType();} }; @@ -94,9 +117,11 @@ namespace scene delete Vertices; } - virtual void setType(video::E_VERTEX_TYPE vertexType) IRR_OVERRIDE { + if ( Vertices && Vertices->getType() == vertexType ) + return; + IVertexList *NewVertices=0; switch (vertexType) @@ -121,8 +146,27 @@ namespace scene { NewVertices->reallocate( Vertices->size() ); - for(u32 n=0;nsize();++n) - NewVertices->push_back((*Vertices)[n]); + switch (Vertices->getType()) // old type + { + case video::EVT_STANDARD: + { + for(u32 n=0;nsize();++n) + NewVertices->push_back((*Vertices)[n]); + break; + } + case video::EVT_2TCOORDS: + { + for(u32 n=0;nsize();++n) + NewVertices->push_back((video::S3DVertex2TCoords&)(*Vertices)[n]); + break; + } + case video::EVT_TANGENTS: + { + for(u32 n=0;nsize();++n) + NewVertices->push_back((video::S3DVertexTangents&)(*Vertices)[n]); + break; + } + } delete Vertices; } @@ -131,6 +175,7 @@ namespace scene } virtual void* getData() IRR_OVERRIDE {return Vertices->pointer();} + virtual const void* getData() const IRR_OVERRIDE {return Vertices->const_pointer();} virtual video::E_VERTEX_TYPE getType() const IRR_OVERRIDE {return Vertices->getType();} @@ -146,6 +191,36 @@ namespace scene Vertices->push_back(element); } + virtual void push_back(const video::S3DVertex2TCoords &element) IRR_OVERRIDE + { + Vertices->push_back(element); + } + + virtual void push_back(const video::S3DVertexTangents &element) IRR_OVERRIDE + { + Vertices->push_back(element); + } + + virtual void setValue(u32 index, const video::S3DVertex &value) IRR_OVERRIDE + { + Vertices->setValue(index, value); + } + + virtual void setValue(u32 index, const video::S3DVertex2TCoords &value) IRR_OVERRIDE + { + Vertices->setValue(index, value); + } + + virtual void setValue(u32 index, const video::S3DVertexTangents &value) IRR_OVERRIDE + { + Vertices->setValue(index, value); + } + + virtual video::S3DVertex& operator [](u32 index) IRR_OVERRIDE + { + return (*Vertices)[index]; + } + virtual video::S3DVertex& operator [](const u32 index) const IRR_OVERRIDE { return (*Vertices)[index]; @@ -161,9 +236,9 @@ namespace scene Vertices->set_used(usedNow); } - virtual void reallocate(u32 new_size) IRR_OVERRIDE + virtual void reallocate(u32 new_size, bool canShrink=true) IRR_OVERRIDE { - Vertices->reallocate(new_size); + Vertices->reallocate(new_size, canShrink); } virtual u32 allocated_size() const IRR_OVERRIDE @@ -171,11 +246,6 @@ namespace scene return Vertices->allocated_size(); } - virtual video::S3DVertex* pointer() IRR_OVERRIDE - { - return Vertices->pointer(); - } - //! get the current hardware mapping hint virtual E_HARDWARE_MAPPING getHardwareMappingHint() const IRR_OVERRIDE { diff --git a/include/IAnimatedMeshMD3.h b/include/IAnimatedMeshMD3.h index 6612516b..1e27fbc1 100644 --- a/include/IAnimatedMeshMD3.h +++ b/include/IAnimatedMeshMD3.h @@ -151,17 +151,6 @@ namespace scene /** Basically its an alternate way to describe a transformation. */ struct SMD3QuaternionTag { - virtual ~SMD3QuaternionTag() - { - position.X = 0.f; - } - - // construct copy constructor - SMD3QuaternionTag( const SMD3QuaternionTag & copyMe ) - { - *this = copyMe; - } - // construct for searching SMD3QuaternionTag( const core::stringc& name ) : Name ( name ) {} @@ -181,14 +170,6 @@ namespace scene return Name == other.Name; } - SMD3QuaternionTag & operator=( const SMD3QuaternionTag & copyMe ) - { - Name = copyMe.Name; - position = copyMe.position; - rotation = copyMe.rotation; - return *this; - } - core::stringc Name; core::vector3df position; core::quaternion rotation; @@ -202,14 +183,6 @@ namespace scene Container.setAllocStrategy(core::ALLOC_STRATEGY_SAFE); } - // construct copy constructor - SMD3QuaternionTagList(const SMD3QuaternionTagList& copyMe) - { - *this = copyMe; - } - - virtual ~SMD3QuaternionTagList() {} - SMD3QuaternionTag* get(const core::stringc& name) { SMD3QuaternionTag search ( name ); @@ -250,12 +223,6 @@ namespace scene Container.push_back(other); } - SMD3QuaternionTagList& operator = (const SMD3QuaternionTagList & copyMe) - { - Container = copyMe.Container; - return *this; - } - private: core::array < SMD3QuaternionTag > Container; }; diff --git a/include/IDynamicMeshBuffer.h b/include/IDynamicMeshBuffer.h index 00ebbaaf..3aed1265 100644 --- a/include/IDynamicMeshBuffer.h +++ b/include/IDynamicMeshBuffer.h @@ -24,46 +24,13 @@ namespace scene virtual void setVertexBuffer(IVertexBuffer *vertexBuffer) =0; virtual void setIndexBuffer(IIndexBuffer *indexBuffer) =0; - //! Get the material of this meshbuffer - /** \return Material of this buffer. */ - virtual video::SMaterial& getMaterial() IRR_OVERRIDE =0; - //! Get the material of this meshbuffer - /** \return Material of this buffer. */ - virtual const video::SMaterial& getMaterial() const IRR_OVERRIDE =0; + // ------------------- Old interface ------------------- // + // That stuff could also be in CDynamicMeshBuffer + // I suppose it was put here to show that the information + // is now basically handled by the vertex/index buffers instead + // of the meshbuffer itself. - //! Get the axis aligned bounding box of this meshbuffer. - /** \return Axis aligned bounding box of this buffer. */ - virtual const core::aabbox3df& getBoundingBox() const IRR_OVERRIDE =0; - - //! Set axis aligned bounding box - /** \param box User defined axis aligned bounding box to use - for this buffer. */ - virtual void setBoundingBox(const core::aabbox3df& box) IRR_OVERRIDE =0; - - //! Recalculates the bounding box. Should be called if the mesh changed. - virtual void recalculateBoundingBox() IRR_OVERRIDE =0; - - //! Append the vertices and indices to the current buffer - /** Only works for compatible vertex types. - \param vertices Pointer to a vertex array. - \param numVertices Number of vertices in the array. - \param indices Pointer to index array. - \param numIndices Number of indices in array. */ - virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) IRR_OVERRIDE - { - - } - - //! Append the meshbuffer to the current buffer - /** Only works for compatible vertex types - \param other Buffer to append to this one. */ - virtual void append(const IMeshBuffer* const other) IRR_OVERRIDE - { - - } - - // ------------------- To be removed? ------------------- // //! get the current hardware mapping hint virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const IRR_OVERRIDE @@ -105,7 +72,6 @@ namespace scene return getIndexBuffer().getChangedID(); } - // ------------------- Old interface ------------------- // //! Get type of vertex data which is stored in this meshbuffer. /** \return Vertex type of this buffer. */ diff --git a/include/IIndexBuffer.h b/include/IIndexBuffer.h index d1bb961a..a39e306d 100644 --- a/include/IIndexBuffer.h +++ b/include/IIndexBuffer.h @@ -20,23 +20,43 @@ namespace scene { public: + //! Pointer to first element virtual void* getData() =0; + //! Const pointer to first element + virtual const void* getData() const =0; + + //! Same as getData(), just closer to core::array interface + void* pointer() { return getData(); } + virtual video::E_INDEX_TYPE getType() const =0; + + //! Change between 16 and 32 bit indices. + /** This copies all indices to a new buffer of corresponding type. + Be careful - going from 32 to 16 bit will only work correctly + if none of your indices is larger than 16 bit. */ virtual void setType(video::E_INDEX_TYPE IndexType) =0; + //! Number of bytes per element virtual u32 stride() const =0; + //! Number of elements virtual u32 size() const =0; - virtual void push_back (const u32 &element) =0; + + //! Add value to end. Note that for 16 bit index types values shouldn't be larger than u16 + virtual void push_back(u32 value) =0; + + //! Set value at index. Note that for 16 bit index types values shouldn't be larger than u16 + /** Buffer must be already large enough. This is basically the non const version of operator [] */ + virtual void setValue(u32 index, u32 value) =0; + + //! Access element value at given index virtual u32 operator [](u32 index) const =0; virtual u32 getLast() =0; - virtual void setValue(u32 index, u32 value) =0; - virtual void set_used(u32 usedNow) =0; - virtual void reallocate(u32 new_size) =0; - virtual u32 allocated_size() const=0; - virtual void* pointer() =0; + virtual void set_used(u32 usedNow) =0; + virtual void reallocate(u32 new_size, bool canShrink=true) =0; + virtual u32 allocated_size() const=0; //! get the current hardware mapping hint virtual E_HARDWARE_MAPPING getHardwareMappingHint() const =0; diff --git a/include/IMeshBuffer.h b/include/IMeshBuffer.h index 6ecbb766..77ce995d 100644 --- a/include/IMeshBuffer.h +++ b/include/IMeshBuffer.h @@ -120,14 +120,16 @@ namespace scene virtual core::vector2df& getTCoords(u32 i) = 0; //! Append the vertices and indices to the current buffer - /** Only works for compatible vertex types. + /** Only works for compatible vertex types + and not implemented for most buffers for now. \param vertices Pointer to a vertex array. \param numVertices Number of vertices in the array. \param indices Pointer to index array. \param numIndices Number of indices in array. */ virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) = 0; - //! Append the meshbuffer to the current buffer + //! Not supported right now by any meshbuffer + //! In theory: Append the meshbuffer to the current buffer /** Only works for compatible vertex types \param other Buffer to append to this one. */ virtual void append(const IMeshBuffer* const other) = 0; diff --git a/include/IMeshLoader.h b/include/IMeshLoader.h index 065d76ef..cd81adb7 100644 --- a/include/IMeshLoader.h +++ b/include/IMeshLoader.h @@ -30,7 +30,7 @@ class IMeshLoader : public virtual IReferenceCounted public: //! Constructor - IMeshLoader() : TextureLoader(0), PreferredIndexType(video::EIT_16BIT) {} + IMeshLoader() : TextureLoader(0), IndexTypeHint(EITH_OPTIMAL) {} //! Destructor virtual ~IMeshLoader() @@ -79,30 +79,47 @@ public: return TextureLoader; } + enum E_INDEX_TYPE_HINT + { + //! Prefer to use 16-bit index buffers even if it breaks the mesh + //! The default (and only option) before Irrlicht 1.9 + EITH_16BIT, + + //! Allow using 32-bit index buffers + EITH_32BIT, + + //! Allow 32-bit, but copy back to 16-bit when 32 is not needed. + //! So tiny overhead (sometimes extra allocation+copying) on loading, + //! but meshes are later more optimal. + //! Default since Irrlicht 1.9 + EITH_OPTIMAL + }; + + //! Give loader a hint if you would prefer 16 or 32 bit meshbuffers. /** - Generally Irrlicht works with 16-bit meshbuffers so far. - Rendering 32-bit meshbuffers works, other functions like + Before Irrlicht 1.9 Irrlicht worked mostly with 16-bit meshbuffers. + Rendering 32-bit meshbuffers works, but some functions like mesh-writing and mesh manipulation might not work yet. NOTE: Most loaders will ignore this hint so far, but hopefully will care about it in the future. */ - void setPreferredIndexType(irr::video::E_INDEX_TYPE typeHint) + void setIndexTypeHint(E_INDEX_TYPE_HINT typeHint) { - PreferredIndexType = typeHint; + IndexTypeHint = typeHint; } - //! Return current preference user has for the index-size of meshbuffers + //! Return current preference user has for the index type of meshbuffers /** Note that this is _not_ necessarily the type used by the meshloader */ - irr::video::E_INDEX_TYPE getPreferredIndexType() const + E_INDEX_TYPE_HINT getIndexTypeHint() const { - return PreferredIndexType; + return IndexTypeHint; } protected: IMeshTextureLoader* TextureLoader; - irr::video::E_INDEX_TYPE PreferredIndexType; + E_INDEX_TYPE_HINT IndexTypeHint; }; diff --git a/include/IQ3Shader.h b/include/IQ3Shader.h index 8541a7fa..68e0e113 100644 --- a/include/IQ3Shader.h +++ b/include/IQ3Shader.h @@ -637,8 +637,6 @@ namespace quake3 { IShader () : ID ( 0 ), VarGroup ( 0 ) {} - virtual ~IShader () {} - bool operator == (const IShader &other ) const { diff --git a/include/IVertexBuffer.h b/include/IVertexBuffer.h index 1a8c6fb8..41336371 100644 --- a/include/IVertexBuffer.h +++ b/include/IVertexBuffer.h @@ -21,6 +21,12 @@ namespace scene //! Pointer to first element of vertex data virtual void* getData() =0; + //! Const pointer to first element + virtual const void* getData() const =0; + + //! Same as getData. + virtual void* pointer() { return getData(); } + virtual video::E_VERTEX_TYPE getType() const =0; virtual void setType(video::E_VERTEX_TYPE vertexType) =0; @@ -30,16 +36,28 @@ namespace scene //! Number of elements virtual u32 size() const =0; - //! Add vertex to end. Note that depending on vertex type this will be one of the types derived from video::S3DVertex. + //! Add vertex to end. + //* Note that if you pass another type than the currently used vertex type then information can be lost */ virtual void push_back(const video::S3DVertex &element) =0; + virtual void push_back(const video::S3DVertex2TCoords &element) =0; + virtual void push_back(const video::S3DVertexTangents &element) =0; + + //! Set value at index. Buffer must be already large enough that element exists. + //* Note that if you pass another type than the currently used vertex type then information can be lost */ + virtual void setValue(u32 index, const video::S3DVertex &value) =0; + virtual void setValue(u32 index, const video::S3DVertex2TCoords &value) =0; + virtual void setValue(u32 index, const video::S3DVertexTangents &value) =0; + + //! Direct access to elements. Risky to use! + /** The reference _must_ be cast to the correct type before use. It's only video::S3DVertex if getType is EVT_STANDARD. + otherwise cast it first to a reference type derived from S3DVertex like S3DVertex2TCoords& or S3DVertexTangents&. */ + virtual video::S3DVertex& operator [](u32 index) = 0; virtual video::S3DVertex& operator [](const u32 index) const =0; virtual video::S3DVertex& getLast() =0; - virtual void set_used(u32 usedNow) =0; - virtual void reallocate(u32 new_size) =0; - virtual u32 allocated_size() const =0; - //! Same as getData() - not sure why we got 2, should probably deprecate (and we don't always have video::S3DVertex*, so just confusing) - virtual video::S3DVertex* pointer() =0; + virtual void set_used(u32 usedNow) =0; + virtual void reallocate(u32 new_size, bool canShrink=true) =0; + virtual u32 allocated_size() const =0; //! get the current hardware mapping hint virtual E_HARDWARE_MAPPING getHardwareMappingHint() const =0; diff --git a/include/S3DVertex.h b/include/S3DVertex.h index 0b48ee96..ddb40f18 100644 --- a/include/S3DVertex.h +++ b/include/S3DVertex.h @@ -44,7 +44,7 @@ const char* const sBuiltInVertexTypeNames[] = struct S3DVertex { //! default constructor - S3DVertex() {} + S3DVertex() : Color(0xffffffff) {} //! constructor S3DVertex(f32 x, f32 y, f32 z, f32 nx, f32 ny, f32 nz, SColor c, f32 tu, f32 tv) @@ -142,7 +142,7 @@ struct S3DVertex2TCoords : public S3DVertex : S3DVertex(pos, normal, color, tcoords), TCoords2(tcoords) {} //! constructor from S3DVertex - S3DVertex2TCoords(S3DVertex& o) : S3DVertex(o) {} + S3DVertex2TCoords(const S3DVertex& o) : S3DVertex(o) {} //! Second set of texture coordinates core::vector2d TCoords2; @@ -214,6 +214,9 @@ struct S3DVertexTangents : public S3DVertex const core::vector3df& binormal=core::vector3df()) : S3DVertex(pos, normal, c, tcoords), Tangent(tangent), Binormal(binormal) { } + //! constructor from S3DVertex + S3DVertexTangents(const S3DVertex& o) : S3DVertex(o) {} + //! Tangent vector along the x-axis of the texture core::vector3df Tangent; diff --git a/include/SMaterial.h b/include/SMaterial.h index 9d775c86..788c8986 100644 --- a/include/SMaterial.h +++ b/include/SMaterial.h @@ -289,9 +289,8 @@ namespace video We (mostly) avoid dynamic memory in SMaterial, so the extra memory will still be allocated. But by lowering MATERIAL_MAX_TEXTURES_USED the - material comparisons and assignments can be faster. Also several other - places in the engine can be faster when reducing this value to the limit - you need. + material comparisons can be faster. Also several other places in the + engine can be faster when reducing this value to the limit you need. NOTE: This should only be changed once and before any call to createDevice. NOTE: Do not set it below 1 or above the value of _IRR_MATERIAL_MAX_TEXTURES_. @@ -318,63 +317,6 @@ namespace video FogEnable(false), NormalizeNormals(false), UseMipMaps(true) { } - //! Copy constructor - /** \param other Material to copy from. */ - SMaterial(const SMaterial& other) - { - // These pointers are checked during assignment - for (u32 i=0; i& other) : X(other.X), Y(other.Y) {} vector2d(const dimension2d& other) : X(other.Width), Y(other.Height) {} @@ -36,8 +34,6 @@ public: vector2d operator-() const { return vector2d(-X, -Y); } - vector2d& operator=(const vector2d& other) { X = other.X; Y = other.Y; return *this; } - vector2d& operator=(const dimension2d& other) { X = other.Width; Y = other.Height; return *this; } vector2d operator+(const vector2d& other) const { return vector2d(X + other.X, Y + other.Y); } diff --git a/include/vector3d.h b/include/vector3d.h index ebea7c46..dfc35b58 100644 --- a/include/vector3d.h +++ b/include/vector3d.h @@ -28,15 +28,11 @@ namespace core vector3d(T nx, T ny, T nz) : X(nx), Y(ny), Z(nz) {} //! Constructor with the same value for all elements explicit vector3d(T n) : X(n), Y(n), Z(n) {} - //! Copy constructor - vector3d(const vector3d& other) : X(other.X), Y(other.Y), Z(other.Z) {} // operators vector3d operator-() const { return vector3d(-X, -Y, -Z); } - vector3d& operator=(const vector3d& other) { X = other.X; Y = other.Y; Z = other.Z; return *this; } - vector3d operator+(const vector3d& other) const { return vector3d(X + other.X, Y + other.Y, Z + other.Z); } vector3d& operator+=(const vector3d& other) { X+=other.X; Y+=other.Y; Z+=other.Z; return *this; } vector3d operator+(const T val) const { return vector3d(X + val, Y + val, Z + val); } diff --git a/source/Irrlicht/CB3DMeshFileLoader.cpp b/source/Irrlicht/CB3DMeshFileLoader.cpp index c473d529..05f8bf5d 100644 --- a/source/Irrlicht/CB3DMeshFileLoader.cpp +++ b/source/Irrlicht/CB3DMeshFileLoader.cpp @@ -136,7 +136,8 @@ bool CB3DMeshFileLoader::load() else { os::Printer::log("Unknown chunk found in mesh base - skipping"); - B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); + if (!B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length)) + return false; B3dStack.erase(B3dStack.size()-1); } } @@ -232,7 +233,8 @@ bool CB3DMeshFileLoader::readChunkNODE(CSkinnedMesh::SJoint *inJoint) else { os::Printer::log("Unknown chunk found in node chunk - skipping"); - B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); + if (!B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length)) + return false; B3dStack.erase(B3dStack.size()-1); } } @@ -315,7 +317,8 @@ bool CB3DMeshFileLoader::readChunkMESH(CSkinnedMesh::SJoint *inJoint) else { os::Printer::log("Unknown chunk found in mesh - skipping"); - B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); + if (!B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length)) + return false; B3dStack.erase(B3dStack.size()-1); } } @@ -859,7 +862,7 @@ bool CB3DMeshFileLoader::readChunkBRUS() while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats { - // This is what blitz basic calls a brush, like a Irrlicht Material + // This is what blitz basic calls a brush, like an Irrlicht material core::stringc name; readString(name); @@ -933,7 +936,7 @@ bool CB3DMeshFileLoader::readChunkBRUS() } } - //If a preceeding texture slot is empty move the others down: + //If a preceding texture slot is empty move the others down: for (i=num_textures; i>0; --i) { for (u32 j=i-1; jwrite(&i, 4); u32 numIndices = mb->getIndexCount(); - const u16 * const idx = (u16 *) mb->getIndices(); - for (u32 j = 0; j < numIndices; j += 3) + if ( mb->getIndexType() == video::EIT_16BIT ) { - u32 tmp = idx[j] + currentMeshBufferIndex; - file->write(&tmp, sizeof(u32)); + const u16 * const idx = mb->getIndices(); + for (u32 j = 0; j < numIndices; j += 3) + { + u32 tmp = idx[j] + currentMeshBufferIndex; + file->write(&tmp, sizeof(u32)); - tmp = idx[j + 1] + currentMeshBufferIndex; - file->write(&tmp, sizeof(u32)); + tmp = idx[j + 1] + currentMeshBufferIndex; + file->write(&tmp, sizeof(u32)); - tmp = idx[j + 2] + currentMeshBufferIndex; - file->write(&tmp, sizeof(u32)); - } + tmp = idx[j + 2] + currentMeshBufferIndex; + file->write(&tmp, sizeof(u32)); + } + } + else if ( mb->getIndexType() == video::EIT_32BIT ) + { + const u32 * const idx = (const u32*) mb->getIndices(); + for (u32 j = 0; j < numIndices; j += 3) + { + u32 tmp = idx[j] + currentMeshBufferIndex; + file->write(&tmp, sizeof(u32)); + + tmp = idx[j + 1] + currentMeshBufferIndex; + file->write(&tmp, sizeof(u32)); + + tmp = idx[j + 2] + currentMeshBufferIndex; + file->write(&tmp, sizeof(u32)); + } + } writeSizeFrom(file, trisSizeAdress+4, trisSizeAdress); // TRIS chunk size currentMeshBufferIndex += mb->getVertexCount(); diff --git a/source/Irrlicht/CGUITable.cpp b/source/Irrlicht/CGUITable.cpp index 206f7ff5..9c89cf19 100644 --- a/source/Irrlicht/CGUITable.cpp +++ b/source/Irrlicht/CGUITable.cpp @@ -1217,7 +1217,7 @@ void CGUITable::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWri Column column; label = "Column"; label += i; label += "name"; - column.Name = core::stringw(in->getAttributeAsString(label.c_str()).c_str()); + column.Name = in->getAttributeAsStringW(label.c_str()); label = "Column"; label += i; label += "width"; column.Width = in->getAttributeAsInt(label.c_str()); label = "Column"; label += i; label += "OrderingMode"; @@ -1252,7 +1252,7 @@ void CGUITable::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWri Cell cell; label = "Row"; label += i; label += "cell"; label += c; label += "text"; - cell.Text = core::stringw(in->getAttributeAsString(label.c_str()).c_str()); + cell.Text = in->getAttributeAsStringW(label.c_str()); breakText( cell.Text, cell.BrokenText, Columns[c].Width ); label = "Row"; label += i; label += "cell"; label += c; label += "color"; cell.Color = in->getAttributeAsColor(label.c_str()); diff --git a/source/Irrlicht/CMemoryFile.cpp b/source/Irrlicht/CMemoryFile.cpp index 22c57e65..a2143615 100644 --- a/source/Irrlicht/CMemoryFile.cpp +++ b/source/Irrlicht/CMemoryFile.cpp @@ -52,14 +52,14 @@ bool CMemoryReadFile::seek(long finalPos, bool relativeMovement) { if (relativeMovement) { - if (Pos + finalPos > Len) + if (Pos + finalPos < 0 || Pos + finalPos > Len) return false; Pos += finalPos; } else { - if (finalPos > Len) + if (finalPos < 0 || finalPos > Len) return false; Pos = finalPos; @@ -133,14 +133,14 @@ bool CMemoryWriteFile::seek(long finalPos, bool relativeMovement) { if (relativeMovement) { - if (Pos + finalPos > Len) + if (Pos + finalPos < 0 || Pos + finalPos > Len) return false; Pos += finalPos; } else { - if (finalPos > Len) + if (finalPos < 0 || finalPos > Len) return false; Pos = finalPos; diff --git a/source/Irrlicht/COBJMeshFileLoader.cpp b/source/Irrlicht/COBJMeshFileLoader.cpp index 2249716f..9fe99b01 100644 --- a/source/Irrlicht/COBJMeshFileLoader.cpp +++ b/source/Irrlicht/COBJMeshFileLoader.cpp @@ -82,7 +82,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file) core::array > normalsBuffer(1000); core::array > textureCoordBuffer(1000); - SObjMtl * currMtl = new SObjMtl(PreferredIndexType); + SObjMtl * currMtl = new SObjMtl(getIndexTypeHint()); Materials.push_back(currMtl); u32 smoothingGroup=0; @@ -330,19 +330,21 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file) { if ( Materials[m]->Meshbuffer->getIndexCount() > 0 ) { + if ( getIndexTypeHint() == EITH_OPTIMAL + && Materials[m]->Meshbuffer->getVertexCount() <= 65536 ) + { + Materials[m]->Meshbuffer->getIndexBuffer().setType(video::EIT_16BIT); + } + + Materials[m]->Meshbuffer->recalculateBoundingBox(); if (Materials[m]->RecalculateNormals) SceneManager->getMeshManipulator()->recalculateNormals(Materials[m]->Meshbuffer); if (Materials[m]->Meshbuffer->Material.MaterialType == video::EMT_PARALLAX_MAP_SOLID) { - SMesh tmp; - tmp.addMeshBuffer(Materials[m]->Meshbuffer); - IMesh* tangentMesh = SceneManager->getMeshManipulator()->createMeshWithTangents(&tmp); - mesh->addMeshBuffer(tangentMesh->getMeshBuffer(0)); - tangentMesh->drop(); + Materials[m]->Meshbuffer->getVertexBuffer().setType(video::EVT_TANGENTS); } - else - mesh->addMeshBuffer( Materials[m]->Meshbuffer ); + mesh->addMeshBuffer( Materials[m]->Meshbuffer ); } } @@ -579,7 +581,7 @@ void COBJMeshFileLoader::readMTL(const c8* fileName, const io::path& relPath) c8 mtlNameBuf[WORD_BUFFER_LENGTH]; bufPtr = goAndCopyNextWord(mtlNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); - currMaterial = new SObjMtl(PreferredIndexType); + currMaterial = new SObjMtl(getIndexTypeHint()); currMaterial->Name = mtlNameBuf; } break; diff --git a/source/Irrlicht/COBJMeshFileLoader.h b/source/Irrlicht/COBJMeshFileLoader.h index 29540560..096b0d75 100644 --- a/source/Irrlicht/COBJMeshFileLoader.h +++ b/source/Irrlicht/COBJMeshFileLoader.h @@ -42,7 +42,9 @@ private: struct SObjMtl { - SObjMtl(irr::video::E_INDEX_TYPE indexType) : IndexType(indexType), Meshbuffer(0), Bumpiness (1.0f), Illumination(0), + SObjMtl(E_INDEX_TYPE_HINT typeHint) + : IndexType(typeHint == EITH_16BIT ? video::EIT_16BIT : video::EIT_32BIT) + , Meshbuffer(0), Bumpiness (1.0f), Illumination(0), RecalculateNormals(false) { Meshbuffer = new CDynamicMeshBuffer(irr::video::EVT_STANDARD, IndexType); diff --git a/source/Irrlicht/CSTLMeshFileLoader.cpp b/source/Irrlicht/CSTLMeshFileLoader.cpp index bf9ffb30..f6e39051 100644 --- a/source/Irrlicht/CSTLMeshFileLoader.cpp +++ b/source/Irrlicht/CSTLMeshFileLoader.cpp @@ -8,7 +8,8 @@ #include "CSTLMeshFileLoader.h" #include "SMesh.h" -#include "SMeshBuffer.h" +#include "CDynamicMeshBuffer.h" +#include "CMemoryFile.h" #include "SAnimatedMesh.h" #include "IReadFile.h" #include "fast_atof.h" @@ -34,14 +35,29 @@ bool CSTLMeshFileLoader::isALoadableFileExtension(const io::path& filename) cons //! \return Pointer to the created mesh. Returns 0 if loading failed. //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). //! See IReferenceCounted::drop() for more information. -IAnimatedMesh* CSTLMeshFileLoader::createMesh(io::IReadFile* file) +IAnimatedMesh* CSTLMeshFileLoader::createMesh(io::IReadFile* fileIn) { - const long filesize = file->getSize(); + const long filesize = fileIn->getSize(); if (filesize < 6) // we need a header return 0; + // We copy the whole file into a memory-read file if it isn't already one. + io::CMemoryReadFile * memoryFile = 0; + if ( fileIn->getType() != io::ERFT_MEMORY_READ_FILE ) + { + u8* fileBuffer = new u8[filesize]; + if ( fileIn->read(fileBuffer, filesize) != (size_t)filesize ) + { + delete[] fileBuffer; + return 0; + } + memoryFile = new io::CMemoryReadFile(fileBuffer, filesize, io::path(""), true); // takes over fileBuffer + } + io::IReadFile* file = memoryFile ? memoryFile : fileIn; + SMesh* mesh = new SMesh(); - SMeshBuffer* meshBuffer = new SMeshBuffer(); + CDynamicMeshBuffer* meshBuffer = new CDynamicMeshBuffer(video::EVT_STANDARD, video::EIT_16BIT); + IVertexBuffer& vertBuffer = meshBuffer->getVertexBuffer(); mesh->addMeshBuffer(meshBuffer); meshBuffer->drop(); @@ -49,8 +65,7 @@ IAnimatedMesh* CSTLMeshFileLoader::createMesh(io::IReadFile* file) core::vector3df normal; bool binary = false; - core::stringc token; - if (getNextToken(file, token) != "solid") + if (getNextToken(file) != "solid") binary = true; // read/skip header u32 binFaceCount = 0; @@ -66,62 +81,64 @@ IAnimatedMesh* CSTLMeshFileLoader::createMesh(io::IReadFile* file) goNextLine(file); u16 attrib=0; - token.reserve(32); + Token.reserve(32); + bool failure = false; while (file->getPos() < filesize) { if (!binary) { - if (getNextToken(file, token) != "facet") + if (getNextToken(file) != "facet") { - if (token=="endsolid") - break; - mesh->drop(); - return 0; + if (Token!="endsolid") + failure = true; + break; } - if (getNextToken(file, token) != "normal") + if (getNextToken(file) != "normal") { - mesh->drop(); - return 0; + failure = true; + break; } } getNextVector(file, normal, binary); if (!binary) { - if (getNextToken(file, token) != "outer") + if (getNextToken(file) != "outer") { - mesh->drop(); - return 0; + failure = true; + break; } - if (getNextToken(file, token) != "loop") + if (getNextToken(file) != "loop") { - mesh->drop(); - return 0; + failure = true; + break; } } for (u32 i=0; i<3; ++i) { if (!binary) { - if (getNextToken(file, token) != "vertex") + if (getNextToken(file) != "vertex") { - mesh->drop(); - return 0; + failure = true; + break; } } getNextVector(file, vertex[i], binary); } + if ( failure ) + break; if (!binary) { - if (getNextToken(file, token) != "endloop") + if (getNextToken(file) != "endloop") { - mesh->drop(); - return 0; + failure = true; + break; } - if (getNextToken(file, token) != "endfacet") + if (getNextToken(file) != "endfacet") { - mesh->drop(); - return 0; + failure = true; + break; } } else @@ -132,41 +149,56 @@ IAnimatedMesh* CSTLMeshFileLoader::createMesh(io::IReadFile* file) #endif } - SMeshBuffer* mb = reinterpret_cast(mesh->getMeshBuffer(mesh->getMeshBufferCount()-1)); - u32 vCount = mb->getVertexCount(); video::SColor color(0xffffffff); if (attrib & 0x8000) color = video::A1R5G5B5toA8R8G8B8(attrib); if (normal==core::vector3df()) normal=core::plane3df(vertex[2],vertex[1],vertex[0]).Normal; - mb->Vertices.push_back(video::S3DVertex(vertex[2],normal,color, core::vector2df())); - mb->Vertices.push_back(video::S3DVertex(vertex[1],normal,color, core::vector2df())); - mb->Vertices.push_back(video::S3DVertex(vertex[0],normal,color, core::vector2df())); - mb->Indices.push_back(vCount); - mb->Indices.push_back(vCount+1); - mb->Indices.push_back(vCount+2); + vertBuffer.push_back(video::S3DVertex(vertex[2],normal,color, core::vector2df())); + vertBuffer.push_back(video::S3DVertex(vertex[1],normal,color, core::vector2df())); + vertBuffer.push_back(video::S3DVertex(vertex[0],normal,color, core::vector2df())); } // end while (file->getPos() < filesize) - mesh->getMeshBuffer(0)->recalculateBoundingBox(); // Create the Animated mesh if there's anything in the mesh SAnimatedMesh* pAM = 0; - if ( 0 != mesh->getMeshBufferCount() ) + if ( !failure && mesh->getMeshBufferCount() > 0 ) { + IIndexBuffer& indexBuffer = meshBuffer->getIndexBuffer(); + u32 vertCount = vertBuffer.size(); + if (vertCount > 65535 ) // Note 65535 instead of 65536 as it divides by 3 + { + if ( getIndexTypeHint() != EITH_16BIT ) + indexBuffer.setType(video::EIT_32BIT); + else + { + // Could split buffer, but probably no one really needs this anymore now with 32-bit support and necessary buffer manipulation functions are not there yet + vertCount = 65535; + } + } + + indexBuffer.reallocate(vertCount); + for (u32 i=0; irecalculateBoundingBox(); mesh->recalculateBoundingBox(); pAM = new SAnimatedMesh(); - pAM->Type = EAMT_OBJ; + pAM->Type = EAMT_STATIC; pAM->addMesh(mesh); pAM->recalculateBoundingBox(); } mesh->drop(); + Token.clear(); + if ( memoryFile ) + memoryFile->drop(); return pAM; } //! Read 3d vector of floats -void CSTLMeshFileLoader::getNextVector(io::IReadFile* file, core::vector3df& vec, bool binary) const +void CSTLMeshFileLoader::getNextVector(io::IReadFile* file, core::vector3df& vec, bool binary) { if (binary) { @@ -182,34 +214,33 @@ void CSTLMeshFileLoader::getNextVector(io::IReadFile* file, core::vector3df& vec else { goNextWord(file); - core::stringc tmp; - getNextToken(file, tmp); - core::fast_atof_move(tmp.c_str(), vec.X); - getNextToken(file, tmp); - core::fast_atof_move(tmp.c_str(), vec.Y); - getNextToken(file, tmp); - core::fast_atof_move(tmp.c_str(), vec.Z); + getNextToken(file); + core::fast_atof_move(Token.c_str(), vec.X); + getNextToken(file); + core::fast_atof_move(Token.c_str(), vec.Y); + getNextToken(file); + core::fast_atof_move(Token.c_str(), vec.Z); } vec.X=-vec.X; } //! Read next word -const core::stringc& CSTLMeshFileLoader::getNextToken(io::IReadFile* file, core::stringc& token) const +const core::stringc& CSTLMeshFileLoader::getNextToken(io::IReadFile* file) { goNextWord(file); u8 c; - token = ""; + Token = ""; while(file->getPos() != file->getSize()) { file->read(&c, 1); // found it, so leave if (core::isspace(c)) break; - token.append(c); + Token.append(c); } - return token; + return Token; } diff --git a/source/Irrlicht/CSTLMeshFileLoader.h b/source/Irrlicht/CSTLMeshFileLoader.h index d5cbdecd..68415186 100644 --- a/source/Irrlicht/CSTLMeshFileLoader.h +++ b/source/Irrlicht/CSTLMeshFileLoader.h @@ -34,12 +34,15 @@ private: // skips to the first non-space character available void goNextWord(io::IReadFile* file) const; // returns the next word - const core::stringc& getNextToken(io::IReadFile* file, core::stringc& token) const; + const core::stringc& getNextToken(io::IReadFile* file); // skip to next printable character after the first line break void goNextLine(io::IReadFile* file) const; //! Read 3d vector of floats - void getNextVector(io::IReadFile* file, core::vector3df& vec, bool binary) const; + void getNextVector(io::IReadFile* file, core::vector3df& vec, bool binary); + + //! Buffering last read token to avoid reallocating string all the time + core::stringc Token; }; } // end namespace scene diff --git a/source/Irrlicht/CSTLMeshWriter.cpp b/source/Irrlicht/CSTLMeshWriter.cpp index f3b14133..4e7af372 100644 --- a/source/Irrlicht/CSTLMeshWriter.cpp +++ b/source/Irrlicht/CSTLMeshWriter.cpp @@ -92,17 +92,37 @@ bool CSTLMeshWriter::writeMeshBinary(io::IWriteFile* file, scene::IMesh* mesh, s { const u32 indexCount = buffer->getIndexCount(); const u16 attributes = 0; - for (u32 j=0; jgetIndexType() == video::EIT_16BIT ) { - const core::vector3df& v1 = buffer->getPosition(buffer->getIndices()[j]); - const core::vector3df& v2 = buffer->getPosition(buffer->getIndices()[j+1]); - const core::vector3df& v3 = buffer->getPosition(buffer->getIndices()[j+2]); - const core::plane3df tmpplane(v1,v2,v3); - file->write(&tmpplane.Normal, 12); - file->write(&v1, 12); - file->write(&v2, 12); - file->write(&v3, 12); - file->write(&attributes, 2); + const u16* indices = buffer->getIndices(); + for (u32 j=0; jgetPosition(indices[j]); + const core::vector3df& v2 = buffer->getPosition(indices[j+1]); + const core::vector3df& v3 = buffer->getPosition(indices[j+2]); + const core::plane3df tmpplane(v1,v2,v3); + file->write(&tmpplane.Normal, 12); + file->write(&v1, 12); + file->write(&v2, 12); + file->write(&v3, 12); + file->write(&attributes, 2); + } + } + else if( buffer->getIndexType() == video::EIT_32BIT ) + { + const u32* indices = (const u32*)buffer->getIndices(); + for (u32 j=0; jgetPosition(indices[j]); + const core::vector3df& v2 = buffer->getPosition(indices[j+1]); + const core::vector3df& v3 = buffer->getPosition(indices[j+2]); + const core::plane3df tmpplane(v1,v2,v3); + file->write(&tmpplane.Normal, 12); + file->write(&v1, 12); + file->write(&v2, 12); + file->write(&v3, 12); + file->write(&attributes, 2); + } } } } @@ -127,12 +147,27 @@ bool CSTLMeshWriter::writeMeshASCII(io::IWriteFile* file, scene::IMesh* mesh, s3 if (buffer) { const u32 indexCount = buffer->getIndexCount(); - for (u32 j=0; jgetIndexType() == video::EIT_16BIT ) { - writeFace(file, - buffer->getPosition(buffer->getIndices()[j]), - buffer->getPosition(buffer->getIndices()[j+1]), - buffer->getPosition(buffer->getIndices()[j+2])); + const u16* indices = buffer->getIndices(); + for (u32 j=0; jgetPosition(indices[j]), + buffer->getPosition(indices[j+1]), + buffer->getPosition(indices[j+2])); + } + } + else if ( buffer->getIndexType() == video::EIT_32BIT ) + { + const u32* indices = (const u32*)buffer->getIndices(); + for (u32 j=0; jgetPosition(indices[j]), + buffer->getPosition(indices[j+1]), + buffer->getPosition(indices[j+2])); + } } file->write("\n",1); } diff --git a/source/Irrlicht/CXMeshFileLoader.cpp b/source/Irrlicht/CXMeshFileLoader.cpp index 30a043e2..4678c854 100644 --- a/source/Irrlicht/CXMeshFileLoader.cpp +++ b/source/Irrlicht/CXMeshFileLoader.cpp @@ -760,10 +760,12 @@ bool CXMeshFileLoader::parseDataObjectMesh(SXMesh &mesh) // read vertices mesh.Vertices.set_used(nVertices); + irr::video::S3DVertex vertex; // set_used doesn't call constructor, so we initalize it explicit here + vertex.Color = 0xFFFFFFFF; for (u32 n=0; n