From 959831f4ef5a3e797f576c3de08cd65032c997ad Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Sun, 13 Jan 2013 18:54:10 +1000 Subject: Remove damned ancient DOS line endings from Irrlicht. Hopefully I did not go overboard. --- .../source/Irrlicht/CLWOMeshFileLoader.cpp | 4228 ++++++++++---------- 1 file changed, 2114 insertions(+), 2114 deletions(-) (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CLWOMeshFileLoader.cpp') diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CLWOMeshFileLoader.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CLWOMeshFileLoader.cpp index 6534727..237b38f 100644 --- a/libraries/irrlicht-1.8/source/Irrlicht/CLWOMeshFileLoader.cpp +++ b/libraries/irrlicht-1.8/source/Irrlicht/CLWOMeshFileLoader.cpp @@ -1,2114 +1,2114 @@ -// Copyright (C) 2007-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#include "CLWOMeshFileLoader.h" -#include "os.h" -#include "SAnimatedMesh.h" -#include "SMesh.h" -#include "IReadFile.h" -#include "ISceneManager.h" -#include "IFileSystem.h" -#include "IVideoDriver.h" -#include "IMeshManipulator.h" - -namespace irr -{ -namespace scene -{ - -#ifdef _DEBUG -#define LWO_READER_DEBUG -#endif - -#define charsToUIntD(a, b, c, d) ((a << 24) | (b << 16) | (c << 8) | d) -inline unsigned int charsToUInt(const char *str) -{ - return (str[0] << 24) | (str[1] << 16) | (str[2] << 8) | str[3]; -} - - -struct tLWOTextureInfo -{ - tLWOTextureInfo() : UVTag(0), DUVTag(0), Flags(0), WidthWrap(2), - HeightWrap(2), OpacType(0), Color(0xffffffff), - Value(0.0f), AntiAliasing(1.0f), Opacity(1.0f), - Axis(255), Projection(0), Active(false) {} - core::stringc Type; - core::stringc Map; - core::stringc AlphaMap; - core::stringc UVname; - u16 UVTag; - u16 DUVTag; - u16 Flags; - u16 WidthWrap; - u16 HeightWrap; - u16 OpacType; - u16 IParam[3]; - core::vector3df Size; - core::vector3df Center; - core::vector3df Falloff; - core::vector3df Velocity; - video::SColor Color; - f32 Value; - f32 AntiAliasing; - f32 Opacity; - f32 FParam[3]; - u8 Axis; - u8 Projection; - bool Active; -}; - -struct CLWOMeshFileLoader::tLWOMaterial -{ - tLWOMaterial() : Meshbuffer(0), TagType(0), Flags(0), ReflMode(3), TranspMode(3), - Glow(0), AlphaMode(2), Luminance(0.0f), Diffuse(1.0f), Specular(0.0f), - Reflection(0.0f), Transparency(0.0f), Translucency(0.0f), - Sharpness(0.0f), ReflSeamAngle(0.0f), ReflBlur(0.0f), - RefrIndex(1.0f), TranspBlur(0.0f), SmoothingAngle(0.0f), - EdgeTransparency(0.0f), HighlightColor(0.0f), ColorFilter(0.0f), - AdditiveTransparency(0.0f), GlowIntensity(0.0f), GlowSize(0.0f), - AlphaValue(0.0f), VertexColorIntensity(0.0f), VertexColor() {} - - core::stringc Name; - scene::SMeshBuffer *Meshbuffer; - core::stringc ReflMap; - u16 TagType; - u16 Flags; - u16 ReflMode; - u16 TranspMode; - u16 Glow; - u16 AlphaMode; - f32 Luminance; - f32 Diffuse; - f32 Specular; - f32 Reflection; - f32 Transparency; - f32 Translucency; - f32 Sharpness; - f32 ReflSeamAngle; - f32 ReflBlur; - f32 RefrIndex; - f32 TranspBlur; - f32 SmoothingAngle; - f32 EdgeTransparency; - f32 HighlightColor; - f32 ColorFilter; - f32 AdditiveTransparency; - f32 GlowIntensity; - f32 GlowSize; - f32 AlphaValue; - f32 VertexColorIntensity; - video::SColorf VertexColor; - u32 Envelope[23]; - tLWOTextureInfo Texture[7]; -}; - -struct tLWOLayerInfo -{ - u16 Number; - u16 Parent; - u16 Flags; - bool Active; - core::stringc Name; - core::vector3df Pivot; -}; - - -//! Constructor -CLWOMeshFileLoader::CLWOMeshFileLoader(scene::ISceneManager* smgr, - io::IFileSystem* fs) -: SceneManager(smgr), FileSystem(fs), File(0), Mesh(0) -{ - #ifdef _DEBUG - setDebugName("CLWOMeshFileLoader"); - #endif -} - - -//! destructor -CLWOMeshFileLoader::~CLWOMeshFileLoader() -{ - if (Mesh) - Mesh->drop(); -} - - -//! returns true if the file maybe is able to be loaded by this class -//! based on the file extension (e.g. ".bsp") -bool CLWOMeshFileLoader::isALoadableFileExtension(const io::path& filename) const -{ - return core::hasFileExtension(filename, "lwo"); -} - - -//! creates/loads an animated mesh from the file. -IAnimatedMesh* CLWOMeshFileLoader::createMesh(io::IReadFile* file) -{ - File = file; - - if (Mesh) - Mesh->drop(); - - Mesh = new SMesh(); - - if (!readFileHeader()) - return 0; - - if (!readChunks()) - return 0; - -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: Creating geometry."); - os::Printer::log("LWO loader: Assigning UV maps."); -#endif - u32 i; - for (i=0; iTexture[j].UVname.size()) - { - for (uvTag=0; uvTagTexture[j].UVname == UvName[uvTag]) - { - Materials[i]->Texture[j].UVTag=uvTag; - break; - } - } - for (uvTag=0; uvTagTexture[j].UVname == DUvName[uvTag]) - { - Materials[i]->Texture[j].DUVTag=uvTag; - break; - } - } - } - } - } -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: Creating polys."); -#endif - // create actual geometry for lwo2 - if (FormatVersion==2) - { - core::array vertexCount; - vertexCount.reallocate(Materials.size()); - for (i=0; iMeshbuffer->Vertices.reallocate(vertexCount[i]); - Materials[i]->Meshbuffer->Indices.reallocate(vertexCount[i]); - } - } - // create actual geometry for lwo2 - for (u32 polyIndex=0; polyIndexMeshbuffer; - const core::array& poly = Indices[polyIndex]; - const u32 polySize=poly.size(); - const u16 uvTag = Materials[tag]->Texture[0].UVTag; - const u16 duvTag = Materials[tag]->Texture[0].DUVTag; - video::S3DVertex vertex; - vertex.Color=0xffffffff; - const u32 vertCount=mb->Vertices.size(); - for (u32 i=0; iVertices.push_back(vertex); - } - // triangulate as trifan - if (polySize>2) - { - for (u32 i=1; iIndices.push_back(vertCount); - mb->Indices.push_back(vertCount+i); - mb->Indices.push_back(vertCount+i+1); - } - } - } -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: Fixing meshbuffers."); -#endif - for (u32 i=0; iName); - os::Printer::log("LWO loader: Vertex count", core::stringc(Materials[i]->Meshbuffer->Vertices.size())); -#endif - if (!Materials[i]->Meshbuffer->Vertices.size()) - { - Materials[i]->Meshbuffer->drop(); - delete Materials[i]; - continue; - } - for (u32 j=0; jMeshbuffer->Vertices.size(); ++j) - Materials[i]->Meshbuffer->Vertices[j].Color=Materials[i]->Meshbuffer->Material.DiffuseColor; - Materials[i]->Meshbuffer->recalculateBoundingBox(); - - // load textures - video::SMaterial& irrMat=Materials[i]->Meshbuffer->Material; - if (Materials[i]->Texture[0].Map != "") // diffuse - irrMat.setTexture(0,loadTexture(Materials[i]->Texture[0].Map)); - if (Materials[i]->Texture[3].Map != "") // reflection - { -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading reflection texture."); -#endif - video::ITexture* reflTexture = loadTexture(Materials[i]->Texture[3].Map); - if (reflTexture && irrMat.getTexture(0)) - irrMat.setTexture(1, irrMat.getTexture(0)); - irrMat.setTexture(0, reflTexture); - irrMat.MaterialType=video::EMT_REFLECTION_2_LAYER; - } - if (Materials[i]->Texture[4].Map != "") // transparency - { -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading transparency texture."); -#endif - video::ITexture* transTexture = loadTexture(Materials[i]->Texture[4].Map); - if (transTexture && irrMat.getTexture(0)) - irrMat.setTexture(1, irrMat.getTexture(0)); - irrMat.setTexture(0, transTexture); - irrMat.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; - } - if (Materials[i]->Texture[6].Map != "") // bump - { -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading bump texture."); -#endif - const u8 pos = irrMat.getTexture(0)?1:0; - irrMat.setTexture(pos, loadTexture(Materials[i]->Texture[6].Map)); - if (irrMat.getTexture(pos)) - { - // SceneManager->getVideoDriver()->makeNormalMapTexture(irrMat.getTexture(1)); - // irrMat.MaterialType=video::EMT_NORMAL_MAP_SOLID; - } - } - - // cope with planar mapping texture coords - if (Materials[i]->Texture[0].Projection != 5) - { - if (FormatVersion!=2) - { - if (Materials[i]->Texture[0].Flags&1) - Materials[i]->Texture[0].Axis=0; - else if (Materials[i]->Texture[0].Flags&2) - Materials[i]->Texture[0].Axis=1; - else if (Materials[i]->Texture[0].Flags&4) - Materials[i]->Texture[0].Axis=2; - } - // if no axis given choose the dominant one - else if (Materials[i]->Texture[0].Axis>2) - { - if (Materials[i]->Meshbuffer->getBoundingBox().getExtent().YMeshbuffer->getBoundingBox().getExtent().X) - { - if (Materials[i]->Meshbuffer->getBoundingBox().getExtent().YMeshbuffer->getBoundingBox().getExtent().Z) - Materials[i]->Texture[0].Axis=1; - else - Materials[i]->Texture[0].Axis=2; - } - else - { - if (Materials[i]->Meshbuffer->getBoundingBox().getExtent().XMeshbuffer->getBoundingBox().getExtent().Z) - Materials[i]->Texture[0].Axis=0; - else - Materials[i]->Texture[0].Axis=2; - } - } - // get the resolution for this axis - f32 resolutionS = core::reciprocal(Materials[i]->Texture[0].Size.Z); - f32 resolutionT = core::reciprocal(Materials[i]->Texture[0].Size.Y); - if (Materials[i]->Texture[0].Axis==1) - { - resolutionS = core::reciprocal(Materials[i]->Texture[0].Size.X); - resolutionT = core::reciprocal(Materials[i]->Texture[0].Size.Z); - } - else if (Materials[i]->Texture[0].Axis==2) - { - resolutionS = core::reciprocal(Materials[i]->Texture[0].Size.X); - resolutionT = core::reciprocal(Materials[i]->Texture[0].Size.Y); - } - // use the two-way planar mapping - SceneManager->getMeshManipulator()->makePlanarTextureMapping(Materials[i]->Meshbuffer, resolutionS, resolutionT, Materials[i]->Texture[0].Axis, Materials[i]->Texture[0].Center); - } - - // add bump maps - if (Materials[i]->Meshbuffer->Material.MaterialType==video::EMT_NORMAL_MAP_SOLID) - { - SMesh* tmpmesh = new SMesh(); - tmpmesh->addMeshBuffer(Materials[i]->Meshbuffer); - SceneManager->getMeshManipulator()->createMeshWithTangents(tmpmesh, true, true); - Mesh->addMeshBuffer(tmpmesh->getMeshBuffer(0)); - tmpmesh->getMeshBuffer(0)->drop(); - tmpmesh->drop(); - } - else - { - SceneManager->getMeshManipulator()->recalculateNormals(Materials[i]->Meshbuffer); - Mesh->addMeshBuffer(Materials[i]->Meshbuffer); - } - Materials[i]->Meshbuffer->drop(); - // clear the material array elements - delete Materials[i]; - } - Mesh->recalculateBoundingBox(); - - SAnimatedMesh* am = new SAnimatedMesh(); - am->Type = EAMT_3DS; - am->addMesh(Mesh); - am->recalculateBoundingBox(); - Mesh->drop(); - Mesh = 0; - - Points.clear(); - Indices.clear(); - MaterialMapping.clear(); - TCoords.clear(); - Materials.clear(); - Images.clear(); - VmPolyPointsIndex.clear(); - VmCoordsIndex.clear(); - UvIndex.clear(); - UvName.clear(); - - return am; -} - - -bool CLWOMeshFileLoader::readChunks() -{ - s32 lastPos; - u32 size; - unsigned int uiType; - char type[5]; - type[4]=0; - tLWOLayerInfo layer; - - while(File->getPos()getSize()) - { - File->read(&type, 4); - //Convert 4-char string to 4-byte integer - //Makes it possible to do a switch statement - uiType = charsToUInt(type); - File->read(&size, 4); -#ifndef __BIG_ENDIAN__ - size=os::Byteswap::byteswap(size); -#endif - lastPos=File->getPos(); - - switch(uiType) - { - case charsToUIntD('L','A','Y','R'): - { -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading layer."); -#endif - u16 tmp16; - File->read(&tmp16, 2); // number - File->read(&tmp16, 2); // flags - size -= 4; -#ifndef __BIG_ENDIAN__ - tmp16=os::Byteswap::byteswap(tmp16); -#endif - if (((FormatVersion==1)&&(tmp16!=1)) || - ((FormatVersion==2)&&(tmp16&1))) - layer.Active=false; - else - layer.Active=true; - if (FormatVersion==2) - size -= readVec(layer.Pivot); - size -= readString(layer.Name); - if (size) - { - File->read(&tmp16, 2); -#ifndef __BIG_ENDIAN__ - tmp16=os::Byteswap::byteswap(tmp16); -#endif - layer.Parent = tmp16; - } - } - break; - case charsToUIntD('P','N','T','S'): - { -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading points."); -#endif - core::vector3df vec; - Points.clear(); - const u32 tmpsize = size/12; - Points.reallocate(tmpsize); - for (u32 i=0; iName=""; - mat->Meshbuffer=new scene::SMeshBuffer(); - size -= readString(mat->Name); - if (FormatVersion!=2) - mat->TagType = 1; // format 2 has more types - Materials.push_back(mat); - } - } - break; - case charsToUIntD('P','T','A','G'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading tag mapping."); -#endif - readTagMapping(size); - break; - case charsToUIntD('V','M','A','D'): // discontinuous vertex mapping, i.e. additional texcoords -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading Vertex mapping VMAD."); -#endif - readDiscVertexMapping(size); -// case charsToUIntD('V','M','P','A'): -// case charsToUIntD('E','N','V','L'): - break; - case charsToUIntD('C','L','I','P'): - { -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading clips."); -#endif - u32 index; - u16 subsize; - File->read(&index, 4); -#ifndef __BIG_ENDIAN__ - index=os::Byteswap::byteswap(index); -#endif - size -= 4; - while (size != 0) - { - File->read(&type, 4); - File->read(&subsize, 2); -#ifndef __BIG_ENDIAN__ - subsize=os::Byteswap::byteswap(subsize); -#endif - size -= 6; - if (strncmp(type, "STIL", 4)) - { - File->seek(subsize, true); - size -= subsize; - continue; - } - core::stringc path; - size -= readString(path, subsize); - #ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loaded clip", path.c_str()); - #endif - Images.push_back(path); - } - } - break; - case charsToUIntD('S','U','R','F'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading material."); -#endif - readMat(size); - break; - case charsToUIntD('B','B','O','X'): - { -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading bbox."); -#endif - // not stored - core::vector3df vec; - for (u32 i=0; i<2; ++i) - readVec(vec); - size -= 24; - } - break; - case charsToUIntD('D','E','S','C'): - case charsToUIntD('T','E','X','T'): - { - core::stringc text; - size -= readString(text, size); -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader text", text); -#endif - } - break; - // not needed - case charsToUIntD('I','C','O','N'): - // not yet supported - case charsToUIntD('P','C','H','S'): - case charsToUIntD('C','R','V','S'): - default: -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: skipping ", type); -#endif - //Go to next chunk - File->seek(lastPos + size, false); - break; - } - } - return true; -} - - -void CLWOMeshFileLoader::readObj1(u32 size) -{ - u32 pos; - u16 numVerts, vertIndex; - s16 material; - video::S3DVertex vertex; - vertex.Color=0xffffffff; - - while (size!=0) - { - File->read(&numVerts, 2); -#ifndef __BIG_ENDIAN__ - numVerts=os::Byteswap::byteswap(numVerts); -#endif - pos=File->getPos(); - // skip forward to material number - File->seek(2*numVerts, true); - File->read(&material, 2); -#ifndef __BIG_ENDIAN__ - material=os::Byteswap::byteswap(material); -#endif - size -=2*numVerts+4; - // detail meshes ? - scene::SMeshBuffer *mb; - if (material<0) - mb=Materials[-material-1]->Meshbuffer; - else - mb=Materials[material-1]->Meshbuffer; - // back to vertex list start - File->seek(pos, false); - - const u16 vertCount=mb->Vertices.size(); - for (u16 i=0; iread(&vertIndex, 2); -#ifndef __BIG_ENDIAN__ - vertIndex=os::Byteswap::byteswap(vertIndex); -#endif - vertex.Pos=Points[vertIndex]; - mb->Vertices.push_back(vertex); - } - for (u16 i=1; iIndices.push_back(vertCount); - mb->Indices.push_back(vertCount+i); - mb->Indices.push_back(vertCount+i+1); - } - // skip material number and detail surface count - // detail surface can be read just as a normal one now - if (material<0) - File->read(&material, 2); - File->read(&material, 2); - } -} - - -void CLWOMeshFileLoader::readVertexMapping(u32 size) -{ - char type[5]={0}; - u16 dimension; - core::stringc name; - File->read(&type, 4); -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: Vertex map type", type); -#endif - File->read(&dimension,2); -#ifndef __BIG_ENDIAN__ - dimension=os::Byteswap::byteswap(dimension); -#endif - size -= 6; - size -= readString(name); -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: Vertex map", name.c_str()); -#endif - if (strncmp(type, "TXUV", 4)) // also support RGB, RGBA, WGHT, ... - { - File->seek(size, true); - return; - } - UvName.push_back(name); - - TCoords.push_back(core::array()); - core::array& UvCoords=TCoords.getLast(); - UvCoords.reallocate(Points.size()); - UvIndex.push_back(core::array()); - core::array& UvPointsArray=UvIndex.getLast(); - UvPointsArray.reallocate(Points.size()); - - u32 index; - core::vector2df tcoord; - while (size) - { - size -= readVX(index); - File->read(&tcoord.X, 4); - File->read(&tcoord.Y, 4); - size -= 8; -#ifndef __BIG_ENDIAN__ - index=os::Byteswap::byteswap(index); - tcoord.X=os::Byteswap::byteswap(tcoord.X); - tcoord.Y=os::Byteswap::byteswap(tcoord.Y); -#endif - UvCoords.push_back(tcoord); - UvPointsArray.push_back(index); - } -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: UvCoords", core::stringc(UvCoords.size())); -#endif -} - - -void CLWOMeshFileLoader::readDiscVertexMapping(u32 size) -{ - char type[5]={0}; - u16 dimension; - core::stringc name; - File->read(&type, 4); -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: Discontinuous vertex map type", type); -#endif - File->read(&dimension,2); -#ifndef __BIG_ENDIAN__ - dimension=os::Byteswap::byteswap(dimension); -#endif - size -= 6; - size -= readString(name); -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: Discontinuous vertex map", name.c_str()); -#endif - if (strncmp(type, "TXUV", 4)) - { - File->seek(size, true); - return; - } - DUvName.push_back(name); - VmPolyPointsIndex.push_back(core::array()); - core::array& VmPolyPoints=VmPolyPointsIndex.getLast(); - - VmCoordsIndex.push_back(core::array()); - core::array& VmCoords=VmCoordsIndex.getLast(); - - u32 vmpolys; - u32 vmpoints; - core::vector2df vmcoords; - while (size) - { - size-=readVX(vmpoints); - size-=readVX(vmpolys); - File->read(&vmcoords.X, 4); - File->read(&vmcoords.Y, 4); - size -= 8; -#ifndef __BIG_ENDIAN__ - vmpoints=os::Byteswap::byteswap(vmpoints); - vmpolys=os::Byteswap::byteswap(vmpolys); - vmcoords.X=os::Byteswap::byteswap(vmcoords.X); - vmcoords.Y=os::Byteswap::byteswap(vmcoords.Y); -#endif - VmCoords.push_back(vmcoords); - VmPolyPoints.push_back(vmpolys); - VmPolyPoints.push_back(vmpoints); - } -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: VmCoords", core::stringc(VmCoords.size())); -#endif -} - - -void CLWOMeshFileLoader::readTagMapping(u32 size) -{ - char type[5]; - type[4]=0; - File->read(&type, 4); - size -= 4; - if ((strncmp(type, "SURF", 4))||(Indices.size()==0)) - { - File->seek(size, true); - return; - } - - while (size!=0) - { - u16 tag; - u32 polyIndex; - size-=readVX(polyIndex); - File->read(&tag, 2); -#ifndef __BIG_ENDIAN__ - tag=os::Byteswap::byteswap(tag); -#endif - size -= 2; - MaterialMapping[polyIndex]=tag; - Materials[tag]->TagType=1; - } -} - - -void CLWOMeshFileLoader::readObj2(u32 size) -{ - char type[5]; - type[4]=0; - File->read(&type, 4); - size -= 4; - Indices.clear(); - if (strncmp(type, "FACE", 4)) // also possible are splines, subdivision patches, metaballs, and bones - { - File->seek(size, true); - return; - } - u16 numVerts=0; - while (size!=0) - { - File->read(&numVerts, 2); -#ifndef __BIG_ENDIAN__ - numVerts=os::Byteswap::byteswap(numVerts); -#endif - // mask out flags - numVerts &= 0x03FF; - - size -= 2; - Indices.push_back(core::array()); - u32 vertIndex; - core::array& polyArray = Indices.getLast(); - polyArray.reallocate(numVerts); - for (u16 i=0; iTagType==1) && (Materials[i]->Name==name)) - { - mat=Materials[i]; - break; - } - } - if (!mat) - { - File->seek(size, true); - return; - } - if (FormatVersion==2) - size -= readString(name); - - video::SMaterial& irrMat=mat->Meshbuffer->Material; - - u8 currTexture=0; - while (size!=0) - { - char type[5]; - type[4]=0; - u32 uiType; - u32 tmp32; - u16 subsize, tmp16; - f32 tmpf32; - File->read(&type, 4); - //Convert 4-char string to 4-byte integer - //Makes it possible to do a switch statement - uiType = charsToUInt(type); - File->read(&subsize, 2); -#ifndef __BIG_ENDIAN__ - subsize=os::Byteswap::byteswap(subsize); -#endif - size -= 6; - switch (uiType) - { - case charsToUIntD('C','O','L','R'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading Ambient color."); -#endif - { - s32 colSize = readColor(irrMat.DiffuseColor); - irrMat.AmbientColor=irrMat.DiffuseColor; - size -= colSize; - subsize -= colSize; - if (FormatVersion==2) - size -= readVX(mat->Envelope[0]); - } - break; - case charsToUIntD('D','I','F','F'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading Diffuse color."); -#endif - { - if (FormatVersion==2) - { - File->read(&mat->Diffuse, 4); -#ifndef __BIG_ENDIAN__ - mat->Diffuse=os::Byteswap::byteswap(mat->Diffuse); -#endif - size -= 4; - subsize -= 4; - size -= readVX(mat->Envelope[1]); - } - else - { - File->read(&tmp16, 2); -#ifndef __BIG_ENDIAN__ - tmp16=os::Byteswap::byteswap(tmp16); -#endif - mat->Diffuse=tmp16/256.0f; - size -= 2; - subsize -= 2; - } - } - break; - case charsToUIntD('V','D','I','F'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading Diffuse color."); -#endif - { - File->read(&mat->Diffuse, 4); -#ifndef __BIG_ENDIAN__ - mat->Diffuse=os::Byteswap::byteswap(mat->Diffuse); -#endif - size -= 4; - } - break; - case charsToUIntD('L','U','M','I'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading luminance."); -#endif - { - if (FormatVersion==2) - { - File->read(&mat->Luminance, 4); -#ifndef __BIG_ENDIAN__ - mat->Luminance=os::Byteswap::byteswap(mat->Luminance); -#endif - size -= 4; - subsize -= 4; - size -= readVX(mat->Envelope[2]); - } - else - { - File->read(&tmp16, 2); -#ifndef __BIG_ENDIAN__ - tmp16=os::Byteswap::byteswap(tmp16); -#endif - mat->Luminance=tmp16/256.0f; - size -= 2; - subsize -= 2; - } } - break; - case charsToUIntD('V','L','U','M'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading luminance."); -#endif - { - File->read(&mat->Luminance, 4); -#ifndef __BIG_ENDIAN__ - mat->Luminance=os::Byteswap::byteswap(mat->Luminance); -#endif - size -= 4; - } - break; - case charsToUIntD('S','P','E','C'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading specular."); -#endif - { - if (FormatVersion==2) - { - File->read(&mat->Specular, 4); -#ifndef __BIG_ENDIAN__ - mat->Specular=os::Byteswap::byteswap(mat->Specular); -#endif - size -= 4; - subsize -= 4; - size -= readVX(mat->Envelope[3]); - } - else - { - File->read(&tmp16, 2); -#ifndef __BIG_ENDIAN__ - tmp16=os::Byteswap::byteswap(tmp16); -#endif - mat->Specular=tmp16/256.0f;; - size -= 2; - subsize -= 2; - } - } - break; - case charsToUIntD('V','S','P','C'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading specular."); -#endif - { - File->read(&mat->Specular, 4); -#ifndef __BIG_ENDIAN__ - mat->Specular=os::Byteswap::byteswap(mat->Specular); -#endif - size -= 4; - } - break; - case charsToUIntD('R','E','F','L'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading reflection."); -#endif - { - if (FormatVersion==2) - { - File->read(&mat->Reflection, 4); -#ifndef __BIG_ENDIAN__ - mat->Reflection=os::Byteswap::byteswap(mat->Reflection); -#endif - size -= 4; - subsize -= 4; - size -= readVX(mat->Envelope[4]); - } - else - { - File->read(&tmp16, 2); -#ifndef __BIG_ENDIAN__ - tmp16=os::Byteswap::byteswap(tmp16); -#endif - mat->Reflection=tmp16/256.0f; - size -= 2; - subsize -= 2; - } - } - break; - case charsToUIntD('V','R','F','L'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading reflection."); -#endif - { - File->read(&mat->Reflection, 4); -#ifndef __BIG_ENDIAN__ - mat->Reflection=os::Byteswap::byteswap(mat->Reflection); -#endif - size -= 4; - } - break; - case charsToUIntD('T','R','A','N'): - { - if (FormatVersion==2) - { - File->read(&mat->Transparency, 4); -#ifndef __BIG_ENDIAN__ - mat->Transparency=os::Byteswap::byteswap(mat->Transparency); -#endif - size -= 4; - subsize -= 4; - size -= readVX(mat->Envelope[5]); - } - else - { - File->read(&tmp16, 2); -#ifndef __BIG_ENDIAN__ - tmp16=os::Byteswap::byteswap(tmp16); -#endif - mat->Transparency=tmp16/256.0f; - size -= 2; - subsize -= 2; - } -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading transparency", core::stringc(mat->Transparency).c_str()); -#endif - } - break; - case charsToUIntD('V','T','R','N'): - { - File->read(&mat->Transparency, 4); -#ifndef __BIG_ENDIAN__ - mat->Transparency=os::Byteswap::byteswap(mat->Transparency); -#endif - size -= 4; - } -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading transparency", core::stringc(mat->Transparency).c_str()); -#endif - break; - case charsToUIntD('T','R','N','L'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading translucency."); -#endif - { - File->read(&mat->Translucency, 4); -#ifndef __BIG_ENDIAN__ - mat->Translucency=os::Byteswap::byteswap(mat->Translucency); -#endif - size -= 4; - subsize -= 4; - if (FormatVersion==2) - size -= readVX(mat->Envelope[6]); - } - break; - case charsToUIntD('G','L','O','S'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading glossy."); -#endif - { - if (FormatVersion == 2) - { - File->read(&irrMat.Shininess, 4); -#ifndef __BIG_ENDIAN__ - irrMat.Shininess=os::Byteswap::byteswap(irrMat.Shininess); -#endif - size -= 4; - subsize -= 4; - size -= readVX(mat->Envelope[7]); - } - else - { - File->read(&tmp16, 2); -#ifndef __BIG_ENDIAN__ - tmp16=os::Byteswap::byteswap(tmp16); -#endif - irrMat.Shininess=tmp16/16.f; - size -= 2; - subsize -= 2; - } - } - break; - case charsToUIntD('S','H','R','P'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading sharpness."); -#endif - { - File->read(&mat->Sharpness, 4); -#ifndef __BIG_ENDIAN__ - mat->Sharpness=os::Byteswap::byteswap(mat->Sharpness); -#endif - size -= 4; - subsize -= 4; - if (FormatVersion==2) - size -= readVX(mat->Envelope[8]); - } - break; - case charsToUIntD('B','U','M','P'): - case charsToUIntD('T','A','M','P'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading bumpiness."); -#endif - { - File->read(&tmpf32, 4); -#ifndef __BIG_ENDIAN__ - tmpf32=os::Byteswap::byteswap(tmpf32); -#endif - if (currTexture==6) - irrMat.MaterialTypeParam=tmpf32; - size -= 4; - subsize -= 4; - if (FormatVersion==2) - size -= readVX(mat->Envelope[9]); - } - break; - case charsToUIntD('S','I','D','E'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading backface culled."); -#endif - { - File->read(&tmp16, 2); -#ifndef __BIG_ENDIAN__ - tmp16=os::Byteswap::byteswap(tmp16); -#endif - if (tmp16==1) - irrMat.BackfaceCulling=true; - else if (tmp16==3) - irrMat.BackfaceCulling=false; - size -= 2; - } - break; - case charsToUIntD('S','M','A','N'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading smoothing angle."); -#endif - { - File->read(&mat->SmoothingAngle, 4); -#ifndef __BIG_ENDIAN__ - mat->SmoothingAngle=os::Byteswap::byteswap(mat->SmoothingAngle); -#endif - size -= 4; - } - break; - case charsToUIntD('R','F','O','P'): - case charsToUIntD('R','F','L','T'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading reflection mode."); -#endif - { - File->read(&mat->ReflMode, 2); -#ifndef __BIG_ENDIAN__ - mat->ReflMode=os::Byteswap::byteswap(mat->ReflMode); -#endif - size -= 2; - } - break; - case charsToUIntD('R','I','M','G'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading reflection map."); -#endif - { - if (FormatVersion==2) - { - size -= readVX(tmp32); - if (tmp32) - mat->ReflMap=Images[tmp32-1]; - } - else - size -= readString(mat->ReflMap, size); - } - break; - case charsToUIntD('R','S','A','N'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading reflection seam angle."); -#endif - { - File->read(&mat->ReflSeamAngle, 4); -#ifndef __BIG_ENDIAN__ - mat->ReflSeamAngle=os::Byteswap::byteswap(mat->ReflSeamAngle); -#endif - size -= 4; - if (FormatVersion==2) - size -= readVX(mat->Envelope[10]); - } - break; - case charsToUIntD('R','B','L','R'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading reflection blur."); -#endif - { - File->read(&mat->ReflBlur, 4); -#ifndef __BIG_ENDIAN__ - mat->ReflBlur=os::Byteswap::byteswap(mat->ReflBlur); -#endif - size -= 4; - if (FormatVersion==2) - size -= readVX(mat->Envelope[11]); - } - break; - case charsToUIntD('R','I','N','D'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading refraction index."); -#endif - { - File->read(&mat->RefrIndex, 4); -#ifndef __BIG_ENDIAN__ - mat->RefrIndex=os::Byteswap::byteswap(mat->RefrIndex); -#endif - size -= 4; - subsize -= 4; - if (FormatVersion==2) - size -= readVX(mat->Envelope[12]); - } - break; - case charsToUIntD('T','R','O','P'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading refraction options."); -#endif - { - File->read(&mat->TranspMode, 2); -#ifndef __BIG_ENDIAN__ - mat->TranspMode=os::Byteswap::byteswap(mat->TranspMode); -#endif - size -= 2; - } - break; - case charsToUIntD('T','I','M','G'): - { - if (FormatVersion==2) - { -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading refraction map."); -#endif - size -= readVX(tmp32); -#ifndef __BIG_ENDIAN__ - tmp32=os::Byteswap::byteswap(tmp32); -#endif - if (tmp32) - mat->Texture[currTexture].Map=Images[tmp32-1]; - } - else - { - size -= readString(mat->Texture[currTexture].Map, size); -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading image", mat->Texture[currTexture].Map.c_str()); -#endif - } - } - break; - case charsToUIntD('T','B','L','R'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading transparency blur."); -#endif - { - File->read(&mat->TranspBlur, 4); -#ifndef __BIG_ENDIAN__ - mat->TranspBlur=os::Byteswap::byteswap(mat->TranspBlur); -#endif - size -= 4; - if (FormatVersion==2) - size -= readVX(mat->Envelope[13]); - } - break; - case charsToUIntD('C','L','R','H'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading highlight color."); -#endif - { - File->read(&mat->HighlightColor, 4); -#ifndef __BIG_ENDIAN__ - mat->HighlightColor=os::Byteswap::byteswap(mat->HighlightColor); -#endif - size -= 4; - if (FormatVersion==2) - size -= readVX(mat->Envelope[14]); - } - break; - case charsToUIntD('C','L','R','F'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading color filter."); -#endif - { - File->read(&mat->ColorFilter, 4); -#ifndef __BIG_ENDIAN__ - mat->ColorFilter=os::Byteswap::byteswap(mat->ColorFilter); -#endif - size -= 4; - if (FormatVersion==2) - size -= readVX(mat->Envelope[15]); - } - break; - case charsToUIntD('A','D','T','R'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading additive transparency."); -#endif - { - File->read(&mat->AdditiveTransparency, 4); -#ifndef __BIG_ENDIAN__ - mat->AdditiveTransparency=os::Byteswap::byteswap(mat->AdditiveTransparency); -#endif - size -= 4; - if (FormatVersion==2) - size -= readVX(mat->Envelope[16]); - } - break; - case charsToUIntD('G','L','O','W'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading glow."); -#endif - { - if (FormatVersion==0) - { - File->read(&mat->GlowIntensity, 4); -#ifndef __BIG_ENDIAN__ - mat->GlowIntensity=os::Byteswap::byteswap(mat->GlowIntensity); -#endif - size -= 4; - } - else - { - File->read(&mat->Glow, 2); -#ifndef __BIG_ENDIAN__ - mat->Glow=os::Byteswap::byteswap(mat->Glow); -#endif - size -= 2; - File->read(&mat->GlowIntensity, 4); -#ifndef __BIG_ENDIAN__ - mat->GlowIntensity=os::Byteswap::byteswap(mat->GlowIntensity); -#endif - size -= 4; - if (FormatVersion==2) - size -= readVX(mat->Envelope[17]); - File->read(&mat->GlowSize, 4); -#ifndef __BIG_ENDIAN__ - mat->GlowSize=os::Byteswap::byteswap(mat->GlowSize); -#endif - size -= 4; - if (FormatVersion==2) - size -= readVX(mat->Envelope[18]); - } - } - break; - case charsToUIntD('G','V','A','L'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading glow intensity."); -#endif - { - File->read(&mat->GlowIntensity, 4); -#ifndef __BIG_ENDIAN__ - mat->GlowIntensity=os::Byteswap::byteswap(mat->GlowIntensity); -#endif - size -= 4; - if (FormatVersion==2) - size -= readVX(mat->Envelope[17]); - } - break; - case charsToUIntD('L','I','N','E'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading isWireframe."); -#endif - { - File->read(&tmp16, 2); -#ifndef __BIG_ENDIAN__ - tmp16=os::Byteswap::byteswap(tmp16); -#endif - if (tmp16&1) - irrMat.Wireframe=true; - size -= 2; - if (size!=0) - { - File->read(&irrMat.Thickness, 4); -#ifndef __BIG_ENDIAN__ - irrMat.Thickness=os::Byteswap::byteswap(irrMat.Thickness); -#endif - size -= 4; - if (FormatVersion==2) - size -= readVX(mat->Envelope[19]); - } - if (size!=0) - { - video::SColor lineColor; - size -= readColor(lineColor); - if (FormatVersion==2) - size -= readVX(mat->Envelope[20]); - } - } - break; - case charsToUIntD('A','L','P','H'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading alpha mode."); -#endif - { - File->read(&mat->AlphaMode, 2); -#ifndef __BIG_ENDIAN__ - mat->AlphaMode=os::Byteswap::byteswap(mat->AlphaMode); -#endif - size -= 2; - File->read(&mat->AlphaValue, 4); -#ifndef __BIG_ENDIAN__ - mat->AlphaValue=os::Byteswap::byteswap(mat->AlphaValue); -#endif - size -= 4; - } - break; - case charsToUIntD('V','C','O','L'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading vertex color."); -#endif - { - File->read(&mat->VertexColorIntensity, 4); -#ifndef __BIG_ENDIAN__ - mat->VertexColorIntensity=os::Byteswap::byteswap(mat->VertexColorIntensity); -#endif - size -= 4; - if (FormatVersion==2) - size -= readVX(mat->Envelope[21]); - File->read(&tmp32, 4); // skip type - size -= 4; - core::stringc tmpname; - size -= readString(tmpname, size); -// mat->VertexColor = getColorVMAP(tmpname); - } - break; - case charsToUIntD('F','L','A','G'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading flag."); -#endif - { - File->read(&mat->Flags, 2); -#ifndef __BIG_ENDIAN__ - mat->Flags=os::Byteswap::byteswap(mat->Flags); -#endif - if (mat->Flags&1) - mat->Luminance=1.0f; - if (mat->Flags&256) - irrMat.BackfaceCulling=false; - size -= 2; - } - break; - case charsToUIntD('E','D','G','E'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading edge."); -#endif - { - File->read(&mat->EdgeTransparency, 4); -#ifndef __BIG_ENDIAN__ - mat->EdgeTransparency=os::Byteswap::byteswap(mat->EdgeTransparency); -#endif - size -= 4; - } - break; - case charsToUIntD('C','T','E','X'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading ctex."); -#endif - currTexture=0; - size -= readString(mat->Texture[currTexture].Type, size); - break; - case charsToUIntD('D','T','E','X'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading dtex."); -#endif - currTexture=1; - size -= readString(mat->Texture[currTexture].Type, size); - break; - case charsToUIntD('S','T','E','X'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading stex."); -#endif - currTexture=2; - size -= readString(mat->Texture[currTexture].Type, size); - break; - case charsToUIntD('R','T','E','X'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading rtex."); -#endif - currTexture=3; - size -= readString(mat->Texture[currTexture].Type, size); - break; - case charsToUIntD('T','T','E','X'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading ttex."); -#endif - currTexture=4; - size -= readString(mat->Texture[currTexture].Type, size); - break; - case charsToUIntD('L','T','E','X'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading ltex."); -#endif - currTexture=5; - size -= readString(mat->Texture[currTexture].Type, size); - break; - case charsToUIntD('B','T','E','X'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading btex."); -#endif - currTexture=6; - size -= readString(mat->Texture[currTexture].Type, size); - break; - case charsToUIntD('T','A','L','P'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading alpha map."); -#endif - size -= readString(mat->Texture[currTexture].AlphaMap, size); - break; - case charsToUIntD('T','F','L','G'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture flag."); -#endif - { - File->read(&mat->Texture[currTexture].Flags, 2); -#ifndef __BIG_ENDIAN__ - mat->Texture[currTexture].Flags=os::Byteswap::byteswap(mat->Texture[currTexture].Flags); -#endif - size -= 2; - } - break; - case charsToUIntD('E','N','A','B'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading isEnabled."); -#endif - { - File->read(&tmp16, 2); -#ifndef __BIG_ENDIAN__ - tmp16=os::Byteswap::byteswap(tmp16); -#endif - mat->Texture[currTexture].Active=(tmp16!=0); - size -= 2; - } - break; - case charsToUIntD('W','R','A','P'): - case charsToUIntD('T','W','R','P'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture wrap."); -#endif - { - File->read(&mat->Texture[currTexture].WidthWrap, 2); -#ifndef __BIG_ENDIAN__ - mat->Texture[currTexture].WidthWrap=os::Byteswap::byteswap(mat->Texture[currTexture].WidthWrap); -#endif - File->read(&mat->Texture[currTexture].HeightWrap, 2); -#ifndef __BIG_ENDIAN__ - mat->Texture[currTexture].HeightWrap=os::Byteswap::byteswap(mat->Texture[currTexture].HeightWrap); -#endif - size -= 4; - } - break; - case charsToUIntD('T','V','E','L'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture velocity."); -#endif - size -= readVec(mat->Texture[currTexture].Velocity); - break; - case charsToUIntD('T','C','L','R'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture color."); -#endif - size -= readColor(mat->Texture[currTexture].Color); - break; - case charsToUIntD('A','A','S','T'): - case charsToUIntD('T','A','A','S'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture antialias."); -#endif - { - tmp16=0; - if (FormatVersion==2) - { - File->read(&tmp16, 2); -#ifndef __BIG_ENDIAN__ - tmp16=os::Byteswap::byteswap(tmp16); -#endif - size -= 2; - } - File->read(&mat->Texture[currTexture].AntiAliasing, 4); -#ifndef __BIG_ENDIAN__ - mat->Texture[currTexture].AntiAliasing=os::Byteswap::byteswap(mat->Texture[currTexture].AntiAliasing); -#endif - if (tmp16 & ~0x01) - mat->Texture[currTexture].AntiAliasing=0.0f; // disabled - size -= 4; - } - break; - case charsToUIntD('T','O','P','C'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture opacity."); -#endif - { - File->read(&mat->Texture[currTexture].Opacity, 4); -#ifndef __BIG_ENDIAN__ - mat->Texture[currTexture].Opacity=os::Byteswap::byteswap(mat->Texture[currTexture].Opacity); -#endif - size -= 4; - } - break; - case charsToUIntD('O','P','A','C'): - { -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture opacity and type."); -#endif - File->read(&mat->Texture[currTexture].OpacType, 2); -#ifndef __BIG_ENDIAN__ - mat->Texture[currTexture].OpacType=os::Byteswap::byteswap(mat->Texture[currTexture].OpacType); -#endif - File->read(&mat->Texture[currTexture].Opacity, 4); -#ifndef __BIG_ENDIAN__ - mat->Texture[currTexture].Opacity=os::Byteswap::byteswap(mat->Texture[currTexture].Opacity); -#endif - size -= 6; - subsize -= 6; - if (FormatVersion==2) - size -= readVX(mat->Envelope[22]); - } - break; - case charsToUIntD('A','X','I','S'): - { - File->read(&tmp16, 2); -#ifndef __BIG_ENDIAN__ - tmp16=os::Byteswap::byteswap(tmp16); -#endif - mat->Texture[currTexture].Axis=(u8)tmp16; - size -= 2; -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading axis value", core::stringc(tmp16).c_str()); -#endif - } - break; - case charsToUIntD('T','M','A','P'): // empty separation chunk - break; - case charsToUIntD('T','C','T','R'): - case charsToUIntD('C','N','T','R'): - { - core::vector3df& center=mat->Texture[currTexture].Center; - size -= readVec(center); - if (FormatVersion==2) - size -= readVX(mat->Envelope[22]); -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture center", (core::stringc(center.X)+" "+core::stringc(center.Y)+" "+core::stringc(center.Z)).c_str()); -#endif - } - break; - case charsToUIntD('T','S','I','Z'): - case charsToUIntD('S','I','Z','E'): - { - core::vector3df& tsize=mat->Texture[currTexture].Size; - size -= readVec(tsize); - if (FormatVersion==2) - size -= readVX(mat->Envelope[22]); -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture size", (core::stringc(tsize.X)+" "+core::stringc(tsize.Y)+" "+core::stringc(tsize.Z)).c_str()); -#endif - } - break; - case charsToUIntD('R','O','T','A'): - { - core::vector3df rotation; - size -= readVec(rotation); - if (FormatVersion==2) - size -= readVX(mat->Envelope[22]); -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture rotation", (core::stringc(rotation.X)+" "+core::stringc(rotation.Y)+" "+core::stringc(rotation.Z)).c_str()); -#endif - } - break; - case charsToUIntD('O','R','E','F'): - { - core::stringc tmpname; - size -= readString(tmpname); -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: texture reference object", tmpname.c_str()); -#endif - } - break; - case charsToUIntD('T','F','A','L'): - case charsToUIntD('F','A','L','L'): - { - if (FormatVersion==2) - { - u16 tmp16; - File->read(&tmp16, 2); - size -= 2; -#ifndef __BIG_ENDIAN__ - tmp16=os::Byteswap::byteswap(tmp16); -#endif - } - - core::vector3df& falloff=mat->Texture[currTexture].Falloff; - size -= readVec(falloff); - if (FormatVersion==2) - size -= readVX(mat->Envelope[22]); -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture falloff"); -#endif - } - break; - case charsToUIntD('C','S','Y','S'): - { - u16 tmp16; - File->read(&tmp16, 2); - size -= 2; -#ifndef __BIG_ENDIAN__ - tmp16=os::Byteswap::byteswap(tmp16); -#endif -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: texture coordinate system", tmp16==0?"object coords":"world coords"); -#endif - } - break; - case charsToUIntD('T','V','A','L'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture value."); -#endif - { - File->read(&tmp16, 2); -#ifndef __BIG_ENDIAN__ - tmp16=os::Byteswap::byteswap(tmp16); -#endif - mat->Texture[currTexture].Value=tmp16/256.0f; - size -= 2; - } - break; - case charsToUIntD('T','F','P','0'): - case charsToUIntD('T','S','P','0'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture param 0."); -#endif - { - File->read(&mat->Texture[currTexture].FParam[0], 4); -#ifndef __BIG_ENDIAN__ - mat->Texture[currTexture].FParam[0]=os::Byteswap::byteswap(mat->Texture[currTexture].FParam[0]); -#endif - size -= 4; - } - break; - case charsToUIntD('T','F','P','1'): - case charsToUIntD('T','S','P','1'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture param 1."); -#endif - { - File->read(&mat->Texture[currTexture].FParam[1], 4); -#ifndef __BIG_ENDIAN__ - mat->Texture[currTexture].FParam[1]=os::Byteswap::byteswap(mat->Texture[currTexture].FParam[1]); -#endif - size -= 4; - } - break; - case charsToUIntD('T','F','P','2'): - case charsToUIntD('T','S','P','2'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture param 2."); -#endif - { - File->read(&mat->Texture[currTexture].FParam[2], 4); -#ifndef __BIG_ENDIAN__ - mat->Texture[currTexture].FParam[2]=os::Byteswap::byteswap(mat->Texture[currTexture].FParam[2]); -#endif - size -= 4; - } - break; - case charsToUIntD('T','F','R','Q'): - case charsToUIntD('T','I','P','0'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture iparam 0."); -#endif - { - File->read(&mat->Texture[currTexture].IParam[0], 2); -#ifndef __BIG_ENDIAN__ - mat->Texture[currTexture].IParam[0]=os::Byteswap::byteswap(mat->Texture[currTexture].IParam[0]); -#endif - size -= 2; - } - break; - case charsToUIntD('T','I','P','1'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture param 1."); -#endif - { - File->read(&mat->Texture[currTexture].IParam[1], 2); -#ifndef __BIG_ENDIAN__ - mat->Texture[currTexture].IParam[1]=os::Byteswap::byteswap(mat->Texture[currTexture].IParam[1]); -#endif - size -= 2; - } - break; - case charsToUIntD('T','I','P','2'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading texture param 2."); -#endif - { - File->read(&mat->Texture[currTexture].IParam[2], 2); -#ifndef __BIG_ENDIAN__ - mat->Texture[currTexture].IParam[2]=os::Byteswap::byteswap(mat->Texture[currTexture].IParam[2]); -#endif - size -= 2; - } - break; - case charsToUIntD('V','M','A','P'): - { - size -= readString(mat->Texture[currTexture].UVname); -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading material vmap binding",mat->Texture[currTexture].UVname.c_str()); -#endif - } - break; - case charsToUIntD('B','L','O','K'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading blok."); -#endif - { - core::stringc ordinal; - File->read(&type, 4); - File->read(&subsize, 2); -#ifndef __BIG_ENDIAN__ - subsize=os::Byteswap::byteswap(subsize); -#endif - size -= 6; - size -= readString(ordinal, size); - } - break; - case charsToUIntD('C','H','A','N'): - { - File->read(&type, 4); - size -= 4; - if (!strncmp(type, "COLR", 4)) - currTexture=0; - else if (!strncmp(type, "DIFF", 4)) - currTexture=1; - else if (!strncmp(type, "LUMI", 4)) - currTexture=5; - else if (!strncmp(type, "SPEC", 4)) - currTexture=2; - else if (!strncmp(type, "REFL", 4)) - currTexture=3; - else if (!strncmp(type, "TRAN", 4)) - currTexture=4; - else if (!strncmp(type, "BUMP", 4)) - currTexture=6; - } -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading channel ", type); -#endif - break; - case charsToUIntD('I','M','A','G'): -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading channel map."); -#endif - { - u16 index; - File->read(&index, 2); -#ifndef __BIG_ENDIAN__ - index=os::Byteswap::byteswap(index); -#endif - size -= 2; - if (index) - mat->Texture[currTexture].Map=Images[index-1]; - } - break; - case charsToUIntD('P','R','O','J'): // define the projection type -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: loading channel projection type."); -#endif - { - u16 index; - File->read(&index, 2); -#ifndef __BIG_ENDIAN__ - index=os::Byteswap::byteswap(index); -#endif - size -= 2; -#ifdef LWO_READER_DEBUG - if (index != 5) - os::Printer::log("LWO loader: wrong channel projection type", core::stringc(index).c_str()); -#endif - mat->Texture[currTexture].Projection=(u8)index; - } - break; - case charsToUIntD('W','R','P','W'): // for cylindrical and spherical projections - case charsToUIntD('W','R','P','H'): // for cylindrical and spherical projections - default: - { -#ifdef LWO_READER_DEBUG - os::Printer::log("LWO loader: skipping ", core::stringc((char*)&uiType, 4)); -#endif - File->seek(subsize, true); - size -= subsize; - } - } - } - - if (mat->Transparency != 0.f) - { - irrMat.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; - } -} - - -u32 CLWOMeshFileLoader::readColor(video::SColor& color) -{ - if (FormatVersion!=2) - { - u8 colorComponent; - File->read(&colorComponent, 1); - color.setRed(colorComponent); - File->read(&colorComponent, 1); - color.setGreen(colorComponent); - File->read(&colorComponent, 1); - color.setBlue(colorComponent); - // unknown value - File->read(&colorComponent, 1); - return 4; - } - else - { - video::SColorf col; - File->read(&col.r, 4); -#ifndef __BIG_ENDIAN__ - col.r=os::Byteswap::byteswap(col.r); -#endif - File->read(&col.g, 4); -#ifndef __BIG_ENDIAN__ - col.g=os::Byteswap::byteswap(col.g); -#endif - File->read(&col.b, 4); -#ifndef __BIG_ENDIAN__ - col.b=os::Byteswap::byteswap(col.b); -#endif - color=col.toSColor(); - return 12; - } -} - -u32 CLWOMeshFileLoader::readString(core::stringc& name, u32 size) -{ - c8 c; - - name=""; - if (size) - name.reserve(size); - File->read(&c, 1); - while (c) - { - name.append(c); - File->read(&c, 1); - } - // read extra 0 upon odd file position - if (File->getPos() & 0x1) - { - File->read(&c, 1); - return (name.size()+2); - } - return (name.size()+1); -} - - -u32 CLWOMeshFileLoader::readVec(core::vector3df& vec) -{ - File->read(&vec.X, 4); -#ifndef __BIG_ENDIAN__ - vec.X=os::Byteswap::byteswap(vec.X); -#endif - File->read(&vec.Y, 4); -#ifndef __BIG_ENDIAN__ - vec.Y=os::Byteswap::byteswap(vec.Y); -#endif - File->read(&vec.Z, 4); -#ifndef __BIG_ENDIAN__ - vec.Z=os::Byteswap::byteswap(vec.Z); -#endif - return 12; -} - - -u32 CLWOMeshFileLoader::readVX(u32& num) -{ - u16 tmpIndex; - - File->read(&tmpIndex, 2); -#ifndef __BIG_ENDIAN__ - tmpIndex=os::Byteswap::byteswap(tmpIndex); -#endif - num=tmpIndex; - if (num >= 0xFF00) - { - File->read(&tmpIndex, 2); -#ifndef __BIG_ENDIAN__ - tmpIndex=os::Byteswap::byteswap(tmpIndex); -#endif - num=((num << 16)|tmpIndex) & ~0xFF000000; - return 4; - } - return 2; -} - - -bool CLWOMeshFileLoader::readFileHeader() -{ - u32 Id; - - File->read(&Id, 4); -#ifndef __BIG_ENDIAN__ - Id=os::Byteswap::byteswap(Id); -#endif - if (Id != 0x464f524d) // FORM - return false; - - //skip the file length - File->read(&Id, 4); - - File->read(&Id, 4); -#ifndef __BIG_ENDIAN__ - Id=os::Byteswap::byteswap(Id); -#endif - // Currently supported: LWOB, LWLO, LWO2 - switch (Id) - { - case 0x4c574f42: - FormatVersion = 0; // LWOB - break; - case 0x4c574c4f: - FormatVersion = 1; // LWLO - break; - case 0x4c574f32: - FormatVersion = 2; // LWO2 - break; - default: - return false; // unsupported - } - - return true; -} - - -video::ITexture* CLWOMeshFileLoader::loadTexture(const core::stringc& file) -{ - video::IVideoDriver* driver = SceneManager->getVideoDriver(); - - if (FileSystem->existFile(file)) - return driver->getTexture(file); - - core::stringc strippedName=FileSystem->getFileBasename(file); - if (FileSystem->existFile(strippedName)) - return driver->getTexture(strippedName); - core::stringc newpath = FileSystem->getFileDir(File->getFileName()); - newpath.append("/"); - newpath.append(strippedName); - if (FileSystem->existFile(newpath)) - return driver->getTexture(newpath); - os::Printer::log("Could not load texture", file.c_str(), ELL_WARNING); - - return 0; -} - - -} // end namespace scene -} // end namespace irr - +// Copyright (C) 2007-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CLWOMeshFileLoader.h" +#include "os.h" +#include "SAnimatedMesh.h" +#include "SMesh.h" +#include "IReadFile.h" +#include "ISceneManager.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "IMeshManipulator.h" + +namespace irr +{ +namespace scene +{ + +#ifdef _DEBUG +#define LWO_READER_DEBUG +#endif + +#define charsToUIntD(a, b, c, d) ((a << 24) | (b << 16) | (c << 8) | d) +inline unsigned int charsToUInt(const char *str) +{ + return (str[0] << 24) | (str[1] << 16) | (str[2] << 8) | str[3]; +} + + +struct tLWOTextureInfo +{ + tLWOTextureInfo() : UVTag(0), DUVTag(0), Flags(0), WidthWrap(2), + HeightWrap(2), OpacType(0), Color(0xffffffff), + Value(0.0f), AntiAliasing(1.0f), Opacity(1.0f), + Axis(255), Projection(0), Active(false) {} + core::stringc Type; + core::stringc Map; + core::stringc AlphaMap; + core::stringc UVname; + u16 UVTag; + u16 DUVTag; + u16 Flags; + u16 WidthWrap; + u16 HeightWrap; + u16 OpacType; + u16 IParam[3]; + core::vector3df Size; + core::vector3df Center; + core::vector3df Falloff; + core::vector3df Velocity; + video::SColor Color; + f32 Value; + f32 AntiAliasing; + f32 Opacity; + f32 FParam[3]; + u8 Axis; + u8 Projection; + bool Active; +}; + +struct CLWOMeshFileLoader::tLWOMaterial +{ + tLWOMaterial() : Meshbuffer(0), TagType(0), Flags(0), ReflMode(3), TranspMode(3), + Glow(0), AlphaMode(2), Luminance(0.0f), Diffuse(1.0f), Specular(0.0f), + Reflection(0.0f), Transparency(0.0f), Translucency(0.0f), + Sharpness(0.0f), ReflSeamAngle(0.0f), ReflBlur(0.0f), + RefrIndex(1.0f), TranspBlur(0.0f), SmoothingAngle(0.0f), + EdgeTransparency(0.0f), HighlightColor(0.0f), ColorFilter(0.0f), + AdditiveTransparency(0.0f), GlowIntensity(0.0f), GlowSize(0.0f), + AlphaValue(0.0f), VertexColorIntensity(0.0f), VertexColor() {} + + core::stringc Name; + scene::SMeshBuffer *Meshbuffer; + core::stringc ReflMap; + u16 TagType; + u16 Flags; + u16 ReflMode; + u16 TranspMode; + u16 Glow; + u16 AlphaMode; + f32 Luminance; + f32 Diffuse; + f32 Specular; + f32 Reflection; + f32 Transparency; + f32 Translucency; + f32 Sharpness; + f32 ReflSeamAngle; + f32 ReflBlur; + f32 RefrIndex; + f32 TranspBlur; + f32 SmoothingAngle; + f32 EdgeTransparency; + f32 HighlightColor; + f32 ColorFilter; + f32 AdditiveTransparency; + f32 GlowIntensity; + f32 GlowSize; + f32 AlphaValue; + f32 VertexColorIntensity; + video::SColorf VertexColor; + u32 Envelope[23]; + tLWOTextureInfo Texture[7]; +}; + +struct tLWOLayerInfo +{ + u16 Number; + u16 Parent; + u16 Flags; + bool Active; + core::stringc Name; + core::vector3df Pivot; +}; + + +//! Constructor +CLWOMeshFileLoader::CLWOMeshFileLoader(scene::ISceneManager* smgr, + io::IFileSystem* fs) +: SceneManager(smgr), FileSystem(fs), File(0), Mesh(0) +{ + #ifdef _DEBUG + setDebugName("CLWOMeshFileLoader"); + #endif +} + + +//! destructor +CLWOMeshFileLoader::~CLWOMeshFileLoader() +{ + if (Mesh) + Mesh->drop(); +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CLWOMeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension(filename, "lwo"); +} + + +//! creates/loads an animated mesh from the file. +IAnimatedMesh* CLWOMeshFileLoader::createMesh(io::IReadFile* file) +{ + File = file; + + if (Mesh) + Mesh->drop(); + + Mesh = new SMesh(); + + if (!readFileHeader()) + return 0; + + if (!readChunks()) + return 0; + +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: Creating geometry."); + os::Printer::log("LWO loader: Assigning UV maps."); +#endif + u32 i; + for (i=0; iTexture[j].UVname.size()) + { + for (uvTag=0; uvTagTexture[j].UVname == UvName[uvTag]) + { + Materials[i]->Texture[j].UVTag=uvTag; + break; + } + } + for (uvTag=0; uvTagTexture[j].UVname == DUvName[uvTag]) + { + Materials[i]->Texture[j].DUVTag=uvTag; + break; + } + } + } + } + } +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: Creating polys."); +#endif + // create actual geometry for lwo2 + if (FormatVersion==2) + { + core::array vertexCount; + vertexCount.reallocate(Materials.size()); + for (i=0; iMeshbuffer->Vertices.reallocate(vertexCount[i]); + Materials[i]->Meshbuffer->Indices.reallocate(vertexCount[i]); + } + } + // create actual geometry for lwo2 + for (u32 polyIndex=0; polyIndexMeshbuffer; + const core::array& poly = Indices[polyIndex]; + const u32 polySize=poly.size(); + const u16 uvTag = Materials[tag]->Texture[0].UVTag; + const u16 duvTag = Materials[tag]->Texture[0].DUVTag; + video::S3DVertex vertex; + vertex.Color=0xffffffff; + const u32 vertCount=mb->Vertices.size(); + for (u32 i=0; iVertices.push_back(vertex); + } + // triangulate as trifan + if (polySize>2) + { + for (u32 i=1; iIndices.push_back(vertCount); + mb->Indices.push_back(vertCount+i); + mb->Indices.push_back(vertCount+i+1); + } + } + } +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: Fixing meshbuffers."); +#endif + for (u32 i=0; iName); + os::Printer::log("LWO loader: Vertex count", core::stringc(Materials[i]->Meshbuffer->Vertices.size())); +#endif + if (!Materials[i]->Meshbuffer->Vertices.size()) + { + Materials[i]->Meshbuffer->drop(); + delete Materials[i]; + continue; + } + for (u32 j=0; jMeshbuffer->Vertices.size(); ++j) + Materials[i]->Meshbuffer->Vertices[j].Color=Materials[i]->Meshbuffer->Material.DiffuseColor; + Materials[i]->Meshbuffer->recalculateBoundingBox(); + + // load textures + video::SMaterial& irrMat=Materials[i]->Meshbuffer->Material; + if (Materials[i]->Texture[0].Map != "") // diffuse + irrMat.setTexture(0,loadTexture(Materials[i]->Texture[0].Map)); + if (Materials[i]->Texture[3].Map != "") // reflection + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading reflection texture."); +#endif + video::ITexture* reflTexture = loadTexture(Materials[i]->Texture[3].Map); + if (reflTexture && irrMat.getTexture(0)) + irrMat.setTexture(1, irrMat.getTexture(0)); + irrMat.setTexture(0, reflTexture); + irrMat.MaterialType=video::EMT_REFLECTION_2_LAYER; + } + if (Materials[i]->Texture[4].Map != "") // transparency + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading transparency texture."); +#endif + video::ITexture* transTexture = loadTexture(Materials[i]->Texture[4].Map); + if (transTexture && irrMat.getTexture(0)) + irrMat.setTexture(1, irrMat.getTexture(0)); + irrMat.setTexture(0, transTexture); + irrMat.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; + } + if (Materials[i]->Texture[6].Map != "") // bump + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading bump texture."); +#endif + const u8 pos = irrMat.getTexture(0)?1:0; + irrMat.setTexture(pos, loadTexture(Materials[i]->Texture[6].Map)); + if (irrMat.getTexture(pos)) + { + // SceneManager->getVideoDriver()->makeNormalMapTexture(irrMat.getTexture(1)); + // irrMat.MaterialType=video::EMT_NORMAL_MAP_SOLID; + } + } + + // cope with planar mapping texture coords + if (Materials[i]->Texture[0].Projection != 5) + { + if (FormatVersion!=2) + { + if (Materials[i]->Texture[0].Flags&1) + Materials[i]->Texture[0].Axis=0; + else if (Materials[i]->Texture[0].Flags&2) + Materials[i]->Texture[0].Axis=1; + else if (Materials[i]->Texture[0].Flags&4) + Materials[i]->Texture[0].Axis=2; + } + // if no axis given choose the dominant one + else if (Materials[i]->Texture[0].Axis>2) + { + if (Materials[i]->Meshbuffer->getBoundingBox().getExtent().YMeshbuffer->getBoundingBox().getExtent().X) + { + if (Materials[i]->Meshbuffer->getBoundingBox().getExtent().YMeshbuffer->getBoundingBox().getExtent().Z) + Materials[i]->Texture[0].Axis=1; + else + Materials[i]->Texture[0].Axis=2; + } + else + { + if (Materials[i]->Meshbuffer->getBoundingBox().getExtent().XMeshbuffer->getBoundingBox().getExtent().Z) + Materials[i]->Texture[0].Axis=0; + else + Materials[i]->Texture[0].Axis=2; + } + } + // get the resolution for this axis + f32 resolutionS = core::reciprocal(Materials[i]->Texture[0].Size.Z); + f32 resolutionT = core::reciprocal(Materials[i]->Texture[0].Size.Y); + if (Materials[i]->Texture[0].Axis==1) + { + resolutionS = core::reciprocal(Materials[i]->Texture[0].Size.X); + resolutionT = core::reciprocal(Materials[i]->Texture[0].Size.Z); + } + else if (Materials[i]->Texture[0].Axis==2) + { + resolutionS = core::reciprocal(Materials[i]->Texture[0].Size.X); + resolutionT = core::reciprocal(Materials[i]->Texture[0].Size.Y); + } + // use the two-way planar mapping + SceneManager->getMeshManipulator()->makePlanarTextureMapping(Materials[i]->Meshbuffer, resolutionS, resolutionT, Materials[i]->Texture[0].Axis, Materials[i]->Texture[0].Center); + } + + // add bump maps + if (Materials[i]->Meshbuffer->Material.MaterialType==video::EMT_NORMAL_MAP_SOLID) + { + SMesh* tmpmesh = new SMesh(); + tmpmesh->addMeshBuffer(Materials[i]->Meshbuffer); + SceneManager->getMeshManipulator()->createMeshWithTangents(tmpmesh, true, true); + Mesh->addMeshBuffer(tmpmesh->getMeshBuffer(0)); + tmpmesh->getMeshBuffer(0)->drop(); + tmpmesh->drop(); + } + else + { + SceneManager->getMeshManipulator()->recalculateNormals(Materials[i]->Meshbuffer); + Mesh->addMeshBuffer(Materials[i]->Meshbuffer); + } + Materials[i]->Meshbuffer->drop(); + // clear the material array elements + delete Materials[i]; + } + Mesh->recalculateBoundingBox(); + + SAnimatedMesh* am = new SAnimatedMesh(); + am->Type = EAMT_3DS; + am->addMesh(Mesh); + am->recalculateBoundingBox(); + Mesh->drop(); + Mesh = 0; + + Points.clear(); + Indices.clear(); + MaterialMapping.clear(); + TCoords.clear(); + Materials.clear(); + Images.clear(); + VmPolyPointsIndex.clear(); + VmCoordsIndex.clear(); + UvIndex.clear(); + UvName.clear(); + + return am; +} + + +bool CLWOMeshFileLoader::readChunks() +{ + s32 lastPos; + u32 size; + unsigned int uiType; + char type[5]; + type[4]=0; + tLWOLayerInfo layer; + + while(File->getPos()getSize()) + { + File->read(&type, 4); + //Convert 4-char string to 4-byte integer + //Makes it possible to do a switch statement + uiType = charsToUInt(type); + File->read(&size, 4); +#ifndef __BIG_ENDIAN__ + size=os::Byteswap::byteswap(size); +#endif + lastPos=File->getPos(); + + switch(uiType) + { + case charsToUIntD('L','A','Y','R'): + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading layer."); +#endif + u16 tmp16; + File->read(&tmp16, 2); // number + File->read(&tmp16, 2); // flags + size -= 4; +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + if (((FormatVersion==1)&&(tmp16!=1)) || + ((FormatVersion==2)&&(tmp16&1))) + layer.Active=false; + else + layer.Active=true; + if (FormatVersion==2) + size -= readVec(layer.Pivot); + size -= readString(layer.Name); + if (size) + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + layer.Parent = tmp16; + } + } + break; + case charsToUIntD('P','N','T','S'): + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading points."); +#endif + core::vector3df vec; + Points.clear(); + const u32 tmpsize = size/12; + Points.reallocate(tmpsize); + for (u32 i=0; iName=""; + mat->Meshbuffer=new scene::SMeshBuffer(); + size -= readString(mat->Name); + if (FormatVersion!=2) + mat->TagType = 1; // format 2 has more types + Materials.push_back(mat); + } + } + break; + case charsToUIntD('P','T','A','G'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading tag mapping."); +#endif + readTagMapping(size); + break; + case charsToUIntD('V','M','A','D'): // discontinuous vertex mapping, i.e. additional texcoords +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading Vertex mapping VMAD."); +#endif + readDiscVertexMapping(size); +// case charsToUIntD('V','M','P','A'): +// case charsToUIntD('E','N','V','L'): + break; + case charsToUIntD('C','L','I','P'): + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading clips."); +#endif + u32 index; + u16 subsize; + File->read(&index, 4); +#ifndef __BIG_ENDIAN__ + index=os::Byteswap::byteswap(index); +#endif + size -= 4; + while (size != 0) + { + File->read(&type, 4); + File->read(&subsize, 2); +#ifndef __BIG_ENDIAN__ + subsize=os::Byteswap::byteswap(subsize); +#endif + size -= 6; + if (strncmp(type, "STIL", 4)) + { + File->seek(subsize, true); + size -= subsize; + continue; + } + core::stringc path; + size -= readString(path, subsize); + #ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loaded clip", path.c_str()); + #endif + Images.push_back(path); + } + } + break; + case charsToUIntD('S','U','R','F'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading material."); +#endif + readMat(size); + break; + case charsToUIntD('B','B','O','X'): + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading bbox."); +#endif + // not stored + core::vector3df vec; + for (u32 i=0; i<2; ++i) + readVec(vec); + size -= 24; + } + break; + case charsToUIntD('D','E','S','C'): + case charsToUIntD('T','E','X','T'): + { + core::stringc text; + size -= readString(text, size); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader text", text); +#endif + } + break; + // not needed + case charsToUIntD('I','C','O','N'): + // not yet supported + case charsToUIntD('P','C','H','S'): + case charsToUIntD('C','R','V','S'): + default: +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: skipping ", type); +#endif + //Go to next chunk + File->seek(lastPos + size, false); + break; + } + } + return true; +} + + +void CLWOMeshFileLoader::readObj1(u32 size) +{ + u32 pos; + u16 numVerts, vertIndex; + s16 material; + video::S3DVertex vertex; + vertex.Color=0xffffffff; + + while (size!=0) + { + File->read(&numVerts, 2); +#ifndef __BIG_ENDIAN__ + numVerts=os::Byteswap::byteswap(numVerts); +#endif + pos=File->getPos(); + // skip forward to material number + File->seek(2*numVerts, true); + File->read(&material, 2); +#ifndef __BIG_ENDIAN__ + material=os::Byteswap::byteswap(material); +#endif + size -=2*numVerts+4; + // detail meshes ? + scene::SMeshBuffer *mb; + if (material<0) + mb=Materials[-material-1]->Meshbuffer; + else + mb=Materials[material-1]->Meshbuffer; + // back to vertex list start + File->seek(pos, false); + + const u16 vertCount=mb->Vertices.size(); + for (u16 i=0; iread(&vertIndex, 2); +#ifndef __BIG_ENDIAN__ + vertIndex=os::Byteswap::byteswap(vertIndex); +#endif + vertex.Pos=Points[vertIndex]; + mb->Vertices.push_back(vertex); + } + for (u16 i=1; iIndices.push_back(vertCount); + mb->Indices.push_back(vertCount+i); + mb->Indices.push_back(vertCount+i+1); + } + // skip material number and detail surface count + // detail surface can be read just as a normal one now + if (material<0) + File->read(&material, 2); + File->read(&material, 2); + } +} + + +void CLWOMeshFileLoader::readVertexMapping(u32 size) +{ + char type[5]={0}; + u16 dimension; + core::stringc name; + File->read(&type, 4); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: Vertex map type", type); +#endif + File->read(&dimension,2); +#ifndef __BIG_ENDIAN__ + dimension=os::Byteswap::byteswap(dimension); +#endif + size -= 6; + size -= readString(name); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: Vertex map", name.c_str()); +#endif + if (strncmp(type, "TXUV", 4)) // also support RGB, RGBA, WGHT, ... + { + File->seek(size, true); + return; + } + UvName.push_back(name); + + TCoords.push_back(core::array()); + core::array& UvCoords=TCoords.getLast(); + UvCoords.reallocate(Points.size()); + UvIndex.push_back(core::array()); + core::array& UvPointsArray=UvIndex.getLast(); + UvPointsArray.reallocate(Points.size()); + + u32 index; + core::vector2df tcoord; + while (size) + { + size -= readVX(index); + File->read(&tcoord.X, 4); + File->read(&tcoord.Y, 4); + size -= 8; +#ifndef __BIG_ENDIAN__ + index=os::Byteswap::byteswap(index); + tcoord.X=os::Byteswap::byteswap(tcoord.X); + tcoord.Y=os::Byteswap::byteswap(tcoord.Y); +#endif + UvCoords.push_back(tcoord); + UvPointsArray.push_back(index); + } +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: UvCoords", core::stringc(UvCoords.size())); +#endif +} + + +void CLWOMeshFileLoader::readDiscVertexMapping(u32 size) +{ + char type[5]={0}; + u16 dimension; + core::stringc name; + File->read(&type, 4); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: Discontinuous vertex map type", type); +#endif + File->read(&dimension,2); +#ifndef __BIG_ENDIAN__ + dimension=os::Byteswap::byteswap(dimension); +#endif + size -= 6; + size -= readString(name); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: Discontinuous vertex map", name.c_str()); +#endif + if (strncmp(type, "TXUV", 4)) + { + File->seek(size, true); + return; + } + DUvName.push_back(name); + VmPolyPointsIndex.push_back(core::array()); + core::array& VmPolyPoints=VmPolyPointsIndex.getLast(); + + VmCoordsIndex.push_back(core::array()); + core::array& VmCoords=VmCoordsIndex.getLast(); + + u32 vmpolys; + u32 vmpoints; + core::vector2df vmcoords; + while (size) + { + size-=readVX(vmpoints); + size-=readVX(vmpolys); + File->read(&vmcoords.X, 4); + File->read(&vmcoords.Y, 4); + size -= 8; +#ifndef __BIG_ENDIAN__ + vmpoints=os::Byteswap::byteswap(vmpoints); + vmpolys=os::Byteswap::byteswap(vmpolys); + vmcoords.X=os::Byteswap::byteswap(vmcoords.X); + vmcoords.Y=os::Byteswap::byteswap(vmcoords.Y); +#endif + VmCoords.push_back(vmcoords); + VmPolyPoints.push_back(vmpolys); + VmPolyPoints.push_back(vmpoints); + } +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: VmCoords", core::stringc(VmCoords.size())); +#endif +} + + +void CLWOMeshFileLoader::readTagMapping(u32 size) +{ + char type[5]; + type[4]=0; + File->read(&type, 4); + size -= 4; + if ((strncmp(type, "SURF", 4))||(Indices.size()==0)) + { + File->seek(size, true); + return; + } + + while (size!=0) + { + u16 tag; + u32 polyIndex; + size-=readVX(polyIndex); + File->read(&tag, 2); +#ifndef __BIG_ENDIAN__ + tag=os::Byteswap::byteswap(tag); +#endif + size -= 2; + MaterialMapping[polyIndex]=tag; + Materials[tag]->TagType=1; + } +} + + +void CLWOMeshFileLoader::readObj2(u32 size) +{ + char type[5]; + type[4]=0; + File->read(&type, 4); + size -= 4; + Indices.clear(); + if (strncmp(type, "FACE", 4)) // also possible are splines, subdivision patches, metaballs, and bones + { + File->seek(size, true); + return; + } + u16 numVerts=0; + while (size!=0) + { + File->read(&numVerts, 2); +#ifndef __BIG_ENDIAN__ + numVerts=os::Byteswap::byteswap(numVerts); +#endif + // mask out flags + numVerts &= 0x03FF; + + size -= 2; + Indices.push_back(core::array()); + u32 vertIndex; + core::array& polyArray = Indices.getLast(); + polyArray.reallocate(numVerts); + for (u16 i=0; iTagType==1) && (Materials[i]->Name==name)) + { + mat=Materials[i]; + break; + } + } + if (!mat) + { + File->seek(size, true); + return; + } + if (FormatVersion==2) + size -= readString(name); + + video::SMaterial& irrMat=mat->Meshbuffer->Material; + + u8 currTexture=0; + while (size!=0) + { + char type[5]; + type[4]=0; + u32 uiType; + u32 tmp32; + u16 subsize, tmp16; + f32 tmpf32; + File->read(&type, 4); + //Convert 4-char string to 4-byte integer + //Makes it possible to do a switch statement + uiType = charsToUInt(type); + File->read(&subsize, 2); +#ifndef __BIG_ENDIAN__ + subsize=os::Byteswap::byteswap(subsize); +#endif + size -= 6; + switch (uiType) + { + case charsToUIntD('C','O','L','R'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading Ambient color."); +#endif + { + s32 colSize = readColor(irrMat.DiffuseColor); + irrMat.AmbientColor=irrMat.DiffuseColor; + size -= colSize; + subsize -= colSize; + if (FormatVersion==2) + size -= readVX(mat->Envelope[0]); + } + break; + case charsToUIntD('D','I','F','F'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading Diffuse color."); +#endif + { + if (FormatVersion==2) + { + File->read(&mat->Diffuse, 4); +#ifndef __BIG_ENDIAN__ + mat->Diffuse=os::Byteswap::byteswap(mat->Diffuse); +#endif + size -= 4; + subsize -= 4; + size -= readVX(mat->Envelope[1]); + } + else + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + mat->Diffuse=tmp16/256.0f; + size -= 2; + subsize -= 2; + } + } + break; + case charsToUIntD('V','D','I','F'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading Diffuse color."); +#endif + { + File->read(&mat->Diffuse, 4); +#ifndef __BIG_ENDIAN__ + mat->Diffuse=os::Byteswap::byteswap(mat->Diffuse); +#endif + size -= 4; + } + break; + case charsToUIntD('L','U','M','I'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading luminance."); +#endif + { + if (FormatVersion==2) + { + File->read(&mat->Luminance, 4); +#ifndef __BIG_ENDIAN__ + mat->Luminance=os::Byteswap::byteswap(mat->Luminance); +#endif + size -= 4; + subsize -= 4; + size -= readVX(mat->Envelope[2]); + } + else + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + mat->Luminance=tmp16/256.0f; + size -= 2; + subsize -= 2; + } } + break; + case charsToUIntD('V','L','U','M'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading luminance."); +#endif + { + File->read(&mat->Luminance, 4); +#ifndef __BIG_ENDIAN__ + mat->Luminance=os::Byteswap::byteswap(mat->Luminance); +#endif + size -= 4; + } + break; + case charsToUIntD('S','P','E','C'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading specular."); +#endif + { + if (FormatVersion==2) + { + File->read(&mat->Specular, 4); +#ifndef __BIG_ENDIAN__ + mat->Specular=os::Byteswap::byteswap(mat->Specular); +#endif + size -= 4; + subsize -= 4; + size -= readVX(mat->Envelope[3]); + } + else + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + mat->Specular=tmp16/256.0f;; + size -= 2; + subsize -= 2; + } + } + break; + case charsToUIntD('V','S','P','C'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading specular."); +#endif + { + File->read(&mat->Specular, 4); +#ifndef __BIG_ENDIAN__ + mat->Specular=os::Byteswap::byteswap(mat->Specular); +#endif + size -= 4; + } + break; + case charsToUIntD('R','E','F','L'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading reflection."); +#endif + { + if (FormatVersion==2) + { + File->read(&mat->Reflection, 4); +#ifndef __BIG_ENDIAN__ + mat->Reflection=os::Byteswap::byteswap(mat->Reflection); +#endif + size -= 4; + subsize -= 4; + size -= readVX(mat->Envelope[4]); + } + else + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + mat->Reflection=tmp16/256.0f; + size -= 2; + subsize -= 2; + } + } + break; + case charsToUIntD('V','R','F','L'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading reflection."); +#endif + { + File->read(&mat->Reflection, 4); +#ifndef __BIG_ENDIAN__ + mat->Reflection=os::Byteswap::byteswap(mat->Reflection); +#endif + size -= 4; + } + break; + case charsToUIntD('T','R','A','N'): + { + if (FormatVersion==2) + { + File->read(&mat->Transparency, 4); +#ifndef __BIG_ENDIAN__ + mat->Transparency=os::Byteswap::byteswap(mat->Transparency); +#endif + size -= 4; + subsize -= 4; + size -= readVX(mat->Envelope[5]); + } + else + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + mat->Transparency=tmp16/256.0f; + size -= 2; + subsize -= 2; + } +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading transparency", core::stringc(mat->Transparency).c_str()); +#endif + } + break; + case charsToUIntD('V','T','R','N'): + { + File->read(&mat->Transparency, 4); +#ifndef __BIG_ENDIAN__ + mat->Transparency=os::Byteswap::byteswap(mat->Transparency); +#endif + size -= 4; + } +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading transparency", core::stringc(mat->Transparency).c_str()); +#endif + break; + case charsToUIntD('T','R','N','L'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading translucency."); +#endif + { + File->read(&mat->Translucency, 4); +#ifndef __BIG_ENDIAN__ + mat->Translucency=os::Byteswap::byteswap(mat->Translucency); +#endif + size -= 4; + subsize -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[6]); + } + break; + case charsToUIntD('G','L','O','S'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading glossy."); +#endif + { + if (FormatVersion == 2) + { + File->read(&irrMat.Shininess, 4); +#ifndef __BIG_ENDIAN__ + irrMat.Shininess=os::Byteswap::byteswap(irrMat.Shininess); +#endif + size -= 4; + subsize -= 4; + size -= readVX(mat->Envelope[7]); + } + else + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + irrMat.Shininess=tmp16/16.f; + size -= 2; + subsize -= 2; + } + } + break; + case charsToUIntD('S','H','R','P'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading sharpness."); +#endif + { + File->read(&mat->Sharpness, 4); +#ifndef __BIG_ENDIAN__ + mat->Sharpness=os::Byteswap::byteswap(mat->Sharpness); +#endif + size -= 4; + subsize -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[8]); + } + break; + case charsToUIntD('B','U','M','P'): + case charsToUIntD('T','A','M','P'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading bumpiness."); +#endif + { + File->read(&tmpf32, 4); +#ifndef __BIG_ENDIAN__ + tmpf32=os::Byteswap::byteswap(tmpf32); +#endif + if (currTexture==6) + irrMat.MaterialTypeParam=tmpf32; + size -= 4; + subsize -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[9]); + } + break; + case charsToUIntD('S','I','D','E'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading backface culled."); +#endif + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + if (tmp16==1) + irrMat.BackfaceCulling=true; + else if (tmp16==3) + irrMat.BackfaceCulling=false; + size -= 2; + } + break; + case charsToUIntD('S','M','A','N'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading smoothing angle."); +#endif + { + File->read(&mat->SmoothingAngle, 4); +#ifndef __BIG_ENDIAN__ + mat->SmoothingAngle=os::Byteswap::byteswap(mat->SmoothingAngle); +#endif + size -= 4; + } + break; + case charsToUIntD('R','F','O','P'): + case charsToUIntD('R','F','L','T'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading reflection mode."); +#endif + { + File->read(&mat->ReflMode, 2); +#ifndef __BIG_ENDIAN__ + mat->ReflMode=os::Byteswap::byteswap(mat->ReflMode); +#endif + size -= 2; + } + break; + case charsToUIntD('R','I','M','G'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading reflection map."); +#endif + { + if (FormatVersion==2) + { + size -= readVX(tmp32); + if (tmp32) + mat->ReflMap=Images[tmp32-1]; + } + else + size -= readString(mat->ReflMap, size); + } + break; + case charsToUIntD('R','S','A','N'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading reflection seam angle."); +#endif + { + File->read(&mat->ReflSeamAngle, 4); +#ifndef __BIG_ENDIAN__ + mat->ReflSeamAngle=os::Byteswap::byteswap(mat->ReflSeamAngle); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[10]); + } + break; + case charsToUIntD('R','B','L','R'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading reflection blur."); +#endif + { + File->read(&mat->ReflBlur, 4); +#ifndef __BIG_ENDIAN__ + mat->ReflBlur=os::Byteswap::byteswap(mat->ReflBlur); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[11]); + } + break; + case charsToUIntD('R','I','N','D'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading refraction index."); +#endif + { + File->read(&mat->RefrIndex, 4); +#ifndef __BIG_ENDIAN__ + mat->RefrIndex=os::Byteswap::byteswap(mat->RefrIndex); +#endif + size -= 4; + subsize -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[12]); + } + break; + case charsToUIntD('T','R','O','P'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading refraction options."); +#endif + { + File->read(&mat->TranspMode, 2); +#ifndef __BIG_ENDIAN__ + mat->TranspMode=os::Byteswap::byteswap(mat->TranspMode); +#endif + size -= 2; + } + break; + case charsToUIntD('T','I','M','G'): + { + if (FormatVersion==2) + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading refraction map."); +#endif + size -= readVX(tmp32); +#ifndef __BIG_ENDIAN__ + tmp32=os::Byteswap::byteswap(tmp32); +#endif + if (tmp32) + mat->Texture[currTexture].Map=Images[tmp32-1]; + } + else + { + size -= readString(mat->Texture[currTexture].Map, size); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading image", mat->Texture[currTexture].Map.c_str()); +#endif + } + } + break; + case charsToUIntD('T','B','L','R'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading transparency blur."); +#endif + { + File->read(&mat->TranspBlur, 4); +#ifndef __BIG_ENDIAN__ + mat->TranspBlur=os::Byteswap::byteswap(mat->TranspBlur); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[13]); + } + break; + case charsToUIntD('C','L','R','H'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading highlight color."); +#endif + { + File->read(&mat->HighlightColor, 4); +#ifndef __BIG_ENDIAN__ + mat->HighlightColor=os::Byteswap::byteswap(mat->HighlightColor); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[14]); + } + break; + case charsToUIntD('C','L','R','F'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading color filter."); +#endif + { + File->read(&mat->ColorFilter, 4); +#ifndef __BIG_ENDIAN__ + mat->ColorFilter=os::Byteswap::byteswap(mat->ColorFilter); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[15]); + } + break; + case charsToUIntD('A','D','T','R'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading additive transparency."); +#endif + { + File->read(&mat->AdditiveTransparency, 4); +#ifndef __BIG_ENDIAN__ + mat->AdditiveTransparency=os::Byteswap::byteswap(mat->AdditiveTransparency); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[16]); + } + break; + case charsToUIntD('G','L','O','W'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading glow."); +#endif + { + if (FormatVersion==0) + { + File->read(&mat->GlowIntensity, 4); +#ifndef __BIG_ENDIAN__ + mat->GlowIntensity=os::Byteswap::byteswap(mat->GlowIntensity); +#endif + size -= 4; + } + else + { + File->read(&mat->Glow, 2); +#ifndef __BIG_ENDIAN__ + mat->Glow=os::Byteswap::byteswap(mat->Glow); +#endif + size -= 2; + File->read(&mat->GlowIntensity, 4); +#ifndef __BIG_ENDIAN__ + mat->GlowIntensity=os::Byteswap::byteswap(mat->GlowIntensity); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[17]); + File->read(&mat->GlowSize, 4); +#ifndef __BIG_ENDIAN__ + mat->GlowSize=os::Byteswap::byteswap(mat->GlowSize); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[18]); + } + } + break; + case charsToUIntD('G','V','A','L'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading glow intensity."); +#endif + { + File->read(&mat->GlowIntensity, 4); +#ifndef __BIG_ENDIAN__ + mat->GlowIntensity=os::Byteswap::byteswap(mat->GlowIntensity); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[17]); + } + break; + case charsToUIntD('L','I','N','E'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading isWireframe."); +#endif + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + if (tmp16&1) + irrMat.Wireframe=true; + size -= 2; + if (size!=0) + { + File->read(&irrMat.Thickness, 4); +#ifndef __BIG_ENDIAN__ + irrMat.Thickness=os::Byteswap::byteswap(irrMat.Thickness); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[19]); + } + if (size!=0) + { + video::SColor lineColor; + size -= readColor(lineColor); + if (FormatVersion==2) + size -= readVX(mat->Envelope[20]); + } + } + break; + case charsToUIntD('A','L','P','H'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading alpha mode."); +#endif + { + File->read(&mat->AlphaMode, 2); +#ifndef __BIG_ENDIAN__ + mat->AlphaMode=os::Byteswap::byteswap(mat->AlphaMode); +#endif + size -= 2; + File->read(&mat->AlphaValue, 4); +#ifndef __BIG_ENDIAN__ + mat->AlphaValue=os::Byteswap::byteswap(mat->AlphaValue); +#endif + size -= 4; + } + break; + case charsToUIntD('V','C','O','L'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading vertex color."); +#endif + { + File->read(&mat->VertexColorIntensity, 4); +#ifndef __BIG_ENDIAN__ + mat->VertexColorIntensity=os::Byteswap::byteswap(mat->VertexColorIntensity); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[21]); + File->read(&tmp32, 4); // skip type + size -= 4; + core::stringc tmpname; + size -= readString(tmpname, size); +// mat->VertexColor = getColorVMAP(tmpname); + } + break; + case charsToUIntD('F','L','A','G'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading flag."); +#endif + { + File->read(&mat->Flags, 2); +#ifndef __BIG_ENDIAN__ + mat->Flags=os::Byteswap::byteswap(mat->Flags); +#endif + if (mat->Flags&1) + mat->Luminance=1.0f; + if (mat->Flags&256) + irrMat.BackfaceCulling=false; + size -= 2; + } + break; + case charsToUIntD('E','D','G','E'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading edge."); +#endif + { + File->read(&mat->EdgeTransparency, 4); +#ifndef __BIG_ENDIAN__ + mat->EdgeTransparency=os::Byteswap::byteswap(mat->EdgeTransparency); +#endif + size -= 4; + } + break; + case charsToUIntD('C','T','E','X'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading ctex."); +#endif + currTexture=0; + size -= readString(mat->Texture[currTexture].Type, size); + break; + case charsToUIntD('D','T','E','X'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading dtex."); +#endif + currTexture=1; + size -= readString(mat->Texture[currTexture].Type, size); + break; + case charsToUIntD('S','T','E','X'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading stex."); +#endif + currTexture=2; + size -= readString(mat->Texture[currTexture].Type, size); + break; + case charsToUIntD('R','T','E','X'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading rtex."); +#endif + currTexture=3; + size -= readString(mat->Texture[currTexture].Type, size); + break; + case charsToUIntD('T','T','E','X'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading ttex."); +#endif + currTexture=4; + size -= readString(mat->Texture[currTexture].Type, size); + break; + case charsToUIntD('L','T','E','X'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading ltex."); +#endif + currTexture=5; + size -= readString(mat->Texture[currTexture].Type, size); + break; + case charsToUIntD('B','T','E','X'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading btex."); +#endif + currTexture=6; + size -= readString(mat->Texture[currTexture].Type, size); + break; + case charsToUIntD('T','A','L','P'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading alpha map."); +#endif + size -= readString(mat->Texture[currTexture].AlphaMap, size); + break; + case charsToUIntD('T','F','L','G'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture flag."); +#endif + { + File->read(&mat->Texture[currTexture].Flags, 2); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].Flags=os::Byteswap::byteswap(mat->Texture[currTexture].Flags); +#endif + size -= 2; + } + break; + case charsToUIntD('E','N','A','B'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading isEnabled."); +#endif + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + mat->Texture[currTexture].Active=(tmp16!=0); + size -= 2; + } + break; + case charsToUIntD('W','R','A','P'): + case charsToUIntD('T','W','R','P'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture wrap."); +#endif + { + File->read(&mat->Texture[currTexture].WidthWrap, 2); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].WidthWrap=os::Byteswap::byteswap(mat->Texture[currTexture].WidthWrap); +#endif + File->read(&mat->Texture[currTexture].HeightWrap, 2); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].HeightWrap=os::Byteswap::byteswap(mat->Texture[currTexture].HeightWrap); +#endif + size -= 4; + } + break; + case charsToUIntD('T','V','E','L'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture velocity."); +#endif + size -= readVec(mat->Texture[currTexture].Velocity); + break; + case charsToUIntD('T','C','L','R'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture color."); +#endif + size -= readColor(mat->Texture[currTexture].Color); + break; + case charsToUIntD('A','A','S','T'): + case charsToUIntD('T','A','A','S'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture antialias."); +#endif + { + tmp16=0; + if (FormatVersion==2) + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + size -= 2; + } + File->read(&mat->Texture[currTexture].AntiAliasing, 4); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].AntiAliasing=os::Byteswap::byteswap(mat->Texture[currTexture].AntiAliasing); +#endif + if (tmp16 & ~0x01) + mat->Texture[currTexture].AntiAliasing=0.0f; // disabled + size -= 4; + } + break; + case charsToUIntD('T','O','P','C'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture opacity."); +#endif + { + File->read(&mat->Texture[currTexture].Opacity, 4); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].Opacity=os::Byteswap::byteswap(mat->Texture[currTexture].Opacity); +#endif + size -= 4; + } + break; + case charsToUIntD('O','P','A','C'): + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture opacity and type."); +#endif + File->read(&mat->Texture[currTexture].OpacType, 2); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].OpacType=os::Byteswap::byteswap(mat->Texture[currTexture].OpacType); +#endif + File->read(&mat->Texture[currTexture].Opacity, 4); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].Opacity=os::Byteswap::byteswap(mat->Texture[currTexture].Opacity); +#endif + size -= 6; + subsize -= 6; + if (FormatVersion==2) + size -= readVX(mat->Envelope[22]); + } + break; + case charsToUIntD('A','X','I','S'): + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + mat->Texture[currTexture].Axis=(u8)tmp16; + size -= 2; +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading axis value", core::stringc(tmp16).c_str()); +#endif + } + break; + case charsToUIntD('T','M','A','P'): // empty separation chunk + break; + case charsToUIntD('T','C','T','R'): + case charsToUIntD('C','N','T','R'): + { + core::vector3df& center=mat->Texture[currTexture].Center; + size -= readVec(center); + if (FormatVersion==2) + size -= readVX(mat->Envelope[22]); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture center", (core::stringc(center.X)+" "+core::stringc(center.Y)+" "+core::stringc(center.Z)).c_str()); +#endif + } + break; + case charsToUIntD('T','S','I','Z'): + case charsToUIntD('S','I','Z','E'): + { + core::vector3df& tsize=mat->Texture[currTexture].Size; + size -= readVec(tsize); + if (FormatVersion==2) + size -= readVX(mat->Envelope[22]); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture size", (core::stringc(tsize.X)+" "+core::stringc(tsize.Y)+" "+core::stringc(tsize.Z)).c_str()); +#endif + } + break; + case charsToUIntD('R','O','T','A'): + { + core::vector3df rotation; + size -= readVec(rotation); + if (FormatVersion==2) + size -= readVX(mat->Envelope[22]); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture rotation", (core::stringc(rotation.X)+" "+core::stringc(rotation.Y)+" "+core::stringc(rotation.Z)).c_str()); +#endif + } + break; + case charsToUIntD('O','R','E','F'): + { + core::stringc tmpname; + size -= readString(tmpname); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: texture reference object", tmpname.c_str()); +#endif + } + break; + case charsToUIntD('T','F','A','L'): + case charsToUIntD('F','A','L','L'): + { + if (FormatVersion==2) + { + u16 tmp16; + File->read(&tmp16, 2); + size -= 2; +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + } + + core::vector3df& falloff=mat->Texture[currTexture].Falloff; + size -= readVec(falloff); + if (FormatVersion==2) + size -= readVX(mat->Envelope[22]); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture falloff"); +#endif + } + break; + case charsToUIntD('C','S','Y','S'): + { + u16 tmp16; + File->read(&tmp16, 2); + size -= 2; +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: texture coordinate system", tmp16==0?"object coords":"world coords"); +#endif + } + break; + case charsToUIntD('T','V','A','L'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture value."); +#endif + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + mat->Texture[currTexture].Value=tmp16/256.0f; + size -= 2; + } + break; + case charsToUIntD('T','F','P','0'): + case charsToUIntD('T','S','P','0'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture param 0."); +#endif + { + File->read(&mat->Texture[currTexture].FParam[0], 4); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].FParam[0]=os::Byteswap::byteswap(mat->Texture[currTexture].FParam[0]); +#endif + size -= 4; + } + break; + case charsToUIntD('T','F','P','1'): + case charsToUIntD('T','S','P','1'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture param 1."); +#endif + { + File->read(&mat->Texture[currTexture].FParam[1], 4); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].FParam[1]=os::Byteswap::byteswap(mat->Texture[currTexture].FParam[1]); +#endif + size -= 4; + } + break; + case charsToUIntD('T','F','P','2'): + case charsToUIntD('T','S','P','2'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture param 2."); +#endif + { + File->read(&mat->Texture[currTexture].FParam[2], 4); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].FParam[2]=os::Byteswap::byteswap(mat->Texture[currTexture].FParam[2]); +#endif + size -= 4; + } + break; + case charsToUIntD('T','F','R','Q'): + case charsToUIntD('T','I','P','0'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture iparam 0."); +#endif + { + File->read(&mat->Texture[currTexture].IParam[0], 2); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].IParam[0]=os::Byteswap::byteswap(mat->Texture[currTexture].IParam[0]); +#endif + size -= 2; + } + break; + case charsToUIntD('T','I','P','1'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture param 1."); +#endif + { + File->read(&mat->Texture[currTexture].IParam[1], 2); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].IParam[1]=os::Byteswap::byteswap(mat->Texture[currTexture].IParam[1]); +#endif + size -= 2; + } + break; + case charsToUIntD('T','I','P','2'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture param 2."); +#endif + { + File->read(&mat->Texture[currTexture].IParam[2], 2); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].IParam[2]=os::Byteswap::byteswap(mat->Texture[currTexture].IParam[2]); +#endif + size -= 2; + } + break; + case charsToUIntD('V','M','A','P'): + { + size -= readString(mat->Texture[currTexture].UVname); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading material vmap binding",mat->Texture[currTexture].UVname.c_str()); +#endif + } + break; + case charsToUIntD('B','L','O','K'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading blok."); +#endif + { + core::stringc ordinal; + File->read(&type, 4); + File->read(&subsize, 2); +#ifndef __BIG_ENDIAN__ + subsize=os::Byteswap::byteswap(subsize); +#endif + size -= 6; + size -= readString(ordinal, size); + } + break; + case charsToUIntD('C','H','A','N'): + { + File->read(&type, 4); + size -= 4; + if (!strncmp(type, "COLR", 4)) + currTexture=0; + else if (!strncmp(type, "DIFF", 4)) + currTexture=1; + else if (!strncmp(type, "LUMI", 4)) + currTexture=5; + else if (!strncmp(type, "SPEC", 4)) + currTexture=2; + else if (!strncmp(type, "REFL", 4)) + currTexture=3; + else if (!strncmp(type, "TRAN", 4)) + currTexture=4; + else if (!strncmp(type, "BUMP", 4)) + currTexture=6; + } +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading channel ", type); +#endif + break; + case charsToUIntD('I','M','A','G'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading channel map."); +#endif + { + u16 index; + File->read(&index, 2); +#ifndef __BIG_ENDIAN__ + index=os::Byteswap::byteswap(index); +#endif + size -= 2; + if (index) + mat->Texture[currTexture].Map=Images[index-1]; + } + break; + case charsToUIntD('P','R','O','J'): // define the projection type +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading channel projection type."); +#endif + { + u16 index; + File->read(&index, 2); +#ifndef __BIG_ENDIAN__ + index=os::Byteswap::byteswap(index); +#endif + size -= 2; +#ifdef LWO_READER_DEBUG + if (index != 5) + os::Printer::log("LWO loader: wrong channel projection type", core::stringc(index).c_str()); +#endif + mat->Texture[currTexture].Projection=(u8)index; + } + break; + case charsToUIntD('W','R','P','W'): // for cylindrical and spherical projections + case charsToUIntD('W','R','P','H'): // for cylindrical and spherical projections + default: + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: skipping ", core::stringc((char*)&uiType, 4)); +#endif + File->seek(subsize, true); + size -= subsize; + } + } + } + + if (mat->Transparency != 0.f) + { + irrMat.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; + } +} + + +u32 CLWOMeshFileLoader::readColor(video::SColor& color) +{ + if (FormatVersion!=2) + { + u8 colorComponent; + File->read(&colorComponent, 1); + color.setRed(colorComponent); + File->read(&colorComponent, 1); + color.setGreen(colorComponent); + File->read(&colorComponent, 1); + color.setBlue(colorComponent); + // unknown value + File->read(&colorComponent, 1); + return 4; + } + else + { + video::SColorf col; + File->read(&col.r, 4); +#ifndef __BIG_ENDIAN__ + col.r=os::Byteswap::byteswap(col.r); +#endif + File->read(&col.g, 4); +#ifndef __BIG_ENDIAN__ + col.g=os::Byteswap::byteswap(col.g); +#endif + File->read(&col.b, 4); +#ifndef __BIG_ENDIAN__ + col.b=os::Byteswap::byteswap(col.b); +#endif + color=col.toSColor(); + return 12; + } +} + +u32 CLWOMeshFileLoader::readString(core::stringc& name, u32 size) +{ + c8 c; + + name=""; + if (size) + name.reserve(size); + File->read(&c, 1); + while (c) + { + name.append(c); + File->read(&c, 1); + } + // read extra 0 upon odd file position + if (File->getPos() & 0x1) + { + File->read(&c, 1); + return (name.size()+2); + } + return (name.size()+1); +} + + +u32 CLWOMeshFileLoader::readVec(core::vector3df& vec) +{ + File->read(&vec.X, 4); +#ifndef __BIG_ENDIAN__ + vec.X=os::Byteswap::byteswap(vec.X); +#endif + File->read(&vec.Y, 4); +#ifndef __BIG_ENDIAN__ + vec.Y=os::Byteswap::byteswap(vec.Y); +#endif + File->read(&vec.Z, 4); +#ifndef __BIG_ENDIAN__ + vec.Z=os::Byteswap::byteswap(vec.Z); +#endif + return 12; +} + + +u32 CLWOMeshFileLoader::readVX(u32& num) +{ + u16 tmpIndex; + + File->read(&tmpIndex, 2); +#ifndef __BIG_ENDIAN__ + tmpIndex=os::Byteswap::byteswap(tmpIndex); +#endif + num=tmpIndex; + if (num >= 0xFF00) + { + File->read(&tmpIndex, 2); +#ifndef __BIG_ENDIAN__ + tmpIndex=os::Byteswap::byteswap(tmpIndex); +#endif + num=((num << 16)|tmpIndex) & ~0xFF000000; + return 4; + } + return 2; +} + + +bool CLWOMeshFileLoader::readFileHeader() +{ + u32 Id; + + File->read(&Id, 4); +#ifndef __BIG_ENDIAN__ + Id=os::Byteswap::byteswap(Id); +#endif + if (Id != 0x464f524d) // FORM + return false; + + //skip the file length + File->read(&Id, 4); + + File->read(&Id, 4); +#ifndef __BIG_ENDIAN__ + Id=os::Byteswap::byteswap(Id); +#endif + // Currently supported: LWOB, LWLO, LWO2 + switch (Id) + { + case 0x4c574f42: + FormatVersion = 0; // LWOB + break; + case 0x4c574c4f: + FormatVersion = 1; // LWLO + break; + case 0x4c574f32: + FormatVersion = 2; // LWO2 + break; + default: + return false; // unsupported + } + + return true; +} + + +video::ITexture* CLWOMeshFileLoader::loadTexture(const core::stringc& file) +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + if (FileSystem->existFile(file)) + return driver->getTexture(file); + + core::stringc strippedName=FileSystem->getFileBasename(file); + if (FileSystem->existFile(strippedName)) + return driver->getTexture(strippedName); + core::stringc newpath = FileSystem->getFileDir(File->getFileName()); + newpath.append("/"); + newpath.append(strippedName); + if (FileSystem->existFile(newpath)) + return driver->getTexture(newpath); + os::Printer::log("Could not load texture", file.c_str(), ELL_WARNING); + + return 0; +} + + +} // end namespace scene +} // end namespace irr + -- cgit v1.1