OSG3DSLoader.h

Go to the documentation of this file.
00001 // copyright (c) 2001-2002 Lev Povalahev
00002 // this is a 3ds importer version 2
00003 
00004 #ifndef L3DS_H
00005 #define L3DS_H
00006 
00007 // includes
00008 #include <vector>
00009 #include <string>
00010 #include <iostream>
00011 
00012 //---------------------------------------------------------
00013 
00014 typedef unsigned long ulong;
00015 typedef unsigned int uint;
00016 typedef unsigned char byte;
00017 
00018 enum LShading {sWireframe, sFlat, sGouraud, sPhong, sMetal};
00019 
00020 enum LOptimizationLevel {oNone, oSimple, oFull};
00021 
00022 // for internal use 
00023 // forward declaration breaks decent STL implemtations
00024 //struct LChunk;
00025 //struct LTri;
00026 
00027 //------------------------------------------------
00028 
00029 struct LVector4
00030 {
00031     float x;
00032     float y;
00033     float z;
00034     float w;
00035 };
00036 
00037 struct LVector3
00038 {
00039     float x;
00040     float y;
00041     float z;
00042 };
00043 
00044 struct LVector2
00045 {
00046     float x;
00047     float y;
00048 };
00049 
00050 struct LColor3
00051 {
00052     float r;
00053     float g;
00054     float b;
00055 };
00056 
00057 //------------------------------------------------
00058 
00059 // LChunk, LTri internal, but as the are used in a
00060 // vector<LTri> declaration they cannot be incomplete
00061 struct LChunk
00062 {
00063     unsigned short id;
00064     uint start;
00065     uint end;
00066 };
00067 
00068 struct LTri
00069 {
00070     unsigned short a;
00071     unsigned short b;
00072     unsigned short c;
00073     ulong smoothingGroups;
00074     LVector3 normal;
00075     LVector3 tangent;
00076     LVector3 binormal;
00077     uint materialId;
00078 };
00079 
00080 struct LTriangle
00081 {
00082     unsigned short a;
00083     unsigned short b;
00084     unsigned short c;
00085 };
00086 
00087 struct LMatrix4
00088 {
00089     float _11, _12, _13, _14;
00090     float _21, _22, _23, _24;
00091     float _31, _32, _33, _34;
00092     float _41, _42, _43, _44;
00093 };
00094 
00095 struct LTriangle2
00096 {
00097     LVector4 vertices[3];
00098     LVector3 vertexNormals[3];
00099     LVector2 textureCoords[3];
00100     LVector3 faceNormal;
00101     uint materialId;
00102 };
00103 
00104 // a structure for a texture map
00105 struct LMap
00106 {
00107     // the strength of the texture map
00108     float strength;
00109     // the file name of the map. only 8.3 format in 3ds files :(
00110     char mapName[255];
00111     float uScale;
00112     float vScale;
00113     float uOffset;
00114     float vOffset;
00115     float angle;
00116     short tiling;
00117 };
00118 
00119 //------------------------------------------------
00120 
00121 class LObject
00122 {
00123 public:
00124     // the default constructor, initilializes the m_name here
00125     LObject();
00126     // the destructor frees memory (m_name)
00127     virtual ~LObject();
00128     // call this to get the name of the object
00129     virtual const std::string& GetName();
00130 
00131     // this methods should not be used by the "user", they're used internally to fill the class
00132     // with valid data when reading from file. If you're about to add an importer for another format you'LL
00133     // have to use these methods
00134     // call this to set the name of the object
00135     virtual void SetName(const std::string& value);
00136     // returns true if the object's name is the name passed as parameter
00137     bool IsObject(const std::string &name);
00138 protected:
00139     // the name of the object
00140     std::string m_name;
00141 };
00142 
00143 //------------------------------------------------
00144 
00145 class LMaterial : public LObject
00146 {
00147 public:
00148     // the default constructor, does the initialization
00149     LMaterial();
00150     // the destructor
00151     virtual ~LMaterial();
00152     // returns the material ID
00153     uint GetID();
00154     // returns the pointer to teh texture map 1
00155     LMap& GetTextureMap1();
00156     // returns the pointer to the texture map 2
00157     LMap& GetTextureMap2();
00158     // returns the pointer to teh opacity map
00159     LMap& GetOpacityMap();
00160     // returns the pointer to the specular (gloss) map
00161     LMap& GetSpecularMap();
00162     // returns the pointer to the bump map
00163     LMap& GetBumpMap();
00164     // returns the pointer to the reflection map
00165     LMap& GetReflectionMap();
00166     // returns the ambient color of the material
00167     LColor3 GetAmbientColor();
00168     // returns the diffuse color of the material
00169     LColor3 GetDiffuseColor();
00170     // returns the specular color of the material
00171     LColor3 GetSpecularColor();
00172     // returns the shininess of the material, ranging from 0(matte) to 1(shiny)
00173     float GetShininess();
00174     // returns the transparency of the material, ranging from 1(fully transparent) to 0(opaque)
00175     float GetTransparency();
00176     // returns the type of shading, see LShading type
00177     LShading GetShadingType();
00178 
00179     // this methods should not be used by the "user", they're used internally to fill the class
00180     // with valid data when reading from file. If you're about to add an importer for another format you'LL
00181     // have to use these methods
00182     // sets the material ID to "value"
00183     void SetID(uint value);
00184     // call this to set the ambient color of the material
00185     void SetAmbientColor(const LColor3 &color);
00186     // sets the diffuse color of the material
00187     void SetDiffuseColor(const LColor3 &color);
00188     // sets the specular color of the material
00189     void SetSpecularColor(const LColor3 &color);
00190     // sets the shininess of the material
00191     void SetShininess(float value);
00192     // sets the transparency of the material
00193     void SetTransparency(float value);
00194     // sets the shading type
00195     void SetShadingType(LShading shading);
00196 protected:
00197     // the unique material ID
00198     int m_id;
00199     // the first texture map
00200     LMap m_texMap1;
00201     // the second texture map
00202     LMap m_texMap2;
00203     // the opacity map
00204     LMap m_opacMap;
00205     // the reflection map
00206     LMap m_reflMap;
00207     // the bump map
00208     LMap m_bumpMap;
00209     // specular map
00210     LMap m_specMap;
00211     // material ambient color
00212     LColor3 m_ambient;
00213     // material diffuse color
00214     LColor3 m_diffuse;
00215     // material specular color
00216     LColor3 m_specular;
00217     // shininess
00218     float m_shininess;
00219     // transparency
00220     float m_transparency;
00221     // the shading type for the material
00222     LShading m_shading;
00223 };
00224 
00225 //------------------------------------------------
00226 
00227 class LMesh : public LObject
00228 {
00229 public:
00230     // the default constructor
00231     LMesh();
00232     // the destructor
00233     virtual ~LMesh();
00234     // clears the mesh, deleteing all data
00235     void Clear();
00236     // returns the number of vertices in the mesh
00237     uint GetVertexCount();
00238     // sets the the size fo the vertex array - for internal use
00239     void SetVertexArraySize(uint value);
00240     // returns the number of triangles in the mesh
00241     uint GetTriangleCount();
00242     // sets the size of the triangle array - for internal use
00243     void SetTriangleArraySize(uint value);
00244     // returns given vertex
00245     const LVector4& GetVertex(uint index);
00246     // returns the given normal
00247     const LVector3& GetNormal(uint index);
00248     // returns the given texture coordinates vector
00249     const LVector2& GetUV(uint index);
00250     // returns the pointer to the array of tangents
00251     const LVector3& GetTangent(uint index);
00252     // returns the pointer to the array of binormals
00253     const LVector3& GetBinormal(uint index);
00254     // sets the vertex at a given index to "vec" - for internal use
00255     void SetVertex(const LVector4 &vec, uint index);
00256     // sets the normal at a given index to "vec" - for internal use
00257     void SetNormal(const LVector3 &vec, uint index);
00258     // sets the texture coordinates vector at a given index to "vec" - for internal use
00259     void SetUV(const LVector2 &vec, uint index);
00260     // sets the tangent at a given index to "vec" - for internal use
00261     void SetTangent(const LVector3 &vec, uint index);
00262     // sets the binormal at a given index to "vec" - for internal use
00263     void SetBinormal(const LVector3 &vec, uint index);
00264     // returns the triangle with a given index
00265     const LTriangle& GetTriangle(uint index);
00266     // returns the triangle with a given index, see LTriangle2 structure description
00267     LTriangle2 GetTriangle2(uint index);
00268     // returns the mesh matrix, should be identity matrix after loading
00269     LMatrix4 GetMatrix();
00270     // sets the mesh matrix to a given matrix - for internal use
00271     void SetMatrix(LMatrix4 m);
00272     // optimizises the mesh using a given optimization level
00273     void Optimize(LOptimizationLevel value);
00274     // sets an internal triangle structure with index "index" - for internal use only
00275     void SetTri(const LTri &tri, uint index);
00276     // returns the pointer to the internal triangle structure - for internal use only
00277     LTri& GetTri(uint index);
00278     // returns the material id with a given index for the mesh
00279     uint GetMaterial(uint index);
00280     // adds a material to the mesh and returns its index - for internal use
00281     uint AddMaterial(uint id);
00282     // returns the number of materials used in the mesh
00283     uint GetMaterialCount();
00284 protected:
00285     // the vertices, normals, etc.
00286     std::vector<LVector4> m_vertices;
00287     std::vector<LVector3> m_normals;
00288     std::vector<LVector3> m_binormals;
00289     std::vector<LVector3> m_tangents;
00290     std::vector<LVector2> m_uv;
00291 
00292     // triangles
00293     std::vector<LTriangle> m_triangles;
00294 
00295     //used internally
00296     std::vector<LTri> m_tris;
00297 
00298     // the transformation matrix.
00299     LMatrix4 m_matrix;
00300 
00301     // the material ID array
00302     std::vector<uint> m_materials;
00303 
00304     // calculates the normals, either using the smoothing groups information or not
00305     void CalcNormals(bool useSmoothingGroups);
00306     // calculates the texture(tangent) space for each vertex
00307     void CalcTextureSpace();
00308     // transforms the vertices by the mesh matrix
00309     void TransformVertices();
00310 };
00311 
00312 //------------------------------------------------
00313 
00314 class LCamera : public LObject
00315 {
00316 public:
00317     // the default constructor
00318     LCamera();
00319     // the destructor
00320     virtual ~LCamera();
00321     // clears the data the class holds
00322     void Clear();
00323     // sets the position of the camera - for internal use
00324     void SetPosition(LVector3 vec);
00325     // returns the position of the camera
00326     LVector3 GetPosition();
00327     // sets the target of the camera - internal use
00328     void SetTarget(LVector3 target);
00329     // returns the target of the camera
00330     LVector3 GetTarget();
00331     // sets the fov - internal use
00332     void SetFOV(float value);
00333     // returns the fov
00334     float GetFOV();
00335     // sets the bank - internal use
00336     void SetBank(float value);
00337     // returns the bank
00338     float GetBank();
00339     // sets the near plane - internal use
00340     void SetNearplane(float value);
00341     // returns the near plane distance
00342     float GetNearplane();
00343     // sets the far plane - internal use
00344     void SetFarplane(float value);
00345     // returns the far plane distance
00346     float GetFarplane();
00347 protected:
00348     LVector3 m_pos;
00349     LVector3 m_target;
00350     float m_bank;
00351     float m_fov;
00352     float m_near;
00353     float m_far;
00354 };
00355 
00356 //------------------------------------------------
00357 
00358 class LLight : public LObject
00359 {
00360 public:
00361     // the default constructor
00362     LLight();
00363     // the destructor
00364     virtual ~LLight();
00365     // clears the data the class holds
00366     void Clear();
00367     // sets the position of the light source - for internal use
00368     void SetPosition(LVector3 vec);
00369     // returns the position of the light source
00370     LVector3 GetPosition();
00371     // sets the color of the light - for internal use
00372     void SetColor(LColor3 color);
00373     // returns the color of the light
00374     LColor3 GetColor();
00375     // sets whether the light is a spotlight or not - internal use
00376     void SetSpotlight(bool value);
00377     // returns true if the light is a spotlight
00378     bool GetSpotlight();
00379     // sets the target of the light - internal use
00380     void SetTarget(LVector3 target);
00381     // returns the target of the spotlight
00382     LVector3 GetTarget();
00383     // sets the hotspot - internal use
00384     void SetHotspot(float value);
00385     // returns the hotspot
00386     float GetHotspot();
00387     // sets falloff - internal use
00388     void SetFalloff(float value);
00389     // returns falloff
00390     float GetFalloff();
00391     // sets attenuationstart - internal use
00392     void SetAttenuationstart(float value);
00393     // returns attenuationstart
00394     float GetAttenuationstart();
00395     // sets attenuationend - internal use
00396     void SetAttenuationend(float value);
00397     // returns attenuationend
00398     float GetAttenuationend();
00399 protected:
00400     LVector3 m_pos;
00401     LColor3 m_color;
00402     bool m_spotlight;
00403     LVector3 m_target;
00404     float m_hotspot;
00405     float m_falloff;
00406     float m_attenuationstart;
00407     float m_attenuationend;
00408 };
00409 
00410 //------------------------------------------------
00411 
00412 class LImporter
00413 {
00414 public:
00415     // the default constructor
00416     LImporter();
00417     // the destructor
00418     virtual ~LImporter();
00419     // reads the model from a file, must be overriden by the child classes
00420     virtual bool Load(std::istream &is) = 0;
00421     virtual bool Load(const char *filename) = 0;
00422     // returns the number of meshes in the scene
00423     uint GetMeshCount();
00424     // returns the number of lights in the scene
00425     uint GetLightCount();
00426     // returns the number of materials in the scene
00427     uint GetMaterialCount();
00428     // returns the number of cameras in the scene
00429     uint GetCameraCount();
00430     // returns a pointer to a mesh
00431     LMesh& GetMesh(uint index);
00432     // returns a pointer to a camera at a given index
00433     LCamera& GetCamera(uint index);
00434     // returns a pointer to a light at a given index
00435     LLight& GetLight(uint index);
00436     // returns the pointer to the material
00437     LMaterial& GetMaterial(uint index);
00438     // returns the pointer to the material with a given name, or NULL if the material was not found
00439     LMaterial* FindMaterial(const std::string &name);
00440     // returns the pointer to the mesh with a given name, or NULL if the mesh with such name
00441     // is not present in the scene
00442     LMesh* FindMesh(const std::string &name);
00443     // returns the pointer to the camera with a given name, or NULL if not found
00444     LLight* FindCamera(const std::string &name);
00445     // returns the pointer to the light with a given name, or NULL if not found
00446     LLight* FindLight(const std::string &name);
00447     // sets the optimization level to a given value
00448     void SetOptimizationLevel(LOptimizationLevel value);
00449     // returns the current optimization level
00450     LOptimizationLevel GetOptimizationLevel();
00451 protected:
00452     // the cameras found in the scene
00453     std::vector<LCamera> m_cameras;
00454     // the lights found in the scene
00455     std::vector<LLight> m_lights;
00456     // triangular meshes
00457     std::vector<LMesh> m_meshes;
00458     // the materials in the scene
00459     std::vector<LMaterial> m_materials;
00460     // level of optimization to perform on the meshes
00461     LOptimizationLevel m_optLevel;
00462     // clears all data.
00463     virtual void Clear();
00464 };
00465 //------------------------------------------------
00466 
00467 class L3DS : public LImporter
00468 {
00469 public:
00470     // the default contructor
00471     L3DS();
00472     // constructs the object and loads the file
00473     L3DS(const char *filename);
00474     // destructor
00475     virtual ~L3DS();
00476     // load 3ds file
00477     virtual bool Load(std::istream &is);
00478     virtual bool Load(const char *filename);
00479 protected:
00480     // used internally for reading
00481     char m_objName[100];
00482     // true if end of file is reached
00483     bool m_eof;
00484     // buffer for loading, used for speedup
00485     unsigned char *m_buffer;
00486     // the size of the buffer
00487     uint m_bufferSize;
00488     // the current cursor position in the buffer
00489     uint m_pos;
00490 
00491     // reads a short value from the buffer
00492     short ReadShort();
00493     // reads an int value from the buffer
00494     int ReadInt();
00495     // reads a char from the buffer
00496     char ReadChar();
00497     //reada a floatvalue from the buffer
00498     float ReadFloat();
00499     //reads an unsigned byte from the buffer
00500     byte ReadByte();
00501     //reads an asciiz string
00502     int ReadASCIIZ(char *buf, int max_count);
00503     // seek wihtin the buffer
00504     void Seek(int offset, int origin);
00505     // returns the position of the cursor
00506     uint Pos();
00507 
00508     // read the chunk and return it.
00509     LChunk ReadChunk();
00510     // read until given chunk is found
00511     bool FindChunk(LChunk &target, const LChunk &parent);
00512     // skip to the end of chunk "chunk"
00513     void SkipChunk(const LChunk &chunk);
00514     // goes to the beginning of the data in teh given chunk
00515     void GotoChunk(const LChunk &chunk);
00516 
00517     // the function read the color chunk (any of the color chunks)
00518     LColor3 ReadColor(const LChunk &chunk);
00519     // the function that read the percentage chunk and returns a float from 0 to 1
00520     float ReadPercentage(const LChunk &chunk);
00521     // this is where 3ds file is being read
00522     bool Read3DS();
00523     // read a light chunk
00524     void ReadLight(const LChunk &parent);
00525     // read a camera chunk
00526     void ReadCamera(const LChunk &parent);
00527     // read a trimesh chunk
00528     void ReadMesh(const LChunk &parent);
00529     // reads the face list, face materials, smoothing groups... and fill rthe information into the mesh
00530     void ReadFaceList(const LChunk &chunk, LMesh &mesh);
00531     // reads the material
00532     void ReadMaterial(const LChunk &parent);
00533     // reads the map info and fills the given map with this information
00534     void ReadMap(const LChunk &chunk, LMap& map);
00535     // reads keyframer data of the OBJECT_NODE_TAG chunk
00536     void ReadKeyframeData(const LChunk &parent);
00537     // reads the keyheader structure from the current offset and returns the frame number
00538     long ReadKeyheader();
00539 };
00540 
00541 //---------------------------------------------------------
00542 
00543 #endif