--- Irrlicht.org/C3DSMeshFileLoader.h 2006-03-22 11:35:14.000000000 +0100 +++ Irrlicht.new/C3DSMeshFileLoader.h 2006-04-03 11:51:09.953251079 +0200 @@ -10,6 +10,7 @@ #include "IVideoDriver.h" #include "irrString.h" #include "SMesh.h" +#include "matrix4.h" namespace irr { @@ -79,9 +80,19 @@ ~SCurrentMaterial() { }; + void clear() { + Material=video::SMaterial(); + Name=""; + Filename[0]=""; + Filename[1]=""; + Filename[2]=""; + Filename[3]=""; + Filename[4]=""; + } + video::SMaterial Material; core::stringc Name; - core::stringc Filename; + core::stringc Filename[5]; }; struct SMaterialGroup @@ -121,35 +132,40 @@ bool readChunk(io::IReadFile* file, ChunkData* parent); bool readMaterialChunk(io::IReadFile* file, ChunkData* parent); + bool readFrameChunk(io::IReadFile* file, ChunkData* parent); + bool readTrackChunk(io::IReadFile* file, ChunkData& data, + IMeshBuffer* mb, const core::vector3df& pivot); bool readObjectChunk(io::IReadFile* file, ChunkData* parent); + bool readPercentageChunk(io::IReadFile* file, ChunkData* chunk, float&percentage); bool readColorChunk(io::IReadFile* file, ChunkData* chunk, video::SColor& out); void readChunkData(io::IReadFile* file, ChunkData& data); - void readAndIgnoreString(io::IReadFile* file, ChunkData& data); void readString(io::IReadFile* file, ChunkData& data, core::stringc& out); void readVertices(io::IReadFile* file, ChunkData& data); void readIndices(io::IReadFile* file, ChunkData& data); void readMaterialGroup(io::IReadFile* file, ChunkData& data); void readTextureCoords(io::IReadFile* file, ChunkData& data); - void composeObject(io::IReadFile* file); + void composeObject(io::IReadFile* file, const core::stringc& name); void loadMaterials(io::IReadFile* file); void cleanUp(); - core::stringc getTextureFileName(core::stringc texture, core::stringc model); + core::stringc getTextureFileName(const core::stringc& texture, core::stringc& model); io::IFileSystem* FileSystem; video::IVideoDriver* Driver; f32* Vertices; - u16 CountVertices; u16* Indices; - u16 CountIndices; - u16 CountTCoords; f32* TCoords; + u16 CountVertices; + u16 CountFaces; // = CountIndices/4 + u16 CountTCoords; core::array MaterialGroups; SCurrentMaterial CurrentMaterial; core::array Materials; + core::array MeshBufferNames; + core::matrix4 TransformationMatrix; SMesh* Mesh; }; --- Irrlicht.org/C3DSMeshFileLoader.cpp 2006-04-05 13:31:43.046607929 +0200 +++ Irrlicht.new/C3DSMeshFileLoader.cpp 2006-04-05 13:31:13.169176445 +0200 @@ -3,8 +3,7 @@ // For conditions of distribution and use, see copyright notice in irrlicht.h #include "C3DSMeshFileLoader.h" -#include #include "os.h" #include "SMeshBuffer.h" #include "SAnimatedMesh.h" @@ -29,16 +28,26 @@ // sub chunks of C3DS_EDIT_MATERIAL const u16 C3DS_MATNAME = 0xA000; -const u16 C3DS_MATLUMINANCE = 0xA010; +const u16 C3DS_MATAMBIENT = 0xA010; const u16 C3DS_MATDIFFUSE = 0xA020; const u16 C3DS_MATSPECULAR = 0xA030; const u16 C3DS_MATSHININESS = 0xA040; +const u16 C3DS_MATSHIN2PCT = 0xA041; +const u16 C3DS_TRANSPARENCY = 0xA050; +const u16 C3DS_TWO_SIDE = 0xA081; +const u16 C3DS_WIRE = 0xA085; +const u16 C3DS_SHADING = 0xA100; const u16 C3DS_MATMAP = 0xA200; -const u16 C3DS_MATREFLMAP = 0xA220; -const u16 C3DS_MATOPACMAP = 0xA210; const u16 C3DS_MATSPECMAP = 0xA204; +const u16 C3DS_MATOPACMAP = 0xA210; +const u16 C3DS_MATREFLMAP = 0xA220; const u16 C3DS_MATBUMPMAP = 0xA230; const u16 C3DS_MATMAPFILE = 0xA300; +const u16 C3DS_MAT_TEXTILING = 0xA351; +const u16 C3DS_MAT_USCALE = 0xA354; +const u16 C3DS_MAT_VSCALE = 0xA356; +const u16 C3DS_MAT_UOFFSET = 0xA358; +const u16 C3DS_MAT_VOFFSET = 0xA35A; // subs of C3DS_EDIT_OBJECT const u16 C3DS_OBJTRIMESH = 0x4100; @@ -49,19 +59,43 @@ const u16 C3DS_TRIFACEMAT = 0x4130; const u16 C3DS_TRIUV = 0x4140; const u16 C3DS_TRISMOOTH = 0x4150; -const u16 C3DS_TRILOCAL = 0x4160; +const u16 C3DS_TRIMATRIX = 0x4160; +const u16 C3DS_MESHCOLOR = 0x4165; + +// subs of C3DS_KEYF3DS +const u16 C3DS_KF_HDR = 0xB00A; +const u16 C3DS_AMBIENT_TAG = 0xB001; +const u16 C3DS_OBJECT_TAG = 0xB002; +const u16 C3DS_CAMERA_TAG = 0xB003; +const u16 C3DS_TARGET_TAG = 0xB004; +const u16 C3DS_LIGHTNODE_TAG = 0xB005; +const u16 C3DS_KF_SEG = 0xB008; +const u16 C3DS_KF_CURTIME = 0xB009; +const u16 C3DS_KF_NODE_HDR = 0xB010; +const u16 C3DS_PIVOTPOINT = 0xB013; +const u16 C3DS_BOUNDBOX = 0xB014; +const u16 C3DS_POS_TRACK_TAG = 0xB020; +const u16 C3DS_ROT_TRACK_TAG = 0xB021; +const u16 C3DS_SCL_TRACK_TAG = 0xB022; +const u16 C3DS_NODE_ID = 0xB030; // different color chunk types -const u16 C3DS_COL_RGB = 0x0010; -const u16 C3DS_COL_TRU = 0x0011; -const u16 C3DS_COL_UNK = 0x0013; +const u16 C3DS_COL_RGB = 0x0010; +const u16 C3DS_COL_TRU = 0x0011; +const u16 C3DS_COL_LIN_24 = 0x0012; +const u16 C3DS_COL_LIN_F = 0x0013; + +// percentage chunk types +const u16 C3DS_PERCENTAGE_I = 0x0030; +const u16 C3DS_PERCENTAGE_F = 0x0031; //! Constructor C3DSMeshFileLoader::C3DSMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver) -: FileSystem(fs), Driver(driver), Vertices(0), CountVertices(0), CountIndices(0), +: FileSystem(fs), Driver(driver), Vertices(0), CountVertices(0), CountFaces(0), Indices(0), TCoords(0), CountTCoords(0), Mesh(0) { + TransformationMatrix.makeIdentity(); if (FileSystem) FileSystem->grab(); @@ -114,14 +147,13 @@ file->seek(0); - file->read(&data.header, sizeof(ChunkHeader)); - if (data.header.id != 0x4D4D) + readChunkData(file, data); + if (data.header.id != C3DS_MAIN3DS ) return false; - CurrentMaterial.Material = video::SMaterial(); - CurrentMaterial.Name = ""; - CurrentMaterial.Filename = ""; + CurrentMaterial.clear(); Materials.clear(); + MeshBufferNames.clear(); cleanUp(); if (Mesh) @@ -154,8 +186,47 @@ } +bool C3DSMeshFileLoader::readPercentageChunk(io::IReadFile* file, + ChunkData* chunk, float& percentage) +{ + ChunkData data; + readChunkData(file, data); + + s16 intpercentage; + + switch(data.header.id) + { + case C3DS_PERCENTAGE_I: + { + // read short + file->read(&intpercentage, 2); + percentage=intpercentage/100.0f; + data.read += 2; + } + break; + case C3DS_PERCENTAGE_F: + { + // read float + file->read(&percentage, 4); + data.read += 4; + } + break; + default: + { + // unknown percentage chunk + os::Printer::log("Unknown percentage chunk in 3Ds file.", ELL_WARNING); + file->seek(data.header.length - data.read, true); + data.read += data.header.length - data.read; + } + } + + chunk->read += data.read; + + return true; +} + bool C3DSMeshFileLoader::readColorChunk(io::IReadFile* file, ChunkData* chunk, - video::SColor& out) + video::SColor& out) { ChunkData data; readChunkData(file, data); @@ -163,28 +234,34 @@ u8 c[3]; f32 cf[3]; - if (sizeof(c) == data.header.length - data.read) + switch(data.header.id) + { + case C3DS_COL_TRU: + case C3DS_COL_LIN_24: { // read 8 bit data - file->read(c, data.header.length - data.read); + file->read(c, sizeof(c)); out.set(255, c[0], c[1], c[2]); - data.read += data.header.length - data.read; + data.read += sizeof(c); } - else - if (sizeof(cf) == data.header.length - data.read) + break; + case C3DS_COL_RGB: + case C3DS_COL_LIN_F: { // read float data - file->read(cf, data.header.length - data.read); + file->read(cf, sizeof(cf)); out.set(255, (s32)(cf[0]*255.0f), (s32)(cf[1]*255.0f), (s32)(cf[2]*255.0f)); - data.read += data.header.length - data.read; + data.read += sizeof(cf); } - else + break; + default: { // unknown color chunk size os::Printer::log("Unknown size of color chunk in 3Ds file.", ELL_WARNING); file->seek(data.header.length - data.read, true); data.read += data.header.length - data.read; } + } chunk->read += data.read; @@ -194,7 +271,7 @@ bool C3DSMeshFileLoader::readMaterialChunk(io::IReadFile* file, ChunkData* parent) { - bool inSubChunk = false; + u16 matSection; while(parent->read < parent->header.length) { @@ -215,8 +292,8 @@ delete [] c; } break; - case C3DS_MATLUMINANCE: - readColorChunk(file, &data, CurrentMaterial.Material.EmissiveColor); + case C3DS_MATAMBIENT: + readColorChunk(file, &data, CurrentMaterial.Material.AmbientColor); break; case C3DS_MATDIFFUSE: readColorChunk(file, &data, CurrentMaterial.Material.DiffuseColor); @@ -224,27 +301,105 @@ case C3DS_MATSPECULAR: readColorChunk(file, &data, CurrentMaterial.Material.SpecularColor); break; - case C3DS_MATREFLMAP: + case C3DS_MATSHININESS: + readPercentageChunk(file, &data, CurrentMaterial.Material.Shininess); + break; + case C3DS_TRANSPARENCY: + { + float percentage; + readPercentageChunk(file, &data, percentage); + if (percentage>0.0f) { + CurrentMaterial.Material.MaterialTypeParam=percentage; + CurrentMaterial.Material.MaterialType=video::EMT_TRANSPARENT_VERTEX_ALPHA; + } else { + CurrentMaterial.Material.MaterialType=video::EMT_SOLID; + } + } + break; + case C3DS_WIRE: + CurrentMaterial.Material.Wireframe=true; + break; + case C3DS_TWO_SIDE: + CurrentMaterial.Material.BackfaceCulling=false; + break; + case C3DS_SHADING: + { + s16 flags; + file->read(&flags, 2); + switch (flags) { + case 0: + CurrentMaterial.Material.Wireframe=true; + break; + case 1: + CurrentMaterial.Material.Wireframe=false; + CurrentMaterial.Material.GouraudShading=false; + break; + case 2: + CurrentMaterial.Material.Wireframe=false; + CurrentMaterial.Material.GouraudShading=true; + break; + default: + // phong and metal missing + break; + } + data.read += data.header.length - data.read; + } + break; case C3DS_MATMAP: - case C3DS_MATOPACMAP: case C3DS_MATSPECMAP: + case C3DS_MATOPACMAP: + case C3DS_MATREFLMAP: case C3DS_MATBUMPMAP: - readMaterialChunk(file, &data); + { + f32 percentage=0; + matSection=data.header.id; + if (matSection!=C3DS_MATREFLMAP) + readPercentageChunk(file, &data, percentage); + } break; case C3DS_MATMAPFILE: { // read texture file name c8* c = new c8[data.header.length - data.read]; file->read(c, data.header.length - data.read); - CurrentMaterial.Filename = c; - CurrentMaterial.Filename.make_lower(); + switch (matSection) { + case C3DS_MATMAP: + CurrentMaterial.Filename[0] = c; + break; + case C3DS_MATSPECMAP: + CurrentMaterial.Filename[1] = c; + break; + case C3DS_MATOPACMAP: + CurrentMaterial.Filename[2] = c; + break; + case C3DS_MATREFLMAP: + CurrentMaterial.Filename[3] = c; + break; + case C3DS_MATBUMPMAP: + CurrentMaterial.Filename[4] = c; + break; + } data.read += data.header.length - data.read; delete [] c; - inSubChunk = true; } break; - case C3DS_MATSHININESS: - // TODO: read shinniess + case C3DS_MAT_TEXTILING: + { + s16 flags; + file->read(&flags, 2); + data.read += 2; + } + break; + case C3DS_MAT_USCALE: + case C3DS_MAT_VSCALE: + case C3DS_MAT_UOFFSET: + case C3DS_MAT_VOFFSET: + { + f32 value; + file->read(&value, 4); + data.read += 4; + } + break; default: // ignore chunk file->seek(data.header.length - data.read, true); @@ -254,8 +409,180 @@ parent->read += data.read; } - if (!inSubChunk) - Materials.push_back(CurrentMaterial); + Materials.push_back(CurrentMaterial); + CurrentMaterial.clear(); + + return true; +} + + + +bool C3DSMeshFileLoader::readTrackChunk(io::IReadFile* file, ChunkData& data, + IMeshBuffer* mb, const core::vector3df& pivot) +{ + u16 flags; + u32 flags2; + // Track flags + file->read(&flags, 2); + file->read(&flags2, 4); + file->read(&flags2, 4); + // Num keys + file->read(&flags2, 4); + file->read(&flags2, 4); + // TCB flags + file->read(&flags, 2); + data.read += 20; + + f32 angle=0.0f; + if (data.header.id== C3DS_ROT_TRACK_TAG) { + // Angle + file->read(&angle, sizeof(f32)); + data.read += sizeof(f32); + } + core::vector3df vec; + file->read(&vec.X, sizeof(f32)); + file->read(&vec.Y, sizeof(f32)); + file->read(&vec.Z, sizeof(f32)); + data.read += 12; + vec-=pivot; + + // apply transformation to mesh buffer + if (mb) { + video::S3DVertex *vertices=(video::S3DVertex*)mb->getVertices(); + if (data.header.id==C3DS_POS_TRACK_TAG) { + for (s32 i=0; igetVertexCount(); ++i) + vertices[i].Pos+=vec; + } else + if (data.header.id==C3DS_ROT_TRACK_TAG) { + //TODO + } else + if (data.header.id==C3DS_SCL_TRACK_TAG) { + //TODO + } + } + // skip further frames + file->seek(data.header.length - data.read, true); + data.read += data.header.length - data.read; + return true; +} + + + +bool C3DSMeshFileLoader::readFrameChunk(io::IReadFile* file, ChunkData* parent) +{ + ChunkData data; + + //KF_HDR is always at the beginning + readChunkData(file, data); + if (data.header.id != C3DS_KF_HDR) + return false; + else { + u16 flags; + file->read(&flags, 2); + c8* c = new c8[data.header.length - data.read-4]; + file->read(c, data.header.length - data.read-4); + file->read(&flags, 2); + + data.read += data.header.length - data.read; + parent->read += data.read; + delete [] c; + } + + IMeshBuffer* mb=0; + core::vector3df pivot,bboxCenter; + while(parent->read < parent->header.length) + { + readChunkData(file, data); + + switch(data.header.id) + { + case C3DS_OBJECT_TAG: + { + mb=0; + pivot.set(0.0f, 0.0f, 0.0f); + } + break; + case C3DS_KF_SEG: + { + u32 flags; + file->read(&flags, 4); + file->read(&flags, 4); + data.read += 8; + } + break; + case C3DS_KF_NODE_HDR: + { + s16 flags; + c8* c = new c8[data.header.length - data.read-6]; + file->read(c, data.header.length - data.read-6); + + // search mesh buffer to apply these transformations to + for (u32 i=0; igetMeshBuffer(i); + break; + } + } + + file->read(&flags, 2); + file->read(&flags, 2); + file->read(&flags, 2); + data.read += data.header.length - data.read; + delete [] c; + } + break; + case C3DS_KF_CURTIME: + { + u32 flags; + file->read(&flags, 4); + data.read += data.header.length - data.read; + } + break; + case C3DS_NODE_ID: + { + u16 flags; + file->read(&flags, 2); + data.read += 2; + } + break; + case C3DS_PIVOTPOINT: + { + file->read(&pivot.X, sizeof(f32)); + file->read(&pivot.Y, sizeof(f32)); + file->read(&pivot.Z, sizeof(f32)); + data.read += data.header.length - data.read; + } + break; + case C3DS_BOUNDBOX: + { + core::aabbox3df bbox; + // abuse bboxCenter as temporary variable + file->read(&bboxCenter.X, sizeof(f32)); + file->read(&bboxCenter.Y, sizeof(f32)); + file->read(&bboxCenter.Z, sizeof(f32)); + bbox.reset(bboxCenter); + file->read(&bboxCenter.X, sizeof(f32)); + file->read(&bboxCenter.Y, sizeof(f32)); + file->read(&bboxCenter.Z, sizeof(f32)); + bbox.addInternalPoint(bboxCenter); + bboxCenter=bbox.getCenter(); + data.read += data.header.length - 24; + } + break; + case C3DS_POS_TRACK_TAG: + case C3DS_ROT_TRACK_TAG: + case C3DS_SCL_TRACK_TAG: + readTrackChunk(file, data, mb, bboxCenter-pivot); + break; + default: + // ignore chunk + file->seek(data.header.length - data.read, true); + data.read += data.header.length - data.read; + } + + parent->read += data.read; + data.read=0; + } return true; } @@ -280,42 +607,32 @@ if (version != 0x03) { os::Printer::log("Cannot load 3ds files of version other than 3.", ELL_ERROR); - return false; +// return false; } } break; case C3DS_EDIT_MATERIAL: readMaterialChunk(file, &data); break; + case C3DS_KEYF3DS: + readFrameChunk(file, &data); + break; case C3DS_EDIT3DS: + break; + case C3DS_MESHVERSION: + case 0x01: { - ChunkData ndata; - readChunkData(file, ndata); - if (ndata.header.id != C3DS_MESHVERSION) - { - os::Printer::log("Mesh version not where expected in 3ds file.", ELL_ERROR); - return false; - } - - u16 version; - file->read(&version, sizeof(u16)); - file->seek(ndata.header.length - ndata.read - 2, true); - data.read += ndata.read; - - /*if (version != 0x03) - { - os::Printer::log("Cannot read 3ds meshes of versions other than 3.", ELL_ERROR); - return false; - }*/ - - readChunk(file, &data); + u32 version; + file->read(&version, sizeof(u32)); + data.read += sizeof(u32); } break; - case C3DS_EDIT_OBJECT: { - readAndIgnoreString(file, data); + core::stringc name; + readString(file, data, name); readObjectChunk(file, &data); + composeObject(file, name); } break; @@ -344,7 +661,6 @@ { case C3DS_OBJTRIMESH: readObjectChunk(file, &data); - composeObject(file); break; case C3DS_TRIVERT: @@ -360,12 +676,26 @@ readMaterialGroup(file, data); break; - case C3DS_TRIUV: // geting texture coordiantes + case C3DS_TRIUV: // getting texture coordinates readTextureCoords(file, data); break; + case C3DS_TRIMATRIX: + { + f32 mat[4][3]; + file->read(&mat, 12*sizeof(f32)); + for (int i=0; i<3; ++i) { + for (int j=0; j<3; ++j) + TransformationMatrix(i,j)=mat[i][j]; + } + for (int j=0; j<3; ++j) { + TransformationMatrix(j,3)=mat[3][j]; + } + TransformationMatrix=TransformationMatrix.getTransposed(); + data.read += 12*sizeof(f32); + } + break; case C3DS_TRISMOOTH: // TODO - case C3DS_TRILOCAL: // TODO default: // ignore chunk file->seek(data.header.length - data.read, true); @@ -379,7 +709,7 @@ } -void C3DSMeshFileLoader::composeObject(io::IReadFile* file) +void C3DSMeshFileLoader::composeObject(io::IReadFile* file, const core::stringc& name) { if (Mesh->getMeshBufferCount() != (s32)Materials.size()) loadMaterials(file); @@ -388,7 +718,7 @@ { // no material group, so add all SMaterialGroup group; - group.faceCount = CountIndices / 3; + group.faceCount = CountFaces; group.faces = new s16[group.faceCount]; for (int i=0; igetMeshBuffer(j); + mat=&Materials[j].Material; + MeshBufferNames[j]=name; break; } - if (mb != 0) { // add geometry to the buffer. video::S3DVertex vtx; - vtx.Color.set(255,255,255,255); + core::vector3df vec; + vtx.Color=mat->DiffuseColor; + if (mat->MaterialType==video::EMT_TRANSPARENT_VERTEX_ALPHA) { + vtx.Color.setAlpha((int)(255.0f*mat->MaterialTypeParam)); + } vtx.Normal.set(0,0,0); for (s32 f=0; f idx) @@ -474,13 +811,13 @@ } -core::stringc C3DSMeshFileLoader::getTextureFileName(core::stringc texture, - core::stringc model) +core::stringc C3DSMeshFileLoader::getTextureFileName(const core::stringc& texture, + core::stringc& model) { s32 idx = -1; idx = model.findLast('/'); - if (idx == -1) + if (idx == -1) idx = model.findLast('\\'); if (idx == -1) @@ -495,31 +832,95 @@ void C3DSMeshFileLoader::loadMaterials(io::IReadFile* file) { // create a mesh buffer for every material - core::stringc modelFilename = file->getFileName(); if (Materials.empty()) os::Printer::log("No materials found in 3ds file.", ELL_INFORMATION); + MeshBufferNames.reallocate(Materials.size()); for (u32 i=0; iaddMeshBuffer(m); m->Material = Materials[i].Material; - if (Materials[i].Filename.size()) + if (Materials[i].Filename[0].size()) { - core::stringc fname = getTextureFileName( - Materials[i].Filename, modelFilename); - - m->Material.Texture1 = Driver->getTexture(Materials[i].Filename.c_str()); + m->Material.Texture1 = Driver->getTexture(Materials[i].Filename[0].c_str()); - if (!m->Material.Texture1) - m->Material.Texture1 = Driver->getTexture(fname.c_str()); + if (!m->Material.Texture1) { + core::stringc fname = getTextureFileName( + Materials[i].Filename[0], modelFilename); + if (fname.size()) + m->Material.Texture1 = Driver->getTexture(fname.c_str()); + } if (!m->Material.Texture1) - os::Printer::log("Could not find a texture for entry in 3ds file", - Materials[i].Filename.c_str(), ELL_WARNING); + os::Printer::log("Could not load a texture for entry in 3ds file", + Materials[i].Filename[0].c_str(), ELL_WARNING); + } + + if (Materials[i].Filename[2].size()) + { + m->Material.Texture1 = Driver->getTexture(Materials[i].Filename[2].c_str()); + + if (!m->Material.Texture1) { + core::stringc fname = getTextureFileName( + Materials[i].Filename[2], modelFilename); + if (fname.size()) + m->Material.Texture1 = Driver->getTexture(fname.c_str()); + } + + if (!m->Material.Texture1) { + os::Printer::log("Could not load a texture for entry in 3ds file", + Materials[i].Filename[2].c_str(), ELL_WARNING); + } else { + m->Material.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; + } + } + + if (Materials[i].Filename[3].size()) + { + m->Material.Texture2=m->Material.Texture1; + m->Material.Texture1=0; + m->Material.Texture1 = Driver->getTexture(Materials[i].Filename[3].c_str()); + + if (!m->Material.Texture1) { + core::stringc fname = getTextureFileName( + Materials[i].Filename[3], modelFilename); + if (fname.size()) + m->Material.Texture1 = Driver->getTexture(fname.c_str()); + } + + if (!m->Material.Texture1) { + os::Printer::log("Could not load a texture for entry in 3ds file", + Materials[i].Filename[3].c_str(), ELL_WARNING); + m->Material.Texture1=m->Material.Texture2; + m->Material.Texture2=0; + } else { + m->Material.MaterialType=video::EMT_REFLECTION_2_LAYER; + } + } + + if (Materials[i].Filename[4].size()) + { + m->Material.Texture2 = Driver->getTexture(Materials[i].Filename[4].c_str()); + + if (!m->Material.Texture2) { + core::stringc fname = getTextureFileName( + Materials[i].Filename[4], modelFilename); + if (fname.size()) + m->Material.Texture2 = Driver->getTexture(fname.c_str()); + } + + if (!m->Material.Texture2) + os::Printer::log("Could not load a texture for entry in 3ds file", + Materials[i].Filename[4].c_str(), ELL_WARNING); + else { + Driver->makeNormalMapTexture(m->Material.Texture2, 9.0f); + m->Material.MaterialType=video::EMT_PARALLAX_MAP_SOLID; + m->Material.MaterialTypeParam=0.035f; + } } m->drop(); @@ -534,7 +935,7 @@ Vertices = 0; delete [] Indices; Indices = 0; - CountIndices = 0; + CountFaces = 0; delete [] TCoords; TCoords = 0; CountTCoords = 0; @@ -584,14 +985,14 @@ void C3DSMeshFileLoader::readIndices(io::IReadFile* file, ChunkData& data) { - file->read(&CountIndices, sizeof(CountIndices)); - data.read += sizeof(CountIndices); + file->read(&CountFaces, sizeof(CountFaces)); + data.read += sizeof(CountFaces); - s32 indexBufferByteSize = CountIndices * sizeof(u16) * 4; + s32 indexBufferByteSize = CountFaces * sizeof(u16) * 4; // Indices are u16s. // After every 3 Indices in the array, there follows an edge flag. - Indices = new u16[CountIndices * 4]; + Indices = new u16[CountFaces * 4]; file->read(Indices, indexBufferByteSize); data.read += indexBufferByteSize; } @@ -625,19 +1026,6 @@ } -void C3DSMeshFileLoader::readAndIgnoreString(io::IReadFile* file, ChunkData& data) -{ - c8 c = 1; - - while (c) - { - if (!file->read(&c, sizeof(c8))) - return; - - ++data.read; - } -} - void C3DSMeshFileLoader::readString(io::IReadFile* file, ChunkData& data, core::stringc& out) { c8 c = 1;