2013-01-09 22:37:23 +00:00
//
// KRMesh.h
// KREngine
//
// Copyright 2012 Kearwood Gilbert. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The views and conclusions contained in the software and documentation are those of the
// authors and should not be interpreted as representing official policies, either expressed
// or implied, of Kearwood Gilbert.
//
2013-01-11 03:21:19 +00:00
# include "KREngine-common.h"
2013-01-09 22:37:23 +00:00
2013-01-11 03:21:19 +00:00
# include "KRContext.h"
# include "KRBone.h"
2014-05-16 00:03:56 -07:00
# include "KRMeshManager.h"
2013-01-09 22:37:23 +00:00
2013-01-11 03:21:19 +00:00
# include "KREngine-common.h"
2013-01-09 22:37:23 +00:00
2017-07-29 01:07:21 -07:00
using namespace kraken ;
2013-01-09 22:37:23 +00:00
# define MAX_VBO_SIZE 65535
# define KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX 4
# define KRENGINE_MAX_NAME_LENGTH 256
// MAX_VBO_SIZE must be divisible by 3 so triangles aren't split across VBO objects...
# define BUFFER_OFFSET(i) ((char *)NULL + (i))
# ifndef KRMesh_I
# define KRMesh_I
2013-01-11 03:21:19 +00:00
# include "KRMaterialManager.h"
# include "KRCamera.h"
# include "KRViewport.h"
# include "KRHitInfo.h"
2013-01-09 22:37:23 +00:00
class KRMaterial ;
class KRNode ;
class KRMesh : public KRResource {
public :
2013-05-24 12:20:47 -07:00
2013-01-09 22:37:23 +00:00
KRMesh ( KRContext & context , std : : string name , KRDataBlock * data ) ;
KRMesh ( KRContext & context , std : : string name ) ;
virtual ~ KRMesh ( ) ;
2014-04-23 01:43:00 -07:00
kraken_stream_level getStreamLevel ( ) ;
void preStream ( float lodCoverage ) ;
2014-03-10 22:32:49 -07:00
2013-01-09 22:37:23 +00:00
bool hasTransparency ( ) ;
typedef enum {
KRENGINE_ATTRIB_VERTEX = 0 ,
KRENGINE_ATTRIB_NORMAL ,
KRENGINE_ATTRIB_TANGENT ,
KRENGINE_ATTRIB_TEXUVA ,
KRENGINE_ATTRIB_TEXUVB ,
KRENGINE_ATTRIB_BONEINDEXES ,
KRENGINE_ATTRIB_BONEWEIGHTS ,
2013-05-13 13:16:25 -07:00
KRENGINE_ATTRIB_VERTEX_SHORT ,
KRENGINE_ATTRIB_NORMAL_SHORT ,
KRENGINE_ATTRIB_TANGENT_SHORT ,
KRENGINE_ATTRIB_TEXUVA_SHORT ,
KRENGINE_ATTRIB_TEXUVB_SHORT ,
2013-01-09 22:37:23 +00:00
KRENGINE_NUM_ATTRIBUTES
} vertex_attrib_t ;
typedef enum {
KRENGINE_MODEL_FORMAT_TRIANGLES = 0 ,
KRENGINE_MODEL_FORMAT_STRIP ,
KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES ,
KRENGINE_MODEL_FORMAT_INDEXED_STRIP
} model_format_t ;
2013-05-24 12:20:47 -07:00
typedef struct {
model_format_t format ;
std : : vector < KRVector3 > vertices ;
std : : vector < __uint16_t > vertex_indexes ;
std : : vector < std : : pair < int , int > > vertex_index_bases ;
std : : vector < KRVector2 > uva ;
std : : vector < KRVector2 > uvb ;
std : : vector < KRVector3 > normals ;
std : : vector < KRVector3 > tangents ;
std : : vector < int > submesh_starts ;
std : : vector < int > submesh_lengths ;
std : : vector < std : : string > material_names ;
std : : vector < std : : string > bone_names ;
std : : vector < std : : vector < int > > bone_indexes ;
std : : vector < KRMat4 > bone_bind_poses ;
std : : vector < std : : vector < float > > bone_weights ;
} mesh_info ;
2013-01-09 22:37:23 +00:00
2014-04-11 01:15:40 -07:00
void render ( const std : : string & object_name , KRCamera * pCamera , std : : vector < KRPointLight * > & point_lights , std : : vector < KRDirectionalLight * > & directional_lights , std : : vector < KRSpotLight * > & spot_lights , const KRViewport & viewport , const KRMat4 & matModel , KRTexture * pLightMap , KRNode : : RenderPass renderPass , const std : : vector < KRBone * > & bones , const KRVector3 & rim_color , float rim_power , float lod_coverage = 0.0f ) ;
2013-01-09 22:37:23 +00:00
std : : string m_lodBaseName ;
virtual std : : string getExtension ( ) ;
virtual bool save ( const std : : string & path ) ;
virtual bool save ( KRDataBlock & data ) ;
2014-05-15 23:33:01 -07:00
void LoadData ( const mesh_info & mi , bool calculate_normals , bool calculate_tangents ) ;
2013-01-09 22:37:23 +00:00
void loadPack ( KRDataBlock * data ) ;
2013-04-24 12:48:55 -07:00
void convertToIndexed ( ) ;
2013-01-24 23:57:55 -08:00
void optimize ( ) ;
2013-04-24 12:48:55 -07:00
void optimizeIndexes ( ) ;
2013-01-09 22:37:23 +00:00
2014-05-27 22:51:52 -07:00
void renderSubmesh ( int iSubmesh , KRNode : : RenderPass renderPass , const std : : string & object_name , const std : : string & material_name , float lodCoverage ) ;
2013-01-09 22:37:23 +00:00
GLfloat getMaxDimension ( ) ;
KRVector3 getMinPoint ( ) const ;
KRVector3 getMaxPoint ( ) const ;
2013-11-09 16:08:08 -08:00
class Submesh {
public :
Submesh ( ) { } ;
~ Submesh ( ) {
2014-05-16 00:03:56 -07:00
for ( auto itr = vbo_data_blocks . begin ( ) ; itr ! = vbo_data_blocks . end ( ) ; itr + + ) {
2013-11-09 16:08:08 -08:00
delete ( * itr ) ;
}
2014-05-16 00:03:56 -07:00
for ( auto itr = vertex_data_blocks . begin ( ) ; itr ! = vertex_data_blocks . end ( ) ; itr + + ) {
delete ( * itr ) ;
}
for ( auto itr = index_data_blocks . begin ( ) ; itr ! = index_data_blocks . end ( ) ; itr + + ) {
2013-11-09 16:08:08 -08:00
delete ( * itr ) ;
}
} ;
2013-01-09 22:37:23 +00:00
GLint start_vertex ;
GLsizei vertex_count ;
char szMaterialName [ KRENGINE_MAX_NAME_LENGTH ] ;
2013-11-09 16:08:08 -08:00
vector < KRDataBlock * > vertex_data_blocks ;
vector < KRDataBlock * > index_data_blocks ;
2014-05-16 00:03:56 -07:00
vector < KRMeshManager : : KRVBOData * > vbo_data_blocks ;
2013-11-09 16:08:08 -08:00
} ;
2013-05-13 13:16:25 -07:00
2013-01-09 22:37:23 +00:00
typedef struct {
2013-05-06 19:33:51 -07:00
union {
struct { // For Indexed triangles / strips
2013-05-08 17:47:27 -07:00
uint16_t index_group ;
uint16_t index_group_offset ;
2013-05-06 19:33:51 -07:00
} ;
int32_t start_vertex ; // For non-indexed trigangles / strips
} ;
2013-01-09 22:37:23 +00:00
int32_t vertex_count ;
char szName [ KRENGINE_MAX_NAME_LENGTH ] ;
} pack_material ;
typedef struct {
char szName [ KRENGINE_MAX_NAME_LENGTH ] ;
2013-05-24 12:20:47 -07:00
float bind_pose [ 16 ] ;
2013-01-09 22:37:23 +00:00
} pack_bone ;
int getLODCoverage ( ) const ;
std : : string getLODBaseName ( ) const ;
static bool lod_sort_predicate ( const KRMesh * m1 , const KRMesh * m2 ) ;
bool has_vertex_attribute ( vertex_attrib_t attribute_type ) const ;
2013-05-13 13:16:25 -07:00
static bool has_vertex_attribute ( int vertex_attrib_flags , vertex_attrib_t attribute_type ) ;
2013-01-09 22:37:23 +00:00
int getSubmeshCount ( ) const ;
int getVertexCount ( int submesh ) const ;
2013-04-24 12:48:55 -07:00
int getTriangleVertexIndex ( int submesh , int index ) const ;
2013-01-09 22:37:23 +00:00
KRVector3 getVertexPosition ( int index ) const ;
KRVector3 getVertexNormal ( int index ) const ;
KRVector3 getVertexTangent ( int index ) const ;
KRVector2 getVertexUVA ( int index ) const ;
KRVector2 getVertexUVB ( int index ) const ;
int getBoneIndex ( int index , int weight_index ) const ;
float getBoneWeight ( int index , int weight_index ) const ;
void setVertexPosition ( int index , const KRVector3 & v ) ;
void setVertexNormal ( int index , const KRVector3 & v ) ;
void setVertexTangent ( int index , const KRVector3 & v ) ;
void setVertexUVA ( int index , const KRVector2 & v ) ;
void setVertexUVB ( int index , const KRVector2 & v ) ;
void setBoneIndex ( int index , int weight_index , int bone_index ) ;
void setBoneWeight ( int index , int weight_index , float bone_weight ) ;
static size_t VertexSizeForAttributes ( __int32_t vertex_attrib_flags ) ;
static size_t AttributeOffset ( __int32_t vertex_attrib , __int32_t vertex_attrib_flags ) ;
int getBoneCount ( ) ;
char * getBoneName ( int bone_index ) ;
2013-05-24 12:20:47 -07:00
KRMat4 getBoneBindPose ( int bone_index ) ;
2013-01-09 22:37:23 +00:00
model_format_t getModelFormat ( ) const ;
bool lineCast ( const KRVector3 & v0 , const KRVector3 & v1 , KRHitInfo & hitinfo ) const ;
bool rayCast ( const KRVector3 & v0 , const KRVector3 & dir , KRHitInfo & hitinfo ) const ;
2014-02-13 00:36:54 -08:00
bool sphereCast ( const KRMat4 & model_to_world , const KRVector3 & v0 , const KRVector3 & v1 , float radius , KRHitInfo & hitinfo ) const ;
2013-01-09 22:37:23 +00:00
static int GetLODCoverage ( const std : : string & name ) ;
2014-05-27 22:51:52 -07:00
void load ( ) ; // Load immediately into the GPU rather than passing through the streamer
protected :
bool m_constant ; // TRUE if this should be always loaded and should not be passed through the streamer
2013-01-09 22:37:23 +00:00
private :
2013-11-09 16:08:08 -08:00
KRDataBlock * m_pData ;
KRDataBlock * m_pMetaData ;
KRDataBlock * m_pIndexBaseData ;
2013-04-24 12:48:55 -07:00
void getSubmeshes ( ) ;
2014-03-10 22:32:49 -07:00
void getMaterials ( ) ;
2013-04-24 12:48:55 -07:00
2014-02-13 00:36:54 -08:00
static bool rayCast ( const KRVector3 & start , const KRVector3 & dir , const KRTriangle3 & tri , const KRVector3 & tri_n0 , const KRVector3 & tri_n1 , const KRVector3 & tri_n2 , KRHitInfo & hitinfo ) ;
2014-02-17 23:36:54 -08:00
static bool sphereCast ( const KRMat4 & model_to_world , const KRVector3 & v0 , const KRVector3 & v1 , float radius , const KRTriangle3 & tri , KRHitInfo & hitinfo ) ;
2013-01-09 22:37:23 +00:00
int m_lodCoverage ; // This LOD level is activated when the bounding box of the model will cover less than this percent of the screen (100 = highest detail model)
vector < KRMaterial * > m_materials ;
set < KRMaterial * > m_uniqueMaterials ;
bool m_hasTransparency ;
KRVector3 m_minPoint , m_maxPoint ;
2013-11-09 16:08:08 -08:00
2013-01-09 22:37:23 +00:00
typedef struct {
char szTag [ 16 ] ;
int32_t model_format ; // 0 == Triangle list, 1 == Triangle strips, 2 == Indexed triangle list, 3 == Indexed triangle strips, rest are reserved (model_format_t enum)
int32_t vertex_attrib_flags ;
int32_t vertex_count ;
int32_t submesh_count ;
int32_t bone_count ;
float minx , miny , minz , maxx , maxy , maxz ; // Axis aligned bounding box, in model's coordinate space
2013-01-24 23:57:55 -08:00
int32_t index_count ;
2013-04-24 12:48:55 -07:00
int32_t index_base_count ;
unsigned char reserved [ 444 ] ; // Pad out to 512 bytes
2013-01-09 22:37:23 +00:00
} pack_header ;
vector < Submesh * > m_submeshes ;
int m_vertex_attribute_offset [ KRENGINE_NUM_ATTRIBUTES ] ;
int m_vertex_size ;
void updateAttributeOffsets ( ) ;
void setName ( const std : : string name ) ;
pack_material * getSubmesh ( int mesh_index ) const ;
unsigned char * getVertexData ( ) const ;
2013-11-09 16:08:08 -08:00
size_t getVertexDataOffset ( ) const ;
2013-01-09 22:37:23 +00:00
unsigned char * getVertexData ( int index ) const ;
2013-01-24 23:57:55 -08:00
__uint16_t * getIndexData ( ) const ;
2013-11-09 16:08:08 -08:00
size_t getIndexDataOffset ( ) const ;
2013-04-24 12:48:55 -07:00
__uint32_t * getIndexBaseData ( ) const ;
2013-01-09 22:37:23 +00:00
pack_header * getHeader ( ) const ;
pack_bone * getBone ( int index ) ;
2013-04-24 12:48:55 -07:00
2013-05-06 19:33:51 -07:00
void getIndexedRange ( int index_group , int & start_index_offset , int & start_vertex_offset , int & index_count , int & vertex_count ) const ;
2013-11-09 16:08:08 -08:00
void releaseData ( ) ;
2014-05-27 22:51:52 -07:00
void createDataBlocks ( KRMeshManager : : KRVBOData : : vbo_type t ) ;
2013-01-09 22:37:23 +00:00
} ;
# endif // KRMesh_I