From 393b5cd1dc438872af89d334ef6e5fcc59f27d47 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Sun, 13 Jan 2013 17:24:39 +1000 Subject: Added Irrlicht 1.8, but without all the Windows binaries. --- .../source/Irrlicht/CMY3DMeshFileLoader.cpp | 882 +++++++++++++++++++++ 1 file changed, 882 insertions(+) create mode 100644 libraries/irrlicht-1.8/source/Irrlicht/CMY3DMeshFileLoader.cpp (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CMY3DMeshFileLoader.cpp') diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CMY3DMeshFileLoader.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CMY3DMeshFileLoader.cpp new file mode 100644 index 0000000..7044721 --- /dev/null +++ b/libraries/irrlicht-1.8/source/Irrlicht/CMY3DMeshFileLoader.cpp @@ -0,0 +1,882 @@ +// 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 originally written by ZDimitor. + +//----------------------------------------------------------------------------- +// This tool created by ZDimitor everyone can use it as wants +//----------------------------------------------------------------------------- + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_MY3D_LOADER_ + +#include "CMY3DMeshFileLoader.h" + +#include "SAnimatedMesh.h" +#include "SMeshBuffer.h" +#include "IReadFile.h" +#include "IAttributes.h" + +#include "CMY3DHelper.h" +#include "os.h" + +// v3.15 - May 16, 2005 + +namespace irr +{ +namespace scene +{ + +static const u32 MY3D_ID = 0x4d593344; +static const u16 MY3D_VER = 0x0003; +static const u16 MY3D_SCENE_HEADER_ID = 0x1000; +static const u16 MY3D_MAT_LIST_ID = 0x2000; +static const u16 MY3D_MAT_HEADER_ID = 0x2100; +static const u16 MY3D_TEX_FNAME_ID = 0x2101; +static const u16 MY3D_TEXDATA_HEADER_ID = 0x2501; +static const u16 MY3D_TEXDATA_RLE_HEADER_ID = 0x2502; +static const u16 MY3D_MESH_LIST_ID = 0x3000; +static const u16 MY3D_MESH_HEADER_ID = 0x3100; +static const u16 MY3D_VERTS_ID = 0x3101; +static const u16 MY3D_FACES_ID = 0x3102; +static const u16 MY3D_TVERTS_ID = 0x3103; +static const u16 MY3D_TFACES_ID = 0x3104; +static const u16 MY3D_FILE_END_ID = 0xFFFF; + +static const unsigned long MY3D_TEXDATA_COMPR_NONE_ID = 0x4e4f4e45; +static const unsigned long MY3D_TEXDATA_COMPR_SIMPLE_ID = 0x53494d50; +static const unsigned long MY3D_TEXDATA_COMPR_RLE_ID = 0x20524c45; + +static const unsigned long MY3D_PIXEL_FORMAT_24 = 0x5f32345f; +static const unsigned long MY3D_PIXEL_FORMAT_16 = 0x5f31365f; + +CMY3DMeshFileLoader::CMY3DMeshFileLoader(ISceneManager* scmgr, io::IFileSystem* fs) + : SceneManager(scmgr), FileSystem(fs) +{ + #ifdef _DEBUG + setDebugName("CMY3DMeshFileLoader"); + #endif + + if (FileSystem) + FileSystem->grab(); +} + + +CMY3DMeshFileLoader::~CMY3DMeshFileLoader() +{ + if (FileSystem) + FileSystem->drop(); +} + + +bool CMY3DMeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "my3d" ); +} + + +IAnimatedMesh* CMY3DMeshFileLoader::createMesh(io::IReadFile* file) +{ + MaterialEntry.clear(); + MeshBufferEntry.clear(); + ChildNodes.clear(); + + // working directory (from which we load the scene) + core::stringc filepath = FileSystem->getFileDir(file->getFileName()); + if (filepath==".") + filepath=""; + else + filepath.append("/"); + + // read file into memory + SMyFileHeader fileHeader; + file->read(&fileHeader, sizeof(SMyFileHeader)); +#ifdef __BIG_ENDIAN__ + fileHeader.MyId = os::Byteswap::byteswap(fileHeader.MyId); + fileHeader.Ver = os::Byteswap::byteswap(fileHeader.Ver); +#endif + + if (fileHeader.MyId!=MY3D_ID || fileHeader.Ver!=MY3D_VER) + { + os::Printer::log("Bad MY3D file header, loading failed!", ELL_ERROR); + return 0; + } + + u16 id; + + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + + if (id!=MY3D_SCENE_HEADER_ID) + { + os::Printer::log("Cannot find MY3D_SCENE_HEADER_ID, loading failed!", ELL_ERROR); + return 0; + } + + SMySceneHeader sceneHeader; + file->read(&sceneHeader, sizeof(SMySceneHeader)); +#ifdef __BIG_ENDIAN__ + sceneHeader.MaterialCount = os::Byteswap::byteswap(sceneHeader.MaterialCount); + sceneHeader.MeshCount = os::Byteswap::byteswap(sceneHeader.MeshCount); +#endif + + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + + if (id!=MY3D_MAT_LIST_ID) + { + os::Printer::log("Can not find MY3D_MAT_LIST_ID, loading failed!", ELL_ERROR); + return 0; + } + + core::stringc texturePath = + SceneManager->getParameters()->getAttributeAsString(MY3D_TEXTURE_PATH); + + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + + c8 namebuf[256]; + for (s32 m=0; mread(&(me.Header), sizeof(SMyMaterialHeader)); + + // read next identificator + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + + bool gotLightMap=false, gotMainMap=false; + + for (u32 t=0; tread(namebuf, 256); + else + { + me.Texture2 = readEmbeddedLightmap(file, namebuf); + if (!me.Texture2) + return 0; + gotLightMap = true; + } + + const core::stringc name(namebuf); + const s32 pos = name.findLast('.'); + const core::stringc LightingMapStr = "LightingMap"; + const s32 ls = LightingMapStr.size(); + const bool isSubString = (LightingMapStr == name.subString(core::max_(0, (pos - ls)), ls)); + if ((isSubString || (name[pos-1]=='m' && + name[pos-2]=='l' && name[pos-3]=='_')) && + !gotLightMap) + { + const bool oldMipMapState = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); + + me.Texture2FileName = texturePath.size() ? texturePath : filepath; + me.Texture2FileName.append("Lightmaps/"); + me.Texture2FileName.append(name); + + if (name.size()) + me.Texture2 = SceneManager->getVideoDriver()->getTexture(me.Texture2FileName); + + me.MaterialType = video::EMT_LIGHTMAP_M2; + gotLightMap = true; + + SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState); + } + else + if (!gotLightMap && gotMainMap) + { + me.Texture2FileName = texturePath.size() ? texturePath : filepath; + me.Texture2FileName.append(name); + + if (name.size()) + me.Texture2 = SceneManager->getVideoDriver()->getTexture(me.Texture2FileName); + + me.MaterialType = video::EMT_REFLECTION_2_LAYER; + } + else + if (!gotMainMap && !gotLightMap) + { + me.Texture1FileName = filepath; + me.Texture1FileName.append(name); + if (name.size()) + me.Texture1 = SceneManager->getVideoDriver()->getTexture(me.Texture1FileName); + + gotMainMap = true; + me.MaterialType = video::EMT_SOLID; + } + else + if (gotLightMap) + { + me.MaterialType = video::EMT_LIGHTMAP_M2; + } + + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + } + + // override material types based on their names + if (!strncmp(me.Header.Name, "AlphaChannel-", 13)) + me.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + else + if (!strncmp(me.Header.Name, "SphereMap-", 10)) + me.MaterialType = video::EMT_SPHERE_MAP; + } + + // loading meshes + + if (id!=MY3D_MESH_LIST_ID) + { + os::Printer::log("Can not find MY3D_MESH_LIST_ID, loading failed!", ELL_ERROR); + return 0; + } + + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + + for (s32 mesh_id=0; mesh_idread(&meshHeader, sizeof(SMyMeshHeader)); + + core::array Vertex; + core::array Face; + core::array TVertex1, TVertex2; + core::array TFace1, TFace2; + + s32 vertsNum=0; + s32 facesNum=0; + + // vertices + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + if (id!=MY3D_VERTS_ID) + { + os::Printer::log("Can not find MY3D_VERTS_ID, loading failed!", ELL_ERROR); + return 0; + } + + file->read(&vertsNum, sizeof(vertsNum)); + Vertex.set_used(vertsNum); + file->read(Vertex.pointer(), sizeof(SMyVertex)*vertsNum); + + // faces + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + if (id!=MY3D_FACES_ID) + { + os::Printer::log("Can not find MY3D_FACES_ID, loading failed!", ELL_ERROR); + return 0; + } + + file->read(&facesNum, sizeof(facesNum)); + Face.set_used(facesNum); + file->read(Face.pointer(), sizeof(SMyFace)*facesNum); + + // reading texture channels + for (s32 tex=0; tex<(s32)meshHeader.TChannelCnt; tex++) + { + // Max 2 texture channels allowed (but in format .my3d can be more) + s32 tVertsNum=0, tFacesNum=0; + + // reading texture coords + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + + if (id!=MY3D_TVERTS_ID) + { + core::stringc msg="Can not find MY3D_TVERTS_ID ("; + msg.append(core::stringc(tex)); + msg.append("texture channel), loading failed!"); + os::Printer::log(msg.c_str(), ELL_ERROR); + return 0; + } + + file->read(&tVertsNum, sizeof(tVertsNum)); + + if (tex==0) + { + // 1st texture channel + TVertex1.set_used(tVertsNum); + file->read(TVertex1.pointer(), sizeof(SMyTVertex)*tVertsNum); + } + else + if (tex==1) + { + // 2nd texture channel + TVertex2.set_used(tVertsNum); + file->read(TVertex2.pointer(), sizeof(SMyTVertex)*tVertsNum); + } + else + { + // skip other texture channels + file->seek(file->getPos()+sizeof(SMyTVertex)*tVertsNum); + } + + // reading texture faces + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + + if (id!=MY3D_TFACES_ID) + { + core::stringc msg="Can not find MY3D_TFACES_ID ("; + msg.append(core::stringc(tex)); + msg.append("texture channel), loading failed!"); + os::Printer::log(msg.c_str(), ELL_ERROR); + return 0; + } + + file->read(&tFacesNum, sizeof(tFacesNum)); + + if (tex==0) + { + // 1st texture channel + TFace1.set_used(tFacesNum); + file->read(TFace1.pointer(), sizeof(SMyFace)*tFacesNum); + } + else if (tex==1) + { + // 2nd texture channel + TFace2.set_used(tFacesNum); + file->read(TFace2.pointer(), sizeof(SMyFace)*tFacesNum); + } + else + { + // skip other texture channels + file->seek(file->getPos()+sizeof(SMyFace)*tFacesNum); + } + } + + // trying to find material + + SMyMaterialEntry* matEnt = getMaterialEntryByIndex(meshHeader.MatIndex); + + // creating geometry for the mesh + + // trying to find mesh buffer for this material + SMeshBufferLightMap* buffer = getMeshBufferByMaterialIndex(meshHeader.MatIndex); + + if (!buffer || + (buffer->Vertices.size()+vertsNum) > SceneManager->getVideoDriver()->getMaximalPrimitiveCount()) + { + // creating new mesh buffer for this material + buffer = new scene::SMeshBufferLightMap(); + + buffer->Material.MaterialType = video::EMT_LIGHTMAP_M2; // EMT_LIGHTMAP_M4 also possible + buffer->Material.Wireframe = false; + buffer->Material.Lighting = false; + + if (matEnt) + { + buffer->Material.MaterialType = matEnt->MaterialType; + + if (buffer->Material.MaterialType == video::EMT_REFLECTION_2_LAYER) + { + buffer->Material.Lighting = true; + buffer->Material.setTexture(1, matEnt->Texture1); + buffer->Material.setTexture(0, matEnt->Texture2); + } + else + { + buffer->Material.setTexture(0, matEnt->Texture1); + buffer->Material.setTexture(1, matEnt->Texture2); + } + + if (buffer->Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL) + { + buffer->Material.BackfaceCulling = true; + buffer->Material.Lighting = true; + } + else + if (buffer->Material.MaterialType == video::EMT_SPHERE_MAP) + { + buffer->Material.Lighting = true; + } + + buffer->Material.AmbientColor = video::SColor( + matEnt->Header.AmbientColor.A, matEnt->Header.AmbientColor.R, + matEnt->Header.AmbientColor.G, matEnt->Header.AmbientColor.B + ); + buffer->Material.DiffuseColor = video::SColor( + matEnt->Header.DiffuseColor.A, matEnt->Header.DiffuseColor.R, + matEnt->Header.DiffuseColor.G, matEnt->Header.DiffuseColor.B + ); + buffer->Material.EmissiveColor = video::SColor( + matEnt->Header.EmissiveColor.A, matEnt->Header.EmissiveColor.R, + matEnt->Header.EmissiveColor.G, matEnt->Header.EmissiveColor.B + ); + buffer->Material.SpecularColor = video::SColor( + matEnt->Header.SpecularColor.A, matEnt->Header.SpecularColor.R, + matEnt->Header.SpecularColor.G, matEnt->Header.SpecularColor.B + ); + } + else + { + buffer->Material.setTexture(0, 0); + buffer->Material.setTexture(1, 0); + + buffer->Material.AmbientColor = video::SColor(255, 255, 255, 255); + buffer->Material.DiffuseColor = video::SColor(255, 255, 255, 255); + buffer->Material.EmissiveColor = video::SColor(0, 0, 0, 0); + buffer->Material.SpecularColor = video::SColor(0, 0, 0, 0); + } + + if (matEnt && matEnt->Header.Transparency!=0) + { + if (buffer->Material.MaterialType == video::EMT_REFLECTION_2_LAYER ) + { + buffer->Material.MaterialType = video::EMT_TRANSPARENT_REFLECTION_2_LAYER; + buffer->Material.Lighting = true; + buffer->Material.BackfaceCulling = true; + } + else + { + buffer->Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + buffer->Material.Lighting = false; + buffer->Material.BackfaceCulling = false; + } + } + else if ( + !buffer->Material.getTexture(1) && + buffer->Material.MaterialType != video::EMT_TRANSPARENT_ALPHA_CHANNEL && + buffer->Material.MaterialType != video::EMT_SPHERE_MAP) + { + buffer->Material.MaterialType = video::EMT_SOLID; + buffer->Material.Lighting = true; + } + + MeshBufferEntry.push_back( + SMyMeshBufferEntry(meshHeader.MatIndex, buffer)); + } + + video::S3DVertex2TCoords VertexA, VertexB, VertexC; + + // vertices (A, B, C) color + video::SColor vert_color; + if (matEnt && + (buffer->Material.MaterialType == video::EMT_TRANSPARENT_VERTEX_ALPHA || + buffer->Material.MaterialType == video::EMT_TRANSPARENT_REFLECTION_2_LAYER)) + { + video::SColor color( + matEnt->Header.DiffuseColor.A, matEnt->Header.DiffuseColor.R, + matEnt->Header.DiffuseColor.G, matEnt->Header.DiffuseColor.B); + + vert_color = color.getInterpolated(video::SColor(0,0,0,0), + 1-matEnt->Header.Transparency); + } + else + { + vert_color = buffer->Material.DiffuseColor; + } + + VertexA.Color = VertexB.Color = VertexC.Color = vert_color; + + if (buffer->Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL) + { + buffer->Indices.reallocate(buffer->Indices.size()+6*facesNum); + buffer->Vertices.reallocate(buffer->Vertices.size()+6*facesNum); + } + else + { + buffer->Indices.reallocate(buffer->Indices.size()+3*facesNum); + buffer->Vertices.reallocate(buffer->Vertices.size()+3*facesNum); + } + for (int f=0; f0) + { + VertexA.TCoords.X = TVertex1[TFace1[f].C].TCoord.X; + VertexA.TCoords.Y = TVertex1[TFace1[f].C].TCoord.Y; + } + + if (meshHeader.TChannelCnt>1) + { + VertexA.TCoords2.X = TVertex2[TFace2[f].C].TCoord.X; + VertexA.TCoords2.Y = TVertex2[TFace2[f].C].TCoord.Y; + } + + // vertex B + + VertexB.Pos.X = Vertex[Face[f].B].Coord.X; + VertexB.Pos.Y = Vertex[Face[f].B].Coord.Y; + VertexB.Pos.Z = Vertex[Face[f].B].Coord.Z; + + VertexB.Normal.X = Vertex[Face[f].B].Normal.X; + VertexB.Normal.Y = Vertex[Face[f].B].Normal.Y; + VertexB.Normal.Z = Vertex[Face[f].B].Normal.Z; + + if (meshHeader.TChannelCnt>0) + { + VertexB.TCoords.X = TVertex1[TFace1[f].B].TCoord.X; + VertexB.TCoords.Y = TVertex1[TFace1[f].B].TCoord.Y; + } + + if (meshHeader.TChannelCnt>1) + { + VertexB.TCoords2.X = TVertex2[TFace2[f].B].TCoord.X; + VertexB.TCoords2.Y = TVertex2[TFace2[f].B].TCoord.Y; + } + + // vertex C + + VertexC.Pos.X = Vertex[Face[f].A].Coord.X; + VertexC.Pos.Y = Vertex[Face[f].A].Coord.Y; + VertexC.Pos.Z = Vertex[Face[f].A].Coord.Z; + + VertexC.Normal.X = Vertex[Face[f].A].Normal.X; + VertexC.Normal.Y = Vertex[Face[f].A].Normal.Y; + VertexC.Normal.Z = Vertex[Face[f].A].Normal.Z; + + if (meshHeader.TChannelCnt>0) + { + VertexC.TCoords.X = TVertex1[TFace1[f].A].TCoord.X; + VertexC.TCoords.Y = TVertex1[TFace1[f].A].TCoord.Y; + } + if (meshHeader.TChannelCnt>1) + { + VertexC.TCoords2.X = TVertex2[TFace2[f].A].TCoord.X; + VertexC.TCoords2.Y = TVertex2[TFace2[f].A].TCoord.Y; + } + + // store 3d data in mesh buffer + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexA); + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexB); + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexC); + + //***************************************************************** + // !!!!!! W A R N I N G !!!!!!! + //***************************************************************** + // For materials with alpha channel we duplicate all faces. + // This has be done for proper lighting calculation of the back faces. + // So you must remember this while you creating your models !!!!! + //***************************************************************** + // !!!!!! W A R N I N G !!!!!!! + //***************************************************************** + + if (buffer->Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL) + { + VertexA.Normal = core::vector3df(-VertexA.Normal.X, -VertexA.Normal.Y, -VertexA.Normal.Z); + VertexB.Normal = core::vector3df(-VertexB.Normal.X, -VertexB.Normal.Y, -VertexB.Normal.Z); + VertexC.Normal = core::vector3df(-VertexC.Normal.X, -VertexC.Normal.Y, -VertexC.Normal.Z); + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexC); + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexB); + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexA); + } + } + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + } + + // creating mesh + SMesh* mesh = new SMesh(); + + for (u32 num=0; numaddMeshBuffer(buffer); + + buffer->recalculateBoundingBox(); + buffer->drop(); + } + + mesh->recalculateBoundingBox(); + + if (id != MY3D_FILE_END_ID) + os::Printer::log("Loading finished, but can not find MY3D_FILE_END_ID token.", ELL_WARNING); + + SAnimatedMesh* am = new SAnimatedMesh(); + + am->addMesh(mesh); + mesh->drop(); + am->recalculateBoundingBox(); + + return am; +} + + +video::ITexture* CMY3DMeshFileLoader::readEmbeddedLightmap(io::IReadFile* file, char* namebuf) +{ + static int LightMapIndex=0; + u16 id; + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + if (id!=MY3D_TEXDATA_HEADER_ID) + { + os::Printer::log("Can not find MY3D_TEXDATA_HEADER_ID, loading failed!", ELL_ERROR); + return 0; + } + + SMyTexDataHeader texDataHeader; + + file->read(&texDataHeader, sizeof(SMyTexDataHeader)); + + strcpy(texDataHeader.Name, namebuf); + + char LightMapName[255]; + sprintf(LightMapName,"My3D.Lightmap.%d",++LightMapIndex); + + core::stringc pixFormatStr; + if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24) + pixFormatStr = "24bit,"; + else + if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_16) + pixFormatStr = "16bit,"; + else + { + core::stringc msg="Unknown format of image data ("; + msg.append(LightMapName); + msg.append("), loading failed!"); + os::Printer::log(msg.c_str(), ELL_ERROR); + return 0; + } + + if (texDataHeader.ComprMode != MY3D_TEXDATA_COMPR_NONE_ID && + texDataHeader.ComprMode != MY3D_TEXDATA_COMPR_RLE_ID && + texDataHeader.ComprMode != MY3D_TEXDATA_COMPR_SIMPLE_ID ) + { + os::Printer::log("Unknown method of compression image data, loading failed!", ELL_ERROR); + return 0; + } + + const u32 num_pixels = texDataHeader.Width*texDataHeader.Height; + + void* data = 0; + + if (texDataHeader.ComprMode==MY3D_TEXDATA_COMPR_NONE_ID) + { + // none compressed image data + if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24) + { + data = (void*) new SMyPixelColor24[num_pixels]; + file->read(data, sizeof(SMyPixelColor24)*num_pixels); + } + else + { + data = (void*) new SMyPixelColor16[num_pixels]; + file->read(data, sizeof(SMyPixelColor16)*num_pixels); + } + } + else + if (texDataHeader.ComprMode==MY3D_TEXDATA_COMPR_RLE_ID) + { + // read RLE header identificator + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + if (id!=MY3D_TEXDATA_RLE_HEADER_ID) + { + os::Printer::log("Can not find MY3D_TEXDATA_RLE_HEADER_ID, loading failed!", ELL_ERROR); + return 0; + } + + // read RLE header + SMyRLEHeader rleHeader; + file->read(&rleHeader, sizeof(SMyRLEHeader)); + + //allocate memory for input and output buffers + void *input_buffer = (void*) new unsigned char[rleHeader.nEncodedBytes]; + void *output_buffer = (void*) new unsigned char[rleHeader.nDecodedBytes]; + + // read encoded data + file->read(input_buffer, rleHeader.nEncodedBytes); + + // decode data + data = 0;//(void*) new unsigned char[rleHeader.nDecodedBytes]; + s32 decodedBytes = core::rle_decode( + (unsigned char*)input_buffer, rleHeader.nEncodedBytes, + (unsigned char*)output_buffer, rleHeader.nDecodedBytes); + + if (decodedBytes!=(s32)rleHeader.nDecodedBytes) + { + os::Printer::log("Error extracting data from RLE compression, loading failed!", ELL_ERROR); + return 0; + } + + // free input buffer + delete [] (unsigned char*)input_buffer; + + // here decoded data + data = output_buffer; + } + else if (texDataHeader.ComprMode==MY3D_TEXDATA_COMPR_SIMPLE_ID) + { + // simple compressed image data + if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24) + data = (void*) new SMyPixelColor24[num_pixels]; + else + data = (void*) new SMyPixelColor16[num_pixels]; + + u32 nReadedPixels=0, nToRead=0; + while (true) + { + file->read(&nToRead, sizeof(nToRead)); + + if ((nReadedPixels+nToRead) > num_pixels) + break; + + if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24) + { + SMyPixelColor24 col24; + file->read(&col24, sizeof(SMyPixelColor24)); + for (u32 p=0; pread(&col16, sizeof(SMyPixelColor16)); + for (u32 p=0; p= num_pixels) + break; + } + + if (nReadedPixels != num_pixels) + { + os::Printer::log("Image data seems to be corrupted, loading failed!", ELL_ERROR); + return 0; + } + } + + //! Creates a software image from a byte array. + video::IImage* light_img = 0; + + if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24) + { + // 24 bit lightmap format + light_img = SceneManager->getVideoDriver()->createImageFromData( + video::ECF_R8G8B8, + core::dimension2d(texDataHeader.Width, texDataHeader.Height), + data, true); + } + else + { + // 16 bit lightmap format + light_img = SceneManager->getVideoDriver()->createImageFromData( + video::ECF_A1R5G5B5, + core::dimension2d(texDataHeader.Width, texDataHeader.Height), + data, true); + } + + const bool oldMipMapState = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); + video::ITexture* lmtex = SceneManager->getVideoDriver()->addTexture(LightMapName, light_img); + SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState); + + light_img->drop(); + return lmtex; +} + + +CMY3DMeshFileLoader::SMyMaterialEntry* CMY3DMeshFileLoader::getMaterialEntryByIndex(u32 matInd) +{ + for (u32 m=0; m& CMY3DMeshFileLoader::getChildNodes() const +{ + return ChildNodes; +} + + +} // end namespace scnene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_MY3D_LOADER_ + -- cgit v1.1