OSG3DSLoader.cpp

Go to the documentation of this file.
00001 // copyright (c) 2001 Lev Povalahev
00002 
00003 #include <cstdio>
00004 #include <cstdlib>
00005 #include <cstring>
00006 #include <cmath>
00007 
00008 #include "OSG3DSLoader.h"
00009 
00010 //using namespace std;
00011 
00012 //-------------------------------------------------------
00013 // generic stuff
00014 //-------------------------------------------------------
00015 
00016 #define SEEK_START           1900
00017 #define SEEK_CURSOR          1901
00018 
00019 // common chunks
00020 // colors
00021 #define COLOR_F             0x0010
00022 #define COLOR_24            0x0011
00023 #define LIN_COLOR_24        0x0012
00024 #define LIN_COLOR_F         0x0013
00025 
00026 // percentage
00027 #define INT_PERCENTAGE      0x0030
00028 #define FLOAT_PERCENTAGE    0x0031
00029 
00030 // ambient light
00031 #define AMBIENT_LIGHT       0x2100
00032 
00033 #define MAIN3DS             0x4D4D
00034 #define EDIT3DS             0x3D3D  // this is the start of the editor config
00035 
00036 // keyframer chunk ids
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 // material entries
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 // the error reporting routine
00106 
00107 // globals
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};
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 // LObject implementation
00217 //-------------------------------------------------------
00218 
00219 LObject::LObject()
00220 {
00221     m_name = "";//.clear();
00222 }
00223 
00224 LObject::~LObject()
00225 {
00226     // nothing here
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 // LMaterial implementation
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 // LMesh implementation
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     // first calculate the face normals
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         // now calculate the normals without using smoothing groups
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         // now calculate the normals _USING_ smoothing groups
00592         // I'm assuming a triangle can only belong to one smoothing group at a time!
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             // first build a list of smoothing groups for the vertex
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             // now we have the list of faces for the vertex sorted by smoothing groups
00631 
00632 
00633             // now duplicate the vertices so that there's only one smoothing group "per vertex"
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         // now rebuild a face list for each vertex, since the old one is invalidated
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         // now compute the normals
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     // copy m_tris to m_triangles
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     // a understandable description of how to do that can be found here:
00702     // http://members.rogers.com/deseric/tangentspace.htm
00703     // first calculate the tangent for each triangle
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     // now for each vertex build a list of face that share this vertex
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     // now average the tangents and compute the binormals as (tangent X normal)
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         //m_binormals[i] = NormalizeVector(v2);
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         //TransformVertices();
00798         CalcNormals(false);
00799         break;
00800     case oFull:
00801         //TransformVertices();
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 // LCamera implementation
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