mirror of
https://github.com/glest/glest-source.git
synced 2025-09-25 23:19:07 +02:00
549 lines
13 KiB
C++
549 lines
13 KiB
C++
// ==============================================================
|
|
// This file is part of MegaGlest (www.glest.org)
|
|
//
|
|
// Md5Model.h -- Copyright (c) 2006 David Henry
|
|
// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda
|
|
//
|
|
// This code is licensed under the MIT license:
|
|
// http://www.opensource.org/licenses/mit-license.php
|
|
//
|
|
// Open Source Initiative OSI - The MIT License (MIT):Licensing
|
|
//
|
|
// The MIT License (MIT)
|
|
// Copyright (c) <year> <copyright holders>
|
|
//
|
|
// 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.//
|
|
//
|
|
// Declarations for MD5 Model Classes (object, mesh, animation and
|
|
// skeleton).
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
#ifndef __MD5_H__
|
|
#define __MD5_H__
|
|
|
|
#ifdef _WIN32
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
#include <memory>
|
|
#endif // _WIN32
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <map>
|
|
#include <fstream>
|
|
#include <stdexcept>
|
|
|
|
#if !defined(_WIN32) || defined(__MINGW32__)
|
|
#include <tr1/memory>
|
|
#endif
|
|
|
|
#include <GL/glew.h>
|
|
|
|
#include "Mathlib.h"
|
|
#include "md5Texture.h"
|
|
|
|
namespace Shared { namespace Graphics { namespace md5 {
|
|
|
|
using std::string;
|
|
using std::vector;
|
|
using std::map;
|
|
|
|
#if defined(_WIN32)
|
|
using std::tr1::shared_ptr;
|
|
#endif
|
|
|
|
// Forward declarations
|
|
class Md5Skeleton;
|
|
class Md5Mesh;
|
|
class Md5Model;
|
|
class Md5Animation;
|
|
class Md5Object;
|
|
class ShaderProgram;
|
|
class ArbVertexProgram;
|
|
class ArbFragmentProgram;;
|
|
|
|
// MD5 Constants
|
|
extern const int kMd5Version;
|
|
|
|
// We can use a specific render path, depending on
|
|
// which shader/program we want to use...
|
|
enum render_path_e
|
|
{
|
|
R_normal,
|
|
R_ARBfp_diffuse,
|
|
R_ARBfp_diffuse_specular,
|
|
R_ARBfp_ds_parallax,
|
|
R_shader
|
|
};
|
|
|
|
// Tangent uniform's location
|
|
//extern GLint tangentLoc;
|
|
|
|
// ARB program's tangent location
|
|
#define TANGENT_LOC 6
|
|
|
|
// OpenGL vector types
|
|
typedef GLfloat vec2_t[2];
|
|
typedef GLfloat vec3_t[3];
|
|
typedef GLfloat vec4_t[4];
|
|
|
|
struct Md5Joint_t
|
|
{
|
|
string name;
|
|
int parent;
|
|
|
|
Vector3f pos;
|
|
Quaternionf orient;
|
|
};
|
|
|
|
|
|
struct Md5Vertex_t
|
|
{
|
|
float st[2]; // Texture coordinates
|
|
|
|
int startWeight; // Start index weights
|
|
int countWeight; // Number of weights
|
|
};
|
|
|
|
|
|
struct Md5Triangle_t
|
|
{
|
|
int index[3]; // Vertex indices
|
|
};
|
|
|
|
|
|
struct Md5Weight_t
|
|
{
|
|
int joint; // Joint index
|
|
float bias;
|
|
|
|
Vector3f pos;
|
|
Vector3f norm;
|
|
Vector3f tan;
|
|
};
|
|
|
|
|
|
struct BoundingBox_t
|
|
{
|
|
Vector3f min;
|
|
Vector3f max;
|
|
};
|
|
|
|
|
|
struct OBBox_t
|
|
{
|
|
Matrix4x4f world;
|
|
|
|
Vector3f center;
|
|
Vector3f extent;
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class Md5Exception - Exception class for MD5 loader classes.
|
|
// This acts like a standard runtime_error exception but
|
|
// know which file or mesh has failed to be loaded.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
class Md5Exception : public std::runtime_error
|
|
{
|
|
public:
|
|
// Constructors
|
|
Md5Exception (const string &error)
|
|
: std::runtime_error (error) { }
|
|
Md5Exception (const string &error, const string &name)
|
|
: std::runtime_error (error), _which (name) { }
|
|
virtual ~Md5Exception () throw () { }
|
|
|
|
public:
|
|
// Public interface
|
|
virtual const char *which () const throw () {
|
|
return _which.c_str ();
|
|
}
|
|
|
|
private:
|
|
// Member variables
|
|
string _which;
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class Md5Skeleton - Skeleton model data class.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
class Md5Skeleton
|
|
{
|
|
public:
|
|
// Constructors/Destructor
|
|
Md5Skeleton () { }
|
|
Md5Skeleton (std::ifstream &file, int numJoints)
|
|
throw (Md5Exception);
|
|
~Md5Skeleton ();
|
|
|
|
private:
|
|
// Internal types
|
|
typedef shared_ptr<Md5Joint_t> Md5JointPtr;
|
|
|
|
public:
|
|
// Public interface
|
|
void draw (const Matrix4x4f &modelView, bool labelJoints);
|
|
|
|
void setNumJoints (int numJoints);
|
|
void addJoint (Md5Joint_t *thisJoint);
|
|
|
|
Md5Skeleton *clone () const;
|
|
|
|
// Accessors
|
|
int numJoints () const { return _joints.size (); }
|
|
Md5Joint_t *joint (int index) const { return _joints[index].get (); }
|
|
|
|
private:
|
|
// Member variables
|
|
vector<Md5JointPtr> _joints;
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class Md5Mesh - Mesh data class.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
class Md5Mesh
|
|
{
|
|
public:
|
|
// Public internal types
|
|
enum
|
|
{
|
|
kHide, // Skip mesh
|
|
kNoDraw, // Don't draw but prepare vertices
|
|
kShow, // Draw mesh
|
|
};
|
|
|
|
typedef shared_ptr<Md5Vertex_t> Md5VertexPtr;
|
|
typedef shared_ptr<Md5Triangle_t> Md5TrianglePtr;
|
|
typedef shared_ptr<Md5Weight_t> Md5WeightPtr;
|
|
|
|
public:
|
|
// Constructor/Destructor
|
|
Md5Mesh (std::ifstream &ifs)
|
|
throw (Md5Exception);
|
|
~Md5Mesh ();
|
|
|
|
public:
|
|
// Public interface
|
|
void setupVertexArrays (Md5Skeleton *skel);
|
|
void computeWeightNormals (Md5Skeleton *skel);
|
|
void computeWeightTangents (Md5Skeleton *skel);
|
|
void computeBoundingBox (Md5Skeleton *skel);
|
|
void renderVertexArrays () const;
|
|
void drawNormals () const;
|
|
|
|
// Hide/NoDraw/Show state
|
|
void setState (int state) { _renderState = state; }
|
|
|
|
// Texture setters
|
|
void setDecalMap (const Texture2D *tex) { _decal = tex; }
|
|
void setSpecularMap (const Texture2D *tex) { _specMap = tex; }
|
|
void setNormalMap (const Texture2D *tex) { _normalMap = tex; }
|
|
void setHeightMap (const Texture2D *tex) { _heightMap = tex; }
|
|
|
|
// Accessors
|
|
const string &name () const { return _name; }
|
|
const BoundingBox_t &boundingBox () const { return _boundingBox; }
|
|
|
|
// Mesh render state
|
|
bool hiden () const { return (_renderState == kHide); }
|
|
bool noDraw () const { return (_renderState == kNoDraw); }
|
|
bool show () const { return (_renderState == kShow); }
|
|
|
|
private:
|
|
// Internal functions
|
|
void preRenderVertexArrays () const;
|
|
void postRenderVertexArrays () const;
|
|
void allocVertexArrays ();
|
|
void setupTexCoordArray ();
|
|
void setupTexture (const Texture2D *tex, GLenum texUnit) const;
|
|
void resetReversedTexture(const Texture2D *tex, GLenum texUnit) const;
|
|
|
|
private:
|
|
// Member variables
|
|
string _name;
|
|
string _shader;
|
|
int _renderState;
|
|
|
|
BoundingBox_t _boundingBox;
|
|
|
|
int _numVerts;
|
|
int _numTris;
|
|
int _numWeights;
|
|
|
|
// Original mesh data
|
|
vector<Md5VertexPtr> _verts;
|
|
vector<Md5TrianglePtr> _tris;
|
|
vector<Md5WeightPtr> _weights;
|
|
|
|
// Final mesh data; vertex arrays for fast rendering
|
|
vector<GLfloat> _vertexArray;
|
|
vector<GLfloat> _normalArray;
|
|
vector<GLfloat> _tangentArray;
|
|
vector<GLfloat> _texCoordArray;
|
|
vector<GLuint> _vertIndices;
|
|
|
|
// Textures
|
|
const Texture2D *_decal;
|
|
const Texture2D *_specMap;
|
|
const Texture2D *_normalMap;
|
|
const Texture2D *_heightMap;
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class Md5Model - MD5 Mesh Model class.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
class Md5Model
|
|
{
|
|
public:
|
|
// Constructor/Destructor
|
|
Md5Model (const string &filename)
|
|
throw (Md5Exception);
|
|
~Md5Model ();
|
|
|
|
public:
|
|
// Internal type definitions
|
|
typedef shared_ptr<Md5Skeleton> Md5SkeletonPtr;
|
|
typedef shared_ptr<Md5Mesh> Md5MeshPtr;
|
|
typedef shared_ptr<Md5Animation> Md5AnimationPtr;
|
|
typedef map<string, Md5AnimationPtr> AnimMap;
|
|
|
|
public:
|
|
// Public interface
|
|
void prepare (Md5Skeleton *skel);
|
|
void drawModel () const;
|
|
bool addAnim (const string &filename);
|
|
|
|
// Setters
|
|
void setMeshRenderState (const string &name, int state);
|
|
void setMeshDecalMap (const string &name, const Texture2D *tex);
|
|
void setMeshSpecularMap (const string &name, const Texture2D *tex);
|
|
void setMeshNormalMap (const string &name, const Texture2D *tex);
|
|
void setMeshHeightMap (const string &name, const Texture2D *tex);
|
|
|
|
// Accessors
|
|
const Md5Animation *anim (const string &name) const;
|
|
int numJoints () const { return _numJoints; }
|
|
const Md5Skeleton *baseSkeleton () const { return _baseSkeleton.get (); }
|
|
const AnimMap &anims () const { return _animList; }
|
|
const BoundingBox_t &bindPoseBoundingBox () const { return _bindPoseBox; }
|
|
|
|
static render_path_e renderPath;
|
|
static ShaderProgram *shader;
|
|
static ArbVertexProgram *vp;
|
|
static ArbFragmentProgram *fp;
|
|
static GLint tangentLoc;
|
|
static bool bDrawNormals;
|
|
|
|
private:
|
|
// Internal functions
|
|
void computeBindPoseBoundingBox ();
|
|
|
|
// Check if an animation is valid for this model,
|
|
// i.e. anim's skeleton matches with model's skeleton
|
|
bool validityCheck (Md5Animation *anim) const;
|
|
|
|
// Access to a mesh, given its name
|
|
Md5Mesh *getMeshByName (const string &name) const;
|
|
|
|
private:
|
|
// Member variables
|
|
int _numJoints;
|
|
int _numMeshes;
|
|
|
|
Md5SkeletonPtr _baseSkeleton;
|
|
|
|
vector<Md5MeshPtr> _meshes;
|
|
AnimMap _animList;
|
|
|
|
BoundingBox_t _bindPoseBox;
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class Md5Animation - MD5 model animation class.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
class Md5Animation
|
|
{
|
|
public:
|
|
// Constructor/Destructor
|
|
Md5Animation (const string &filename)
|
|
throw (Md5Exception);
|
|
~Md5Animation ();
|
|
|
|
private:
|
|
// Internal type
|
|
struct JointInfo
|
|
{
|
|
string name;
|
|
int parent;
|
|
|
|
// NOTE: this structure is stored in
|
|
// little-endian format
|
|
union JointFlags
|
|
{
|
|
short value;
|
|
|
|
struct
|
|
{
|
|
bool tx: 1;
|
|
bool ty: 1;
|
|
bool tz: 1;
|
|
|
|
bool qx: 1;
|
|
bool qy: 1;
|
|
bool qz: 1;
|
|
};
|
|
} flags;
|
|
|
|
int startIndex;
|
|
};
|
|
|
|
struct BaseFrameJoint
|
|
{
|
|
Vector3f pos;
|
|
Quaternionf orient;
|
|
};
|
|
|
|
typedef shared_ptr<Md5Skeleton> Md5SkeletonPtr;
|
|
typedef shared_ptr<BoundingBox_t> BoundingBoxPtr;
|
|
|
|
public:
|
|
// Public interface
|
|
void interpolate (int frameA, int frameB,
|
|
float interp, Md5Skeleton *out) const;
|
|
|
|
// Accessors
|
|
int maxFrame () const { return _numFrames - 1; }
|
|
int frameRate () const { return _frameRate; }
|
|
const string &name () const { return _name; }
|
|
|
|
Md5Skeleton *frame (int frame) const {
|
|
return _skelframes[frame].get ();
|
|
}
|
|
|
|
const BoundingBox_t *frameBounds (int frame) const {
|
|
return _bboxes[frame].get ();
|
|
}
|
|
|
|
private:
|
|
// Internal functions
|
|
void buildFrameSkeleton (vector<JointInfo> &jointInfos,
|
|
vector<BaseFrameJoint> &baseFrame,
|
|
vector<float> &animFrameData);
|
|
|
|
private:
|
|
// Member variables
|
|
int _numFrames;
|
|
int _frameRate;
|
|
|
|
string _name;
|
|
|
|
// Store each frame as a skeleton
|
|
vector<Md5SkeletonPtr> _skelframes;
|
|
|
|
// Bounding boxes for each frame
|
|
vector<BoundingBoxPtr> _bboxes;
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class Md5Object - MD5 object class.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
class Md5Object
|
|
{
|
|
public:
|
|
// Public internal types/enums
|
|
enum
|
|
{
|
|
kDrawModel = 1,
|
|
kDrawSkeleton = 2,
|
|
kDrawJointLabels = 4,
|
|
};
|
|
|
|
public:
|
|
// Contructor/Destructor
|
|
Md5Object (Md5Model *model);
|
|
virtual ~Md5Object ();
|
|
|
|
public:
|
|
// Public interface
|
|
void animate (double dt);
|
|
void computeBoundingBox ();
|
|
void prepare (bool softwareTransformation);
|
|
void render () const;
|
|
|
|
// Setters
|
|
void setMd5Model (Md5Model *model);
|
|
void setAnim (const string &name);
|
|
void setModelViewMatrix (const Matrix4x4f &mat) { _modelView = mat; }
|
|
void setRenderFlags (int flags) { _renderFlags = flags; }
|
|
|
|
// Accessors
|
|
int renderFlags () const { return _renderFlags; }
|
|
const Md5Model *getModelPtr () const { return _model; }
|
|
const string currAnimName () const { return _currAnimName; }
|
|
const OBBox_t &boundingBox () const { return _bbox; }
|
|
|
|
protected:
|
|
// Member variables;
|
|
Md5Model *_model;
|
|
Md5Skeleton *_animatedSkeleton;
|
|
|
|
Matrix4x4f _modelView;
|
|
bool _softwareTransformation;
|
|
|
|
const Md5Animation *_currAnim;
|
|
string _currAnimName;
|
|
unsigned int _currFrame;
|
|
unsigned int _nextFrame;
|
|
|
|
double _last_time;
|
|
double _max_time;
|
|
|
|
int _renderFlags;
|
|
|
|
OBBox_t _bbox;
|
|
};
|
|
|
|
}}} //end namespace
|
|
|
|
#endif // __MD5_H__
|