From effc8802a77375437b676ac4534789e819731671 Mon Sep 17 00:00:00 2001 From: Aki Date: Fri, 5 Apr 2024 20:57:38 +0200 Subject: l3ds is a third party library --- MagicEx/CMakeLists.txt | 3 +- MagicEx/l3ds.cpp | 1790 --------------------------------------- MagicEx/l3ds.h | 457 ---------- NOTICE | 4 + third-party/CMakeLists.txt | 1 + third-party/l3ds/CMakeLists.txt | 4 + third-party/l3ds/include/l3ds.h | 457 ++++++++++ third-party/l3ds/l3ds.cpp | 1790 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 2257 insertions(+), 2249 deletions(-) delete mode 100644 MagicEx/l3ds.cpp delete mode 100644 MagicEx/l3ds.h create mode 100644 third-party/l3ds/CMakeLists.txt create mode 100644 third-party/l3ds/include/l3ds.h create mode 100644 third-party/l3ds/l3ds.cpp diff --git a/MagicEx/CMakeLists.txt b/MagicEx/CMakeLists.txt index 965312c..9c8038a 100644 --- a/MagicEx/CMakeLists.txt +++ b/MagicEx/CMakeLists.txt @@ -1,10 +1,9 @@ project(MagicEx) add_library( ${PROJECT_NAME} STATIC - l3ds.cpp MagicLoad.cpp ModelFile3DS.cpp ModelFileMAG.cpp ModelFileOBJ.cpp) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(${PROJECT_NAME} PUBLIC StarsEx) +target_link_libraries(${PROJECT_NAME} PUBLIC StarsEx PRIVATE l3ds) diff --git a/MagicEx/l3ds.cpp b/MagicEx/l3ds.cpp deleted file mode 100644 index 4c34ab5..0000000 --- a/MagicEx/l3ds.cpp +++ /dev/null @@ -1,1790 +0,0 @@ -// copyright (c) 2001 Lev Povalahev - -#include "l3ds.h" - -#include -#include -#include -#include - -//using namespace std; - -//------------------------------------------------------- -// generic stuff -//------------------------------------------------------- - -typedef unsigned long ulong; - -#define SEEK_START 1900 -#define SEEK_CURSOR 1901 - -// common chunks -// colors -#define COLOR_F 0x0010 -#define COLOR_24 0x0011 -#define LIN_COLOR_24 0x0012 -#define LIN_COLOR_F 0x0013 -// percentage -#define INT_PERCENTAGE 0x0030 -#define FLOAT_PERCENTAGE 0x0031 -// ambient light -#define AMBIENT_LIGHT 0x2100 - - -#define MAIN3DS 0x4D4D -#define EDIT3DS 0x3D3D // this is the start of the editor config - -// keyframer chunk ids -#define KFDATA 0xB000 // the keyframer section -#define KFHDR 0xB00A -#define OBJECT_NODE_TAG 0xB002 -#define NODE_HDR 0xB010 -#define PIVOT 0xB013 -#define POS_TRACK_TAG 0xB020 -#define ROT_TRACK_TAG 0xB021 -#define SCL_TRACK_TAG 0xB022 - -// material entries -#define MAT_ENTRY 0xAFFF -#define MAT_NAME 0xA000 -#define MAT_AMBIENT 0xA010 -#define MAT_DIFFUSE 0xA020 -#define MAT_SPECULAR 0xA030 -#define MAT_SHININESS 0xA040 -#define MAT_SHIN2PCT 0xA041 -#define MAT_TRANSPARENCY 0xA050 -#define MAT_SHADING 0xA100 -#define MAT_TWO_SIDE 0xA081 -#define MAT_ADDITIVE 0xA083 -#define MAT_WIRE 0xA085 -#define MAT_FACEMAP 0xA088 -#define MAT_WIRESIZE 0xA087 -#define MAT_DECAL 0xA082 -#define MAT_TEXMAP 0xA200 -#define MAT_MAPNAME 0xA300 -#define MAT_MAP_TILING 0xA351 -#define MAT_MAP_USCALE 0xA354 -#define MAT_MAP_VSCALE 0xA356 -#define MAT_MAP_UOFFSET 0xA358 -#define MAT_MAP_VOFFSET 0xA35A -#define MAT_MAP_ANG 0xA35C -#define MAT_TEX2MAP 0xA33A -#define MAT_OPACMAP 0xA210 -#define MAT_BUMPMAP 0xA230 -#define MAT_SPECMAP 0xA204 -#define MAT_SHINMAP 0xA33C -#define MAT_REFLMAP 0xA220 -#define MAT_ACUBIC 0xA310 - -#define EDIT_OBJECT 0x4000 -#define OBJ_TRIMESH 0x4100 -#define OBJ_LIGHT 0x4600 -#define OBJ_CAMERA 0x4700 -#define LIT_OFF 0x4620 -#define LIT_SPOT 0x4610 -#define TRI_VERTEXLIST 0x4110 -#define TRI_VERTEXOPTIONS 0x4111 - -#define TRI_FACELIST 0x4120 - #define TRI_MAT_GROUP 0x4130 - #define TRI_SMOOTH_GROUP 0x4150 - -#define TRI_FACEMAPPING 0x4140 -#define TRI_MATRIX 0x4160 - -#define SPOTLIGHT 0x4610 - -//---------------------------------- - -#define MAX_SHARED_TRIS 100 - -// the error reporting routine - -void ErrorMsg(const char *msg) -{ - -} - -struct LChunk -{ - unsigned short id; - uint start; - uint end; -}; - -struct LTri -{ - unsigned short a; - unsigned short b; - unsigned short c; - ulong smoothingGroups; - LVector3 normal; - LVector3 tangent; - LVector3 binormal; - uint materialId; -}; - -// globals - -LColor3 black = {0, 0, 0}; - -LVector3 zero3 = {0, 0, 0}; - -LVector4 zero4 = {0, 0, 0, 0}; - -LMap emptyMap = {0, "", 1, 1, 0, 0, 0}; - -LVector3 _4to3(const LVector4 &vec) -{ - LVector3 t; - t.x = vec.x; - t.y = vec.y; - t.z = vec.z; - return t; -} - -LVector3 AddVectors(const LVector3 &a, const LVector3 &b) -{ - LVector3 t; - t.x = a.x+b.x; - t.y = a.y+b.y; - t.z = a.z+b.z; - return t; -} - -LVector3 SubtractVectors(const LVector3 &a, const LVector3 &b) -{ - LVector3 t; - t.x = a.x-b.x; - t.y = a.y-b.y; - t.z = a.z-b.z; - return t; -} - -float VectorLength(const LVector3 &vec) -{ - return (float)sqrt(vec.x*vec.x + vec.y*vec.y+vec.z*vec.z); -} - -LVector3 NormalizeVector(const LVector3 &vec) -{ - float a = VectorLength(vec); - if (a == 0) - return vec; - float b = 1/a; - LVector3 v; - v.x = vec.x*b; - v.y = vec.y*b; - v.z = vec.z*b; - return v; -} - -LVector3 CrossProduct(const LVector3 &a, const LVector3 &b) -{ - LVector3 v; - v.x = a.y*b.z - a.z*b.y; - v.y = a.z*b.x - a.x*b.z; - v.z = a.x*b.y - a.y*b.x; - return v; -} - -void LoadIdentityMatrix(LMatrix4 &m) -{ - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - m.m[i][j] = (i==j) ? 1.0f : 0.0f; -} - -LVector4 VectorByMatrix(const LMatrix4 &m, const LVector4 &vec) -{ - LVector4 res; - - res.x = m.m[0][0]*vec.x + m.m[1][0]*vec.y + m.m[2][0]*vec.z + m.m[3][0]*vec.w; - res.y = m.m[0][1]*vec.x + m.m[1][1]*vec.y + m.m[2][1]*vec.z + m.m[3][1]*vec.w; - res.z = m.m[0][2]*vec.x + m.m[1][2]*vec.y + m.m[2][2]*vec.z + m.m[3][2]*vec.w; - res.w = m.m[0][3]*vec.x + m.m[1][3]*vec.y + m.m[2][3]*vec.z + m.m[3][3]*vec.w; - - if (res.w != 0) { - float b = 1/res.w; - res.x *= b; - res.y *= b; - res.z *= b; - res.w = 1; - } - else { - res.w = 1; - } - - return res; -} - -void QuatToMatrix(const LVector4 &quat, LMatrix4 &m) -{ - -} - -//------------------------------------------------------- -// LObject implementation -//------------------------------------------------------- - -LObject::LObject() -{ - m_name = "";//.clear(); -} - -LObject::~LObject() -{ - // nothing here -} - -void LObject::SetName(const std::string& value) -{ - m_name = value; -} - -const std::string& LObject::GetName() -{ - return m_name; -} - -bool LObject::IsObject(const std::string &name) -{ - return (m_name == name); -} - - -//------------------------------------------------------- -// LMaterial implementation -//------------------------------------------------------- - -LMaterial::LMaterial() -: LObject() -{ - m_id = 0; - m_texMap1 = emptyMap; - m_texMap2 = emptyMap; - m_opacMap = emptyMap; - m_bumpMap = emptyMap; - m_reflMap = emptyMap; - m_specMap = emptyMap; - m_ambient = black; - m_diffuse = black; - m_specular = black; - m_shading = sGouraud; - m_shininess = 0; - m_transparency = 0; -} - -LMaterial::~LMaterial() -{ - -} - -uint LMaterial::GetID() -{ - return m_id; -} - -LMap& LMaterial::GetTextureMap1() -{ - return m_texMap1; -} - -LMap& LMaterial::GetTextureMap2() -{ - return m_texMap2; -} - -LMap& LMaterial::GetOpacityMap() -{ - return m_opacMap; -} - -LMap& LMaterial::GetSpecularMap() -{ - return m_specMap; -} - -LMap& LMaterial::GetBumpMap() -{ - return m_bumpMap; -} - -LMap& LMaterial::GetReflectionMap() -{ - return m_reflMap; -} - -LColor3 LMaterial::GetAmbientColor() -{ - return m_ambient; -} - -LColor3 LMaterial::GetDiffuseColor() -{ - return m_diffuse; -} - -LColor3 LMaterial::GetSpecularColor() -{ - return m_specular; -} - -float LMaterial::GetShininess() -{ - return m_shininess; -} - -float LMaterial::GetTransparency() -{ - return m_transparency; -} - -LShading LMaterial::GetShadingType() -{ - return m_shading; -} - -void LMaterial::SetID(uint value) -{ - m_id = value; -} - -void LMaterial::SetAmbientColor(const LColor3 &color) -{ - m_ambient = color; -} - -void LMaterial::SetDiffuseColor(const LColor3 &color) -{ - m_diffuse = color; -} - -void LMaterial::SetSpecularColor(const LColor3 &color) -{ - m_specular = color; -} - -void LMaterial::SetShininess(float value) -{ - m_shininess = value; - if (m_shininess < 0) - m_shininess = 0; - if (m_shininess > 1) - m_shininess = 1; -} - -void LMaterial::SetTransparency(float value) -{ - m_transparency = value; - if (m_transparency < 0) - m_transparency = 0; - if (m_transparency > 1) - m_transparency = 1; -} - -void LMaterial::SetShadingType(LShading shading) -{ - m_shading = shading; -} - -//------------------------------------------------------- -// LMesh implementation -//------------------------------------------------------- - -LMesh::LMesh() -: LObject() -{ - Clear(); -} - -LMesh::~LMesh() -{ - Clear(); -} - -void LMesh::Clear() -{ - m_vertices.clear(); - m_normals.clear(); - m_uv.clear(); - m_tangents.clear(); - m_binormals.clear(); - m_triangles.clear(); - m_tris.clear(); - m_materials.clear(); - LoadIdentityMatrix(m_matrix); -} - -uint LMesh::GetVertexCount() -{ - return m_vertices.size(); -} - -void LMesh::SetVertexArraySize(uint value) -{ - m_vertices.resize(value); - m_normals.resize(value); - m_uv.resize(value); - m_tangents.resize(value); - m_binormals.resize(value); -} - -uint LMesh::GetTriangleCount() -{ - return m_triangles.size(); -} - -void LMesh::SetTriangleArraySize(uint value) -{ - m_triangles.resize(value); - m_tris.resize(value); -} - -const LVector4& LMesh::GetVertex(uint index) -{ - return m_vertices[index]; -} - -const LVector3& LMesh::GetNormal(uint index) -{ - return m_normals[index]; -} - -const LVector2& LMesh::GetUV(uint index) -{ - return m_uv[index]; -} - -const LVector3& LMesh::GetTangent(uint index) -{ - return m_tangents[index]; -} - -const LVector3& LMesh::GetBinormal(uint index) -{ - return m_binormals[index]; -} - -void LMesh::SetVertex(const LVector4 &vec, uint index) -{ - if (index >= m_vertices.size()) - return; - m_vertices[index] = vec; -} - -void LMesh::SetNormal(const LVector3 &vec, uint index) -{ - if (index >= m_vertices.size()) - return; - m_normals[index] = vec; -} - -void LMesh::SetUV(const LVector2 &vec, uint index) -{ - if (index >= m_vertices.size()) - return; - m_uv[index] = vec; -} - -void LMesh::SetTangent(const LVector3 &vec, uint index) -{ - if (index >= m_vertices.size()) - return; - m_tangents[index] = vec; -} - -void LMesh::SetBinormal(const LVector3 &vec, uint index) -{ - if (index >= m_vertices.size()) - return; - m_binormals[index] = vec; -} - -const LTriangle& LMesh::GetTriangle(uint index) -{ - return m_triangles[index]; -} - -LTriangle2 LMesh::GetTriangle2(uint index) -{ - LTriangle2 f; - LTriangle t = GetTriangle(index); - f.vertices[0] = GetVertex(t.a); - f.vertices[1] = GetVertex(t.b); - f.vertices[2] = GetVertex(t.c); - - f.vertexNormals[0] = GetNormal(t.a); - f.vertexNormals[1] = GetNormal(t.b); - f.vertexNormals[2] = GetNormal(t.c); - - f.textureCoords[0] = GetUV(t.a); - f.textureCoords[1] = GetUV(t.b); - f.textureCoords[2] = GetUV(t.c); - - LVector3 a, b; - - a = SubtractVectors(_4to3(f.vertices[1]), _4to3(f.vertices[0])); - b = SubtractVectors(_4to3(f.vertices[1]), _4to3(f.vertices[2])); - - f.faceNormal = CrossProduct(b, a); - - f.faceNormal = NormalizeVector(f.faceNormal); - - f.materialId = m_tris[index].materialId; - - return f; -} - -LMatrix4 LMesh::GetMatrix() -{ - return m_matrix; -} - -void LMesh::SetMatrix(LMatrix4 m) -{ - m_matrix = m; -} - -void LMesh::TransformVertices() -{ - for (uint i=0; i > array; - array.resize(m_vertices.size()); - for (i=0; i smGroups; - std::vector< std::vector > smList; - - uint loop_size = m_vertices.size(); - - for (i=0; i 1) - for (uint j=1; j< smGroups.size(); j++) - { - m_vertices.push_back(m_vertices[i]); - m_normals.push_back(m_normals[i]); - m_uv.push_back(m_uv[i]); - m_tangents.push_back(m_tangents[i]); - m_binormals.push_back(m_binormals[i]); - - uint t = m_vertices.size()-1; - for (uint h=0; h > array; - array.resize(m_vertices.size()); - for (int i=0; i<(int)m_triangles.size(); i++) - { - uint k = m_tris[i].a; - array[k].push_back(i); - - k = m_tris[i].b; - array[k].push_back(i); - - k = m_tris[i].c; - array[k].push_back(i); - } - - // now average the tangents and compute the binormals as (tangent X normal) - for (int i=0; i<(int)m_vertices.size(); i++) - { - v1 = zero3; - v2 = zero3; - int t = array[i].size(); - - for (int k=0; k= m_triangles.size()) - return; - m_tris[index] = tri; -} - -LTri& LMesh::GetTri(uint index) -{ - return m_tris[index]; -} - -uint LMesh::GetMaterial(uint index) -{ - return m_materials[index]; -} - -uint LMesh::AddMaterial(uint id) -{ - m_materials.push_back(id); - return m_materials.size()-1; -} - -uint LMesh::GetMaterialCount() -{ - return m_materials.size(); -} - -//------------------------------------------------------- -// LLight implementation -//------------------------------------------------------- - -LLight::LLight() -: LObject() -{ - Clear(); -} - -LLight::~LLight() -{ - -} - -void LLight::Clear() -{ - m_pos.x = m_pos.y = m_pos.z = 0.0f; - m_color.r = m_color.g = m_color.b = 0.0f; - m_spotlight = false; -} - -void LLight::SetPosition(LVector3 vec) -{ - m_pos = vec; -} - -LVector3 LLight::GetPosition() -{ - return m_pos; -} - -void LLight::SetColor(LColor3 color) -{ - m_color = color; -} - -LColor3 LLight::GetColor() -{ - return m_color; -} - -void LLight::SetSpotlight(bool value) -{ - m_spotlight = value; -} - -bool LLight::GetSpotlight() -{ - return m_spotlight; -} - -void LLight::SetTarget(LVector3 target) -{ - m_target = target; -} - -LVector3 LLight::GetTarget() -{ - return m_target; -} - -void LLight::SetHotspot(float value) -{ - m_hotspot = value; -} - -float LLight::GetHotspot() -{ - return m_hotspot; -} - -void LLight::SetFalloff(float value) -{ - m_falloff = value; -} - -float LLight::GetFalloff() -{ - return m_falloff; -} - -//------------------------------------------------------- -// LImporter implementation -//------------------------------------------------------- - -LImporter::LImporter() -{ - Clear(); -} - -LImporter::~LImporter() -{ - Clear(); -} - -uint LImporter::GetMeshCount() -{ - return m_meshes.size(); -} - -uint LImporter::GetLightCount() -{ - return m_lights.size(); -} - -uint LImporter::GetMaterialCount() -{ - return m_materials.size(); -} - -LMesh& LImporter::GetMesh(uint index) -{ - return m_meshes[index]; -} - -LLight& LImporter::GetLight(uint index) -{ - return m_lights[index]; -} - -LMaterial& LImporter::GetMaterial(uint index) -{ - return m_materials[index]; -} - -LMaterial* LImporter::FindMaterial(const std::string& name) -{ - for (uint i=0; i 0) - free(m_buffer); -} - -bool L3DS::LoadFile(const char *filename) -{ - FILE *f; - f = fopen(filename, "rb"); - if (f == 0) - { - ErrorMsg("L3DS::LoadFile - cannot open file"); - return false; - } - fseek(f, 0, SEEK_END); - m_bufferSize = ftell(f); - fseek(f, 0, SEEK_SET); - m_buffer = (unsigned char*) calloc(m_bufferSize, 1); - if (m_buffer == 0) - { - ErrorMsg("L3DS::LoadFile - not enough memory (malloc failed)"); - return false; - } - if (fread(m_buffer, m_bufferSize, 1, f) != 1) - { - fclose(f); - free(m_buffer); - m_bufferSize = 0; - ErrorMsg("L3DS::LoadFile - error reading from file"); - return false; - } - fclose(f); - Clear(); - bool res = Read3DS(); - free(m_buffer); - m_buffer = 0; - m_bufferSize = 0; - return res; -} - -short L3DS::ReadShort() -{ - if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+2)=m_bufferSize)) - { - count = 0; - m_eof = true; - return count; - } - count = 0; - char c = ReadChar(); - while ((c!=0) && (count= m_bufferSize) - m_pos = m_bufferSize-1; - m_eof = false; -} - -uint L3DS::Pos() -{ - return m_pos; -} - -LChunk L3DS::ReadChunk() -{ - LChunk chunk; - chunk.id = ReadShort(); - int a = ReadInt(); - chunk.start = Pos(); - chunk.end = chunk.start+a-6; - return chunk; -} - -bool L3DS::FindChunk(LChunk &target, const LChunk &parent) -{ - if (Pos() >= parent.end) - return false; - LChunk chunk; - chunk = ReadChunk(); - while (( chunk.id != target.id) && (chunk.end <= parent.end)) - { - SkipChunk(chunk); - if (chunk.end >= parent.end) - break; - chunk = ReadChunk(); - } - if (chunk.id == target.id) - { - target.start = chunk.start; - target.end = chunk.end; - return true; - } - return false; -} - -void L3DS::SkipChunk(const LChunk &chunk) -{ - Seek(chunk.end, SEEK_START); -} - -void L3DS::GotoChunk(const LChunk &chunk) -{ - Seek(chunk.start, SEEK_START); -} - -LColor3 L3DS::ReadColor(const LChunk &chunk) -{ - LColor3 col = black; - GotoChunk(chunk); - switch (chunk.id) - { - case COLOR_F: - col.r = ReadFloat(); - col.g = ReadFloat(); - col.b = ReadFloat(); - break; - case COLOR_24: - col.r = ReadByte()/255.0f; - col.g = ReadByte()/255.0f; - col.b = ReadByte()/255.0f; - break; - case LIN_COLOR_F: - col.r = ReadFloat(); - col.g = ReadFloat(); - col.b = ReadFloat(); - break; - case LIN_COLOR_24: - col.r = ReadByte()/255.0f; - col.g = ReadByte()/255.0f; - col.b = ReadByte()/255.0f; - break; - default: - ErrorMsg("L3DS::ReadColor - error this is not a color chunk"); - } - return col; -} - -float L3DS::ReadPercentage(const LChunk &chunk) -{ - GotoChunk(chunk); - switch (chunk.id) - { - case INT_PERCENTAGE: - return (ReadShort()/100.0f); - case FLOAT_PERCENTAGE: - return ReadFloat(); - } - ErrorMsg("L3DS::ReadPercentage - error, the chunk is not a percentage chunk"); - return 0; -} - -bool L3DS::Read3DS() -{ - LChunk mainchunk; - LChunk edit; - edit.id = EDIT3DS; - mainchunk = ReadChunk(); - if (mainchunk.id != MAIN3DS) - { - ErrorMsg("L3DS::Read3DS - wrong file format"); - return false; - } - if (!FindChunk(edit, mainchunk)) - return false; - LChunk obj; - LChunk ml; - - GotoChunk(edit); - obj.id = MAT_ENTRY; - while (FindChunk(obj, edit)) - { - ReadMaterial(obj); - SkipChunk(obj); - } - GotoChunk(edit); - - obj.id = EDIT_OBJECT; - { - while (FindChunk(obj, edit)) - { - ReadASCIIZ(m_objName, 99); - ml = ReadChunk(); - if (ml.id == OBJ_TRIMESH) - ReadMesh(ml); - if (ml.id == OBJ_LIGHT) - ReadLight(ml); - SkipChunk(obj); - } - } - - // read the keyframer data here to find out correct object orientation - - LChunk keyframer; - keyframer.id = KFDATA; - - LChunk objtrack; - objtrack.id = OBJECT_NODE_TAG; - - GotoChunk(mainchunk); - if (FindChunk(keyframer, mainchunk)) - { // keyframer chunk is present - GotoChunk(keyframer); - while (FindChunk(objtrack, keyframer)) - { - ReadKeyframeData(objtrack); - SkipChunk(objtrack); - } - } - - for (uint i=0; i= parent.end) - break; - chunk = ReadChunk(); - - } - } - m_lights.push_back(light); -} - -void L3DS::ReadMesh(const LChunk &parent) -{ - unsigned short count, i; - LVector4 p; - LMatrix4 m; - LVector2 t; - p.w = 1.0f; - LMesh mesh; - mesh.SetName(m_objName); - GotoChunk(parent); - LChunk chunk = ReadChunk(); - while (chunk.end <= parent.end) - { - switch (chunk.id) - { - case TRI_VERTEXLIST: - count = ReadShort(); - mesh.SetVertexArraySize(count); - for (i=0; i < count; i++) - { - p.x = ReadFloat(); - p.y = ReadFloat(); - p.z = ReadFloat(); - mesh.SetVertex(p, i); - } - break; - case TRI_FACEMAPPING: - count = ReadShort(); - if (mesh.GetVertexCount() == 0) - mesh.SetVertexArraySize(count); - for (i=0; i < count; i++) - { - t.x = ReadFloat(); - t.y = ReadFloat(); - mesh.SetUV(t, i); - } - break; - case TRI_FACELIST: - ReadFaceList(chunk, mesh); - break; - case TRI_MATRIX: - { - for (int i = 0; i < 4; i++) - for (int j = 0; j < 3; j++) - m.m[i][j] = ReadFloat(); - - m.m[0][3] = 0.0f; - m.m[1][3] = 0.0f; - m.m[2][3] = 0.0f; - m.m[3][3] = 1.0f; - - mesh.SetMatrix(m); - } - break; - default: - break; - } - SkipChunk(chunk); - if (chunk.end >= parent.end) - break; - chunk = ReadChunk(); - } - m_meshes.push_back(mesh); -} - -void L3DS::ReadFaceList(const LChunk &chunk, LMesh &mesh) -{ - // variables - unsigned short count, t; - uint i; - LTri tri; - LChunk ch; - char str[20]; - //uint mat; - - // consistency checks - if (chunk.id != TRI_FACELIST) - { - ErrorMsg("L3DS::ReadFaceList - internal error: wrong chunk passed as parameter"); - return; - } - GotoChunk(chunk); - tri.smoothingGroups = 1; - // read the number of faces - count = ReadShort(); - mesh.SetTriangleArraySize(count); - for (i=0; iGetID(); - mesh.AddMaterial(mat_id); - count = ReadShort(); - for (i=0; i 0) - { - ReadKeyheader(); - pos.x = ReadFloat(); - pos.y = ReadFloat(); - pos.z = ReadFloat(); - } - } - GotoChunk(parent); - - // now read the rotation track - LVector4 rot = zero4; - - LChunk rotchunk; - rotchunk.id = ROT_TRACK_TAG; - - frames = 0; - if (FindChunk(rotchunk, parent)) - { - GotoChunk(rotchunk); - // read the trackheader structure - ReadShort(); - ReadInt(); - ReadInt(); - frames = ReadInt(); - if (frames > 0) - { - ReadKeyheader(); - rot.x = ReadFloat(); - rot.y = ReadFloat(); - rot.z = ReadFloat(); - rot.w = ReadFloat(); - } - } - GotoChunk(parent); - - // now read the scaling chunk - LVector3 scale; - scale.x = 1; - scale.y = 1; - scale.z = 1; - - LChunk scalechunk; - scalechunk.id = SCL_TRACK_TAG; - - frames = 0; - - if (FindChunk(scalechunk, parent)) - { - GotoChunk(scalechunk); - // read the trackheader structure - ReadShort(); - ReadInt(); - ReadInt(); - frames = ReadInt(); - if (frames > 0) - { - ReadKeyheader(); - scale.x = ReadFloat(); - scale.y = ReadFloat(); - scale.z = ReadFloat(); - } - } - GotoChunk(parent); - - -} - -long L3DS::ReadKeyheader() -{ - long frame; - frame = ReadInt(); - short opts = ReadShort(); - if (opts & 32768) // 32768 is 1000000000000000 binary - { // tension is present - ReadFloat(); - } - if (opts & 16384) // 16384 is 0100000000000000 binary - { // continuity is present - ReadFloat(); - } - if (opts & 8192) - { // bias info present - ReadFloat(); - } - if (opts & 4096) - { // "ease to" present - ReadFloat(); - } - if (opts & 2048) - { // "ease from" present - ReadFloat(); - } - return frame; -} \ No newline at end of file diff --git a/MagicEx/l3ds.h b/MagicEx/l3ds.h deleted file mode 100644 index ea0a032..0000000 --- a/MagicEx/l3ds.h +++ /dev/null @@ -1,457 +0,0 @@ -// copyright (c) 2001-2002 Lev Povalahev -// this is a 3ds importer version 2 - -#ifndef L3DS_H -#define L3DS_H - -// includes -#include -#include - -//--------------------------------------------------------- - -typedef unsigned int uint; -typedef unsigned char byte; - -enum LShading {sWireframe, sFlat, sGouraud, sPhong, sMetal}; - -enum LOptimizationLevel {oNone, oSimple, oFull}; - -// for internal use -struct LChunk; -struct LTri; - -//------------------------------------------------ - -struct LVector4 -{ - float x; - float y; - float z; - float w; - - int operator==(const LVector4& v) const { return x==v.x && y==v.y && z==v.z && w==v.w; } -}; - -struct LVector3 -{ - float x; - float y; - float z; - - int operator==(const LVector3& v) const { return x==v.x && y==v.y && z==v.z; } -}; - -struct LVector2 -{ - float x; - float y; - - int operator==(const LVector2& v) const { return x==v.x && y==v.y; } -}; - -struct LColor3 -{ - float r; - float g; - float b; - - int operator==(const LColor3& v) const { return r==v.r && g==v.g && b==v.b; } -}; - -//------------------------------------------------ - -struct LTriangle -{ - unsigned short a; - unsigned short b; - unsigned short c; -}; - -struct LMatrix4 -{ - float m[4][4]; -}; - -struct LTriangle2 -{ - LVector4 vertices[3]; - LVector3 vertexNormals[3]; - LVector2 textureCoords[3]; - LVector3 faceNormal; - uint materialId; -}; - -// a structure for a texture map -struct LMap -{ - // the strength of the texture map - float strength; - // the file name of the map. only 8.3 format in 3ds files :( - char mapName[255]; - float uScale; - float vScale; - float uOffset; - float vOffset; - float angle; -}; - -//------------------------------------------------ - -class LObject -{ -public: - // the default constructor, initilializes the m_name here - LObject(); - // the destructor frees memory (m_name) - virtual ~LObject(); - // call this to get the name of the object - virtual const std::string& GetName(); - - // this methods should not be used by the "user", they're used internally to fill the class - // with valid data when reading from file. If you're about to add an importer for another format you'LL - // have to use these methods - // call this to set the name of the object - virtual void SetName(const std::string& value); - // returns true if the object's name is the name passed as parameter - bool IsObject(const std::string &name); -protected: - // the name of the object - std::string m_name; -}; - -//------------------------------------------------ - -class LMaterial : public LObject -{ -public: - // the default constructor, does the initialization - LMaterial(); - // the destructor - virtual ~LMaterial(); - // returns the material ID - uint GetID(); - // returns the pointer to teh texture map 1 - LMap& GetTextureMap1(); - // returns the pointer to the texture map 2 - LMap& GetTextureMap2(); - // returns the pointer to teh opacity map - LMap& GetOpacityMap(); - // returns the pointer to the specular (gloss) map - LMap& GetSpecularMap(); - // returns the pointer to the bump map - LMap& GetBumpMap(); - // returns the pointer to the reflection map - LMap& GetReflectionMap(); - // returns the ambient color of the material - LColor3 GetAmbientColor(); - // returns the diffuse color of the material - LColor3 GetDiffuseColor(); - // returns the specular color of the material - LColor3 GetSpecularColor(); - // returns the shininess of the material, ranging from 0(matte) to 1(shiny) - float GetShininess(); - // returns the transparency of the material, ranging from 1(fully transparent) to 0(opaque) - float GetTransparency(); - // returns the type of shading, see LShading type - LShading GetShadingType(); - - // this methods should not be used by the "user", they're used internally to fill the class - // with valid data when reading from file. If you're about to add an importer for another format you'LL - // have to use these methods - // sets the material ID to "value" - void SetID(uint value); - // call this to set the ambient color of the material - void SetAmbientColor(const LColor3 &color); - // sets the diffuse color of the material - void SetDiffuseColor(const LColor3 &color); - // sets the specular color of the material - void SetSpecularColor(const LColor3 &color); - // sets the shininess of the material - void SetShininess(float value); - // sets the transparency of the material - void SetTransparency(float value); - // sets the shading type - void SetShadingType(LShading shading); -protected: - // the unique material ID - int m_id; - // the first texture map - LMap m_texMap1; - // the second texture map - LMap m_texMap2; - // the opacity map - LMap m_opacMap; - // the reflection map - LMap m_reflMap; - // the bump map - LMap m_bumpMap; - // specular map - LMap m_specMap; - // material ambient color - LColor3 m_ambient; - // material diffuse color - LColor3 m_diffuse; - // material specular color - LColor3 m_specular; - // shininess - float m_shininess; - // transparency - float m_transparency; - // the shading type for the material - LShading m_shading; -}; - -//------------------------------------------------ - -class LMesh : public LObject -{ -public: - // the default constructor - LMesh(); - // the destructor - virtual ~LMesh(); - // clears the mesh, deleteing all data - void Clear(); - // returns the number of vertices in the mesh - uint GetVertexCount(); - // sets the the size fo the vertex array - for internal use - void SetVertexArraySize(uint value); - // returns the number of triangles in the mesh - uint GetTriangleCount(); - // sets the size of the triangle array - for internal use - void SetTriangleArraySize(uint value); - // returns given vertex - const LVector4& GetVertex(uint index); - // returns the given normal - const LVector3& GetNormal(uint index); - // returns the given texture coordinates vector - const LVector2& GetUV(uint index); - // returns the pointer to the array of tangents - const LVector3& GetTangent(uint index); - // returns the pointer to the array of binormals - const LVector3& GetBinormal(uint index); - // sets the vertex at a given index to "vec" - for internal use - void SetVertex(const LVector4 &vec, uint index); - // sets the normal at a given index to "vec" - for internal use - void SetNormal(const LVector3 &vec, uint index); - // sets the texture coordinates vector at a given index to "vec" - for internal use - void SetUV(const LVector2 &vec, uint index); - // sets the tangent at a given index to "vec" - for internal use - void SetTangent(const LVector3 &vec, uint index); - // sets the binormal at a given index to "vec" - for internal use - void SetBinormal(const LVector3 &vec, uint index); - // returns the triangle with a given index - const LTriangle& GetTriangle(uint index); - // returns the triangle with a given index, see LTriangle2 structure description - LTriangle2 GetTriangle2(uint index); - // returns the mesh matrix, should be identity matrix after loading - LMatrix4 GetMatrix(); - // sets the mesh matrix to a given matrix - for internal use - void SetMatrix(LMatrix4 m); - // optimizises the mesh using a given optimization level - void Optimize(LOptimizationLevel value); - // sets an internal triangle structure with index "index" - for internal use only - void SetTri(const LTri &tri, uint index); - // returns the pointer to the internal triangle structure - for internal use only - LTri& GetTri(uint index); - // returns the material id with a given index for the mesh - uint GetMaterial(uint index); - // adds a material to the mesh and returns its index - for internal use - uint AddMaterial(uint id); - // returns the number of materials used in the mesh - uint GetMaterialCount(); -protected: - // the vertices, normals, etc. - std::vector m_vertices; - std::vector m_normals; - std::vector m_binormals; - std::vector m_tangents; - std::vector m_uv; - - // triangles - std::vector m_triangles; - - //used internally - std::vector m_tris; - - // the transformation matrix. - LMatrix4 m_matrix; - - // the material ID array - std::vector m_materials; - - // calculates the normals, either using the smoothing groups information or not - void CalcNormals(bool useSmoothingGroups); - // calculates the texture(tangent) space for each vertex - void CalcTextureSpace(); - // transforms the vertices by the mesh matrix - void TransformVertices(); -}; - -//------------------------------------------------ - -class LLight : public LObject -{ -public: - // the default constructor - LLight(); - // the destructor - virtual ~LLight(); - // clears the data the class holds - void Clear(); - // sets the position of the light source - for internal use - void SetPosition(LVector3 vec); - // returns the position of the light source - LVector3 GetPosition(); - // sets the color of the light - for internal use - void SetColor(LColor3 color); - // returns the color of the light - LColor3 GetColor(); - // sets whether the light is a spotlight or not - internal use - void SetSpotlight(bool value); - // returns true if the light is a spotlight - bool GetSpotlight(); - // sets the target of the light - internal use - void SetTarget(LVector3 target); - // returns the target of the spotlight - LVector3 GetTarget(); - // sets the hotspot - internal use - void SetHotspot(float value); - // returns the hotspot - float GetHotspot(); - // sets falloff - internal use - void SetFalloff(float value); - // returns falloff - float GetFalloff(); -protected: - LVector3 m_pos; - LColor3 m_color; - bool m_spotlight; - LVector3 m_target; - float m_hotspot; - float m_falloff; -}; - -//------------------------------------------------ - -class LImporter -{ -public: - // the default constructor - LImporter(); - // the destructor - virtual ~LImporter(); - // reads the model from a file, must be overriden by the child classes - virtual bool LoadFile(const char *filename) = 0; - // returns the number of meshes in the scene - uint GetMeshCount(); - // returns the number of lights in the scene - uint GetLightCount(); - // returns the number of materials in the scene - uint GetMaterialCount(); - // returns a pointer to a mesh - LMesh& GetMesh(uint index); - // returns a pointer to a light at a given index - LLight& GetLight(uint index); - // returns the pointer to the material - LMaterial& GetMaterial(uint index); - // returns the pointer to the material with a given name, or NULL if the material was not found - LMaterial* FindMaterial(const std::string &name); - // returns the pointer to the mesh with a given name, or NULL if the mesh with such name - // is not present in the scene - LMesh* FindMesh(const std::string &name); - // returns the pointer to the light with a given name, or NULL if not found - LLight* FindLight(const std::string &name); - // sets the optimization level to a given value - void SetOptimizationLevel(LOptimizationLevel value); - // returns the current optimization level - LOptimizationLevel GetOptimizationLevel(); -protected: - // the lights found in the scene - std::vector m_lights; - // triangular meshes - std::vector m_meshes; - // the materials in the scene - std::vector m_materials; - // level of optimization to perform on the meshes - LOptimizationLevel m_optLevel; - // clears all data. - virtual void Clear(); -}; -//------------------------------------------------ - -class L3DS : public LImporter -{ -public: - // the default contructor - L3DS(); - // constructs the object and loads the file - L3DS(const char *filename); - // destructor - virtual ~L3DS(); - // load 3ds file - virtual bool LoadFile(const char *filename); -protected: - // used internally for reading - char m_objName[100]; - // true if end of file is reached - bool m_eof; - // buffer for loading, used for speedup - unsigned char *m_buffer; - // the size of the buffer - uint m_bufferSize; - // the current cursor position in the buffer - uint m_pos; - - // reads a short value from the buffer - short ReadShort(); - // reads an int value from the buffer - int ReadInt(); - // reads a char from the buffer - char ReadChar(); - //reada a floatvalue from the buffer - float ReadFloat(); - //reads an unsigned byte from the buffer - byte ReadByte(); - //reads an asciiz string - int ReadASCIIZ(char *buf, int max_count); - // seek wihtin the buffer - void Seek(int offset, int origin); - // returns the position of the cursor - uint Pos(); - - // read the chunk and return it. - LChunk ReadChunk(); - // read until given chunk is found - bool FindChunk(LChunk &target, const LChunk &parent); - // skip to the end of chunk "chunk" - void SkipChunk(const LChunk &chunk); - // goes to the beginning of the data in teh given chunk - void GotoChunk(const LChunk &chunk); - - // the function read the color chunk (any of the color chunks) - LColor3 ReadColor(const LChunk &chunk); - // the function that read the percentage chunk and returns a float from 0 to 1 - float ReadPercentage(const LChunk &chunk); - // this is where 3ds file is being read - bool Read3DS(); - // read a light chunk - void ReadLight(const LChunk &parent); - // read a trimesh chunk - void ReadMesh(const LChunk &parent); - // reads the face list, face materials, smoothing groups... and fill rthe information into the mesh - void ReadFaceList(const LChunk &chunk, LMesh &mesh); - // reads the material - void ReadMaterial(const LChunk &parent); - // reads the map info and fills the given map with this information - void ReadMap(const LChunk &chunk, LMap& map); - // reads keyframer data of the OBJECT_NODE_TAG chunk - void ReadKeyframeData(const LChunk &parent); - // reads the keyheader structure from the current offset and returns the frame number - long ReadKeyheader(); -}; - -//--------------------------------------------------------- - -#endif \ No newline at end of file diff --git a/NOTICE b/NOTICE index 20af89c..19edc8d 100644 --- a/NOTICE +++ b/NOTICE @@ -62,3 +62,7 @@ Starshatter: The Open Source Project uses googletest: Copyright 2008, Google Inc. googletest is reeleased under BSD 3-Clause license. See . + + +Starshatter: The Open Source Project uses l3ds: +Copyright (c) 2001, Lev Povalahev diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt index 2c9f2f1..5b1d796 100644 --- a/third-party/CMakeLists.txt +++ b/third-party/CMakeLists.txt @@ -10,6 +10,7 @@ add_subdirectory(zlib) make_available(gtest infoware libpng ogg vorbis zlib) add_subdirectory(Opcode) add_subdirectory(sha1) +add_subdirectory(l3ds) install( TARGETS png15 Opcode RUNTIME diff --git a/third-party/l3ds/CMakeLists.txt b/third-party/l3ds/CMakeLists.txt new file mode 100644 index 0000000..89c13d2 --- /dev/null +++ b/third-party/l3ds/CMakeLists.txt @@ -0,0 +1,4 @@ +project(l3ds) +add_library(${PROJECT_NAME} SHARED l3ds.cpp) +target_include_directories(${PROJECT_NAME} PUBLIC include) +install(TARGETS ${PROJECT_NAME} RUNTIME COMPONENT Runtime DESTINATION ${CMAKE_INSTALL_PREFIX}) diff --git a/third-party/l3ds/include/l3ds.h b/third-party/l3ds/include/l3ds.h new file mode 100644 index 0000000..69a8e6d --- /dev/null +++ b/third-party/l3ds/include/l3ds.h @@ -0,0 +1,457 @@ +// copyright (c) 2001-2002 Lev Povalahev +// this is a 3ds importer version 2 + +#ifndef L3DS_H +#define L3DS_H + +// includes +#include +#include + +//--------------------------------------------------------- + +typedef unsigned int uint; +typedef unsigned char byte; + +enum LShading {sWireframe, sFlat, sGouraud, sPhong, sMetal}; + +enum LOptimizationLevel {oNone, oSimple, oFull}; + +// for internal use +struct LChunk; +struct LTri; + +//------------------------------------------------ + +struct LVector4 +{ + float x; + float y; + float z; + float w; + + int operator==(const LVector4& v) const { return x==v.x && y==v.y && z==v.z && w==v.w; } +}; + +struct LVector3 +{ + float x; + float y; + float z; + + int operator==(const LVector3& v) const { return x==v.x && y==v.y && z==v.z; } +}; + +struct LVector2 +{ + float x; + float y; + + int operator==(const LVector2& v) const { return x==v.x && y==v.y; } +}; + +struct LColor3 +{ + float r; + float g; + float b; + + int operator==(const LColor3& v) const { return r==v.r && g==v.g && b==v.b; } +}; + +//------------------------------------------------ + +struct LTriangle +{ + unsigned short a; + unsigned short b; + unsigned short c; +}; + +struct LMatrix4 +{ + float m[4][4]; +}; + +struct LTriangle2 +{ + LVector4 vertices[3]; + LVector3 vertexNormals[3]; + LVector2 textureCoords[3]; + LVector3 faceNormal; + uint materialId; +}; + +// a structure for a texture map +struct LMap +{ + // the strength of the texture map + float strength; + // the file name of the map. only 8.3 format in 3ds files :( + char mapName[255]; + float uScale; + float vScale; + float uOffset; + float vOffset; + float angle; +}; + +//------------------------------------------------ + +class LObject +{ +public: + // the default constructor, initilializes the m_name here + LObject(); + // the destructor frees memory (m_name) + virtual ~LObject(); + // call this to get the name of the object + virtual const std::string& GetName(); + + // this methods should not be used by the "user", they're used internally to fill the class + // with valid data when reading from file. If you're about to add an importer for another format you'LL + // have to use these methods + // call this to set the name of the object + virtual void SetName(const std::string& value); + // returns true if the object's name is the name passed as parameter + bool IsObject(const std::string &name); +protected: + // the name of the object + std::string m_name; +}; + +//------------------------------------------------ + +class LMaterial : public LObject +{ +public: + // the default constructor, does the initialization + LMaterial(); + // the destructor + virtual ~LMaterial(); + // returns the material ID + uint GetID(); + // returns the pointer to teh texture map 1 + LMap& GetTextureMap1(); + // returns the pointer to the texture map 2 + LMap& GetTextureMap2(); + // returns the pointer to teh opacity map + LMap& GetOpacityMap(); + // returns the pointer to the specular (gloss) map + LMap& GetSpecularMap(); + // returns the pointer to the bump map + LMap& GetBumpMap(); + // returns the pointer to the reflection map + LMap& GetReflectionMap(); + // returns the ambient color of the material + LColor3 GetAmbientColor(); + // returns the diffuse color of the material + LColor3 GetDiffuseColor(); + // returns the specular color of the material + LColor3 GetSpecularColor(); + // returns the shininess of the material, ranging from 0(matte) to 1(shiny) + float GetShininess(); + // returns the transparency of the material, ranging from 1(fully transparent) to 0(opaque) + float GetTransparency(); + // returns the type of shading, see LShading type + LShading GetShadingType(); + + // this methods should not be used by the "user", they're used internally to fill the class + // with valid data when reading from file. If you're about to add an importer for another format you'LL + // have to use these methods + // sets the material ID to "value" + void SetID(uint value); + // call this to set the ambient color of the material + void SetAmbientColor(const LColor3 &color); + // sets the diffuse color of the material + void SetDiffuseColor(const LColor3 &color); + // sets the specular color of the material + void SetSpecularColor(const LColor3 &color); + // sets the shininess of the material + void SetShininess(float value); + // sets the transparency of the material + void SetTransparency(float value); + // sets the shading type + void SetShadingType(LShading shading); +protected: + // the unique material ID + int m_id; + // the first texture map + LMap m_texMap1; + // the second texture map + LMap m_texMap2; + // the opacity map + LMap m_opacMap; + // the reflection map + LMap m_reflMap; + // the bump map + LMap m_bumpMap; + // specular map + LMap m_specMap; + // material ambient color + LColor3 m_ambient; + // material diffuse color + LColor3 m_diffuse; + // material specular color + LColor3 m_specular; + // shininess + float m_shininess; + // transparency + float m_transparency; + // the shading type for the material + LShading m_shading; +}; + +//------------------------------------------------ + +class LMesh : public LObject +{ +public: + // the default constructor + LMesh(); + // the destructor + virtual ~LMesh(); + // clears the mesh, deleteing all data + void Clear(); + // returns the number of vertices in the mesh + uint GetVertexCount(); + // sets the the size fo the vertex array - for internal use + void SetVertexArraySize(uint value); + // returns the number of triangles in the mesh + uint GetTriangleCount(); + // sets the size of the triangle array - for internal use + void SetTriangleArraySize(uint value); + // returns given vertex + const LVector4& GetVertex(uint index); + // returns the given normal + const LVector3& GetNormal(uint index); + // returns the given texture coordinates vector + const LVector2& GetUV(uint index); + // returns the pointer to the array of tangents + const LVector3& GetTangent(uint index); + // returns the pointer to the array of binormals + const LVector3& GetBinormal(uint index); + // sets the vertex at a given index to "vec" - for internal use + void SetVertex(const LVector4 &vec, uint index); + // sets the normal at a given index to "vec" - for internal use + void SetNormal(const LVector3 &vec, uint index); + // sets the texture coordinates vector at a given index to "vec" - for internal use + void SetUV(const LVector2 &vec, uint index); + // sets the tangent at a given index to "vec" - for internal use + void SetTangent(const LVector3 &vec, uint index); + // sets the binormal at a given index to "vec" - for internal use + void SetBinormal(const LVector3 &vec, uint index); + // returns the triangle with a given index + const LTriangle& GetTriangle(uint index); + // returns the triangle with a given index, see LTriangle2 structure description + LTriangle2 GetTriangle2(uint index); + // returns the mesh matrix, should be identity matrix after loading + LMatrix4 GetMatrix(); + // sets the mesh matrix to a given matrix - for internal use + void SetMatrix(LMatrix4 m); + // optimizises the mesh using a given optimization level + void Optimize(LOptimizationLevel value); + // sets an internal triangle structure with index "index" - for internal use only + void SetTri(const LTri &tri, uint index); + // returns the pointer to the internal triangle structure - for internal use only + LTri& GetTri(uint index); + // returns the material id with a given index for the mesh + uint GetMaterial(uint index); + // adds a material to the mesh and returns its index - for internal use + uint AddMaterial(uint id); + // returns the number of materials used in the mesh + uint GetMaterialCount(); +protected: + // the vertices, normals, etc. + std::vector m_vertices; + std::vector m_normals; + std::vector m_binormals; + std::vector m_tangents; + std::vector m_uv; + + // triangles + std::vector m_triangles; + + //used internally + std::vector m_tris; + + // the transformation matrix. + LMatrix4 m_matrix; + + // the material ID array + std::vector m_materials; + + // calculates the normals, either using the smoothing groups information or not + void CalcNormals(bool useSmoothingGroups); + // calculates the texture(tangent) space for each vertex + void CalcTextureSpace(); + // transforms the vertices by the mesh matrix + void TransformVertices(); +}; + +//------------------------------------------------ + +class LLight : public LObject +{ +public: + // the default constructor + LLight(); + // the destructor + virtual ~LLight(); + // clears the data the class holds + void Clear(); + // sets the position of the light source - for internal use + void SetPosition(LVector3 vec); + // returns the position of the light source + LVector3 GetPosition(); + // sets the color of the light - for internal use + void SetColor(LColor3 color); + // returns the color of the light + LColor3 GetColor(); + // sets whether the light is a spotlight or not - internal use + void SetSpotlight(bool value); + // returns true if the light is a spotlight + bool GetSpotlight(); + // sets the target of the light - internal use + void SetTarget(LVector3 target); + // returns the target of the spotlight + LVector3 GetTarget(); + // sets the hotspot - internal use + void SetHotspot(float value); + // returns the hotspot + float GetHotspot(); + // sets falloff - internal use + void SetFalloff(float value); + // returns falloff + float GetFalloff(); +protected: + LVector3 m_pos; + LColor3 m_color; + bool m_spotlight; + LVector3 m_target; + float m_hotspot; + float m_falloff; +}; + +//------------------------------------------------ + +class LImporter +{ +public: + // the default constructor + LImporter(); + // the destructor + virtual ~LImporter(); + // reads the model from a file, must be overriden by the child classes + virtual bool LoadFile(const char *filename) = 0; + // returns the number of meshes in the scene + uint GetMeshCount(); + // returns the number of lights in the scene + uint GetLightCount(); + // returns the number of materials in the scene + uint GetMaterialCount(); + // returns a pointer to a mesh + LMesh& GetMesh(uint index); + // returns a pointer to a light at a given index + LLight& GetLight(uint index); + // returns the pointer to the material + LMaterial& GetMaterial(uint index); + // returns the pointer to the material with a given name, or NULL if the material was not found + LMaterial* FindMaterial(const std::string &name); + // returns the pointer to the mesh with a given name, or NULL if the mesh with such name + // is not present in the scene + LMesh* FindMesh(const std::string &name); + // returns the pointer to the light with a given name, or NULL if not found + LLight* FindLight(const std::string &name); + // sets the optimization level to a given value + void SetOptimizationLevel(LOptimizationLevel value); + // returns the current optimization level + LOptimizationLevel GetOptimizationLevel(); +protected: + // the lights found in the scene + std::vector m_lights; + // triangular meshes + std::vector m_meshes; + // the materials in the scene + std::vector m_materials; + // level of optimization to perform on the meshes + LOptimizationLevel m_optLevel; + // clears all data. + virtual void Clear(); +}; +//------------------------------------------------ + +class L3DS : public LImporter +{ +public: + // the default contructor + L3DS(); + // constructs the object and loads the file + L3DS(const char *filename); + // destructor + virtual ~L3DS(); + // load 3ds file + virtual bool LoadFile(const char *filename); +protected: + // used internally for reading + char m_objName[100]; + // true if end of file is reached + bool m_eof; + // buffer for loading, used for speedup + unsigned char *m_buffer; + // the size of the buffer + uint m_bufferSize; + // the current cursor position in the buffer + uint m_pos; + + // reads a short value from the buffer + short ReadShort(); + // reads an int value from the buffer + int ReadInt(); + // reads a char from the buffer + char ReadChar(); + //reada a floatvalue from the buffer + float ReadFloat(); + //reads an unsigned byte from the buffer + byte ReadByte(); + //reads an asciiz string + int ReadASCIIZ(char *buf, int max_count); + // seek wihtin the buffer + void Seek(int offset, int origin); + // returns the position of the cursor + uint Pos(); + + // read the chunk and return it. + LChunk ReadChunk(); + // read until given chunk is found + bool FindChunk(LChunk &target, const LChunk &parent); + // skip to the end of chunk "chunk" + void SkipChunk(const LChunk &chunk); + // goes to the beginning of the data in teh given chunk + void GotoChunk(const LChunk &chunk); + + // the function read the color chunk (any of the color chunks) + LColor3 ReadColor(const LChunk &chunk); + // the function that read the percentage chunk and returns a float from 0 to 1 + float ReadPercentage(const LChunk &chunk); + // this is where 3ds file is being read + bool Read3DS(); + // read a light chunk + void ReadLight(const LChunk &parent); + // read a trimesh chunk + void ReadMesh(const LChunk &parent); + // reads the face list, face materials, smoothing groups... and fill rthe information into the mesh + void ReadFaceList(const LChunk &chunk, LMesh &mesh); + // reads the material + void ReadMaterial(const LChunk &parent); + // reads the map info and fills the given map with this information + void ReadMap(const LChunk &chunk, LMap& map); + // reads keyframer data of the OBJECT_NODE_TAG chunk + void ReadKeyframeData(const LChunk &parent); + // reads the keyheader structure from the current offset and returns the frame number + long ReadKeyheader(); +}; + +//--------------------------------------------------------- + +#endif diff --git a/third-party/l3ds/l3ds.cpp b/third-party/l3ds/l3ds.cpp new file mode 100644 index 0000000..50b27b8 --- /dev/null +++ b/third-party/l3ds/l3ds.cpp @@ -0,0 +1,1790 @@ +// copyright (c) 2001 Lev Povalahev + +#include "l3ds.h" + +#include +#include +#include +#include + +//using namespace std; + +//------------------------------------------------------- +// generic stuff +//------------------------------------------------------- + +typedef unsigned long ulong; + +#define SEEK_START 1900 +#define SEEK_CURSOR 1901 + +// common chunks +// colors +#define COLOR_F 0x0010 +#define COLOR_24 0x0011 +#define LIN_COLOR_24 0x0012 +#define LIN_COLOR_F 0x0013 +// percentage +#define INT_PERCENTAGE 0x0030 +#define FLOAT_PERCENTAGE 0x0031 +// ambient light +#define AMBIENT_LIGHT 0x2100 + + +#define MAIN3DS 0x4D4D +#define EDIT3DS 0x3D3D // this is the start of the editor config + +// keyframer chunk ids +#define KFDATA 0xB000 // the keyframer section +#define KFHDR 0xB00A +#define OBJECT_NODE_TAG 0xB002 +#define NODE_HDR 0xB010 +#define PIVOT 0xB013 +#define POS_TRACK_TAG 0xB020 +#define ROT_TRACK_TAG 0xB021 +#define SCL_TRACK_TAG 0xB022 + +// material entries +#define MAT_ENTRY 0xAFFF +#define MAT_NAME 0xA000 +#define MAT_AMBIENT 0xA010 +#define MAT_DIFFUSE 0xA020 +#define MAT_SPECULAR 0xA030 +#define MAT_SHININESS 0xA040 +#define MAT_SHIN2PCT 0xA041 +#define MAT_TRANSPARENCY 0xA050 +#define MAT_SHADING 0xA100 +#define MAT_TWO_SIDE 0xA081 +#define MAT_ADDITIVE 0xA083 +#define MAT_WIRE 0xA085 +#define MAT_FACEMAP 0xA088 +#define MAT_WIRESIZE 0xA087 +#define MAT_DECAL 0xA082 +#define MAT_TEXMAP 0xA200 +#define MAT_MAPNAME 0xA300 +#define MAT_MAP_TILING 0xA351 +#define MAT_MAP_USCALE 0xA354 +#define MAT_MAP_VSCALE 0xA356 +#define MAT_MAP_UOFFSET 0xA358 +#define MAT_MAP_VOFFSET 0xA35A +#define MAT_MAP_ANG 0xA35C +#define MAT_TEX2MAP 0xA33A +#define MAT_OPACMAP 0xA210 +#define MAT_BUMPMAP 0xA230 +#define MAT_SPECMAP 0xA204 +#define MAT_SHINMAP 0xA33C +#define MAT_REFLMAP 0xA220 +#define MAT_ACUBIC 0xA310 + +#define EDIT_OBJECT 0x4000 +#define OBJ_TRIMESH 0x4100 +#define OBJ_LIGHT 0x4600 +#define OBJ_CAMERA 0x4700 +#define LIT_OFF 0x4620 +#define LIT_SPOT 0x4610 +#define TRI_VERTEXLIST 0x4110 +#define TRI_VERTEXOPTIONS 0x4111 + +#define TRI_FACELIST 0x4120 + #define TRI_MAT_GROUP 0x4130 + #define TRI_SMOOTH_GROUP 0x4150 + +#define TRI_FACEMAPPING 0x4140 +#define TRI_MATRIX 0x4160 + +#define SPOTLIGHT 0x4610 + +//---------------------------------- + +#define MAX_SHARED_TRIS 100 + +// the error reporting routine + +void ErrorMsg(const char *msg) +{ + +} + +struct LChunk +{ + unsigned short id; + uint start; + uint end; +}; + +struct LTri +{ + unsigned short a; + unsigned short b; + unsigned short c; + ulong smoothingGroups; + LVector3 normal; + LVector3 tangent; + LVector3 binormal; + uint materialId; +}; + +// globals + +LColor3 black = {0, 0, 0}; + +LVector3 zero3 = {0, 0, 0}; + +LVector4 zero4 = {0, 0, 0, 0}; + +LMap emptyMap = {0, "", 1, 1, 0, 0, 0}; + +LVector3 _4to3(const LVector4 &vec) +{ + LVector3 t; + t.x = vec.x; + t.y = vec.y; + t.z = vec.z; + return t; +} + +LVector3 AddVectors(const LVector3 &a, const LVector3 &b) +{ + LVector3 t; + t.x = a.x+b.x; + t.y = a.y+b.y; + t.z = a.z+b.z; + return t; +} + +LVector3 SubtractVectors(const LVector3 &a, const LVector3 &b) +{ + LVector3 t; + t.x = a.x-b.x; + t.y = a.y-b.y; + t.z = a.z-b.z; + return t; +} + +float VectorLength(const LVector3 &vec) +{ + return (float)sqrt(vec.x*vec.x + vec.y*vec.y+vec.z*vec.z); +} + +LVector3 NormalizeVector(const LVector3 &vec) +{ + float a = VectorLength(vec); + if (a == 0) + return vec; + float b = 1/a; + LVector3 v; + v.x = vec.x*b; + v.y = vec.y*b; + v.z = vec.z*b; + return v; +} + +LVector3 CrossProduct(const LVector3 &a, const LVector3 &b) +{ + LVector3 v; + v.x = a.y*b.z - a.z*b.y; + v.y = a.z*b.x - a.x*b.z; + v.z = a.x*b.y - a.y*b.x; + return v; +} + +void LoadIdentityMatrix(LMatrix4 &m) +{ + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + m.m[i][j] = (i==j) ? 1.0f : 0.0f; +} + +LVector4 VectorByMatrix(const LMatrix4 &m, const LVector4 &vec) +{ + LVector4 res; + + res.x = m.m[0][0]*vec.x + m.m[1][0]*vec.y + m.m[2][0]*vec.z + m.m[3][0]*vec.w; + res.y = m.m[0][1]*vec.x + m.m[1][1]*vec.y + m.m[2][1]*vec.z + m.m[3][1]*vec.w; + res.z = m.m[0][2]*vec.x + m.m[1][2]*vec.y + m.m[2][2]*vec.z + m.m[3][2]*vec.w; + res.w = m.m[0][3]*vec.x + m.m[1][3]*vec.y + m.m[2][3]*vec.z + m.m[3][3]*vec.w; + + if (res.w != 0) { + float b = 1/res.w; + res.x *= b; + res.y *= b; + res.z *= b; + res.w = 1; + } + else { + res.w = 1; + } + + return res; +} + +void QuatToMatrix(const LVector4 &quat, LMatrix4 &m) +{ + +} + +//------------------------------------------------------- +// LObject implementation +//------------------------------------------------------- + +LObject::LObject() +{ + m_name = "";//.clear(); +} + +LObject::~LObject() +{ + // nothing here +} + +void LObject::SetName(const std::string& value) +{ + m_name = value; +} + +const std::string& LObject::GetName() +{ + return m_name; +} + +bool LObject::IsObject(const std::string &name) +{ + return (m_name == name); +} + + +//------------------------------------------------------- +// LMaterial implementation +//------------------------------------------------------- + +LMaterial::LMaterial() +: LObject() +{ + m_id = 0; + m_texMap1 = emptyMap; + m_texMap2 = emptyMap; + m_opacMap = emptyMap; + m_bumpMap = emptyMap; + m_reflMap = emptyMap; + m_specMap = emptyMap; + m_ambient = black; + m_diffuse = black; + m_specular = black; + m_shading = sGouraud; + m_shininess = 0; + m_transparency = 0; +} + +LMaterial::~LMaterial() +{ + +} + +uint LMaterial::GetID() +{ + return m_id; +} + +LMap& LMaterial::GetTextureMap1() +{ + return m_texMap1; +} + +LMap& LMaterial::GetTextureMap2() +{ + return m_texMap2; +} + +LMap& LMaterial::GetOpacityMap() +{ + return m_opacMap; +} + +LMap& LMaterial::GetSpecularMap() +{ + return m_specMap; +} + +LMap& LMaterial::GetBumpMap() +{ + return m_bumpMap; +} + +LMap& LMaterial::GetReflectionMap() +{ + return m_reflMap; +} + +LColor3 LMaterial::GetAmbientColor() +{ + return m_ambient; +} + +LColor3 LMaterial::GetDiffuseColor() +{ + return m_diffuse; +} + +LColor3 LMaterial::GetSpecularColor() +{ + return m_specular; +} + +float LMaterial::GetShininess() +{ + return m_shininess; +} + +float LMaterial::GetTransparency() +{ + return m_transparency; +} + +LShading LMaterial::GetShadingType() +{ + return m_shading; +} + +void LMaterial::SetID(uint value) +{ + m_id = value; +} + +void LMaterial::SetAmbientColor(const LColor3 &color) +{ + m_ambient = color; +} + +void LMaterial::SetDiffuseColor(const LColor3 &color) +{ + m_diffuse = color; +} + +void LMaterial::SetSpecularColor(const LColor3 &color) +{ + m_specular = color; +} + +void LMaterial::SetShininess(float value) +{ + m_shininess = value; + if (m_shininess < 0) + m_shininess = 0; + if (m_shininess > 1) + m_shininess = 1; +} + +void LMaterial::SetTransparency(float value) +{ + m_transparency = value; + if (m_transparency < 0) + m_transparency = 0; + if (m_transparency > 1) + m_transparency = 1; +} + +void LMaterial::SetShadingType(LShading shading) +{ + m_shading = shading; +} + +//------------------------------------------------------- +// LMesh implementation +//------------------------------------------------------- + +LMesh::LMesh() +: LObject() +{ + Clear(); +} + +LMesh::~LMesh() +{ + Clear(); +} + +void LMesh::Clear() +{ + m_vertices.clear(); + m_normals.clear(); + m_uv.clear(); + m_tangents.clear(); + m_binormals.clear(); + m_triangles.clear(); + m_tris.clear(); + m_materials.clear(); + LoadIdentityMatrix(m_matrix); +} + +uint LMesh::GetVertexCount() +{ + return m_vertices.size(); +} + +void LMesh::SetVertexArraySize(uint value) +{ + m_vertices.resize(value); + m_normals.resize(value); + m_uv.resize(value); + m_tangents.resize(value); + m_binormals.resize(value); +} + +uint LMesh::GetTriangleCount() +{ + return m_triangles.size(); +} + +void LMesh::SetTriangleArraySize(uint value) +{ + m_triangles.resize(value); + m_tris.resize(value); +} + +const LVector4& LMesh::GetVertex(uint index) +{ + return m_vertices[index]; +} + +const LVector3& LMesh::GetNormal(uint index) +{ + return m_normals[index]; +} + +const LVector2& LMesh::GetUV(uint index) +{ + return m_uv[index]; +} + +const LVector3& LMesh::GetTangent(uint index) +{ + return m_tangents[index]; +} + +const LVector3& LMesh::GetBinormal(uint index) +{ + return m_binormals[index]; +} + +void LMesh::SetVertex(const LVector4 &vec, uint index) +{ + if (index >= m_vertices.size()) + return; + m_vertices[index] = vec; +} + +void LMesh::SetNormal(const LVector3 &vec, uint index) +{ + if (index >= m_vertices.size()) + return; + m_normals[index] = vec; +} + +void LMesh::SetUV(const LVector2 &vec, uint index) +{ + if (index >= m_vertices.size()) + return; + m_uv[index] = vec; +} + +void LMesh::SetTangent(const LVector3 &vec, uint index) +{ + if (index >= m_vertices.size()) + return; + m_tangents[index] = vec; +} + +void LMesh::SetBinormal(const LVector3 &vec, uint index) +{ + if (index >= m_vertices.size()) + return; + m_binormals[index] = vec; +} + +const LTriangle& LMesh::GetTriangle(uint index) +{ + return m_triangles[index]; +} + +LTriangle2 LMesh::GetTriangle2(uint index) +{ + LTriangle2 f; + LTriangle t = GetTriangle(index); + f.vertices[0] = GetVertex(t.a); + f.vertices[1] = GetVertex(t.b); + f.vertices[2] = GetVertex(t.c); + + f.vertexNormals[0] = GetNormal(t.a); + f.vertexNormals[1] = GetNormal(t.b); + f.vertexNormals[2] = GetNormal(t.c); + + f.textureCoords[0] = GetUV(t.a); + f.textureCoords[1] = GetUV(t.b); + f.textureCoords[2] = GetUV(t.c); + + LVector3 a, b; + + a = SubtractVectors(_4to3(f.vertices[1]), _4to3(f.vertices[0])); + b = SubtractVectors(_4to3(f.vertices[1]), _4to3(f.vertices[2])); + + f.faceNormal = CrossProduct(b, a); + + f.faceNormal = NormalizeVector(f.faceNormal); + + f.materialId = m_tris[index].materialId; + + return f; +} + +LMatrix4 LMesh::GetMatrix() +{ + return m_matrix; +} + +void LMesh::SetMatrix(LMatrix4 m) +{ + m_matrix = m; +} + +void LMesh::TransformVertices() +{ + for (uint i=0; i > array; + array.resize(m_vertices.size()); + for (i=0; i smGroups; + std::vector< std::vector > smList; + + uint loop_size = m_vertices.size(); + + for (i=0; i 1) + for (uint j=1; j< smGroups.size(); j++) + { + m_vertices.push_back(m_vertices[i]); + m_normals.push_back(m_normals[i]); + m_uv.push_back(m_uv[i]); + m_tangents.push_back(m_tangents[i]); + m_binormals.push_back(m_binormals[i]); + + uint t = m_vertices.size()-1; + for (uint h=0; h > array; + array.resize(m_vertices.size()); + for (int i=0; i<(int)m_triangles.size(); i++) + { + uint k = m_tris[i].a; + array[k].push_back(i); + + k = m_tris[i].b; + array[k].push_back(i); + + k = m_tris[i].c; + array[k].push_back(i); + } + + // now average the tangents and compute the binormals as (tangent X normal) + for (int i=0; i<(int)m_vertices.size(); i++) + { + v1 = zero3; + v2 = zero3; + int t = array[i].size(); + + for (int k=0; k= m_triangles.size()) + return; + m_tris[index] = tri; +} + +LTri& LMesh::GetTri(uint index) +{ + return m_tris[index]; +} + +uint LMesh::GetMaterial(uint index) +{ + return m_materials[index]; +} + +uint LMesh::AddMaterial(uint id) +{ + m_materials.push_back(id); + return m_materials.size()-1; +} + +uint LMesh::GetMaterialCount() +{ + return m_materials.size(); +} + +//------------------------------------------------------- +// LLight implementation +//------------------------------------------------------- + +LLight::LLight() +: LObject() +{ + Clear(); +} + +LLight::~LLight() +{ + +} + +void LLight::Clear() +{ + m_pos.x = m_pos.y = m_pos.z = 0.0f; + m_color.r = m_color.g = m_color.b = 0.0f; + m_spotlight = false; +} + +void LLight::SetPosition(LVector3 vec) +{ + m_pos = vec; +} + +LVector3 LLight::GetPosition() +{ + return m_pos; +} + +void LLight::SetColor(LColor3 color) +{ + m_color = color; +} + +LColor3 LLight::GetColor() +{ + return m_color; +} + +void LLight::SetSpotlight(bool value) +{ + m_spotlight = value; +} + +bool LLight::GetSpotlight() +{ + return m_spotlight; +} + +void LLight::SetTarget(LVector3 target) +{ + m_target = target; +} + +LVector3 LLight::GetTarget() +{ + return m_target; +} + +void LLight::SetHotspot(float value) +{ + m_hotspot = value; +} + +float LLight::GetHotspot() +{ + return m_hotspot; +} + +void LLight::SetFalloff(float value) +{ + m_falloff = value; +} + +float LLight::GetFalloff() +{ + return m_falloff; +} + +//------------------------------------------------------- +// LImporter implementation +//------------------------------------------------------- + +LImporter::LImporter() +{ + Clear(); +} + +LImporter::~LImporter() +{ + Clear(); +} + +uint LImporter::GetMeshCount() +{ + return m_meshes.size(); +} + +uint LImporter::GetLightCount() +{ + return m_lights.size(); +} + +uint LImporter::GetMaterialCount() +{ + return m_materials.size(); +} + +LMesh& LImporter::GetMesh(uint index) +{ + return m_meshes[index]; +} + +LLight& LImporter::GetLight(uint index) +{ + return m_lights[index]; +} + +LMaterial& LImporter::GetMaterial(uint index) +{ + return m_materials[index]; +} + +LMaterial* LImporter::FindMaterial(const std::string& name) +{ + for (uint i=0; i 0) + free(m_buffer); +} + +bool L3DS::LoadFile(const char *filename) +{ + FILE *f; + f = fopen(filename, "rb"); + if (f == 0) + { + ErrorMsg("L3DS::LoadFile - cannot open file"); + return false; + } + fseek(f, 0, SEEK_END); + m_bufferSize = ftell(f); + fseek(f, 0, SEEK_SET); + m_buffer = (unsigned char*) calloc(m_bufferSize, 1); + if (m_buffer == 0) + { + ErrorMsg("L3DS::LoadFile - not enough memory (malloc failed)"); + return false; + } + if (fread(m_buffer, m_bufferSize, 1, f) != 1) + { + fclose(f); + free(m_buffer); + m_bufferSize = 0; + ErrorMsg("L3DS::LoadFile - error reading from file"); + return false; + } + fclose(f); + Clear(); + bool res = Read3DS(); + free(m_buffer); + m_buffer = 0; + m_bufferSize = 0; + return res; +} + +short L3DS::ReadShort() +{ + if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+2)=m_bufferSize)) + { + count = 0; + m_eof = true; + return count; + } + count = 0; + char c = ReadChar(); + while ((c!=0) && (count= m_bufferSize) + m_pos = m_bufferSize-1; + m_eof = false; +} + +uint L3DS::Pos() +{ + return m_pos; +} + +LChunk L3DS::ReadChunk() +{ + LChunk chunk; + chunk.id = ReadShort(); + int a = ReadInt(); + chunk.start = Pos(); + chunk.end = chunk.start+a-6; + return chunk; +} + +bool L3DS::FindChunk(LChunk &target, const LChunk &parent) +{ + if (Pos() >= parent.end) + return false; + LChunk chunk; + chunk = ReadChunk(); + while (( chunk.id != target.id) && (chunk.end <= parent.end)) + { + SkipChunk(chunk); + if (chunk.end >= parent.end) + break; + chunk = ReadChunk(); + } + if (chunk.id == target.id) + { + target.start = chunk.start; + target.end = chunk.end; + return true; + } + return false; +} + +void L3DS::SkipChunk(const LChunk &chunk) +{ + Seek(chunk.end, SEEK_START); +} + +void L3DS::GotoChunk(const LChunk &chunk) +{ + Seek(chunk.start, SEEK_START); +} + +LColor3 L3DS::ReadColor(const LChunk &chunk) +{ + LColor3 col = black; + GotoChunk(chunk); + switch (chunk.id) + { + case COLOR_F: + col.r = ReadFloat(); + col.g = ReadFloat(); + col.b = ReadFloat(); + break; + case COLOR_24: + col.r = ReadByte()/255.0f; + col.g = ReadByte()/255.0f; + col.b = ReadByte()/255.0f; + break; + case LIN_COLOR_F: + col.r = ReadFloat(); + col.g = ReadFloat(); + col.b = ReadFloat(); + break; + case LIN_COLOR_24: + col.r = ReadByte()/255.0f; + col.g = ReadByte()/255.0f; + col.b = ReadByte()/255.0f; + break; + default: + ErrorMsg("L3DS::ReadColor - error this is not a color chunk"); + } + return col; +} + +float L3DS::ReadPercentage(const LChunk &chunk) +{ + GotoChunk(chunk); + switch (chunk.id) + { + case INT_PERCENTAGE: + return (ReadShort()/100.0f); + case FLOAT_PERCENTAGE: + return ReadFloat(); + } + ErrorMsg("L3DS::ReadPercentage - error, the chunk is not a percentage chunk"); + return 0; +} + +bool L3DS::Read3DS() +{ + LChunk mainchunk; + LChunk edit; + edit.id = EDIT3DS; + mainchunk = ReadChunk(); + if (mainchunk.id != MAIN3DS) + { + ErrorMsg("L3DS::Read3DS - wrong file format"); + return false; + } + if (!FindChunk(edit, mainchunk)) + return false; + LChunk obj; + LChunk ml; + + GotoChunk(edit); + obj.id = MAT_ENTRY; + while (FindChunk(obj, edit)) + { + ReadMaterial(obj); + SkipChunk(obj); + } + GotoChunk(edit); + + obj.id = EDIT_OBJECT; + { + while (FindChunk(obj, edit)) + { + ReadASCIIZ(m_objName, 99); + ml = ReadChunk(); + if (ml.id == OBJ_TRIMESH) + ReadMesh(ml); + if (ml.id == OBJ_LIGHT) + ReadLight(ml); + SkipChunk(obj); + } + } + + // read the keyframer data here to find out correct object orientation + + LChunk keyframer; + keyframer.id = KFDATA; + + LChunk objtrack; + objtrack.id = OBJECT_NODE_TAG; + + GotoChunk(mainchunk); + if (FindChunk(keyframer, mainchunk)) + { // keyframer chunk is present + GotoChunk(keyframer); + while (FindChunk(objtrack, keyframer)) + { + ReadKeyframeData(objtrack); + SkipChunk(objtrack); + } + } + + for (uint i=0; i= parent.end) + break; + chunk = ReadChunk(); + + } + } + m_lights.push_back(light); +} + +void L3DS::ReadMesh(const LChunk &parent) +{ + unsigned short count, i; + LVector4 p; + LMatrix4 m; + LVector2 t; + p.w = 1.0f; + LMesh mesh; + mesh.SetName(m_objName); + GotoChunk(parent); + LChunk chunk = ReadChunk(); + while (chunk.end <= parent.end) + { + switch (chunk.id) + { + case TRI_VERTEXLIST: + count = ReadShort(); + mesh.SetVertexArraySize(count); + for (i=0; i < count; i++) + { + p.x = ReadFloat(); + p.y = ReadFloat(); + p.z = ReadFloat(); + mesh.SetVertex(p, i); + } + break; + case TRI_FACEMAPPING: + count = ReadShort(); + if (mesh.GetVertexCount() == 0) + mesh.SetVertexArraySize(count); + for (i=0; i < count; i++) + { + t.x = ReadFloat(); + t.y = ReadFloat(); + mesh.SetUV(t, i); + } + break; + case TRI_FACELIST: + ReadFaceList(chunk, mesh); + break; + case TRI_MATRIX: + { + for (int i = 0; i < 4; i++) + for (int j = 0; j < 3; j++) + m.m[i][j] = ReadFloat(); + + m.m[0][3] = 0.0f; + m.m[1][3] = 0.0f; + m.m[2][3] = 0.0f; + m.m[3][3] = 1.0f; + + mesh.SetMatrix(m); + } + break; + default: + break; + } + SkipChunk(chunk); + if (chunk.end >= parent.end) + break; + chunk = ReadChunk(); + } + m_meshes.push_back(mesh); +} + +void L3DS::ReadFaceList(const LChunk &chunk, LMesh &mesh) +{ + // variables + unsigned short count, t; + uint i; + LTri tri; + LChunk ch; + char str[20]; + //uint mat; + + // consistency checks + if (chunk.id != TRI_FACELIST) + { + ErrorMsg("L3DS::ReadFaceList - internal error: wrong chunk passed as parameter"); + return; + } + GotoChunk(chunk); + tri.smoothingGroups = 1; + // read the number of faces + count = ReadShort(); + mesh.SetTriangleArraySize(count); + for (i=0; iGetID(); + mesh.AddMaterial(mat_id); + count = ReadShort(); + for (i=0; i 0) + { + ReadKeyheader(); + pos.x = ReadFloat(); + pos.y = ReadFloat(); + pos.z = ReadFloat(); + } + } + GotoChunk(parent); + + // now read the rotation track + LVector4 rot = zero4; + + LChunk rotchunk; + rotchunk.id = ROT_TRACK_TAG; + + frames = 0; + if (FindChunk(rotchunk, parent)) + { + GotoChunk(rotchunk); + // read the trackheader structure + ReadShort(); + ReadInt(); + ReadInt(); + frames = ReadInt(); + if (frames > 0) + { + ReadKeyheader(); + rot.x = ReadFloat(); + rot.y = ReadFloat(); + rot.z = ReadFloat(); + rot.w = ReadFloat(); + } + } + GotoChunk(parent); + + // now read the scaling chunk + LVector3 scale; + scale.x = 1; + scale.y = 1; + scale.z = 1; + + LChunk scalechunk; + scalechunk.id = SCL_TRACK_TAG; + + frames = 0; + + if (FindChunk(scalechunk, parent)) + { + GotoChunk(scalechunk); + // read the trackheader structure + ReadShort(); + ReadInt(); + ReadInt(); + frames = ReadInt(); + if (frames > 0) + { + ReadKeyheader(); + scale.x = ReadFloat(); + scale.y = ReadFloat(); + scale.z = ReadFloat(); + } + } + GotoChunk(parent); + + +} + +long L3DS::ReadKeyheader() +{ + long frame; + frame = ReadInt(); + short opts = ReadShort(); + if (opts & 32768) // 32768 is 1000000000000000 binary + { // tension is present + ReadFloat(); + } + if (opts & 16384) // 16384 is 0100000000000000 binary + { // continuity is present + ReadFloat(); + } + if (opts & 8192) + { // bias info present + ReadFloat(); + } + if (opts & 4096) + { // "ease to" present + ReadFloat(); + } + if (opts & 2048) + { // "ease from" present + ReadFloat(); + } + return frame; +} -- cgit v1.1