00001
00002
00003 #include <cstdio>
00004 #include <cstdlib>
00005 #include <cstring>
00006 #include <cmath>
00007
00008 #include "OSG3DSLoader.h"
00009
00010
00011
00012
00013
00014
00015
00016 #define SEEK_START 1900
00017 #define SEEK_CURSOR 1901
00018
00019
00020
00021 #define COLOR_F 0x0010
00022 #define COLOR_24 0x0011
00023 #define LIN_COLOR_24 0x0012
00024 #define LIN_COLOR_F 0x0013
00025
00026
00027 #define INT_PERCENTAGE 0x0030
00028 #define FLOAT_PERCENTAGE 0x0031
00029
00030
00031 #define AMBIENT_LIGHT 0x2100
00032
00033 #define MAIN3DS 0x4D4D
00034 #define EDIT3DS 0x3D3D // this is the start of the editor config
00035
00036
00037 #define KFDATA 0xB000 // the keyframer section
00038 #define KFHDR 0xB00A
00039 #define OBJECT_NODE_TAG 0xB002
00040 #define NODE_HDR 0xB010
00041 #define PIVOT 0xB013
00042 #define POS_TRACK_TAG 0xB020
00043 #define ROT_TRACK_TAG 0xB021
00044 #define SCL_TRACK_TAG 0xB022
00045
00046
00047 #define MAT_ENTRY 0xAFFF
00048 #define MAT_NAME 0xA000
00049 #define MAT_AMBIENT 0xA010
00050 #define MAT_DIFFUSE 0xA020
00051 #define MAT_SPECULAR 0xA030
00052 #define MAT_SHININESS 0xA040
00053 #define MAT_SHIN2PCT 0xA041
00054 #define MAT_TRANSPARENCY 0xA050
00055 #define MAT_SHADING 0xA100
00056 #define MAT_TWO_SIDE 0xA081
00057 #define MAT_ADDITIVE 0xA083
00058 #define MAT_WIRE 0xA085
00059 #define MAT_FACEMAP 0xA088
00060 #define MAT_WIRESIZE 0xA087
00061 #define MAT_DECAL 0xA082
00062 #define MAT_TEXMAP 0xA200
00063 #define MAT_MAPNAME 0xA300
00064 #define MAT_MAP_TILING 0xA351
00065 #define MAT_MAP_USCALE 0xA354
00066 #define MAT_MAP_VSCALE 0xA356
00067 #define MAT_MAP_UOFFSET 0xA358
00068 #define MAT_MAP_VOFFSET 0xA35A
00069 #define MAT_MAP_ANG 0xA35C
00070 #define MAT_TEX2MAP 0xA33A
00071 #define MAT_OPACMAP 0xA210
00072 #define MAT_BUMPMAP 0xA230
00073 #define MAT_SPECMAP 0xA204
00074 #define MAT_SHINMAP 0xA33C
00075 #define MAT_REFLMAP 0xA220
00076 #define MAT_ACUBIC 0xA310
00077
00078 #define EDIT_OBJECT 0x4000
00079 #define OBJ_TRIMESH 0x4100
00080 #define OBJ_LIGHT 0x4600
00081 #define OBJ_CAMERA 0x4700
00082
00083 #define CAM_RANGES 0x4720
00084
00085 #define LIT_OFF 0x4620
00086 #define LIT_SPOT 0x4610
00087 #define LIT_INRANGE 0x4659
00088 #define LIT_OUTRANGE 0x465A
00089
00090 #define TRI_VERTEXLIST 0x4110
00091 #define TRI_VERTEXOPTIONS 0x4111
00092 #define TRI_FACELIST 0x4120
00093 #define TRI_MAT_GROUP 0x4130
00094 #define TRI_SMOOTH_GROUP 0x4150
00095 #define TRI_FACEMAPPING 0x4140
00096 #define TRI_MATRIX 0x4160
00097 #define TRI_TEXTURE_INFO 0x4170
00098
00099 #define SPOTLIGHT 0x4610
00100
00101
00102
00103 #define MAX_SHARED_TRIS 100
00104
00105
00106
00107
00108
00109 LColor3 black = {0, 0, 0};
00110
00111 LVector3 zero3 = {0, 0, 0};
00112
00113 LVector4 zero4 = {0, 0, 0, 0};
00114
00115 LMap emptyMap = {0, "", 1, 1, 0, 0, 0, 0};
00116
00117 LVector3 _4to3(const LVector4 &vec)
00118 {
00119 LVector3 t;
00120 t.x = vec.x;
00121 t.y = vec.y;
00122 t.z = vec.z;
00123 return t;
00124 }
00125
00126 LVector3 AddVectors(const LVector3 &a, const LVector3 &b)
00127 {
00128 LVector3 t;
00129 t.x = a.x+b.x;
00130 t.y = a.y+b.y;
00131 t.z = a.z+b.z;
00132 return t;
00133 }
00134
00135 LVector3 SubtractVectors(const LVector3 &a, const LVector3 &b)
00136 {
00137 LVector3 t;
00138 t.x = a.x-b.x;
00139 t.y = a.y-b.y;
00140 t.z = a.z-b.z;
00141 return t;
00142 }
00143
00144 float VectorLength(const LVector3 &vec)
00145 {
00146 return float(sqrt(vec.x*vec.x + vec.y*vec.y+vec.z*vec.z));
00147 }
00148
00149 LVector3 NormalizeVector(const LVector3 &vec)
00150 {
00151 float a = VectorLength(vec);
00152 if (a == 0)
00153 return vec;
00154 float b = 1/a;
00155 LVector3 v;
00156 v.x = vec.x*b;
00157 v.y = vec.y*b;
00158 v.z = vec.z*b;
00159 return v;
00160 }
00161
00162 LVector3 CrossProduct(const LVector3 &a, const LVector3 &b)
00163 {
00164 LVector3 v;
00165 v.x = a.y*b.z - a.z*b.y;
00166 v.y = a.z*b.x - a.x*b.z;
00167 v.z = a.x*b.y - a.y*b.x;
00168 return v;
00169 }
00170
00171 void LoadIdentityMatrix(LMatrix4 &m)
00172 {
00173 m._11 = 1.0f;
00174 m._12 = 0.0f;
00175 m._13 = 0.0f;
00176 m._14 = 0.0f;
00177
00178 m._21 = 0.0f;
00179 m._22 = 1.0f;
00180 m._23 = 0.0f;
00181 m._24 = 0.0f;
00182
00183 m._31 = 0.0f;
00184 m._32 = 0.0f;
00185 m._33 = 1.0f;
00186 m._34 = 0.0f;
00187
00188 m._41 = 0.0f;
00189 m._42 = 0.0f;
00190 m._43 = 1.0f;
00191 m._44 = 0.0f;
00192 }
00193
00194 LVector4 VectorByMatrix(const LMatrix4 &m, const LVector4 &vec)
00195 {
00196 LVector4 res;
00197 res.x = m._11*vec.x + m._12*vec.y + m._13*vec.z + m._14*vec.w;
00198 res.y = m._21*vec.x + m._22*vec.y + m._23*vec.z + m._24*vec.w;
00199 res.z = m._31*vec.x + m._32*vec.y + m._33*vec.z + m._34*vec.w;
00200 res.w = m._41*vec.x + m._42*vec.y + m._43*vec.z + m._44*vec.w;
00201 if (res.w != 0)
00202 {
00203 float b = 1/res.w;
00204 res.x *= b;
00205 res.y *= b;
00206 res.z *= b;
00207 res.w = 1;
00208 }
00209 else
00210 res.w = 1;
00211
00212 return res;
00213 }
00214
00215
00216
00217
00218
00219 LObject::LObject()
00220 {
00221 m_name = "";
00222 }
00223
00224 LObject::~LObject()
00225 {
00226
00227 }
00228
00229 void LObject::SetName(const std::string& value)
00230 {
00231 m_name = value;
00232 }
00233
00234 const std::string& LObject::GetName()
00235 {
00236 return m_name;
00237 }
00238
00239 bool LObject::IsObject(const std::string &name)
00240 {
00241 return (m_name == name);
00242 }
00243
00244
00245
00246
00247
00248
00249 LMaterial::LMaterial()
00250 : LObject()
00251 {
00252 m_id = 0;
00253 m_texMap1 = emptyMap;
00254 m_texMap2 = emptyMap;
00255 m_opacMap = emptyMap;
00256 m_bumpMap = emptyMap;
00257 m_reflMap = emptyMap;
00258 m_specMap = emptyMap;
00259 m_ambient = black;
00260 m_diffuse = black;
00261 m_specular = black;
00262 m_shading = sGouraud;
00263 m_shininess = 0;
00264 m_transparency = 0;
00265 }
00266
00267 LMaterial::~LMaterial()
00268 {
00269
00270 }
00271
00272 uint LMaterial::GetID()
00273 {
00274 return m_id;
00275 }
00276
00277 LMap& LMaterial::GetTextureMap1()
00278 {
00279 return m_texMap1;
00280 }
00281
00282 LMap& LMaterial::GetTextureMap2()
00283 {
00284 return m_texMap2;
00285 }
00286
00287 LMap& LMaterial::GetOpacityMap()
00288 {
00289 return m_opacMap;
00290 }
00291
00292 LMap& LMaterial::GetSpecularMap()
00293 {
00294 return m_specMap;
00295 }
00296
00297 LMap& LMaterial::GetBumpMap()
00298 {
00299 return m_bumpMap;
00300 }
00301
00302 LMap& LMaterial::GetReflectionMap()
00303 {
00304 return m_reflMap;
00305 }
00306
00307 LColor3 LMaterial::GetAmbientColor()
00308 {
00309 return m_ambient;
00310 }
00311
00312 LColor3 LMaterial::GetDiffuseColor()
00313 {
00314 return m_diffuse;
00315 }
00316
00317 LColor3 LMaterial::GetSpecularColor()
00318 {
00319 return m_specular;
00320 }
00321
00322 float LMaterial::GetShininess()
00323 {
00324 return m_shininess;
00325 }
00326
00327 float LMaterial::GetTransparency()
00328 {
00329 return m_transparency;
00330 }
00331
00332 LShading LMaterial::GetShadingType()
00333 {
00334 return m_shading;
00335 }
00336
00337 void LMaterial::SetID(uint value)
00338 {
00339 m_id = value;
00340 }
00341
00342 void LMaterial::SetAmbientColor(const LColor3 &color)
00343 {
00344 m_ambient = color;
00345 }
00346
00347 void LMaterial::SetDiffuseColor(const LColor3 &color)
00348 {
00349 m_diffuse = color;
00350 }
00351
00352 void LMaterial::SetSpecularColor(const LColor3 &color)
00353 {
00354 m_specular = color;
00355 }
00356
00357 void LMaterial::SetShininess(float value)
00358 {
00359 m_shininess = value;
00360 if (m_shininess < 0)
00361 m_shininess = 0;
00362 if (m_shininess > 1)
00363 m_shininess = 1;
00364 }
00365
00366 void LMaterial::SetTransparency(float value)
00367 {
00368 m_transparency = value;
00369 if (m_transparency < 0)
00370 m_transparency = 0;
00371 if (m_transparency > 1)
00372 m_transparency = 1;
00373 }
00374
00375 void LMaterial::SetShadingType(LShading shading)
00376 {
00377 m_shading = shading;
00378 }
00379
00380
00381
00382
00383
00384 LMesh::LMesh()
00385 : LObject()
00386 {
00387 Clear();
00388 }
00389
00390 LMesh::~LMesh()
00391 {
00392 Clear();
00393 }
00394
00395 void LMesh::Clear()
00396 {
00397 m_vertices.clear();
00398 m_normals.clear();
00399 m_uv.clear();
00400 m_tangents.clear();
00401 m_binormals.clear();
00402 m_triangles.clear();
00403 m_tris.clear();
00404 m_materials.clear();
00405 LoadIdentityMatrix(m_matrix);
00406 }
00407
00408 uint LMesh::GetVertexCount()
00409 {
00410 return m_vertices.size();
00411 }
00412
00413 void LMesh::SetVertexArraySize(uint value)
00414 {
00415 m_vertices.resize(value);
00416 m_normals.resize(value);
00417 m_uv.resize(value);
00418 m_tangents.resize(value);
00419 m_binormals.resize(value);
00420 }
00421
00422 uint LMesh::GetTriangleCount()
00423 {
00424 return m_triangles.size();
00425 }
00426
00427 void LMesh::SetTriangleArraySize(uint value)
00428 {
00429 m_triangles.resize(value);
00430 m_tris.resize(value);
00431 }
00432
00433 const LVector4& LMesh::GetVertex(uint index)
00434 {
00435 return m_vertices[index];
00436 }
00437
00438 const LVector3& LMesh::GetNormal(uint index)
00439 {
00440 return m_normals[index];
00441 }
00442
00443 const LVector2& LMesh::GetUV(uint index)
00444 {
00445 return m_uv[index];
00446 }
00447
00448 const LVector3& LMesh::GetTangent(uint index)
00449 {
00450 return m_tangents[index];
00451 }
00452
00453 const LVector3& LMesh::GetBinormal(uint index)
00454 {
00455 return m_binormals[index];
00456 }
00457
00458 void LMesh::SetVertex(const LVector4 &vec, uint index)
00459 {
00460 if (index >= m_vertices.size())
00461 return;
00462 m_vertices[index] = vec;
00463 }
00464
00465 void LMesh::SetNormal(const LVector3 &vec, uint index)
00466 {
00467 if (index >= m_vertices.size())
00468 return;
00469 m_normals[index] = vec;
00470 }
00471
00472 void LMesh::SetUV(const LVector2 &vec, uint index)
00473 {
00474 if (index >= m_vertices.size())
00475 return;
00476 m_uv[index] = vec;
00477 }
00478
00479 void LMesh::SetTangent(const LVector3 &vec, uint index)
00480 {
00481 if (index >= m_vertices.size())
00482 return;
00483 m_tangents[index] = vec;
00484 }
00485
00486 void LMesh::SetBinormal(const LVector3 &vec, uint index)
00487 {
00488 if (index >= m_vertices.size())
00489 return;
00490 m_binormals[index] = vec;
00491 }
00492
00493 const LTriangle& LMesh::GetTriangle(uint index)
00494 {
00495 return m_triangles[index];
00496 }
00497
00498 LTriangle2 LMesh::GetTriangle2(uint index)
00499 {
00500 LTriangle2 f;
00501 LTriangle t = GetTriangle(index);
00502 f.vertices[0] = GetVertex(t.a);
00503 f.vertices[1] = GetVertex(t.b);
00504 f.vertices[2] = GetVertex(t.c);
00505
00506 f.vertexNormals[0] = GetNormal(t.a);
00507 f.vertexNormals[1] = GetNormal(t.b);
00508 f.vertexNormals[2] = GetNormal(t.c);
00509
00510 f.textureCoords[0] = GetUV(t.a);
00511 f.textureCoords[1] = GetUV(t.b);
00512 f.textureCoords[2] = GetUV(t.c);
00513
00514 LVector3 a, b;
00515
00516 a = SubtractVectors(_4to3(f.vertices[1]), _4to3(f.vertices[0]));
00517 b = SubtractVectors(_4to3(f.vertices[1]), _4to3(f.vertices[2]));
00518
00519 f.faceNormal = CrossProduct(b, a);
00520
00521 f.faceNormal = NormalizeVector(f.faceNormal);
00522
00523 f.materialId = m_tris[index].materialId;
00524
00525 return f;
00526 }
00527
00528 LMatrix4 LMesh::GetMatrix()
00529 {
00530 return m_matrix;
00531 }
00532
00533 void LMesh::SetMatrix(LMatrix4 m)
00534 {
00535 m_matrix = m;
00536 }
00537
00538 void LMesh::TransformVertices()
00539 {
00540 for (uint i=0; i<m_vertices.size(); i++)
00541 m_vertices[i] = VectorByMatrix(m_matrix, m_vertices[i]);
00542 }
00543
00544 void LMesh::CalcNormals(bool useSmoothingGroups)
00545 {
00546 uint i;
00547
00548 for (i=0; i<m_triangles.size(); i++)
00549 {
00550 LVector3 a, b;
00551 a = SubtractVectors(_4to3(m_vertices[m_tris[i].b]), _4to3(m_vertices[m_tris[i].a]));
00552 b = SubtractVectors(_4to3(m_vertices[m_tris[i].b]), _4to3(m_vertices[m_tris[i].c]));
00553 m_tris[i].normal = NormalizeVector(CrossProduct(b, a));
00554 }
00555
00556 std::vector< std::vector<int> > array;
00557 array.resize(m_vertices.size());
00558 for (i=0; i<m_triangles.size(); i++)
00559 {
00560 uint k = m_tris[i].a;
00561 array[k].push_back(i);
00562
00563 k = m_tris[i].b;
00564 array[k].push_back(i);
00565
00566 k = m_tris[i].c;
00567 array[k].push_back(i);
00568 }
00569
00570 LVector3 temp;
00571
00572 if (!useSmoothingGroups)
00573 {
00574
00575 for (i=0; i<m_vertices.size(); i++)
00576 {
00577 temp = zero3;
00578 int t = array[i].size();
00579
00580 for (int k=0; k<t; k++)
00581 {
00582 temp.x += m_tris[array[i][k]].normal.x;
00583 temp.y += m_tris[array[i][k]].normal.y;
00584 temp.z += m_tris[array[i][k]].normal.z;
00585 }
00586 m_normals[i] = NormalizeVector(temp);
00587 }
00588 }
00589 else
00590 {
00591
00592
00593 std::vector<ulong> smGroups;
00594 std::vector< std::vector <uint> > smList;
00595
00596 uint loop_size = m_vertices.size();
00597
00598 for (i=0; i<loop_size; i++)
00599 {
00600 int t = array[i].size();
00601
00602 if (t == 0)
00603 continue;
00604
00605 smGroups.clear();
00606 smList.clear();
00607 smGroups.push_back(m_tris[array[i][0]].smoothingGroups);
00608 smList.resize(smGroups.size());
00609 smList[smGroups.size()-1].push_back(array[i][0]);
00610
00611
00612 for (int k=0; k<t; k++)
00613 {
00614 bool found = false;
00615 for (uint j=0; j<smGroups.size(); j++)
00616 {
00617 if (m_tris[array[i][k]].smoothingGroups == smGroups[j])
00618 {
00619 smList[j].push_back(array[i][k]);
00620 found = true;
00621 }
00622 }
00623 if (!found)
00624 {
00625 smGroups.push_back(m_tris[array[i][k]].smoothingGroups);
00626 smList.resize(smGroups.size());
00627 smList[smGroups.size()-1].push_back(array[i][k]);
00628 }
00629 }
00630
00631
00632
00633
00634 if (smGroups.size() > 1)
00635 for (uint j=1; j< smGroups.size(); j++)
00636 {
00637 m_vertices.push_back(m_vertices[i]);
00638 m_normals.push_back(m_normals[i]);
00639 m_uv.push_back(m_uv[i]);
00640 m_tangents.push_back(m_tangents[i]);
00641 m_binormals.push_back(m_binormals[i]);
00642
00643 uint t = m_vertices.size()-1;
00644 for (uint h=0; h<smList[j].size(); h++)
00645 {
00646 if (m_tris[smList[j][h]].a == i)
00647 m_tris[smList[j][h]].a = t;
00648 if (m_tris[smList[j][h]].b == i)
00649 m_tris[smList[j][h]].b = t;
00650 if (m_tris[smList[j][h]].c == i)
00651 m_tris[smList[j][h]].c = t;
00652 }
00653 }
00654 }
00655
00656
00657 for (i=0; i<array.size(); i++)
00658 array[i].clear();
00659 array.clear();
00660 array.resize(m_vertices.size());
00661 for (i=0; i<m_triangles.size(); i++)
00662 {
00663 uint k = m_tris[i].a;
00664 array[k].push_back(i);
00665
00666 k = m_tris[i].b;
00667 array[k].push_back(i);
00668
00669 k = m_tris[i].c;
00670 array[k].push_back(i);
00671 }
00672
00673
00674 for (i=0; i<m_vertices.size(); i++)
00675 {
00676 temp = zero3;
00677 int t = array[i].size();
00678
00679 for (int k=0; k<t; k++)
00680 {
00681 temp.x += m_tris[array[i][k]].normal.x;
00682 temp.y += m_tris[array[i][k]].normal.y;
00683 temp.z += m_tris[array[i][k]].normal.z;
00684 }
00685 m_normals[i] = NormalizeVector(temp);
00686 }
00687
00688 }
00689
00690
00691 for (i=0; i<m_triangles.size(); i++)
00692 {
00693 m_triangles[i].a = m_tris[i].a;
00694 m_triangles[i].b = m_tris[i].b;
00695 m_triangles[i].c = m_tris[i].c;
00696 }
00697 }
00698
00699 void LMesh::CalcTextureSpace()
00700 {
00701
00702
00703
00704 LVector3 x_vec,
00705 y_vec,
00706 z_vec;
00707 LVector3 v1, v2;
00708 for (uint i=0; i<m_triangles.size(); i++)
00709 {
00710 v1.x = m_vertices[m_tris[i].b].x - m_vertices[m_tris[i].a].x;
00711 v1.y = m_uv[m_tris[i].b].x - m_uv[m_tris[i].a].x;
00712 v1.z = m_uv[m_tris[i].b].y - m_uv[m_tris[i].a].y;
00713
00714 v2.x = m_vertices[m_tris[i].c].x - m_vertices[m_tris[i].a].x;
00715 v2.y = m_uv[m_tris[i].c].x - m_uv[m_tris[i].a].x;
00716 v2.z = m_uv[m_tris[i].c].y - m_uv[m_tris[i].a].y;
00717
00718 x_vec = CrossProduct(v1, v2);
00719
00720 v1.x = m_vertices[m_tris[i].b].y - m_vertices[m_tris[i].a].y;
00721 v1.y = m_uv[m_tris[i].b].x - m_uv[m_tris[i].a].x;
00722 v1.z = m_uv[m_tris[i].b].y - m_uv[m_tris[i].a].y;
00723
00724 v2.x = m_vertices[m_tris[i].c].y - m_vertices[m_tris[i].a].y;
00725 v2.y = m_uv[m_tris[i].c].x - m_uv[m_tris[i].a].x;
00726 v2.z = m_uv[m_tris[i].c].y - m_uv[m_tris[i].a].y;
00727
00728 y_vec = CrossProduct(v1, v2);
00729
00730 v1.x = m_vertices[m_tris[i].b].z - m_vertices[m_tris[i].a].z;
00731 v1.y = m_uv[m_tris[i].b].x - m_uv[m_tris[i].a].x;
00732 v1.z = m_uv[m_tris[i].b].y - m_uv[m_tris[i].a].y;
00733
00734 v2.x = m_vertices[m_tris[i].c].z - m_vertices[m_tris[i].a].z;
00735 v2.y = m_uv[m_tris[i].c].x - m_uv[m_tris[i].a].x;
00736 v2.z = m_uv[m_tris[i].c].y - m_uv[m_tris[i].a].y;
00737
00738 z_vec = CrossProduct(v1, v2);
00739
00740 m_tris[i].tangent.x = -(x_vec.y/x_vec.x);
00741 m_tris[i].tangent.y = -(y_vec.y/y_vec.x);
00742 m_tris[i].tangent.z = -(z_vec.y/z_vec.x);
00743
00744 m_tris[i].binormal.x = -(x_vec.z/x_vec.x);
00745 m_tris[i].binormal.y = -(y_vec.z/y_vec.x);
00746 m_tris[i].binormal.z = -(z_vec.z/z_vec.x);
00747
00748 }
00749
00750
00751 std::vector< std::vector<int> > array;
00752 array.resize(m_vertices.size());
00753 for (size_t i=0; i<m_triangles.size(); i++)
00754 {
00755 uint k = m_tris[i].a;
00756 array[k].push_back(i);
00757
00758 k = m_tris[i].b;
00759 array[k].push_back(i);
00760
00761 k = m_tris[i].c;
00762 array[k].push_back(i);
00763 }
00764
00765
00766 for (size_t i=0; i<m_vertices.size(); i++)
00767 {
00768 v1 = zero3;
00769 v2 = zero3;
00770 int t = array[i].size();
00771
00772 for (int k=0; k<t; k++)
00773 {
00774 v1.x += m_tris[array[i][k]].tangent.x;
00775 v1.y += m_tris[array[i][k]].tangent.y;
00776 v1.z += m_tris[array[i][k]].tangent.z;
00777
00778 v2.x += m_tris[array[i][k]].binormal.x;
00779 v2.y += m_tris[array[i][k]].binormal.y;
00780 v2.z += m_tris[array[i][k]].binormal.z;
00781 }
00782 m_tangents[i] = NormalizeVector(v1);
00783
00784
00785 m_binormals[i] = NormalizeVector(CrossProduct(m_tangents[i], m_normals[i]));
00786 }
00787 }
00788
00789 void LMesh::Optimize(LOptimizationLevel value)
00790 {
00791 switch (value)
00792 {
00793 case oNone:
00794 TransformVertices();
00795 break;
00796 case oSimple:
00797
00798 CalcNormals(false);
00799 break;
00800 case oFull:
00801
00802 CalcNormals(true);
00803 CalcTextureSpace();
00804 break;
00805 }
00806 }
00807
00808 void LMesh::SetTri(const LTri &tri, uint index)
00809 {
00810 if (index >= m_triangles.size())
00811 return;
00812 m_tris[index] = tri;
00813 }
00814
00815 LTri& LMesh::GetTri(uint index)
00816 {
00817 return m_tris[index];
00818 }
00819
00820 uint LMesh::GetMaterial(uint index)
00821 {
00822 return m_materials[index];
00823 }
00824
00825 uint LMesh::AddMaterial(uint id)
00826 {
00827 m_materials.push_back(id);
00828 return m_materials.size()-1;
00829 }
00830
00831 uint LMesh::GetMaterialCount()
00832 {
00833 return m_materials.size();
00834 }
00835
00836
00837
00838
00839
00840 LCamera::LCamera()
00841 : LObject()
00842 {
00843 Clear();
00844 }
00845
00846 LCamera::~LCamera()
00847 {
00848
00849 }
00850
00851 void LCamera::Clear()
00852 {
00853 m_pos.x = m_pos.y = m_pos.z = 0.0f;
00854 m_target.x = m_target.y = m_target.z = 0.0f;
00855 m_fov = 80;
00856 m_bank = 0;;
00857 m_near = 10;
00858 m_far = 10000;
00859 }
00860
00861 void LCamera::SetPosition(LVector3 vec)
00862 {
00863 m_pos = vec;
00864 }
00865
00866 LVector3 LCamera::GetPosition()
00867 {
00868 return m_pos;
00869 }
00870
00871 void LCamera::SetTarget(LVector3 target)
00872 {
00873 m_target = target;
00874 }
00875
00876 LVector3 LCamera::GetTarget()
00877 {
00878 return m_target;
00879 }
00880
00881 void LCamera::SetFOV(float value)
00882 {
00883 m_fov = value;
00884 }
00885
00886 float LCamera::GetFOV()
00887 {
00888 return m_fov;
00889 }
00890
00891 void LCamera::SetBank(float value)
00892 {
00893 m_bank = value;
00894 }
00895
00896 float LCamera::GetBank()
00897 {
00898 return m_bank;
00899 }
00900
00901 void LCamera::SetNearplane(float value)
00902 {
00903 m_near = value;
00904 }
00905
00906 float LCamera::GetNearplane()
00907 {
00908 return m_near;
00909 }
00910
00911 void LCamera::SetFarplane(float value)
00912 {
00913 m_far = value;
00914 }
00915
00916 float LCamera::GetFarplane()
00917 {
00918 return m_far;
00919 }
00920
00921
00922
00923
00924
00925 LLight::LLight()
00926 : LObject()
00927 {
00928 Clear();
00929 }
00930
00931 LLight::~LLight()
00932 {
00933
00934 }
00935
00936 void LLight::Clear()
00937 {
00938 m_pos.x = m_pos.y = m_pos.z = 0.0f;
00939 m_color.r = m_color.g = m_color.b = 0.0f;
00940 m_spotlight = false;
00941 m_attenuationend = 100;
00942 m_attenuationstart = 1000;
00943 }
00944
00945 void LLight::SetPosition(LVector3 vec)
00946 {
00947 m_pos = vec;
00948 }
00949
00950 LVector3 LLight::GetPosition()
00951 {
00952 return m_pos;
00953 }
00954
00955 void LLight::SetColor(LColor3 color)
00956 {
00957 m_color = color;
00958 }
00959
00960 LColor3 LLight::GetColor()
00961 {
00962 return m_color;
00963 }
00964
00965 void LLight::SetSpotlight(bool value)
00966 {
00967 m_spotlight = value;
00968 }
00969
00970 bool LLight::GetSpotlight()
00971 {
00972 return m_spotlight;
00973 }
00974
00975 void LLight::SetTarget(LVector3 target)
00976 {
00977 m_target = target;
00978 }
00979
00980 LVector3 LLight::GetTarget()
00981 {
00982 return m_target;
00983 }
00984
00985 void LLight::SetHotspot(float value)
00986 {
00987 m_hotspot = value;
00988 }
00989
00990 float LLight::GetHotspot()
00991 {
00992 return m_hotspot;
00993 }
00994
00995 void LLight::SetFalloff(float value)
00996 {
00997 m_falloff = value;
00998 }
00999
01000 float LLight::GetFalloff()
01001 {
01002 return m_falloff;
01003 }
01004
01005 void LLight::SetAttenuationstart(float value)
01006 {
01007 m_attenuationend = value;
01008 }
01009
01010 float LLight::GetAttenuationstart()
01011 {
01012 return m_attenuationend;
01013 }
01014
01015 void LLight::SetAttenuationend(float value)
01016 {
01017 m_attenuationstart = value;
01018 }
01019
01020 float LLight::GetAttenuationend()
01021 {
01022 return m_attenuationstart;
01023 }
01024
01025
01026
01027
01028
01029 LImporter::LImporter()
01030 {
01031 Clear();
01032 }
01033
01034 LImporter::~LImporter()
01035 {
01036 Clear();
01037 }
01038
01039 uint LImporter::GetMeshCount()
01040 {
01041 return m_meshes.size();
01042 }
01043
01044 uint LImporter::GetLightCount()
01045 {
01046 return m_lights.size();
01047 }
01048
01049 uint LImporter::GetMaterialCount()
01050 {
01051 return m_materials.size();
01052 }
01053
01054 uint LImporter::GetCameraCount()
01055 {
01056 return m_cameras.size();
01057 }
01058
01059 LMesh& LImporter::GetMesh(uint index)
01060 {
01061 return m_meshes[index];
01062 }
01063
01064 LLight& LImporter::GetLight(uint index)
01065 {
01066 return m_lights[index];
01067 }
01068
01069 LMaterial& LImporter::GetMaterial(uint index)
01070 {
01071 return m_materials[index];
01072 }
01073
01074 LCamera& LImporter::GetCamera(uint index)
01075 {
01076 return m_cameras[index];
01077 }
01078
01079 LMaterial* LImporter::FindMaterial(const std::string& name)
01080 {
01081 for (uint i=0; i<m_materials.size(); i++)
01082 if (m_materials[i].IsObject(name))
01083 return &m_materials[i];
01084 return 0;
01085 }
01086
01087 LMesh* LImporter::FindMesh(const std::string& name)
01088 {
01089 for (uint i=0; i<m_meshes.size(); i++)
01090 if (m_meshes[i].IsObject(name))
01091 return &m_meshes[i];
01092 return 0;
01093 }
01094
01095 LLight* LImporter::FindLight(const std::string& name)
01096 {
01097 for (uint i=0; i<m_lights.size(); i++)
01098 if (m_lights[i].IsObject(name))
01099 return &m_lights[i];
01100 return 0;
01101 }
01102
01103 void LImporter::Clear()
01104 {
01105 m_meshes.clear();
01106 m_lights.clear();
01107 m_materials.clear();
01108 m_optLevel = oFull;
01109 }
01110
01111 void LImporter::SetOptimizationLevel(LOptimizationLevel value)
01112 {
01113 m_optLevel = value;
01114 }
01115
01116 LOptimizationLevel LImporter::GetOptimizationLevel()
01117 {
01118 return m_optLevel;
01119 }
01120
01121
01122
01123
01124
01125 L3DS::L3DS()
01126 : LImporter()
01127 {
01128 m_buffer = 0;
01129 m_bufferSize = 0;
01130 m_pos = 0;
01131 m_eof = false;
01132 }
01133
01134 L3DS::L3DS(const char *filename)
01135 : LImporter()
01136 {
01137 m_buffer = 0;
01138 m_bufferSize = 0;
01139 m_pos = 0;
01140 m_eof = false;
01141 Load(filename);
01142 }
01143
01144 L3DS::~L3DS()
01145 {
01146 if (m_bufferSize > 0)
01147 free(m_buffer);
01148 }
01149
01150 bool L3DS::Load(std::istream &is)
01151 {
01152
01153 is.seekg(0, std::ios::end);
01154 m_bufferSize = is.tellg();
01155 is.seekg(0, std::ios::beg);
01156
01157 m_buffer = static_cast<unsigned char*>(calloc(m_bufferSize, 1));
01158 if (m_buffer == 0)
01159 {
01160 fprintf(stderr, "L3DS::LoadFile - not enough memory (malloc failed)");
01161 return false;
01162 }
01163 is.read(reinterpret_cast<char *>(m_buffer), m_bufferSize);
01164 if(is.gcount() != std::streamsize(m_bufferSize))
01165 {
01166 free(m_buffer);
01167 m_bufferSize = 0;
01168 fprintf(stderr, "L3DS::LoadFile - error reading from stream");
01169 return false;
01170 }
01171
01172 Clear();
01173 bool res = Read3DS();
01174 free(m_buffer);
01175 m_buffer = 0;
01176 m_bufferSize = 0;
01177 return res;
01178 }
01179
01180 bool L3DS::Load(const char *filename)
01181 {
01182 FILE *f;
01183 f = fopen(filename, "rb");
01184 if (f == 0)
01185 {
01186 fprintf(stderr, "L3DS::LoadFile - cannot open file");
01187 return false;
01188 }
01189 fseek(f, 0, SEEK_END);
01190 m_bufferSize = ftell(f);
01191 fseek(f, 0, SEEK_SET);
01192 m_buffer = static_cast<unsigned char *>(calloc(m_bufferSize, 1));
01193 if (m_buffer == 0)
01194 {
01195 fprintf(stderr, "L3DS::LoadFile - not enough memory (malloc failed)");
01196 return false;
01197 }
01198 if (fread(m_buffer, m_bufferSize, 1, f) != 1)
01199 {
01200 fclose(f);
01201 free(m_buffer);
01202 m_bufferSize = 0;
01203 fprintf(stderr, "L3DS::LoadFile - error reading from file");
01204 return false;
01205 }
01206 fclose(f);
01207
01208 Clear();
01209 bool res = Read3DS();
01210 free(m_buffer);
01211 m_buffer = 0;
01212 m_bufferSize = 0;
01213 return res;
01214 }
01215
01216 short L3DS::ReadShort()
01217 {
01218 if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+2)<m_bufferSize))
01219 {
01220 short *w = reinterpret_cast<short *>(m_buffer+m_pos);
01221 short s = *w;
01222 m_pos += 2;
01223 return s;
01224 }
01225 m_eof = true;
01226 return 0;
01227 }
01228
01229 int L3DS::ReadInt()
01230 {
01231 if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+4)<m_bufferSize))
01232 {
01233 int *w = reinterpret_cast<int *>(m_buffer+m_pos);
01234 int s = *w;
01235 m_pos += 4;
01236 return s;
01237 }
01238 m_eof = true;
01239 return 0;
01240 }
01241
01242 char L3DS::ReadChar()
01243 {
01244 if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+1)<m_bufferSize))
01245 {
01246 char s = char(*(m_buffer+m_pos));
01247 m_pos += 1;
01248 return s;
01249 }
01250 m_eof = true;
01251 return 0;
01252 }
01253
01254 float L3DS::ReadFloat()
01255 {
01256 if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+4)<m_bufferSize))
01257 {
01258 float *w = reinterpret_cast<float *>(m_buffer+m_pos);
01259 float s = *w;
01260 m_pos += 4;
01261 return s;
01262 }
01263 m_eof = true;
01264 return 0.0;
01265 }
01266
01267 byte L3DS::ReadByte()
01268 {
01269 if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+1)<m_bufferSize))
01270 {
01271 byte s = byte(*(m_buffer+m_pos));
01272 m_pos += 1;
01273 return s;
01274 }
01275 m_eof = true;
01276 return 0;
01277 }
01278
01279 int L3DS::ReadASCIIZ(char *buf, int max_count)
01280 {
01281 int count;
01282 if ((m_buffer==0) || (m_bufferSize == 0) || (m_pos>=m_bufferSize))
01283 {
01284 count = 0;
01285 m_eof = true;
01286 return count;
01287 }
01288 count = 0;
01289 char c = ReadChar();
01290 while ((c!=0) && (count<max_count-1))
01291 {
01292 buf[count] = c;
01293 count ++;
01294 c = ReadChar();
01295 }
01296 buf[count] = 0;
01297 return count;
01298 }
01299
01300 void L3DS::Seek(int offset, int origin)
01301 {
01302 if (origin == SEEK_START)
01303 m_pos = offset;
01304 if (origin == SEEK_CURSOR)
01305 m_pos += offset;
01306 if (static_cast<signed>(m_pos) < 0)
01307 m_pos = 0;
01308 if (m_pos >= m_bufferSize)
01309 m_pos = m_bufferSize-1;
01310 m_eof = false;
01311 }
01312
01313 uint L3DS::Pos()
01314 {
01315 return m_pos;
01316 }
01317
01318 LChunk L3DS::ReadChunk()
01319 {
01320 LChunk chunk;
01321 chunk.id = ReadShort();
01322 int a = ReadInt();
01323 chunk.start = Pos();
01324 chunk.end = chunk.start+a-6;
01325 return chunk;
01326 }
01327
01328 bool L3DS::FindChunk(LChunk &target, const LChunk &parent)
01329 {
01330 if (Pos() >= parent.end)
01331 return false;
01332 LChunk chunk;
01333 chunk = ReadChunk();
01334 while (( chunk.id != target.id) && (chunk.end <= parent.end))
01335 {
01336 SkipChunk(chunk);
01337 if (chunk.end >= parent.end)
01338 break;
01339 unsigned short id = chunk.id;
01340 uint end = chunk.end;
01341 chunk = ReadChunk();
01342
01343 if(id == chunk.id && end == chunk.end)
01344 break;
01345 }
01346 if (chunk.id == target.id)
01347 {
01348 target.start = chunk.start;
01349 target.end = chunk.end;
01350 return true;
01351 }
01352 return false;
01353 }
01354
01355 void L3DS::SkipChunk(const LChunk &chunk)
01356 {
01357 Seek(chunk.end, SEEK_START);
01358 }
01359
01360 void L3DS::GotoChunk(const LChunk &chunk)
01361 {
01362 Seek(chunk.start, SEEK_START);
01363 }
01364
01365 LColor3 L3DS::ReadColor(const LChunk &chunk)
01366 {
01367 LColor3 col = black;
01368 GotoChunk(chunk);
01369 switch (chunk.id)
01370 {
01371 case COLOR_F:
01372 col.r = ReadFloat();
01373 col.g = ReadFloat();
01374 col.b = ReadFloat();
01375 break;
01376 case COLOR_24:
01377 col.r = ReadByte()/255.0f;
01378 col.g = ReadByte()/255.0f;
01379 col.b = ReadByte()/255.0f;
01380 break;
01381 case LIN_COLOR_F:
01382 col.r = ReadFloat();
01383 col.g = ReadFloat();
01384 col.b = ReadFloat();
01385 break;
01386 case LIN_COLOR_24:
01387 col.r = ReadByte()/255.0f;
01388 col.g = ReadByte()/255.0f;
01389 col.b = ReadByte()/255.0f;
01390 break;
01391 default:
01392 fprintf(stderr, "L3DS::ReadColor - error this is not a color chunk");
01393 }
01394 return col;
01395 }
01396
01397 float L3DS::ReadPercentage(const LChunk &chunk)
01398 {
01399 GotoChunk(chunk);
01400 switch (chunk.id)
01401 {
01402 case INT_PERCENTAGE:
01403 return (ReadShort()/100.0f);
01404 case FLOAT_PERCENTAGE:
01405 return ReadFloat();
01406 }
01407 fprintf(stderr, "L3DS::ReadPercentage - error, the chunk is not a percentage chunk");
01408 return 0;
01409 }
01410
01411 bool L3DS::Read3DS()
01412 {
01413 LChunk mainchunk;
01414 LChunk edit;
01415 edit.id = EDIT3DS;
01416 mainchunk = ReadChunk();
01417 if (mainchunk.id != MAIN3DS)
01418 {
01419 fprintf(stderr, "L3DS::Read3DS - wrong file format");
01420 return false;
01421 }
01422 if (!FindChunk(edit, mainchunk))
01423 return false;
01424 LChunk obj;
01425 LChunk ml;
01426
01427 GotoChunk(edit);
01428 obj.id = MAT_ENTRY;
01429 while (FindChunk(obj, edit))
01430 {
01431 ReadMaterial(obj);
01432 SkipChunk(obj);
01433 }
01434 GotoChunk(edit);
01435
01436 obj.id = EDIT_OBJECT;
01437 {
01438 while (FindChunk(obj, edit))
01439 {
01440 ReadASCIIZ(m_objName, 99);
01441 ml = ReadChunk();
01442 if (ml.id == OBJ_TRIMESH)
01443 ReadMesh(ml);
01444 else
01445 if (ml.id == OBJ_LIGHT)
01446 ReadLight(ml);
01447 else
01448 if (ml.id == OBJ_CAMERA)
01449 ReadCamera(ml);
01450 SkipChunk(obj);
01451 }
01452 }
01453
01454
01455
01456 LChunk keyframer;
01457 keyframer.id = KFDATA;
01458
01459 LChunk objtrack;
01460 objtrack.id = OBJECT_NODE_TAG;
01461
01462 GotoChunk(mainchunk);
01463 if (FindChunk(keyframer, mainchunk))
01464 {
01465 GotoChunk(keyframer);
01466 while (FindChunk(objtrack, keyframer))
01467 {
01468 ReadKeyframeData(objtrack);
01469 SkipChunk(objtrack);
01470 }
01471 }
01472
01473 for (uint i=0; i<m_meshes.size(); i++)
01474 m_meshes[i].Optimize(m_optLevel);
01475 m_pos = 0;
01476 strcpy(m_objName, "");
01477 return true;
01478 }
01479
01480 void L3DS::ReadLight(const LChunk &parent)
01481 {
01482 float t;
01483 LVector3 v;
01484 LLight light;
01485 light.SetName(m_objName);
01486 v.x = ReadFloat();
01487 v.y = ReadFloat();
01488 v.z = ReadFloat();
01489 light.SetPosition(v);
01490 LChunk chunk = ReadChunk();
01491 while (chunk.end <= parent.end)
01492 {
01493 switch (chunk.id)
01494 {
01495 case COLOR_24:
01496 case COLOR_F:
01497 case LIN_COLOR_F:
01498 case LIN_COLOR_24:
01499 light.SetColor(ReadColor(chunk));
01500 break;
01501 case SPOTLIGHT:
01502 v.x = ReadFloat();
01503 v.y = ReadFloat();
01504 v.z = ReadFloat();
01505 light.SetTarget(v);
01506 t = ReadFloat();
01507 light.SetHotspot(t);
01508 t = ReadFloat();
01509 light.SetFalloff(t);
01510 break;
01511 case LIT_INRANGE:
01512 light.SetAttenuationstart(ReadFloat());
01513 break;
01514 case LIT_OUTRANGE:
01515 light.SetAttenuationend(ReadFloat());
01516 break;
01517 default:
01518 break;
01519 }
01520 SkipChunk(chunk);
01521 if (chunk.end >= parent.end)
01522 break;
01523 chunk = ReadChunk();
01524
01525 }
01526 m_lights.push_back(light);
01527 }
01528
01529 void L3DS::ReadCamera(const LChunk &parent)
01530 {
01531 LVector3 v,t;
01532 LCamera camera;
01533 camera.SetName(m_objName);
01534 v.x = ReadFloat();
01535 v.y = ReadFloat();
01536 v.z = ReadFloat();
01537 t.x = ReadFloat();
01538 t.y = ReadFloat();
01539 t.z = ReadFloat();
01540 camera.SetPosition(v);
01541 camera.SetTarget(t);
01542 camera.SetBank(ReadFloat());
01543 camera.SetFOV(2400.0f/ReadFloat());
01544 LChunk chunk = ReadChunk();
01545 while (chunk.end <= parent.end)
01546 {
01547 switch (chunk.id)
01548 {
01549 case CAM_RANGES:
01550 camera.SetNearplane(ReadFloat());
01551 camera.SetFarplane(ReadFloat());
01552 break;
01553 default:
01554 break;
01555 }
01556 SkipChunk(chunk);
01557 if (chunk.end >= parent.end)
01558 break;
01559 chunk = ReadChunk();
01560
01561 }
01562 m_cameras.push_back(camera);
01563 }
01564
01565 void L3DS::ReadMesh(const LChunk &parent)
01566 {
01567 unsigned short count, i;
01568 LVector4 p;
01569 LMatrix4 m;
01570 LVector2 t;
01571 p.w = 1.0f;
01572 LMesh mesh;
01573 mesh.SetName(m_objName);
01574 GotoChunk(parent);
01575 LChunk chunk = ReadChunk();
01576 while (chunk.end <= parent.end)
01577 {
01578 switch (chunk.id)
01579 {
01580 case TRI_VERTEXLIST:
01581 count = ReadShort();
01582 mesh.SetVertexArraySize(count);
01583 for (i=0; i < count; i++)
01584 {
01585 p.x = ReadFloat();
01586 p.y = ReadFloat();
01587 p.z = ReadFloat();
01588 mesh.SetVertex(p, i);
01589 }
01590 break;
01591 case TRI_FACEMAPPING:
01592 count = ReadShort();
01593 if (mesh.GetVertexCount() == 0)
01594 mesh.SetVertexArraySize(count);
01595 for (i=0; i < count; i++)
01596 {
01597 t.x = ReadFloat();
01598 t.y = ReadFloat();
01599 mesh.SetUV(t, i);
01600 }
01601 break;
01602 case TRI_FACELIST:
01603 ReadFaceList(chunk, mesh);
01604 break;
01605 case TRI_MATRIX:
01606 m._11 = ReadFloat();
01607 m._12 = ReadFloat();
01608 m._13 = ReadFloat();
01609
01610 m._21 = ReadFloat();
01611 m._22 = ReadFloat();
01612 m._23 = ReadFloat();
01613
01614 m._31 = ReadFloat();
01615 m._32 = ReadFloat();
01616 m._33 = ReadFloat();
01617
01618 m._41 = ReadFloat();
01619 m._42 = ReadFloat();
01620 m._43 = ReadFloat();
01621
01622 m._14 = 0.0f;
01623 m._24 = 0.0f;
01624 m._34 = 0.0f;
01625 m._44 = 1.0f;
01626
01627 mesh.SetMatrix(m);
01628 break;
01629 default:
01630 break;
01631 }
01632 SkipChunk(chunk);
01633 if (chunk.end >= parent.end)
01634 break;
01635 chunk = ReadChunk();
01636 }
01637 m_meshes.push_back(mesh);
01638 }
01639
01640 void L3DS::ReadFaceList(const LChunk &chunk, LMesh &mesh)
01641 {
01642
01643 unsigned short count, t;
01644 uint i;
01645 LTri tri;
01646 LChunk ch;
01647 char str[20];
01648
01649
01650
01651 if (chunk.id != TRI_FACELIST)
01652 {
01653 fprintf(stderr, "L3DS::ReadFaceList - internal error: wrong chunk passed as parameter");
01654 return;
01655 }
01656 GotoChunk(chunk);
01657 tri.smoothingGroups = 1;
01658
01659 count = ReadShort();
01660 mesh.SetTriangleArraySize(count);
01661 for (i=0; i<count; i++)
01662 {
01663 tri.a = ReadShort();
01664 tri.b = ReadShort();
01665 tri.c = ReadShort();
01666 ReadShort();
01667 mesh.SetTri(tri, i);
01668 }
01669
01670 ch = ReadChunk();
01671 int mat_id;
01672 while (ch.end <= chunk.end)
01673 {
01674 switch (ch.id)
01675 {
01676 case TRI_MAT_GROUP:
01677 ReadASCIIZ(str, 20);
01678 mat_id = FindMaterial(str)->GetID();
01679 mesh.AddMaterial(mat_id);
01680 count = ReadShort();
01681 for (i=0; i<count; i++)
01682 {
01683 t = ReadShort();
01684 mesh.GetTri(t).materialId = mat_id;
01685 }
01686 break;
01687 case TRI_SMOOTH_GROUP:
01688 for (i=0; i<mesh.GetTriangleCount(); i++)
01689 mesh.GetTri(i).smoothingGroups = ulong(ReadInt());
01690 break;
01691 }
01692 SkipChunk(ch);
01693 ch = ReadChunk();
01694 }
01695 }
01696
01697 void L3DS::ReadMaterial(const LChunk &parent)
01698 {
01699
01700 LChunk chunk;
01701 LChunk child;
01702 char str[30];
01703 LMaterial mat;
01704 short sh;
01705
01706 GotoChunk(parent);
01707
01708 chunk = ReadChunk();
01709 while (chunk.end <= parent.end)
01710 {
01711 switch (chunk.id)
01712 {
01713 case MAT_NAME:
01714 ReadASCIIZ(str, 30);
01715 mat.SetName(str);
01716 break;
01717 case MAT_AMBIENT:
01718 child = ReadChunk();
01719 mat.SetAmbientColor(ReadColor(child));
01720 break;
01721 case MAT_DIFFUSE:
01722 child = ReadChunk();
01723 mat.SetDiffuseColor(ReadColor(child));
01724 break;
01725 case MAT_SPECULAR:
01726 child = ReadChunk();
01727 mat.SetSpecularColor(ReadColor(child));
01728 break;
01729 case MAT_SHININESS:
01730 child = ReadChunk();
01731 mat.SetShininess(ReadPercentage(child));
01732 break;
01733 case MAT_TRANSPARENCY:
01734 child = ReadChunk();
01735 mat.SetTransparency(ReadPercentage(child));
01736 break;
01737 case MAT_SHADING:
01738 sh = ReadShort();
01739 switch (sh)
01740 {
01741 case 0:
01742 mat.SetShadingType(sWireframe);
01743 break;
01744 case 1:
01745 mat.SetShadingType(sFlat);
01746 break;
01747 case 2:
01748 mat.SetShadingType(sGouraud);
01749 break;
01750 case 3:
01751 mat.SetShadingType(sPhong);
01752 break;
01753 case 4:
01754 mat.SetShadingType(sMetal);
01755 break;
01756 }
01757 break;
01758 case MAT_WIRE:
01759 mat.SetShadingType(sWireframe);
01760 break;
01761 case MAT_TEXMAP:
01762 ReadMap(chunk, mat.GetTextureMap1());
01763 break;
01764 case MAT_TEX2MAP:
01765 ReadMap(chunk, mat.GetTextureMap2());
01766 break;
01767 case MAT_OPACMAP:
01768 ReadMap(chunk, mat.GetOpacityMap());
01769 break;
01770 case MAT_BUMPMAP:
01771 ReadMap(chunk, mat.GetBumpMap());
01772 break;
01773 case MAT_SPECMAP:
01774 ReadMap(chunk, mat.GetSpecularMap());
01775 break;
01776 case MAT_REFLMAP:
01777
01778 #if 1
01779 ReadMap(chunk, mat.GetReflectionMap());
01780 #else
01781 child = ReadChunk();
01782 mat.GetReflectionMap().strength = ReadPercentage(child);
01783 SkipChunk(child);
01784 child = ReadChunk();
01785 if (child.id != MAT_MAPNAME)
01786 {
01787 fprintf(stderr, "L3DS::ReadMaterial - error, expected chunk not found");
01788 return;
01789 }
01790 ReadASCIIZ(str, 30);
01791 if (strcmp(str, "") == 0)
01792 strcpy(mat.GetReflectionMap().mapName, "auto");
01793 #endif
01794 break;
01795 }
01796
01797 SkipChunk(chunk);
01798 chunk = ReadChunk();
01799 }
01800 m_materials.push_back(mat);
01801 m_materials[m_materials.size()-1].SetID(m_materials.size()-1);
01802 }
01803
01804 void L3DS::ReadMap(const LChunk &chunk, LMap& map)
01805 {
01806 LChunk child;
01807 char str[20];
01808 GotoChunk(chunk);
01809 child = ReadChunk();
01810 while (child.end <= chunk.end)
01811 {
01812 switch (child.id)
01813 {
01814 case INT_PERCENTAGE:
01815 map.strength = ReadPercentage(child);
01816 break;
01817 case MAT_MAPNAME:
01818 ReadASCIIZ(str, 20);
01819 strcpy(map.mapName, str);
01820 break;
01821 case MAT_MAP_TILING:
01822 map.tiling = ReadShort();
01823 break;
01824 case MAT_MAP_USCALE:
01825 map.uScale = ReadFloat();
01826 break;
01827 case MAT_MAP_VSCALE:
01828 map.vScale = ReadFloat();
01829 break;
01830 case MAT_MAP_UOFFSET:
01831 map.uOffset = ReadFloat();
01832 break;
01833 case MAT_MAP_VOFFSET:
01834 map.vOffset = ReadFloat();
01835 break;
01836 case MAT_MAP_ANG:
01837 map.angle = ReadFloat();
01838 break;
01839 }
01840 SkipChunk(child);
01841 child = ReadChunk();
01842 }
01843 }
01844
01845 void L3DS::ReadKeyframeData(const LChunk &parent)
01846 {
01847 uint frames = 0;
01848
01849 LChunk node_hdr;
01850 node_hdr.id = NODE_HDR;
01851
01852 char str[20];
01853 LMesh *mesh;
01854
01855 GotoChunk(parent);
01856 if (!FindChunk(node_hdr, parent))
01857 return;
01858 GotoChunk(node_hdr);
01859 ReadASCIIZ(str, 19);
01860 mesh = FindMesh(str);
01861 if (mesh == 0)
01862 return;
01863 GotoChunk(parent);
01864
01865
01866
01867
01868 LChunk pivotchunk;
01869 pivotchunk.id = PIVOT;
01870 if (FindChunk(pivotchunk, parent))
01871 {
01872 GotoChunk(pivotchunk);
01873 ReadFloat();
01874 ReadFloat();
01875 ReadFloat();
01876 }
01877 GotoChunk(parent);
01878
01879
01880
01881
01882 frames = 0;
01883
01884 LChunk poschunk;
01885 poschunk.id = POS_TRACK_TAG;
01886 if (FindChunk(poschunk, parent))
01887 {
01888 GotoChunk(poschunk);
01889
01890 ReadShort();
01891 ReadInt();
01892 ReadInt();
01893 frames = ReadInt();
01894 if (frames > 0)
01895 {
01896 ReadKeyheader();
01897 ReadFloat();
01898 ReadFloat();
01899 ReadFloat();
01900 }
01901 }
01902 GotoChunk(parent);
01903
01904
01905
01906
01907 LChunk rotchunk;
01908 rotchunk.id = ROT_TRACK_TAG;
01909
01910 frames = 0;
01911 if (FindChunk(rotchunk, parent))
01912 {
01913 GotoChunk(rotchunk);
01914
01915 ReadShort();
01916 ReadInt();
01917 ReadInt();
01918 frames = ReadInt();
01919 if (frames > 0)
01920 {
01921 ReadKeyheader();
01922 ReadFloat();
01923 ReadFloat();
01924 ReadFloat();
01925 ReadFloat();
01926 }
01927 }
01928 GotoChunk(parent);
01929
01930
01931
01932
01933
01934
01935
01936 LChunk scalechunk;
01937 scalechunk.id = SCL_TRACK_TAG;
01938
01939 frames = 0;
01940
01941 if (FindChunk(scalechunk, parent))
01942 {
01943 GotoChunk(scalechunk);
01944
01945 ReadShort();
01946 ReadInt();
01947 ReadInt();
01948 frames = ReadInt();
01949 if (frames > 0)
01950 {
01951 ReadKeyheader();
01952 ReadFloat();
01953 ReadFloat();
01954 ReadFloat();
01955 }
01956 }
01957 GotoChunk(parent);
01958 }
01959
01960 long L3DS::ReadKeyheader()
01961 {
01962 long frame;
01963 frame = ReadInt();
01964 short opts = ReadShort();
01965 if (opts & 32768)
01966 {
01967 ReadFloat();
01968 }
01969 if (opts & 16384)
01970 {
01971 ReadFloat();
01972 }
01973 if (opts & 8192)
01974 {
01975 ReadFloat();
01976 }
01977 if (opts & 4096)
01978 {
01979 ReadFloat();
01980 }
01981 if (opts & 2048)
01982 {
01983 ReadFloat();
01984 }
01985 return frame;
01986 }