summaryrefslogtreecommitdiffhomepage
path: root/MagicEx/l3ds.cpp
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2024-04-05 20:57:38 +0200
committerAki <please@ignore.pl>2024-04-05 20:57:51 +0200
commiteffc8802a77375437b676ac4534789e819731671 (patch)
tree4b752b61487bef73f3fce28c1f0a402f0a3ecc76 /MagicEx/l3ds.cpp
parentbeeacf69d68f366cbbc9701bb7dabd23a898c8c7 (diff)
downloadstarshatter-effc8802a77375437b676ac4534789e819731671.zip
starshatter-effc8802a77375437b676ac4534789e819731671.tar.gz
starshatter-effc8802a77375437b676ac4534789e819731671.tar.bz2
l3ds is a third party library
Diffstat (limited to 'MagicEx/l3ds.cpp')
-rw-r--r--MagicEx/l3ds.cpp1790
1 files changed, 0 insertions, 1790 deletions
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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-//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<m_vertices.size(); i++)
- m_vertices[i] = VectorByMatrix(m_matrix, m_vertices[i]);
-
- LoadIdentityMatrix(m_matrix);
-}
-
-void LMesh::CalcNormals(bool useSmoothingGroups)
-{
- uint i;
- // first calculate the face normals
- for (i=0; i<m_triangles.size(); i++)
- {
- LVector3 a, b;
- a = SubtractVectors(_4to3(m_vertices[m_tris[i].b]), _4to3(m_vertices[m_tris[i].a]));
- b = SubtractVectors(_4to3(m_vertices[m_tris[i].b]), _4to3(m_vertices[m_tris[i].c]));
- m_tris[i].normal = NormalizeVector(CrossProduct(b, a));
- }
-
- std::vector< std::vector<int> > array;
- array.resize(m_vertices.size());
- for (i=0; i<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);
- }
-
- LVector3 temp;
-
- if (!useSmoothingGroups)
- {
- // now calculate the normals without using smoothing groups
- for (i=0; i<m_vertices.size(); i++)
- {
- temp = zero3;
- int t = array[i].size();
-
- for (int k=0; k<t; k++)
- {
- temp.x += m_tris[array[i][k]].normal.x;
- temp.y += m_tris[array[i][k]].normal.y;
- temp.z += m_tris[array[i][k]].normal.z;
- }
- m_normals[i] = NormalizeVector(temp);
- }
- }
- else
- {
- // now calculate the normals _USING_ smoothing groups
- // I'm assuming a triangle can only belong to one smoothing group at a time!
- std::vector<ulong> smGroups;
- std::vector< std::vector <uint> > smList;
-
- uint loop_size = m_vertices.size();
-
- for (i=0; i<loop_size; i++)
- {
- int t = array[i].size();
-
- if (t == 0)
- continue;
-
- smGroups.clear();
- smList.clear();
- smGroups.push_back(m_tris[array[i][0]].smoothingGroups);
- smList.resize(smGroups.size());
- smList[smGroups.size()-1].push_back(array[i][0]);
-
- // first build a list of smoothing groups for the vertex
- for (int k=0; k<t; k++)
- {
- bool found = false;
- for (uint j=0; j<smGroups.size(); j++)
- {
- if (m_tris[array[i][k]].smoothingGroups == smGroups[j])
- {
- smList[j].push_back(array[i][k]);
- found = true;
- }
- }
- if (!found)
- {
- smGroups.push_back(m_tris[array[i][k]].smoothingGroups);
- smList.resize(smGroups.size());
- smList[smGroups.size()-1].push_back(array[i][k]);
- }
- }
- // now we have the list of faces for the vertex sorted by smoothing groups
-
-
- // now duplicate the vertices so that there's only one smoothing group "per vertex"
- if (smGroups.size() > 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<smList[j].size(); h++)
- {
- if (m_tris[smList[j][h]].a == i)
- m_tris[smList[j][h]].a = t;
- if (m_tris[smList[j][h]].b == i)
- m_tris[smList[j][h]].b = t;
- if (m_tris[smList[j][h]].c == i)
- m_tris[smList[j][h]].c = t;
- }
- }
- }
-
- // now rebuild a face list for each vertex, since the old one is invalidated
- for (i=0; i<array.size(); i++)
- array[i].clear();
- array.clear();
- array.resize(m_vertices.size());
- for (i=0; i<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 compute the normals
- for (i=0; i<m_vertices.size(); i++)
- {
- temp = zero3;
- int t = array[i].size();
-
- for (int k=0; k<t; k++)
- {
- temp.x += m_tris[array[i][k]].normal.x;
- temp.y += m_tris[array[i][k]].normal.y;
- temp.z += m_tris[array[i][k]].normal.z;
- }
- m_normals[i] = NormalizeVector(temp);
- }
-
- }
-
- // copy m_tris to m_triangles
- for (i=0; i<m_triangles.size(); i++)
- {
- m_triangles[i].a = m_tris[i].a;
- m_triangles[i].b = m_tris[i].b;
- m_triangles[i].c = m_tris[i].c;
- }
-
-}
-
-void LMesh::CalcTextureSpace()
-{
- // a understandable description of how to do that can be found here:
- // http://members.rogers.com/deseric/tangentspace.htm
- // first calculate the tangent for each triangle
- LVector3 x_vec,
- y_vec,
- z_vec;
- LVector3 v1, v2;
- for (uint i=0; i<m_triangles.size(); i++)
- {
- v1.x = m_vertices[m_tris[i].b].x - m_vertices[m_tris[i].a].x;
- v1.y = m_uv[m_tris[i].b].x - m_uv[m_tris[i].a].x;
- v1.z = m_uv[m_tris[i].b].y - m_uv[m_tris[i].a].y;
-
- v2.x = m_vertices[m_tris[i].c].x - m_vertices[m_tris[i].a].x;
- v2.y = m_uv[m_tris[i].c].x - m_uv[m_tris[i].a].x;
- v2.z = m_uv[m_tris[i].c].y - m_uv[m_tris[i].a].y;
-
- x_vec = CrossProduct(v1, v2);
-
- v1.x = m_vertices[m_tris[i].b].y - m_vertices[m_tris[i].a].y;
- v1.y = m_uv[m_tris[i].b].x - m_uv[m_tris[i].a].x;
- v1.z = m_uv[m_tris[i].b].y - m_uv[m_tris[i].a].y;
-
- v2.x = m_vertices[m_tris[i].c].y - m_vertices[m_tris[i].a].y;
- v2.y = m_uv[m_tris[i].c].x - m_uv[m_tris[i].a].x;
- v2.z = m_uv[m_tris[i].c].y - m_uv[m_tris[i].a].y;
-
- y_vec = CrossProduct(v1, v2);
-
- v1.x = m_vertices[m_tris[i].b].z - m_vertices[m_tris[i].a].z;
- v1.y = m_uv[m_tris[i].b].x - m_uv[m_tris[i].a].x;
- v1.z = m_uv[m_tris[i].b].y - m_uv[m_tris[i].a].y;
-
- v2.x = m_vertices[m_tris[i].c].z - m_vertices[m_tris[i].a].z;
- v2.y = m_uv[m_tris[i].c].x - m_uv[m_tris[i].a].x;
- v2.z = m_uv[m_tris[i].c].y - m_uv[m_tris[i].a].y;
-
- z_vec = CrossProduct(v1, v2);
-
- m_tris[i].tangent.x = -(x_vec.y/x_vec.x);
- m_tris[i].tangent.y = -(y_vec.y/y_vec.x);
- m_tris[i].tangent.z = -(z_vec.y/z_vec.x);
-
- m_tris[i].binormal.x = -(x_vec.z/x_vec.x);
- m_tris[i].binormal.y = -(y_vec.z/y_vec.x);
- m_tris[i].binormal.z = -(z_vec.z/z_vec.x);
-
- }
-
- // now for each vertex build a list of face that share this vertex
- std::vector< std::vector<int> > 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<t; k++)
- {
- v1.x += m_tris[array[i][k]].tangent.x;
- v1.y += m_tris[array[i][k]].tangent.y;
- v1.z += m_tris[array[i][k]].tangent.z;
-
- v2.x += m_tris[array[i][k]].binormal.x;
- v2.y += m_tris[array[i][k]].binormal.y;
- v2.z += m_tris[array[i][k]].binormal.z;
- }
- m_tangents[i] = NormalizeVector(v1);
- //m_binormals[i] = NormalizeVector(v2);
-
- m_binormals[i] = NormalizeVector(CrossProduct(m_tangents[i], m_normals[i]));
- }
-}
-
-void LMesh::Optimize(LOptimizationLevel value)
-{
- switch (value)
- {
- case oNone:
- TransformVertices();
- break;
- case oSimple:
- TransformVertices();
- CalcNormals(false);
- break;
- case oFull:
- TransformVertices();
- CalcNormals(true);
- CalcTextureSpace();
- break;
- }
-}
-
-void LMesh::SetTri(const LTri &tri, uint index)
-{
- if (index >= 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<m_materials.size(); i++)
- if (m_materials[i].IsObject(name))
- return &m_materials[i];
- return 0;
-}
-
-LMesh* LImporter::FindMesh(const std::string& name)
-{
- for (uint i=0; i<m_meshes.size(); i++)
- if (m_meshes[i].IsObject(name))
- return &m_meshes[i];
- return 0;
-}
-
-LLight* LImporter::FindLight(const std::string& name)
-{
- for (uint i=0; i<m_lights.size(); i++)
- if (m_lights[i].IsObject(name))
- return &m_lights[i];
- return 0;
-}
-
-void LImporter::Clear()
-{
- m_meshes.clear();
- m_lights.clear();
- m_materials.clear();
- m_optLevel = oFull;
-}
-
-void LImporter::SetOptimizationLevel(LOptimizationLevel value)
-{
- m_optLevel = value;
-}
-
-LOptimizationLevel LImporter::GetOptimizationLevel()
-{
- return m_optLevel;
-}
-
-//-------------------------------------------------------
-// L3DS implementation
-//-------------------------------------------------------
-
-L3DS::L3DS()
-: LImporter()
-{
- m_buffer = 0;
- m_bufferSize = 0;
- m_pos = 0;
- m_eof = false;
-}
-
-L3DS::L3DS(const char *filename)
-: LImporter()
-{
- m_buffer = 0;
- m_bufferSize = 0;
- m_pos = 0;
- m_eof = false;
- LoadFile(filename);
-}
-
-L3DS::~L3DS()
-{
- if (m_bufferSize > 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))
- {
- short *w = (short*)(m_buffer+m_pos);
- short s = *w;//(short)*(m_buffer+m_pos);
- m_pos += 2;
- return s;
- }
- m_eof = true;
- return 0;
-}
-
-int L3DS::ReadInt()
-{
- if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+4)<m_bufferSize))
- {
- int *w = (int*)(m_buffer+m_pos);
- int s = *w;//(int)*(m_buffer+m_pos);
- m_pos += 4;
- return s;
- }
- m_eof = true;
- return 0;
-}
-
-char L3DS::ReadChar()
-{
- if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+1)<m_bufferSize))
- {
- char s = (char)*(m_buffer+m_pos);
- m_pos += 1;
- return s;
- }
- m_eof = true;
- return 0;
-}
-
-float L3DS::ReadFloat()
-{
- if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+4)<m_bufferSize))
- {
- float *w = (float*)(m_buffer+m_pos);
- float s = *w;//(float)*(m_buffer+m_pos);
- m_pos += 4;
- return s;
- }
- m_eof = true;
- return 0.0;
-}
-
-byte L3DS::ReadByte()
-{
- if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+1)<m_bufferSize))
- {
- byte s = (byte)*(m_buffer+m_pos);
- m_pos += 1;
- return s;
- }
- m_eof = true;
- return 0;
-}
-
-int L3DS::ReadASCIIZ(char *buf, int max_count)
-{
- int count;
- if ((m_buffer==0) || (m_bufferSize == 0) || (m_pos>=m_bufferSize))
- {
- count = 0;
- m_eof = true;
- return count;
- }
- count = 0;
- char c = ReadChar();
- while ((c!=0) && (count<max_count-1))
- {
- buf[count] = c;
- count ++;
- c = ReadChar();
- }
- buf[count] = 0;
- return count;
-}
-
-void L3DS::Seek(int offset, int origin)
-{
- if (origin == SEEK_START)
- m_pos = offset;
- if (origin == SEEK_CURSOR)
- m_pos += offset;
- if (m_pos >= 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<m_meshes.size(); i++) {
- m_meshes[i].Optimize(m_optLevel);
- }
-
- m_pos = 0;
- strcpy(m_objName, "");
- return true;
-}
-
-void L3DS::ReadLight(const LChunk &parent)
-{
- float t;
- LVector3 v;
- LLight light;
- light.SetName(m_objName);
- GotoChunk(parent);
- LChunk chunk = ReadChunk();
- if (chunk.id == OBJ_LIGHT)
- {
- v.x = ReadFloat();
- v.y = ReadFloat();
- v.z = ReadFloat();
- if (chunk.end < parent.end)
- chunk = ReadChunk();
- while (chunk.end <= parent.end)
- {
- switch (chunk.id)
- {
- case COLOR_24:
- case COLOR_F:
- case LIN_COLOR_F:
- case LIN_COLOR_24:
- light.SetColor(ReadColor(chunk));
- break;
- case SPOTLIGHT:
- v.x = ReadFloat();
- v.y = ReadFloat();
- v.z = ReadFloat();
- light.SetTarget(v);
- t = ReadFloat();
- light.SetHotspot(t);
- t = ReadFloat();
- light.SetFalloff(t);
- break;
- default:
- break;
- }
- SkipChunk(chunk);
- if (chunk.end >= 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; i<count; i++)
- {
- tri.a = ReadShort();
- tri.b = ReadShort();
- tri.c = ReadShort();
- ReadShort();
- mesh.SetTri(tri, i);
- }
- // now read the optional chunks
- ch = ReadChunk();
- while (ch.end <= chunk.end)
- {
- switch (ch.id)
- {
- case TRI_MAT_GROUP: {
- ReadASCIIZ(str, 20);
- int mat_id = FindMaterial(str)->GetID();
- mesh.AddMaterial(mat_id);
- count = ReadShort();
- for (i=0; i<count; i++) {
- t = ReadShort();
- mesh.GetTri(t).materialId = mat_id;
- }
- }
- break;
-
- case TRI_SMOOTH_GROUP:
- for (i=0; i<mesh.GetTriangleCount(); i++)
- mesh.GetTri(i).smoothingGroups = (ulong) ReadInt();
- break;
- }
- SkipChunk(ch);
- ch = ReadChunk();
- }
-}
-
-void L3DS::ReadMaterial(const LChunk &parent)
-{
- // variables
- LChunk chunk;
- LChunk child;
- char str[30];
- LMaterial mat;
- short sh;
-
- GotoChunk(parent);
-
- chunk = ReadChunk();
- while (chunk.end <= parent.end)
- {
- switch (chunk.id)
- {
- case MAT_NAME:
- ReadASCIIZ(str, 30);
- mat.SetName(str);
- break;
- case MAT_AMBIENT:
- child = ReadChunk();
- mat.SetAmbientColor(ReadColor(child));
- break;
- case MAT_DIFFUSE:
- child = ReadChunk();
- mat.SetDiffuseColor(ReadColor(child));
- break;
- case MAT_SPECULAR:
- child = ReadChunk();
- mat.SetSpecularColor(ReadColor(child));
- break;
- case MAT_SHININESS:
- child = ReadChunk();
- mat.SetShininess(ReadPercentage(child));
- break;
- case MAT_TRANSPARENCY:
- child = ReadChunk();
- mat.SetTransparency(ReadPercentage(child));
- break;
- case MAT_SHADING:
- sh = ReadShort();
- switch (sh)
- {
- case 0:
- mat.SetShadingType(sWireframe);
- break;
- case 1:
- mat.SetShadingType(sFlat);
- break;
- case 2:
- mat.SetShadingType(sGouraud);
- break;
- case 3:
- mat.SetShadingType(sPhong);
- break;
- case 4:
- mat.SetShadingType(sMetal);
- break;
- }
- break;
- case MAT_WIRE:
- mat.SetShadingType(sWireframe);
- break;
- case MAT_TEXMAP:
- ReadMap(chunk, mat.GetTextureMap1());
- break;
- case MAT_TEX2MAP:
- ReadMap(chunk, mat.GetTextureMap2());
- break;
- case MAT_OPACMAP:
- ReadMap(chunk, mat.GetOpacityMap());
- break;
- case MAT_BUMPMAP:
- ReadMap(chunk, mat.GetBumpMap());
- break;
- case MAT_SPECMAP:
- ReadMap(chunk, mat.GetSpecularMap());
- break;
- case MAT_REFLMAP:
- child = ReadChunk();
- mat.GetReflectionMap().strength = ReadPercentage(child);
- SkipChunk(child);
- child = ReadChunk();
- if (child.id != MAT_MAPNAME)
- {
- ErrorMsg("L3DS::ReadMaterial - error, expected chunk not found");
- return;
- }
- ReadASCIIZ(str, 30);
- if (strcmp(str, "") == 0)
- strcpy(mat.GetReflectionMap().mapName, "auto");
- break;
- }
-
- SkipChunk(chunk);
- chunk = ReadChunk();
- }
- m_materials.push_back(mat);
- m_materials[m_materials.size()-1].SetID(m_materials.size()-1);
-}
-
-void L3DS::ReadMap(const LChunk &chunk, LMap& map)
-{
- LChunk child;
- char str[20];
- GotoChunk(chunk);
- child = ReadChunk();
- while (child.end <= chunk.end)
- {
- switch (child.id)
- {
- case INT_PERCENTAGE:
- map.strength = ReadPercentage(child);
- break;
- case MAT_MAPNAME:
- ReadASCIIZ(str, 20);
- strcpy(map.mapName, str);
- break;
- case MAT_MAP_USCALE:
- map.uScale = ReadFloat();
- break;
- case MAT_MAP_VSCALE:
- map.vScale = ReadFloat();
- break;
- case MAT_MAP_UOFFSET:
- map.uOffset = ReadFloat();
- break;
- case MAT_MAP_VOFFSET:
- map.vOffset = ReadFloat();
- break;
- case MAT_MAP_ANG:
- map.angle = ReadFloat();
- break;
- }
- SkipChunk(child);
- child = ReadChunk();
- }
-}
-
-void L3DS::ReadKeyframeData(const LChunk &parent)
-{
- uint frames = 0;
-
- LChunk node_hdr;
- node_hdr.id = NODE_HDR;
-
- char str[20];
- LMesh *mesh;
-
- GotoChunk(parent);
- if (!FindChunk(node_hdr, parent))
- return;
- GotoChunk(node_hdr);
- ReadASCIIZ(str, 19);
- mesh = FindMesh(str);
- if (mesh == 0)
- return;
- GotoChunk(parent);
-
- // read the pivot
- LVector3 pivot = zero3;
-
- LChunk pivotchunk;
- pivotchunk.id = PIVOT;
- if (FindChunk(pivotchunk, parent))
- {
- GotoChunk(pivotchunk);
- pivot.x = ReadFloat();
- pivot.y = ReadFloat();
- pivot.z = ReadFloat();
- }
- GotoChunk(parent);
-
- // read frame 0 from the position track
- LVector3 pos = zero3;
-
- frames = 0;
-
- LChunk poschunk;
- poschunk.id = POS_TRACK_TAG;
- if (FindChunk(poschunk, parent))
- {
- GotoChunk(poschunk);
- // read the trackheader structure
- ReadShort();
- ReadInt();
- ReadInt();
- frames = ReadInt();
- if (frames > 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