diff options
author | cutealien <cutealien@dfc29bdd-3216-0410-991c-e03cc46cb475> | 2020-01-03 19:05:16 +0000 |
---|---|---|
committer | cutealien <cutealien@dfc29bdd-3216-0410-991c-e03cc46cb475> | 2020-01-03 19:05:16 +0000 |
commit | 2ae2a551a6290f46734307bbfdafea4b1a2cf2ba (patch) | |
tree | ba2f0b468640e44899fed3df2d4cc58795f4a003 /source/Irrlicht/CLMTSMeshFileLoader.cpp | |
download | irrlicht-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/CLMTSMeshFileLoader.cpp')
-rw-r--r-- | source/Irrlicht/CLMTSMeshFileLoader.cpp | 380 |
1 files changed, 380 insertions, 0 deletions
diff --git a/source/Irrlicht/CLMTSMeshFileLoader.cpp b/source/Irrlicht/CLMTSMeshFileLoader.cpp new file mode 100644 index 0000000..b972ec5 --- /dev/null +++ b/source/Irrlicht/CLMTSMeshFileLoader.cpp @@ -0,0 +1,380 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt
+// This file is part of the "Irrlicht Engine".
+// For conditions of distribution and use, see copyright notice in irrlicht.h
+// This file was written by Jonas Petersen and modified by Nikolaus Gebhardt.
+// See CLMTSMeshFileLoder.h for details.
+/*
+
+CLMTSMeshFileLoader.cpp
+
+LMTSMeshFileLoader
+Written by Jonas Petersen (a.k.a. jox)
+
+Version 1.5 - 15 March 2005
+
+Get the latest version here: http://development.mindfloaters.de/
+
+This class allows loading meshes with lightmaps (*.lmts + *.tga files) that were created
+using Pulsar LMTools by Lord Trancos (http://www.geocities.com/dxlab/index_en.html)
+
+Notes:
+- This version does not support user data in the *.lmts files, but still loads those files (by skipping the extra data).
+
+License:
+--------
+
+It's free. You are encouraged to give me credit if you use it in your software.
+
+Version History:
+----------------
+
+Version 1.5 - 15 March 2005
+- Did a better cleanup. No memory leaks in case of an loading error.
+- Added "#include <stdio.h>" for sprintf.
+
+Version 1.4 - 12 March 2005
+- Fixed bug in texture and subset loading code that would possibly cause crash.
+- Fixed memory cleanup to avoid leak when loading more then one mesh
+- Used the irrlicht Logger instead of cerr to output warnings and errors.
+ For this I had to change the constructor
+ from:
+ CLMTSMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver)
+ to:
+ CLMTSMeshFileLoader(IrrlichtDevice* device)
+
+Version 1.3 - 15 February 2005
+- Fixed bug that prevented loading more than one different lmts files.
+- Removed unnecessary "#include <os.h>".
+- Added "std::" in front of "cerr". This was necessary for Visual Studio .NET,
+ I hope it's not disturbing other compilers.
+- Added warning message when a texture can not be loaded.
+- Changed the documentation a bit (minor).
+
+Version 1.2
+- To avoid confusion I skipped version 1.2 because the website was offering
+version 1.2 even though it was only version 1.1. Sorry about that.
+
+Version 1.1 - 29 July 2004
+- Added setTexturePath() function
+- Minor improvements
+
+Version 1.0 - 29 July 2004
+- Initial release
+
+
+*/
+//////////////////////////////////////////////////////////////////////
+
+#include "IrrCompileConfig.h"
+#ifdef _IRR_COMPILE_WITH_LMTS_LOADER_
+
+#include "CLMTSMeshFileLoader.h"
+#include "CMeshTextureLoader.h"
+#include "SMeshBufferLightMap.h"
+#include "SAnimatedMesh.h"
+#include "SMeshBuffer.h"
+#include "irrString.h"
+#include "IReadFile.h"
+#include "IAttributes.h"
+#include "ISceneManager.h"
+#include "os.h"
+
+namespace irr
+{
+namespace scene
+{
+
+CLMTSMeshFileLoader::CLMTSMeshFileLoader(io::IFileSystem* fs,
+ video::IVideoDriver* driver, io::IAttributes* parameters)
+ : Textures(0), Subsets(0), Triangles(0),
+ Parameters(parameters), Driver(driver), FileSystem(fs), FlipEndianess(false)
+{
+ #ifdef _DEBUG
+ setDebugName("CLMTSMeshFileLoader");
+ #endif
+
+ if (Driver)
+ Driver->grab();
+
+ if (FileSystem)
+ FileSystem->grab();
+
+ TextureLoader = new CMeshTextureLoader( FileSystem, Driver );
+}
+
+
+CLMTSMeshFileLoader::~CLMTSMeshFileLoader()
+{
+ cleanup();
+
+ if (Driver)
+ Driver->drop();
+
+ if (FileSystem)
+ FileSystem->drop();
+}
+
+
+void CLMTSMeshFileLoader::cleanup()
+{
+ delete [] Textures;
+ Textures = 0;
+ delete [] Subsets;
+ Subsets = 0;
+ delete [] Triangles;
+ Triangles = 0;
+}
+
+
+bool CLMTSMeshFileLoader::isALoadableFileExtension(const io::path& filename) const
+{
+ return core::hasFileExtension ( filename, "lmts" );
+}
+
+
+IAnimatedMesh* CLMTSMeshFileLoader::createMesh(io::IReadFile* file)
+{
+ if ( getMeshTextureLoader() )
+ getMeshTextureLoader()->setMeshFile(file);
+
+ u32 i;
+ u32 id;
+
+ // HEADER
+
+ file->read(&Header, sizeof(SLMTSHeader));
+ if (Header.MagicID == 0x4C4D5354)
+ {
+ FlipEndianess = true;
+ Header.MagicID = os::Byteswap::byteswap(Header.MagicID);
+ Header.Version = os::Byteswap::byteswap(Header.Version);
+ Header.HeaderSize = os::Byteswap::byteswap(Header.HeaderSize);
+ Header.TextureCount = os::Byteswap::byteswap(Header.TextureCount);
+ Header.SubsetCount = os::Byteswap::byteswap(Header.SubsetCount);
+ Header.TriangleCount = os::Byteswap::byteswap(Header.TriangleCount);
+ Header.SubsetSize = os::Byteswap::byteswap(Header.SubsetSize);
+ Header.VertexSize = os::Byteswap::byteswap(Header.VertexSize);
+ }
+ if (Header.MagicID != 0x53544D4C) { // "LMTS"
+ os::Printer::log("LMTS ERROR: wrong header magic id!", ELL_ERROR);
+ return 0;
+ }
+
+ //Skip any User Data (arbitrary app specific data)
+
+ const s32 userSize = Header.HeaderSize - sizeof(SLMTSHeader);
+ if (userSize>0)
+ file->seek(userSize,true);
+
+ // TEXTURES
+
+ file->read(&id, sizeof(u32));
+ if (FlipEndianess)
+ id = os::Byteswap::byteswap(id);
+ if (id != 0x54584554) { // "TEXT"
+ os::Printer::log("LMTS ERROR: wrong texture magic id!", ELL_ERROR);
+ return 0;
+ }
+
+ Textures = new SLMTSTextureInfoEntry[Header.TextureCount];
+
+ file->read(Textures, sizeof(SLMTSTextureInfoEntry)*Header.TextureCount);
+ if (FlipEndianess)
+ {
+ for (i=0; i<Header.TextureCount; ++i)
+ Textures[i].Flags = os::Byteswap::byteswap(Textures[i].Flags);
+ }
+
+ // SUBSETS
+
+ file->read(&id, sizeof(u32));
+ if (FlipEndianess)
+ id = os::Byteswap::byteswap(id);
+ if (id != 0x53425553) // "SUBS"
+ {
+ os::Printer::log("LMTS ERROR: wrong subset magic id!", ELL_ERROR);
+ cleanup();
+ return 0;
+ }
+
+ Subsets = new SLMTSSubsetInfoEntry[Header.SubsetCount];
+ const s32 subsetUserSize = Header.SubsetSize - sizeof(SLMTSSubsetInfoEntry);
+
+ for (i=0; i<Header.SubsetCount; ++i)
+ {
+ file->read(&Subsets[i], sizeof(SLMTSSubsetInfoEntry));
+ if (FlipEndianess)
+ {
+ Subsets[i].Offset = os::Byteswap::byteswap(Subsets[i].Offset);
+ Subsets[i].Count = os::Byteswap::byteswap(Subsets[i].Count);
+ Subsets[i].TextID1 = os::Byteswap::byteswap(Subsets[i].TextID1);
+ Subsets[i].TextID2 = os::Byteswap::byteswap(Subsets[i].TextID2);
+ }
+ if (subsetUserSize>0)
+ file->seek(subsetUserSize,true);
+ }
+
+ // TRIANGLES
+
+ file->read(&id, sizeof(u32));
+ if (FlipEndianess)
+ id = os::Byteswap::byteswap(id);
+ if (id != 0x53495254) // "TRIS"
+ {
+ os::Printer::log("LMTS ERROR: wrong triangle magic id!", ELL_ERROR);
+ cleanup();
+ return 0;
+ }
+
+ Triangles = new SLMTSTriangleDataEntry[(Header.TriangleCount*3)];
+ const s32 triUserSize = Header.VertexSize - sizeof(SLMTSTriangleDataEntry);
+
+ for (i=0; i<(Header.TriangleCount*3); ++i)
+ {
+ file->read(&Triangles[i], sizeof(SLMTSTriangleDataEntry));
+ if (FlipEndianess)
+ {
+ Triangles[i].X = os::Byteswap::byteswap(Triangles[i].X);
+ Triangles[i].Y = os::Byteswap::byteswap(Triangles[i].Y);
+ Triangles[i].Z = os::Byteswap::byteswap(Triangles[i].Z);
+ Triangles[i].U1 = os::Byteswap::byteswap(Triangles[i].U1);
+ Triangles[i].V1 = os::Byteswap::byteswap(Triangles[i].U2);
+ Triangles[i].U2 = os::Byteswap::byteswap(Triangles[i].V1);
+ Triangles[i].V2 = os::Byteswap::byteswap(Triangles[i].V2);
+ }
+ if (triUserSize>0)
+ file->seek(triUserSize,true);
+ }
+
+ /////////////////////////////////////////////////////////////////
+
+ SMesh* mesh = new SMesh();
+
+ constructMesh(mesh);
+
+ loadTextures(mesh);
+
+ cleanup();
+
+ SAnimatedMesh* am = new SAnimatedMesh();
+ am->Type = EAMT_LMTS; // not unknown to irrlicht anymore
+
+ am->addMesh(mesh);
+ am->recalculateBoundingBox();
+ mesh->drop();
+ return am;
+}
+
+
+void CLMTSMeshFileLoader::constructMesh(SMesh* mesh)
+{
+ for (s32 i=0; i<Header.SubsetCount; ++i)
+ {
+ scene::SMeshBufferLightMap* meshBuffer = new scene::SMeshBufferLightMap();
+
+ // EMT_LIGHTMAP_M2/EMT_LIGHTMAP_M4 also possible
+ meshBuffer->Material.MaterialType = video::EMT_LIGHTMAP;
+ meshBuffer->Material.Wireframe = false;
+ meshBuffer->Material.Lighting = false;
+
+ mesh->addMeshBuffer(meshBuffer);
+
+ const u32 offs = Subsets[i].Offset * 3;
+
+ for (u32 sc=0; sc<Subsets[i].Count; sc++)
+ {
+ const u32 idx = meshBuffer->getVertexCount();
+
+ for (u32 vu=0; vu<3; ++vu)
+ {
+ const SLMTSTriangleDataEntry& v = Triangles[offs+(3*sc)+vu];
+ meshBuffer->Vertices.push_back(
+ video::S3DVertex2TCoords(
+ v.X, v.Y, v.Z,
+ video::SColor(255,255,255,255),
+ v.U1, v.V1, v.U2, v.V2));
+ }
+ const core::vector3df normal = core::plane3df(
+ meshBuffer->Vertices[idx].Pos,
+ meshBuffer->Vertices[idx+1].Pos,
+ meshBuffer->Vertices[idx+2].Pos).Normal;
+
+ meshBuffer->Vertices[idx].Normal = normal;
+ meshBuffer->Vertices[idx+1].Normal = normal;
+ meshBuffer->Vertices[idx+2].Normal = normal;
+
+ meshBuffer->Indices.push_back(idx);
+ meshBuffer->Indices.push_back(idx+1);
+ meshBuffer->Indices.push_back(idx+2);
+ }
+ meshBuffer->drop();
+ }
+
+ for (u32 j=0; j<mesh->MeshBuffers.size(); ++j)
+ mesh->MeshBuffers[j]->recalculateBoundingBox();
+
+ mesh->recalculateBoundingBox();
+}
+
+
+void CLMTSMeshFileLoader::loadTextures(SMesh* mesh)
+{
+ if (!Driver || !FileSystem)
+ return;
+
+ // load textures
+
+ // a little too much space, but won't matter here
+ core::array<video::ITexture*> tex;
+ tex.reallocate(Header.TextureCount);
+ core::array<video::ITexture*> lig;
+ lig.reallocate(Header.TextureCount);
+ core::array<u32> id2id;
+ id2id.reallocate(Header.TextureCount);
+
+ if ( getMeshTextureLoader() )
+ {
+ if ( Parameters->existsAttribute(LMTS_TEXTURE_PATH) )
+ getMeshTextureLoader()->setTexturePath(Parameters->getAttributeAsString(LMTS_TEXTURE_PATH));
+ }
+
+ core::stringc s;
+ for (u32 t=0; t<Header.TextureCount; ++t)
+ {
+ video::ITexture* tmptex = getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(Textures[t].Filename) : NULL;
+ if ( !tmptex )
+ {
+ os::Printer::log("LMTS WARNING: Texture does not exist", s.c_str(), ELL_WARNING);
+ }
+
+ if (Textures[t].Flags & 0x01)
+ {
+ id2id.push_back(lig.size());
+ lig.push_back(tmptex);
+ }
+ else
+ {
+ id2id.push_back(tex.size());
+ tex.push_back(tmptex);
+ }
+ }
+
+ // attach textures to materials.
+
+ for (u32 i=0; i<Header.SubsetCount; ++i)
+ {
+ if (Subsets[i].TextID1 < Header.TextureCount && id2id[Subsets[i].TextID1] < tex.size())
+ mesh->getMeshBuffer(i)->getMaterial().setTexture(0, tex[id2id[Subsets[i].TextID1]]);
+ if (Subsets[i].TextID2 < Header.TextureCount && id2id[Subsets[i].TextID2] < lig.size())
+ mesh->getMeshBuffer(i)->getMaterial().setTexture(1, lig[id2id[Subsets[i].TextID2]]);
+
+ if (!mesh->getMeshBuffer(i)->getMaterial().getTexture(1))
+ mesh->getMeshBuffer(i)->getMaterial().MaterialType = video::EMT_SOLID;
+ }
+}
+
+
+} // end namespace scene
+} // end namespace irr
+
+#endif // _IRR_COMPILE_WITH_LMTS_LOADER_
|