245 lines
7.4 KiB
C++
245 lines
7.4 KiB
C++
//-----------------------------------------------------------------------------
|
|
// Copyright (c) 2007 dhpoware. All Rights Reserved.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the "Software"),
|
|
// to deal in the Software without restriction, including without limitation
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
// and/or sell copies of the Software, and to permit persons to whom the
|
|
// Software is furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
// IN THE SOFTWARE.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#ifndef _OBJMODEL_H
|
|
#define _OBJMODEL_H
|
|
|
|
#include <map>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Alias|Wavefront OBJ file loader.
|
|
//
|
|
// This OBJ file loader contains the following restrictions:
|
|
// 1. Group information is ignored. Faces are grouped based on the material
|
|
// that each face uses.
|
|
// 2. Object information is ignored. This loader will merge everything into a
|
|
// single object.
|
|
// 3. The MTL file must be located in the same directory as the OBJ file. If
|
|
// it isn't then the MTL file will fail to load and a default material is
|
|
// used instead.
|
|
// 4. This loader triangulates all polygonal faces during importing.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
namespace Engine {
|
|
|
|
class OBJModel
|
|
{
|
|
public:
|
|
struct Material
|
|
{
|
|
float ambient[4];
|
|
float diffuse[4];
|
|
float specular[4];
|
|
float shininess; // [0 = min shininess, 1 = max shininess]
|
|
float alpha; // [0 = fully transparent, 1 = fully opaque]
|
|
|
|
std::string name;
|
|
std::string colorMapFilename;
|
|
std::string bumpMapFilename;
|
|
};
|
|
|
|
struct Vertex
|
|
{
|
|
float position[3];
|
|
float texCoord[2];
|
|
float normal[3];
|
|
float tangent[4];
|
|
float bitangent[3];
|
|
};
|
|
|
|
struct Mesh
|
|
{
|
|
int startIndex;
|
|
int triangleCount;
|
|
const Material *pMaterial;
|
|
};
|
|
|
|
OBJModel();
|
|
~OBJModel();
|
|
|
|
void destroy();
|
|
bool import(const char *pszFilename, bool rebuildNormals = false);
|
|
void normalize(float scaleTo = 1.0f, bool center = true);
|
|
void reverseWinding();
|
|
|
|
// Getter methods.
|
|
|
|
void getCenter(float &x, float &y, float &z) const;
|
|
float getWidth() const;
|
|
float getHeight() const;
|
|
float getLength() const;
|
|
float getRadius() const;
|
|
|
|
const int *getIndexBuffer() const;
|
|
int getIndexSize() const;
|
|
|
|
const Material &getMaterial(int i) const;
|
|
const Mesh &getMesh(int i) const;
|
|
|
|
int getNumberOfIndices() const;
|
|
int getNumberOfMaterials() const;
|
|
int getNumberOfMeshes() const;
|
|
int getNumberOfTriangles() const;
|
|
int getNumberOfVertices() const;
|
|
|
|
const std::string &getPath() const;
|
|
|
|
const Vertex &getVertex(int i) const;
|
|
const Vertex *getVertexBuffer() const;
|
|
int getVertexSize() const;
|
|
|
|
bool hasNormals() const;
|
|
bool hasPositions() const;
|
|
bool hasTangents() const;
|
|
bool hasTextureCoords() const;
|
|
|
|
private:
|
|
void addTrianglePos(int index, int material,
|
|
int v0, int v1, int v2);
|
|
void addTrianglePosNormal(int index, int material,
|
|
int v0, int v1, int v2,
|
|
int vn0, int vn1, int vn2);
|
|
void addTrianglePosTexCoord(int index, int material,
|
|
int v0, int v1, int v2,
|
|
int vt0, int vt1, int vt2);
|
|
void addTrianglePosTexCoordNormal(int index, int material,
|
|
int v0, int v1, int v2,
|
|
int vt0, int vt1, int vt2,
|
|
int vn0, int vn1, int vn2);
|
|
int addVertex(int hash, const Vertex *pVertex);
|
|
void bounds(float center[3], float &width, float &height,
|
|
float &length, float &radius) const;
|
|
void buildMeshes();
|
|
void generateNormals();
|
|
void generateTangents();
|
|
void importGeometryFirstPass(FILE *pFile);
|
|
void importGeometrySecondPass(FILE *pFile);
|
|
bool importMaterials(const char *pszFilename);
|
|
void scale(float scaleFactor, float offset[3]);
|
|
|
|
bool m_hasPositions;
|
|
bool m_hasTextureCoords;
|
|
bool m_hasNormals;
|
|
bool m_hasTangents;
|
|
|
|
int m_numberOfVertexCoords;
|
|
int m_numberOfTextureCoords;
|
|
int m_numberOfNormals;
|
|
int m_numberOfTriangles;
|
|
int m_numberOfMaterials;
|
|
int m_numberOfMeshes;
|
|
|
|
float m_center[3];
|
|
float m_width;
|
|
float m_height;
|
|
float m_length;
|
|
float m_radius;
|
|
|
|
std::string m_directoryPath;
|
|
|
|
std::vector<Mesh> m_meshes;
|
|
std::vector<Material> m_materials;
|
|
std::vector<Vertex> m_vertexBuffer;
|
|
std::vector<int> m_indexBuffer;
|
|
std::vector<int> m_attributeBuffer;
|
|
std::vector<float> m_vertexCoords;
|
|
std::vector<float> m_textureCoords;
|
|
std::vector<float> m_normals;
|
|
|
|
std::map<std::string, int> m_materialCache;
|
|
std::map<int, std::vector<int> > m_vertexCache;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
inline void OBJModel::getCenter(float &x, float &y, float &z) const
|
|
{ x = m_center[0]; y = m_center[1]; z = m_center[2]; }
|
|
|
|
inline float OBJModel::getWidth() const
|
|
{ return m_width; }
|
|
|
|
inline float OBJModel::getHeight() const
|
|
{ return m_height; }
|
|
|
|
inline float OBJModel::getLength() const
|
|
{ return m_length; }
|
|
|
|
inline float OBJModel::getRadius() const
|
|
{ return m_radius; }
|
|
|
|
inline const int *OBJModel::getIndexBuffer() const
|
|
{ return &m_indexBuffer[0]; }
|
|
|
|
inline int OBJModel::getIndexSize() const
|
|
{ return static_cast<int>(sizeof(int)); }
|
|
|
|
inline const OBJModel::Material &OBJModel::getMaterial(int i) const
|
|
{ return m_materials[i]; }
|
|
|
|
inline const OBJModel::Mesh &OBJModel::getMesh(int i) const
|
|
{ return m_meshes[i]; }
|
|
|
|
inline int OBJModel::getNumberOfIndices() const
|
|
{ return m_numberOfTriangles * 3; }
|
|
|
|
inline int OBJModel::getNumberOfMaterials() const
|
|
{ return m_numberOfMaterials; }
|
|
|
|
inline int OBJModel::getNumberOfMeshes() const
|
|
{ return m_numberOfMeshes; }
|
|
|
|
inline int OBJModel::getNumberOfTriangles() const
|
|
{ return m_numberOfTriangles; }
|
|
|
|
inline int OBJModel::getNumberOfVertices() const
|
|
{ return static_cast<int>(m_vertexBuffer.size()); }
|
|
|
|
inline const std::string &OBJModel::getPath() const
|
|
{ return m_directoryPath; }
|
|
|
|
inline const OBJModel::Vertex &OBJModel::getVertex(int i) const
|
|
{ return m_vertexBuffer[i]; }
|
|
|
|
inline const OBJModel::Vertex *OBJModel::getVertexBuffer() const
|
|
{ return &m_vertexBuffer[0]; }
|
|
|
|
inline int OBJModel::getVertexSize() const
|
|
{ return static_cast<int>(sizeof(Vertex)); }
|
|
|
|
inline bool OBJModel::hasNormals() const
|
|
{ return m_hasNormals; }
|
|
|
|
inline bool OBJModel::hasPositions() const
|
|
{ return m_hasPositions; }
|
|
|
|
inline bool OBJModel::hasTangents() const
|
|
{ return m_hasTangents; }
|
|
|
|
inline bool OBJModel::hasTextureCoords() const
|
|
{ return m_hasTextureCoords; }
|
|
|
|
}
|
|
|
|
#endif
|