aboutsummaryrefslogtreecommitdiff
path: root/source/Irrlicht/CSMFMeshFileLoader.cpp
diff options
context:
space:
mode:
authorcutealien <cutealien@dfc29bdd-3216-0410-991c-e03cc46cb475>2020-01-03 19:05:16 +0000
committercutealien <cutealien@dfc29bdd-3216-0410-991c-e03cc46cb475>2020-01-03 19:05:16 +0000
commit2ae2a551a6290f46734307bbfdafea4b1a2cf2ba (patch)
treeba2f0b468640e44899fed3df2d4cc58795f4a003 /source/Irrlicht/CSMFMeshFileLoader.cpp
downloadirrlicht-2ae2a551a6290f46734307bbfdafea4b1a2cf2ba.tar.xz
Merging r5975 through r6036 from trunk to ogl-es branch.
GLES drivers adapted, but only did make compile-tests. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@6038 dfc29bdd-3216-0410-991c-e03cc46cb475
Diffstat (limited to 'source/Irrlicht/CSMFMeshFileLoader.cpp')
-rw-r--r--source/Irrlicht/CSMFMeshFileLoader.cpp242
1 files changed, 242 insertions, 0 deletions
diff --git a/source/Irrlicht/CSMFMeshFileLoader.cpp b/source/Irrlicht/CSMFMeshFileLoader.cpp
new file mode 100644
index 0000000..d6ddb13
--- /dev/null
+++ b/source/Irrlicht/CSMFMeshFileLoader.cpp
@@ -0,0 +1,242 @@
+// Copyright (C) 2010-2012 Gaz Davidson / Joseph Ellis
+// This file is part of the "Irrlicht Engine".
+// For conditions of distribution and use, see copyright notice in irrlicht.h
+
+#include "IrrCompileConfig.h"
+
+#ifdef _IRR_COMPILE_WITH_SMF_LOADER_
+
+#include "CSMFMeshFileLoader.h"
+#include "CMeshTextureLoader.h"
+#include "SAnimatedMesh.h"
+#include "SMeshBuffer.h"
+#include "IReadFile.h"
+#include "coreutil.h"
+#include "os.h"
+#include "IVideoDriver.h"
+
+namespace irr
+{
+namespace scene
+{
+
+CSMFMeshFileLoader::CSMFMeshFileLoader(irr::io::IFileSystem* fs, video::IVideoDriver* driver)
+{
+ TextureLoader = new CMeshTextureLoader( fs, driver );
+}
+
+//! Returns true if the file might be loaded by this class.
+bool CSMFMeshFileLoader::isALoadableFileExtension(const io::path& filename) const
+{
+ return core::hasFileExtension(filename, "smf");
+}
+
+//! Creates/loads an animated mesh from the file.
+IAnimatedMesh* CSMFMeshFileLoader::createMesh(io::IReadFile* file)
+{
+ if ( !file )
+ return 0;
+
+ if ( getMeshTextureLoader() )
+ getMeshTextureLoader()->setMeshFile(file);
+
+ // create empty mesh
+ SMesh *mesh = new SMesh();
+
+ // load file
+ u16 version;
+ u8 flags;
+ s32 limbCount;
+ s32 i;
+
+ io::BinaryFile::read(file, version);
+ io::BinaryFile::read(file, flags);
+ io::BinaryFile::read(file, limbCount);
+
+ // load mesh data
+ core::matrix4 identity;
+ for (i=0; i < limbCount; ++i)
+ loadLimb(file, mesh, identity);
+
+ // recalculate buffer bounding boxes
+ for (i=0; i < (s32)mesh->getMeshBufferCount(); ++i)
+ mesh->getMeshBuffer(i)->recalculateBoundingBox();
+
+ mesh->recalculateBoundingBox();
+ SAnimatedMesh *am = new SAnimatedMesh();
+ am->addMesh(mesh);
+ mesh->drop();
+ am->recalculateBoundingBox();
+
+ return am;
+}
+
+void CSMFMeshFileLoader::loadLimb(io::IReadFile* file, SMesh* mesh, const core::matrix4 &parentTransformation)
+{
+ core::matrix4 transformation;
+
+ // limb transformation
+ core::vector3df translate, rotate, scale;
+ io::BinaryFile::read(file, translate);
+ io::BinaryFile::read(file, rotate);
+ io::BinaryFile::read(file, scale);
+
+ transformation.setTranslation(translate);
+ transformation.setRotationDegrees(rotate);
+ transformation.setScale(scale);
+
+ transformation = parentTransformation * transformation;
+
+ core::stringc textureName, textureGroupName;
+
+ // texture information
+ io::BinaryFile::read(file, textureGroupName);
+ io::BinaryFile::read(file, textureName);
+
+ // attempt to load texture using known formats
+ video::ITexture* texture = 0;
+
+ const c8* extensions[] = {".jpg", ".png", ".tga", ".bmp", 0};
+
+ for (const c8 **ext = extensions; !texture && *ext; ++ext)
+ {
+ texture = getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(textureName + *ext) : NULL;
+ if (texture)
+ {
+ textureName = textureName + *ext;
+ break;
+ }
+ }
+ // find the correct mesh buffer
+ u32 i;
+ for (i=0; i<mesh->MeshBuffers.size(); ++i)
+ if (mesh->MeshBuffers[i]->getMaterial().TextureLayer[0].Texture == texture)
+ break;
+
+ // create mesh buffer if none was found
+ if (i == mesh->MeshBuffers.size())
+ {
+ CMeshBuffer<video::S3DVertex>* mb = new CMeshBuffer<video::S3DVertex>();
+ mb->Material.TextureLayer[0].Texture = texture;
+
+ // horribly hacky way to do this, maybe it's in the flags?
+ if (core::hasFileExtension(textureName, "tga", "png"))
+ mb->Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
+ else
+ mb->Material.MaterialType = video::EMT_SOLID;
+
+ mesh->MeshBuffers.push_back(mb);
+ }
+
+ CMeshBuffer<video::S3DVertex>* mb = (CMeshBuffer<video::S3DVertex>*)mesh->MeshBuffers[i];
+
+ u16 vertexCount, firstVertex = mb->getVertexCount();
+
+ io::BinaryFile::read(file, vertexCount);
+ mb->Vertices.reallocate(mb->Vertices.size() + vertexCount);
+
+ // add vertices and set positions
+ for (i=0; i<vertexCount; ++i)
+ {
+ core::vector3df pos;
+ io::BinaryFile::read(file, pos);
+ transformation.transformVect(pos);
+ video::S3DVertex vert;
+ vert.Color = 0xFFFFFFFF;
+ vert.Pos = pos;
+ mb->Vertices.push_back(vert);
+ }
+
+ // set vertex normals
+ for (i=0; i < vertexCount; ++i)
+ {
+ core::vector3df normal;
+ io::BinaryFile::read(file, normal);
+ transformation.rotateVect(normal);
+ mb->Vertices[firstVertex + i].Normal = normal;
+ }
+ // set texture coordinates
+
+ for (i=0; i < vertexCount; ++i)
+ {
+ core::vector2df tcoords;
+ io::BinaryFile::read(file, tcoords);
+ mb->Vertices[firstVertex + i].TCoords = tcoords;
+ }
+
+ // triangles
+ u32 triangleCount;
+ // vertexCount used as temporary
+ io::BinaryFile::read(file, vertexCount);
+ triangleCount=3*vertexCount;
+ mb->Indices.reallocate(mb->Indices.size() + triangleCount);
+
+ for (i=0; i < triangleCount; ++i)
+ {
+ u16 index;
+ io::BinaryFile::read(file, index);
+ mb->Indices.push_back(firstVertex + index);
+ }
+
+ // read limbs
+ s32 limbCount;
+ io::BinaryFile::read(file, limbCount);
+
+ for (s32 l=0; l < limbCount; ++l)
+ loadLimb(file, mesh, transformation);
+}
+
+} // namespace scene
+
+// todo: at some point in the future let's move these to a place where everyone can use them.
+namespace io
+{
+
+#if _BIGENDIAN
+#define _SYSTEM_BIG_ENDIAN_ (true)
+#else
+#define _SYSTEM_BIG_ENDIAN_ (false)
+#endif
+
+template <class T>
+void BinaryFile::read(io::IReadFile* file, T &out, bool bigEndian)
+{
+ file->read((void*)&out, sizeof(out));
+ if (bigEndian != (_SYSTEM_BIG_ENDIAN_))
+ out = os::Byteswap::byteswap(out);
+}
+
+//! reads a 3d vector from the file, moving the file pointer along
+void BinaryFile::read(io::IReadFile* file, core::vector3df &outVector2d, bool bigEndian)
+{
+ BinaryFile::read(file, outVector2d.X, bigEndian);
+ BinaryFile::read(file, outVector2d.Y, bigEndian);
+ BinaryFile::read(file, outVector2d.Z, bigEndian);
+}
+
+//! reads a 2d vector from the file, moving the file pointer along
+void BinaryFile::read(io::IReadFile* file, core::vector2df &outVector2d, bool bigEndian)
+{
+ BinaryFile::read(file, outVector2d.X, bigEndian);
+ BinaryFile::read(file, outVector2d.Y, bigEndian);
+}
+
+//! reads a null terminated string from the file, moving the file pointer along
+void BinaryFile::read(io::IReadFile* file, core::stringc &outString, bool bigEndian)
+{
+ c8 c;
+ file->read((void*)&c, 1);
+
+ while (c)
+ {
+ outString += c;
+ file->read((void*)&c, 1);
+ }
+}
+
+} // namespace io
+
+} // namespace irr
+
+#endif // compile with SMF loader
+