initial mesh and physics support

This commit is contained in:
gmueller 2011-01-19 23:20:08 +01:00
parent 6fcb3dbff4
commit 12153ffbea
16 changed files with 4231 additions and 20 deletions

View File

@ -17,12 +17,14 @@ include_directories (${GREMLIN_SOURCE_DIR}/libs/glfw/include)
include_directories (${GREMLIN_SOURCE_DIR}/libs/spark/include) include_directories (${GREMLIN_SOURCE_DIR}/libs/spark/include)
include_directories (${GREMLIN_SOURCE_DIR}/libs/enet/include) include_directories (${GREMLIN_SOURCE_DIR}/libs/enet/include)
include_directories (${GREMLIN_SOURCE_DIR}/libs/bullet) include_directories (${GREMLIN_SOURCE_DIR}/libs/bullet)
include_directories (${GREMLIN_SOURCE_DIR}/libs/trimeshloader/include)
find_package(OpenGL) find_package(OpenGL)
add_subdirectory (libs/enet) add_subdirectory (libs/enet)
add_subdirectory (libs/pugixml) add_subdirectory (libs/pugixml)
add_subdirectory (libs/bullet) add_subdirectory (libs/bullet)
add_subdirectory (libs/trimeshloader)
add_subdirectory (src/common) add_subdirectory (src/common)
add_subdirectory (src/server) add_subdirectory (src/server)

View File

@ -0,0 +1,7 @@
include_directories (include)
add_library (trimeshloader
src/tl3ds
src/tlobj
src/trimeshloader
)

View File

@ -0,0 +1,36 @@
*** RELEASE 0.0.12
2007/05/28 - Cirdan
* again bug fixes in obj code
*** RELEASE 0.0.11
2007/05/28 - Cirdan
* relative indices
* bug fix in new obj code
*** RELEASE 0.0.10
2007/05/28 - Cirdan
* use a faster lookup method in obj code
2007/04/24 - Cirdan
* fixed a memory leak in tlLoad3DS/tlLoadObj functions
* added flexible vertex formats for high level loading
2007/04/17 - Cirdan
* renamed tlTrimeshFrom[3ds|Obj]State to tlCreateTrimeshFrom[3ds|Obj]State
* changed license from MIT to zlib
2007/04/17 - Cirdan
* replaced "0" with NULL
2007/04/16 - Cirdan
* added tl3dsCheckFileExtension and tlObjCheckFileExtension functions.

1252
libs/trimeshloader/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,21 @@
Authors
-------
Gero Müller <gero.mueller@cloo.de>
Contributions
-------------
Paolo Manna (many good ideas and feedback)
Website
-------
http://trimeshloader.sourceforge.net
Versioning
----------
[Major].[Minor].[Patchlevel] e.g. 1.0.1
Where all releases with the same Major revision need to be API compatible.

View File

@ -0,0 +1,135 @@
/*
* Copyright (c) 2007 Gero Mueller <gero.mueller@cloo.de>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef TRIMESH_LOADER_3DS_H
#define TRIMESH_LOADER_3DS_H
/**
@file tl3ds.h
@brief Trimeshloader 3DS parser public header file
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef TRIMESH_LOADER_EXPORT
#define TRIMESH_LOADER_API
#else
#define TRIMESH_LOADER_API extern
#endif
/** @defgroup low_level_3ds_api Trimeshloader low level 3DS API
* @{
*/
/** Structure describing the parsing state. the user has no direkt access to it. */
typedef struct tl3dsState tl3dsState;
/** Create a new parsing state.
* \return A new parsing state, which needs to be deleted after parsing. NULL on error.
*/
TRIMESH_LOADER_API tl3dsState *tl3dsCreateState();
/** Reset the parsing state
* \param state pointer to an previously created state.
*/
TRIMESH_LOADER_API int tl3dsResetState( tl3dsState *state );
/** Destroy a previously created state.
* \param state pointer to an previously created state.
*/
TRIMESH_LOADER_API void tl3dsDestroyState( tl3dsState *state );
/** Parse a chunk of data.
* \param state a previously created state.
* \param buffer pointer to the chunk of data to be parsed
* \param length number of bytes to be parsed
* \param last indicator if this is the last chunk. 1 = yes, 0 = no.
* \return Returns 0 on success, 1 on error.
*/
TRIMESH_LOADER_API int tl3dsParse(
tl3dsState *state,
const char *buffer,
unsigned int length,
int last );
/* data access */
TRIMESH_LOADER_API unsigned int tl3dsObjectCount( tl3dsState *state );
TRIMESH_LOADER_API const char *tl3dsObjectName(
tl3dsState *state,
unsigned int object );
TRIMESH_LOADER_API unsigned int tl3dsObjectFaceCount(
tl3dsState *state,
unsigned int object );
TRIMESH_LOADER_API unsigned int tl3dsObjectFaceIndex(
tl3dsState *state,
unsigned int object );
TRIMESH_LOADER_API unsigned int tl3dsVertexCount( tl3dsState *state );
TRIMESH_LOADER_API int tl3dsGetVertexDouble(
tl3dsState *state,
unsigned int index,
double *x, double *y, double *z,
double *tu, double *tv,
double *nx, double *ny, double *nz );
TRIMESH_LOADER_API int tl3dsGetVertex(
tl3dsState *state,
unsigned int index,
float *x, float *y, float *z,
float *tu, float *tv,
float *nx, float *ny, float *nz );
TRIMESH_LOADER_API unsigned int tl3dsFaceCount(
tl3dsState *state );
TRIMESH_LOADER_API int tl3dsGetFaceInt(
tl3dsState *state,
unsigned int index,
unsigned int *a,
unsigned int *b,
unsigned int *c );
TRIMESH_LOADER_API int tl3dsGetFace(
tl3dsState *state,
unsigned int index,
unsigned short *a,
unsigned short *b,
unsigned short *c );
TRIMESH_LOADER_API int tl3dsCheckFileExtension( const char *filename );
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,120 @@
/*
* Copyright (c) 2007 Gero Mueller <gero.mueller@cloo.de>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef TRIMESH_LOADER_OBJ_H
#define TRIMESH_LOADER_OBJ_H
/**
@file tlobj.h
@brief Trimeshloader OBJ parser public header file
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef TRIMESH_LOADER_EXPORT
#define TRIMESH_LOADER_API
#else
#define TRIMESH_LOADER_API extern
#endif
/** @defgroup low_level_obj_api Trimeshloader low level OBJ API
* @{
*/
typedef struct tlObjState tlObjState;
/* state handling */
TRIMESH_LOADER_API tlObjState *tlObjCreateState();
TRIMESH_LOADER_API int tlObjResetState( tlObjState *state );
TRIMESH_LOADER_API void tlObjDestroyState( tlObjState *state );
/* parsing */
TRIMESH_LOADER_API int tlObjParse(
tlObjState *state,
const char *buffer,
unsigned int length,
int last );
/* data access */
TRIMESH_LOADER_API unsigned int tlObjObjectCount( tlObjState *state );
TRIMESH_LOADER_API const char *tlObjObjectName(
tlObjState *state,
unsigned int object );
TRIMESH_LOADER_API unsigned int tlObjObjectFaceCount(
tlObjState *state,
unsigned int object );
TRIMESH_LOADER_API unsigned int tlObjObjectFaceIndex(
tlObjState *state,
unsigned int object );
TRIMESH_LOADER_API unsigned int tlObjVertexCount( tlObjState *state );
TRIMESH_LOADER_API int tlObjGetVertexDouble(
tlObjState *state,
unsigned int index,
double *x, double *y, double *z,
double *tu, double *tv,
double *nx, double *ny, double *nz );
TRIMESH_LOADER_API int tlObjGetVertex(
tlObjState *state,
unsigned int index,
float *x, float *y, float *z,
float *tu, float *tv,
float *nx, float *ny, float *nz );
TRIMESH_LOADER_API unsigned int tlObjFaceCount(
tlObjState *state );
TRIMESH_LOADER_API int tlObjGetFaceInt(
tlObjState *state,
unsigned int index,
unsigned int *a,
unsigned int *b,
unsigned int *c );
TRIMESH_LOADER_API int tlObjGetFace(
tlObjState *state,
unsigned int index,
unsigned short *a,
unsigned short *b,
unsigned short *c );
TRIMESH_LOADER_API int tlObjCheckFileExtension( const char *filename );
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,159 @@
/*
* Copyright (c) 2007 Gero Mueller <gero.mueller@cloo.de>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
/** \mainpage trimeshloader-0.1
* \section project_page Project Page
* \url http://sourceforge.net/projects/trimeshloader
* \section website Website with tutorials
* \url http://trimeshloader.sourceforge.net
*/
/**
@file trimeshloader.h
@brief Trimeshloader public header file
*/
#ifndef TRIMESH_LOADER_H
#define TRIMESH_LOADER_H
#include "tlobj.h"
#include "tl3ds.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef TRIMESH_LOADER_EXPORT
#define TRIMESH_LOADER_API
#else
#define TRIMESH_LOADER_API extern
#endif
/** @defgroup high_level_api Trimeshloader high level API
* @{
*/
/** Structure describing an Object (or SubMesh, Batch) */
typedef struct tlObject
{
/** Name of the Object */
char *name;
/** First face in the index list */
unsigned int face_index;
/** Face count */
unsigned int face_count;
} tlObject;
/** Used as format flag in loading functions: load the position of the vertex */
#define TL_FVF_XYZ 1
/** Used as format flag in loading functions: load the texturecoordinate of the vertex */
#define TL_FVF_UV 2
/** Used as format flag in loading functions: load the normal of the vertex */
#define TL_FVF_NORMAL 4
/** Structure describing an Trimesh (index triangle list) containing objects, vertices (point, texture coordinate and normal) and triangle indices */
typedef struct tlTrimesh
{
/** pointer to the vertex data */
float *vertices;
/** number of vertices */
unsigned int vertex_count;
/** format of the vertices */
unsigned int vertex_format;
/** size/stride of each vertex, in bytes */
unsigned int vertex_size;
/** pointer to the face (triangle) indices (3 unsigned shorts) */
unsigned short *faces;
/** number of faces */
unsigned int face_count;
/** list of objects in this trimesh */
tlObject *objects;
/** number of objects */
unsigned int object_count;
} tlTrimesh;
/** Load an 3DS file in an tlTrimesh structure
* \param filename Pointer to NULL-terminated string containing the filename
* \param vertex_format Defines the vertex format. any format combination of TL_FVF_XYZ, TL_FVF_UV, TL_FVF_NORMAL
* \return Returns a new tlTrimesh object, which needs to be deleted with tlDeleteTrimesh. NULL on error.
*/
TRIMESH_LOADER_API tlTrimesh *tlLoad3DS( const char*filename, unsigned int vertex_format );
/** Load an OBJ file in an tlTrimesh structure
* \param filename Pointer to NULL-terminated string containing the filename
* \param vertex_format Defines the vertex format. any format combination of TL_FVF_XYZ, TL_FVF_UV, TL_FVF_NORMAL
* \return Returns a new tlTrimesh object, which needs to be deleted with tlDeleteTrimesh. NULL on error.
*/
TRIMESH_LOADER_API tlTrimesh *tlLoadOBJ( const char*filename, unsigned int vertex_format );
/** Create an a tlTrimesh structure from a tlObjState
* \param state Pointer to state after parsing.
* \param vertex_format Defines the vertex format. any format combination of TL_FVF_XYZ, TL_FVF_UV, TL_FVF_NORMAL
* \return Returns a new tlTrimesh object, which needs to be deleted with tlDeleteTrimesh. NULL on error.
*/
TRIMESH_LOADER_API tlTrimesh *tlCreateTrimeshFromObjState( tlObjState *state, unsigned int vertex_format );
/** Create an a tlTrimesh structure from a tl3dsState
* \param state Pointer to state after parsing.
* \param vertex_format Defines the vertex format. any format combination of TL_FVF_XYZ, TL_FVF_UV, TL_FVF_NORMAL
* \return Returns a new tlTrimesh object, which needs to be deleted with tlDeleteTrimesh. NULL on error.
*/
TRIMESH_LOADER_API tlTrimesh *tlCreateTrimeshFrom3dsState( tl3dsState *state, unsigned int vertex_format );
/** Load an 3DS or OBJ file in an tlTrimesh structure. Automatic extension parsing is done.
* \param filename Pointer to NULL-terminated string containing the filename
* \param vertex_format Defines the vertex format. any format combination of TL_FVF_XYZ, TL_FVF_UV, TL_FVF_NORMAL
* \return Returns a new tlTrimesh object, which needs to be deleted with tlDeleteTrimesh. NULL on error.
*/
TRIMESH_LOADER_API tlTrimesh *tlLoadTrimesh( const char*filename, unsigned int vertex_format );
/** Delete an previously loaded tlTrimesh object
* \param trimesh Previously loaded tlTrimesh object
*/
TRIMESH_LOADER_API void tlDeleteTrimesh( tlTrimesh *trimesh );
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /*TRIMESHLOADER_H_*/

View File

@ -0,0 +1,909 @@
/*
* Copyright (c) 2007 Gero Mueller <gero.mueller@cloo.de>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "tl3ds.h"
#include <string.h>
#include <stdlib.h>
/*----------------------------------------------------------------------------*/
typedef enum tl3dsParsingState
{
TDS_STATE_READ_CHUNK_ID,
TDS_STATE_READ_CHUNK_LENGTH,
TDS_STATE_READ_OBJECT_NAME,
TDS_STATE_SKIP_CHUNK,
TDS_STATE_READ_POINT_COUNT,
TDS_STATE_READ_POINTS,
TDS_STATE_READ_TEXCOORD_COUNT,
TDS_STATE_READ_TEXCOORDS,
TDS_STATE_READ_FACE_COUNT,
TDS_STATE_READ_FACES,
TDS_STATE_DONE
} tl3dsParsingState;
/*----------------------------------------------------------------------------*/
typedef struct tl3dsObject
{
char *name;
unsigned int index, count;
} tl3dsObject;
/*----------------------------------------------------------------------------*/
struct tl3dsState
{
unsigned short chunk_id;
unsigned int chunk_length;
char *buffer;
unsigned int buffer_size;
unsigned int buffer_length;
unsigned int counter;
unsigned int item_count;
tl3dsParsingState parsing_state;
float *point_buffer;
unsigned int point_buffer_size;
unsigned int point_count;
float *texcoord_buffer;
unsigned int texcoord_buffer_size;
unsigned int texcoord_count;
unsigned short *face_buffer;
unsigned int face_buffer_size;
unsigned int face_count;
tl3dsObject **object_buffer;
unsigned int object_count;
};
/*----------------------------------------------------------------------------*/
static unsigned int tds_le()
{
const char endian[8] = { 1, 0, 0, 0, 0, 0, 0, 0 };
unsigned int i = *((unsigned int *)endian);
/* LE uint64: i = 1 */
/* LE uint32: i = 1 */
/* LE uint16: i = 1 */
/* BE uint32: i > 1 */
/* BE uint32: i > 1 */
/* BE uint16: i > 1 */
if( i == 1 )
return 1;
else
return 0;
}
/*----------------------------------------------------------------------------*/
static float tds_read_le_float( const char *ptr )
{
float f = 0;
char *fptr = (char *)&f;
if( tds_le() )
{
fptr[0] = ptr[0];
fptr[1] = ptr[1];
fptr[2] = ptr[2];
fptr[3] = ptr[3];
}
else
{
fptr[0] = ptr[3];
fptr[1] = ptr[2];
fptr[2] = ptr[1];
fptr[3] = ptr[0];
}
return f;
}
/*----------------------------------------------------------------------------*/
static unsigned short tds_read_le_ushort( const char *ptr )
{
unsigned short s = 0;
char *sptr = (char *)&s;
if( tds_le() )
{
sptr[0] = ptr[0];
sptr[1] = ptr[1];
}
else
{
sptr[0] = ptr[1];
sptr[1] = ptr[0];
}
return s;
}
/*----------------------------------------------------------------------------*/
static unsigned int tds_read_le_uint( const char *ptr )
{
unsigned int i = 0;
char *iptr = (char *)&i;
if( tds_le() )
{
iptr[0] = ptr[0];
iptr[1] = ptr[1];
iptr[2] = ptr[2];
iptr[3] = ptr[3];
}
else
{
iptr[0] = ptr[3];
iptr[1] = ptr[2];
iptr[2] = ptr[1];
iptr[3] = ptr[0];
}
return i;
}
/*----------------------------------------------------------------------------*/
static int tds_buffer_reserve( tl3dsState *state, unsigned int size )
{
unsigned int new_size = 1;
char *new_buffer = 0;
if( state == NULL )
return 1;
if( state->buffer_size >= size )
return 0;
while( new_size < size )
new_size = new_size * 2;
new_buffer = (char *)realloc( state->buffer, new_size );
if( new_buffer )
{
state->buffer = new_buffer;
state->buffer_size = new_size;
}
return 0;
}
/*----------------------------------------------------------------------------*/
static void tds_buffer_add( tl3dsState *state, char c )
{
if( tds_buffer_reserve( state, state->buffer_length + 1 ) != 0 )
return;
state->buffer[ state->buffer_length ] = c;
state->buffer_length++;
}
/*----------------------------------------------------------------------------*/
static int tds_object_buffer_add(
tl3dsState *state,
const char *name,
unsigned int name_length )
{
tl3dsObject **new_object_buffer = 0;
unsigned int new_object_count = state->object_count + 1;
new_object_buffer = (tl3dsObject **)realloc(
state->object_buffer,
sizeof(tl3dsObject *) * new_object_count );
if( new_object_buffer )
{
/* create the new object */
tl3dsObject *new_object = (tl3dsObject *)malloc( sizeof(tl3dsObject) );
memset( new_object, 0, sizeof(tl3dsObject) );
/* copy the name */
new_object->name = (char *)malloc( name_length );
memcpy( new_object->name, name, name_length );
/* add the new object */
new_object_buffer[ new_object_count - 1 ] = new_object;
/* update state */
state->object_buffer = new_object_buffer;
state->object_count = new_object_count;
return 0;
}
return 1;
}
/*----------------------------------------------------------------------------*/
static void tds_point_buffer_grow( tl3dsState *state, unsigned int count )
{
unsigned int new_size = (state->point_count + count ) * 3 * sizeof(float);
float *new_buffer = realloc( state->point_buffer, new_size );
if( new_buffer )
{
state->point_buffer = new_buffer;
state->point_buffer_size = new_size;
}
}
/*----------------------------------------------------------------------------*/
static void tds_point_buffer_add( tl3dsState *state, float x, float y, float z )
{
unsigned int new_size = (state->point_count + 1 ) * 3 * sizeof(float);
if( state->point_buffer_size < new_size )
return;
state->point_buffer[state->point_count * 3] = x;
state->point_buffer[state->point_count * 3 + 1] = y;
state->point_buffer[state->point_count * 3 + 2] = z;
state->point_count++;
}
/*----------------------------------------------------------------------------*/
static void tds_texcoord_buffer_grow( tl3dsState *state, unsigned int count )
{
unsigned int new_size = (state->texcoord_count + count ) * 2 * sizeof(float);
float *new_buffer = realloc( state->texcoord_buffer, new_size );
if( new_buffer )
{
state->texcoord_buffer = new_buffer;
state->texcoord_buffer_size = new_size;
}
}
/*----------------------------------------------------------------------------*/
static void tds_texcoord_buffer_add( tl3dsState *state, float u, float v )
{
unsigned int new_size = (state->texcoord_count + 1 ) * 2 * sizeof(float);
if( state->texcoord_buffer_size < new_size )
return;
state->texcoord_buffer[state->texcoord_count * 2] = u;
state->texcoord_buffer[state->texcoord_count * 2 + 1] = v;
state->texcoord_count++;
}
/*----------------------------------------------------------------------------*/
static void tds_face_buffer_grow( tl3dsState *state, unsigned int count )
{
unsigned int new_size
= (state->face_count + count ) * 3 * sizeof(unsigned short);
unsigned short *new_buffer = realloc( state->face_buffer, new_size );
if( new_buffer )
{
state->face_buffer = new_buffer;
state->face_buffer_size = new_size;
}
}
/*----------------------------------------------------------------------------*/
static void tds_face_buffer_add(
tl3dsState *state,
unsigned short a,
unsigned short b,
unsigned short c )
{
unsigned int new_size
= (state->face_count + 1 ) * 3 * sizeof(unsigned short);
if( state->face_buffer_size < new_size )
return;
state->face_buffer[state->face_count * 3] = a;
state->face_buffer[state->face_count * 3 + 1] = b;
state->face_buffer[state->face_count * 3 + 2] = c;
state->face_count++;
}
/*----------------------------------------------------------------------------*/
tl3dsState *tl3dsCreateState()
{
tl3dsState *state = malloc( sizeof(tl3dsState) );
if( state )
{
memset( state, 0, sizeof(tl3dsState) );
state->parsing_state = TDS_STATE_READ_CHUNK_ID;
}
return state;
}
/*----------------------------------------------------------------------------*/
int tl3dsResetState( tl3dsState *state )
{
unsigned int i;
if( state->buffer )
free( state->buffer );
if( state->object_buffer )
{
for( i = 0; i < state->object_count; i++ )
{
tl3dsObject *obj = state->object_buffer[i];
if( obj == 0 )
continue;
if( obj->name )
free( obj->name );
free( obj );
}
free( state->object_buffer );
}
if( state->point_buffer )
free( state->point_buffer );
if( state->texcoord_buffer )
free( state->texcoord_buffer );
if( state->face_buffer )
free( state->face_buffer );
memset( state, 0, sizeof(tl3dsState) );
state->parsing_state = TDS_STATE_READ_CHUNK_ID;
return 0;
}
/*----------------------------------------------------------------------------*/
void tl3dsDestroyState( tl3dsState *state )
{
if( state )
{
tl3dsResetState( state );
free( state );
}
}
/*----------------------------------------------------------------------------*/
int tl3dsParse(
tl3dsState *state,
const char *buffer,
unsigned int length,
int last )
{
unsigned int i = 0;
if( state == NULL )
return 1;
while( i < length )
{
char c = buffer[i];
switch( state->parsing_state )
{
case TDS_STATE_READ_CHUNK_ID:
tds_buffer_add( state, c );
if( state->buffer_length == 2 )
{
state->chunk_id = tds_read_le_ushort( state->buffer );
state->buffer_length = 0;
state->parsing_state = TDS_STATE_READ_CHUNK_LENGTH;
}
++i;
break;
case TDS_STATE_READ_CHUNK_LENGTH:
tds_buffer_add( state, c );
if( state->buffer_length == 4 )
{
state->chunk_length = tds_read_le_uint( state->buffer );
state->buffer_length = 0;
switch( state->chunk_id )
{
case 0x4d4d: /* MAIN CHUNK */
case 0x4100: /* TRI_OBJECT */
case 0x3d3d: /* 3D EDITOR CHUNK */
state->parsing_state = TDS_STATE_READ_CHUNK_ID;
break;
case 0x4000: /* OBJECT */
state->parsing_state = TDS_STATE_READ_OBJECT_NAME;
break;
case 0x4110: /* POINT_ARRAY */
state->parsing_state = TDS_STATE_READ_POINT_COUNT;
break;
case 0x4120: /* FACE_ARRAY */
state->parsing_state = TDS_STATE_READ_FACE_COUNT;
break;
case 0x4140: /* TEX_ARRAY */
state->parsing_state = TDS_STATE_READ_TEXCOORD_COUNT;
break;
default:
state->parsing_state = TDS_STATE_SKIP_CHUNK;
state->counter = 6;
break;
}
}
++i;
break;
case TDS_STATE_READ_OBJECT_NAME:
tds_buffer_add( state, c );
if( c == 0 )
{
tds_object_buffer_add(
state,
state->buffer,
state->buffer_length );
/* continue with chunks */
state->parsing_state = TDS_STATE_READ_CHUNK_ID;
state->buffer_length = 0;
}
++i;
break;
case TDS_STATE_READ_POINT_COUNT:
tds_buffer_add( state, c );
if( state->buffer_length == 2 )
{
state->item_count = tds_read_le_ushort( state->buffer );
tds_point_buffer_grow( state, state->item_count );
state->parsing_state = TDS_STATE_READ_POINTS;
state->buffer_length = 0;
state->counter = 0;
}
++i;
break;
case TDS_STATE_READ_POINTS:
tds_buffer_add( state, c );
if( state->buffer_length == 12 )
{
tds_point_buffer_add(
state,
tds_read_le_float( state->buffer ),
tds_read_le_float( state->buffer + 4 ),
tds_read_le_float( state->buffer + 8 ) );
state->counter++;
state->buffer_length = 0;
if( state->counter >= state->item_count )
{
state->parsing_state = TDS_STATE_READ_CHUNK_ID;
state->buffer_length = 0;
}
}
++i;
break;
case TDS_STATE_READ_TEXCOORD_COUNT:
tds_buffer_add( state, c );
if( state->buffer_length == 2 )
{
state->item_count = tds_read_le_ushort( state->buffer );
tds_texcoord_buffer_grow( state, state->item_count );
state->parsing_state = TDS_STATE_READ_TEXCOORDS;
state->buffer_length = 0;
state->counter = 0;
}
++i;
break;
case TDS_STATE_READ_TEXCOORDS:
tds_buffer_add( state, c );
if( state->buffer_length == 8 )
{
tds_texcoord_buffer_add(
state,
tds_read_le_float( state->buffer ),
tds_read_le_float( state->buffer + 4 ) );
state->counter++;
state->buffer_length = 0;
if( state->counter >= state->item_count )
state->parsing_state = TDS_STATE_READ_CHUNK_ID;
}
++i;
break;
case TDS_STATE_READ_FACE_COUNT:
tds_buffer_add( state, c );
if( state->buffer_length == 2 )
{
state->item_count = tds_read_le_ushort( state->buffer );
tds_face_buffer_grow( state, state->item_count );
state->object_buffer[state->object_count-1]->count
= state->item_count;
if( state->object_count > 1 )
state->object_buffer[state->object_count - 1]->index
= state->object_buffer[state->object_count-2]->index
+ state->object_buffer[state->object_count-2]->count;
state->parsing_state = TDS_STATE_READ_FACES;
state->buffer_length = 0;
state->counter = 0;
}
++i;
break;
case TDS_STATE_READ_FACES:
tds_buffer_add( state, c );
if( state->buffer_length == 8 )
{
tds_face_buffer_add(
state,
tds_read_le_ushort( state->buffer ),
tds_read_le_ushort( state->buffer + 2),
tds_read_le_ushort( state->buffer + 4 ) );
state->counter++;
state->buffer_length = 0;
if( state->counter >= state->item_count )
state->parsing_state = TDS_STATE_READ_CHUNK_ID;
}
++i;
break;
case TDS_STATE_SKIP_CHUNK:
++i;
++state->counter;
if( state->counter >= state->chunk_length )
state->parsing_state = TDS_STATE_READ_CHUNK_ID;
break;
default:
++i;
break;
}
}
if( last )
state->parsing_state = TDS_STATE_DONE;
return 0;
}
/*----------------------------------------------------------------------------*/
unsigned int tl3dsObjectCount( tl3dsState *state )
{
if( state == NULL )
return 0;
if( state->parsing_state != TDS_STATE_DONE )
return 0;
return state->object_count;
}
/*----------------------------------------------------------------------------*/
const char *tl3dsObjectName( tl3dsState *state, unsigned int object )
{
if( state == NULL )
return NULL;
if( state->parsing_state != TDS_STATE_DONE )
return NULL;
if( object >= state->object_count )
return NULL;
return state->object_buffer[object]->name;
}
/*----------------------------------------------------------------------------*/
unsigned int tl3dsObjectFaceCount( tl3dsState *state, unsigned int object )
{
if( state == NULL )
return 0;
if( state->parsing_state != TDS_STATE_DONE )
return 0;
if( object >= state->object_count )
return 0;
return state->object_buffer[object]->count;
}
/*----------------------------------------------------------------------------*/
unsigned int tl3dsObjectFaceIndex( tl3dsState *state, unsigned int object )
{
if( state == NULL )
return 0;
if( state->parsing_state != TDS_STATE_DONE )
return 0;
if( object >= state->object_count )
return 0;
return state->object_buffer[object]->index;
}
/*----------------------------------------------------------------------------*/
unsigned int tl3dsVertexCount( tl3dsState *state )
{
if( state == NULL )
return 0;
if( state->parsing_state != TDS_STATE_DONE )
return 0;
return state->point_count;
}
/*----------------------------------------------------------------------------*/
int tl3dsGetVertexDouble(
tl3dsState *state,
unsigned int index,
double *x, double *y, double *z,
double *tu, double *tv,
double *nx, double *ny, double *nz )
{
if( state == NULL )
return 1;
if( index >= state->point_count )
return 1;
if( state->point_buffer && index < state->point_count )
{
if( x )
*x = (float)state->point_buffer[ index * 3 ];
if( y )
*y = (float)state->point_buffer[ index * 3 + 1];
if( z )
*z = (float)state->point_buffer[ index * 3 + 2];
}
if( state->texcoord_buffer && index < state->texcoord_count )
{
if( tu )
*tu = (float)state->texcoord_buffer[ index * 2 ];
if( tv )
*tv = (float)state->texcoord_buffer[ index * 2 + 1];
}
if( nx )
*nx = 0;
if( ny )
*ny = 0;
if( nz )
*nz = 0;
return 0;
}
/*----------------------------------------------------------------------------*/
int tl3dsGetVertex(
tl3dsState *state,
unsigned int index,
float *x, float *y, float *z,
float *tu, float *tv,
float *nx, float *ny, float *nz )
{
if( state == NULL )
return 1;
if( index >= state->point_count )
return 1;
if( state->point_buffer && index < state->point_count )
{
if( x )
*x = (float)state->point_buffer[ index * 3 ];
if( y )
*y = (float)state->point_buffer[ index * 3 + 1];
if( z )
*z = (float)state->point_buffer[ index * 3 + 2];
}
if( state->texcoord_buffer && index < state->texcoord_count )
{
if( tu )
*tu = (float)state->texcoord_buffer[ index * 2 ];
if( tv )
*tv = (float)state->texcoord_buffer[ index * 2 + 1];
}
if( nx )
*nx = 0;
if( ny )
*ny = 0;
if( nz )
*nz = 0;
return 0;
}
/*----------------------------------------------------------------------------*/
unsigned int tl3dsFaceCount( tl3dsState *state )
{
if( state == NULL )
return 0;
return state->face_count;
}
/*----------------------------------------------------------------------------*/
int tl3dsGetFaceInt(
tl3dsState *state,
unsigned int index,
unsigned int *a,
unsigned int *b,
unsigned int *c )
{
unsigned int face = 0;
if( state == NULL )
return 1;
if( state->face_buffer && face <= state->face_count )
{
if( a )
*a = state->face_buffer[ index * 3 ];
if( b )
*b = state->face_buffer[ index * 3 + 1 ];
if( c )
*c = state->face_buffer[ index * 3 + 2 ];
}
return 0;
}
/*----------------------------------------------------------------------------*/
int tl3dsGetFace(
tl3dsState *state,
unsigned int index,
unsigned short *a,
unsigned short *b,
unsigned short *c )
{
unsigned int face = 0;
if( state == NULL )
return 1;
if( state->face_buffer && face <= state->face_count )
{
if( a )
*a = state->face_buffer[ index * 3 ];
if( b )
*b = state->face_buffer[ index * 3 + 1 ];
if( c )
*c = state->face_buffer[ index * 3 + 2 ];
}
return 0;
}
/*----------------------------------------------------------------------------*/
int tl3dsCheckFileExtension( const char *filename )
{
const char *ext = 0, *tmp = filename;
if( filename == NULL )
return 1;
while( *tmp != 0 )
{
if( *tmp == '.' )
ext = tmp + 1;
tmp++;
}
/* no extension found */
if( ext == 0 )
return 1;
if( (ext[0] == '3')
&& (ext[1] == 'd' || ext[1] == 'D')
&& (ext[2] == 's' || ext[2] == 'S')
&& (ext[3] == 0) )
return 0;
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,280 @@
/*
* Copyright (c) 2007 Gero Mueller <gero.mueller@cloo.de>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "trimeshloader.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/*----------------------------------------------------------------------------*/
tlTrimesh *tlCreateTrimeshFrom3dsState( tl3dsState *state, unsigned int vertex_format )
{
tlTrimesh *trimesh = NULL;
unsigned int i = 0, index = 0;
float *x = NULL, *y = NULL, *z = NULL;
float *u = NULL, *v = NULL;
float *nx = NULL, *ny = NULL, *nz = NULL;
if( state == NULL )
return NULL;
trimesh = malloc( sizeof(tlTrimesh) );
trimesh->object_count = tl3dsObjectCount( state );
trimesh->objects = malloc( sizeof(tlObject) * trimesh->object_count );
for( i = 0; i < trimesh->object_count; i++ )
{
unsigned int length = strlen( tl3dsObjectName( state, i ) ) + 1;
trimesh->objects[i].name = malloc( length );
memcpy( trimesh->objects[i].name, tl3dsObjectName( state, i ), length );
trimesh->objects[i].face_index = tl3dsObjectFaceIndex( state, i );
trimesh->objects[i].face_count = tl3dsObjectFaceCount( state, i );
}
trimesh->face_count = tl3dsFaceCount( state );
trimesh->faces = malloc( sizeof(unsigned short) * trimesh->face_count * 3 );
for( i = 0; i < trimesh->face_count; i++ )
{
unsigned int offset = i * 3;
tl3dsGetFace( state, i,
&trimesh->faces[offset],
&trimesh->faces[offset + 1],
&trimesh->faces[offset + 2] );
}
trimesh->vertex_count = tl3dsVertexCount( state );
trimesh->vertex_format = vertex_format;
trimesh->vertex_size = vertex_format & TL_FVF_XYZ ? 3 * sizeof(float) : 0;
trimesh->vertex_size += vertex_format & TL_FVF_UV ? 2 * sizeof(float) : 0;
trimesh->vertex_size += vertex_format & TL_FVF_NORMAL ? 3 * sizeof(float) : 0;
trimesh->vertices = malloc( trimesh->vertex_count * trimesh->vertex_size );
index = 0;
for( i = 0; i < trimesh->vertex_count; i++ )
{
if( vertex_format & TL_FVF_XYZ )
{
x = &trimesh->vertices[index++];
y = &trimesh->vertices[index++];
z = &trimesh->vertices[index++];
}
if( vertex_format & TL_FVF_UV )
{
u = &trimesh->vertices[index++];
v = &trimesh->vertices[index++];
}
if( vertex_format & TL_FVF_NORMAL )
{
nx = &trimesh->vertices[index++];
ny = &trimesh->vertices[index++];
nz = &trimesh->vertices[index++];
}
tl3dsGetVertex( state, i, x, y, z, u, v, nx, ny, nz );
}
return trimesh;
}
/*----------------------------------------------------------------------------*/
tlTrimesh *tlLoad3DS( const char *filename, unsigned int vertex_format )
{
FILE *f = 0;
tlTrimesh *trimesh = NULL;
if( filename == NULL )
return NULL;
f = fopen( filename, "r" );
if( f )
{
tl3dsState *state = NULL;
state = tl3dsCreateState();
if( state )
{
char buffer[1024];
unsigned int size = 0;
while( !feof( f ) )
{
size = (unsigned int) fread( buffer, 1, sizeof(buffer), f );
tl3dsParse( state, buffer, size, size < sizeof(buffer) ? 1 : 0 );
}
trimesh = tlCreateTrimeshFrom3dsState( state, vertex_format );
tl3dsDestroyState( state );
}
fclose( f );
}
return trimesh;
}
/*----------------------------------------------------------------------------*/
tlTrimesh *tlCreateTrimeshFromObjState( tlObjState *state, unsigned int vertex_format )
{
tlTrimesh *trimesh = NULL;
unsigned int i = 0, index = 0;
float *x = NULL, *y = NULL, *z = NULL;
float *u = NULL, *v = NULL;
float *nx = NULL, *ny = NULL, *nz = NULL;
if( state == NULL )
return NULL;
trimesh = malloc( sizeof(tlTrimesh) );
trimesh->object_count = tlObjObjectCount( state );
trimesh->objects = malloc( sizeof(tlObject) * trimesh->object_count );
for( i = 0; i < trimesh->object_count; i++ )
{
unsigned int length = strlen( tlObjObjectName( state, i ) ) + 1;
trimesh->objects[i].name = malloc( length );
memcpy( trimesh->objects[i].name, tlObjObjectName( state, i ), length );
trimesh->objects[i].face_index = tlObjObjectFaceIndex( state, i );
trimesh->objects[i].face_count = tlObjObjectFaceCount( state, i );
}
trimesh->face_count = tlObjFaceCount( state );
trimesh->faces = malloc( sizeof(unsigned short) * trimesh->face_count * 3 );
for( i = 0; i < trimesh->face_count; i++ )
{
unsigned int offset = i * 3;
tlObjGetFace( state, i,
&trimesh->faces[offset],
&trimesh->faces[offset + 1],
&trimesh->faces[offset + 2] );
}
trimesh->vertex_count = tlObjVertexCount( state );
trimesh->vertex_format = vertex_format;
trimesh->vertex_size = vertex_format & TL_FVF_XYZ ? 3 * sizeof(float) : 0;
trimesh->vertex_size += vertex_format & TL_FVF_UV ? 2 * sizeof(float) : 0;
trimesh->vertex_size += vertex_format & TL_FVF_NORMAL ? 3 * sizeof(float) : 0;
trimesh->vertices = malloc( trimesh->vertex_count * trimesh->vertex_size );
index = 0;
for( i = 0; i < trimesh->vertex_count; i++ )
{
if( vertex_format & TL_FVF_XYZ )
{
x = &trimesh->vertices[index++];
y = &trimesh->vertices[index++];
z = &trimesh->vertices[index++];
}
if( vertex_format & TL_FVF_UV )
{
u = &trimesh->vertices[index++];
v = &trimesh->vertices[index++];
}
if( vertex_format & TL_FVF_NORMAL )
{
nx = &trimesh->vertices[index++];
ny = &trimesh->vertices[index++];
nz = &trimesh->vertices[index++];
}
tlObjGetVertex( state, i, x, y, z, u, v, nx, ny, nz );
}
return trimesh;
}
/*----------------------------------------------------------------------------*/
tlTrimesh *tlLoadOBJ( const char *filename, unsigned int vertex_format )
{
FILE *f = 0;
tlTrimesh *trimesh = NULL;
if( filename == NULL )
return NULL;
f = fopen( filename, "r" );
if( f )
{
tlObjState *state = NULL;
state = tlObjCreateState();
if( state )
{
char buffer[1024];
unsigned int size = 0;
while( !feof( f ) )
{
size = (unsigned int) fread( buffer, 1, sizeof(buffer), f );
tlObjParse( state, buffer, size, size < sizeof(buffer) ? 1 : 0 );
}
trimesh = tlCreateTrimeshFromObjState( state, vertex_format );
tlObjDestroyState( state );
}
fclose( f );
}
return trimesh;
}
/*----------------------------------------------------------------------------*/
tlTrimesh *tlLoadTrimesh( const char* filename, unsigned int vertex_format )
{
tlTrimesh *trimesh = NULL;
if( tl3dsCheckFileExtension( filename ) == 0 )
trimesh = tlLoad3DS( filename, vertex_format );
else if( tlObjCheckFileExtension( filename ) == 0 )
trimesh = tlLoadOBJ( filename, vertex_format );
return trimesh;
}
/*----------------------------------------------------------------------------*/
void tlDeleteTrimesh( tlTrimesh *trimesh )
{
unsigned int i = 0;
if( trimesh == NULL )
return;
for( i = 0; i < trimesh->object_count; i++ )
free( trimesh->objects[i].name );
free( trimesh->objects );
free( trimesh->faces );
free( trimesh->vertices );
free( trimesh );
}

View File

@ -71,15 +71,30 @@ void draw_team(Team *team) {
gluSphere(quadratic, 50.f, 32, 32); gluSphere(quadratic, 50.f, 32, 32);
glPopMatrix(); glPopMatrix();
} }
GLuint wallTex = 0;
void draw_player(player_t *player) { void Client::drawPlayer(player_t *player) {
if (player->status == 0) if (player->status == 0)
return; return;
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, player->team->color); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, player->team->color);
glMatrixMode( GL_MODELVIEW); glMatrixMode( GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
glTranslated(player->x, player->y, player->z); glTranslated(player->x, player->y, player->z);
gluSphere(quadratic, 10.f, 32, 32); glEnableClientState( GL_VERTEX_ARRAY);
glEnableClientState( GL_TEXTURE_COORD_ARRAY);
glEnableClientState( GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, game.shipMesh->vertex_size,
game.shipMesh->vertices);
glTexCoordPointer(2, GL_FLOAT, game.shipMesh->vertex_size,
game.shipMesh->vertices + 3);
glNormalPointer(GL_FLOAT, game.shipMesh->vertex_size,
game.shipMesh->vertices + 5);
for (size_t i = 0; i < game.shipMesh->object_count; i++) {
glDrawElements(GL_TRIANGLES, game.shipMesh->objects[i].face_count * 3,
GL_UNSIGNED_SHORT,
&game.shipMesh->faces[game.shipMesh->objects[i].face_index]);
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix(); glPopMatrix();
} }
@ -152,9 +167,7 @@ void setup_explosion() {
textures[4]); textures[4]);
} }
GLuint wallTex = 0; void Client::drawLevel() {
void draw_box() {
if (wallTex == 0) { if (wallTex == 0) {
glGenTextures(1, &wallTex); glGenTextures(1, &wallTex);
@ -180,13 +193,14 @@ void draw_box() {
//glDisable( GL_DEPTH_TEST); //glDisable( GL_DEPTH_TEST);
// glEnable( GL_LIGHTING); // glEnable( GL_LIGHTING);
// glDisable( GL_BLEND); // glDisable( GL_BLEND);
glColor4f(1, 1, 1, 1);
glMatrixMode( GL_MODELVIEW); glMatrixMode( GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
#if 0
glTranslated(2000.0, 0.0, 0.0); glTranslated(2000.0, 0.0, 0.0);
//glScaled(5000.0f, 5000.0f, 5000.0f); //glScaled(5000.0f, 5000.0f, 5000.0f);
float s = 3000.0f, t = 10.0f; float s = 3000.0f, t = 10.0f;
// Just in case we set all vertices to white. // Just in case we set all vertices to white.
glColor4f(1, 1, 1, 1);
// Render the front quad // Render the front quad
glBegin( GL_QUADS); glBegin( GL_QUADS);
@ -278,6 +292,24 @@ void draw_box() {
glTexCoord2f(t, 0); glTexCoord2f(t, 0);
glVertex3f(s, -s, -s); glVertex3f(s, -s, -s);
glEnd(); glEnd();
#else
glEnableClientState( GL_VERTEX_ARRAY);
glEnableClientState( GL_TEXTURE_COORD_ARRAY);
glEnableClientState( GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, game.levelMesh->vertex_size,
game.levelMesh->vertices);
glTexCoordPointer(2, GL_FLOAT, game.levelMesh->vertex_size,
game.levelMesh->vertices + 3);
glNormalPointer(GL_FLOAT, game.levelMesh->vertex_size,
game.levelMesh->vertices + 5);
for (size_t i = 0; i < game.levelMesh->object_count; i++) {
glDrawElements(GL_TRIANGLES, game.levelMesh->objects[i].face_count * 3,
GL_UNSIGNED_SHORT,
&game.levelMesh->faces[game.levelMesh->objects[i].face_index]);
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
#endif
// Restore enable bits and matrix // Restore enable bits and matrix
glPopAttrib(); glPopAttrib();
@ -450,7 +482,7 @@ void Client::update() {
draw_team(&game.teams[i]); draw_team(&game.teams[i]);
for (size_t i = 0; i < GAME_PLAYER_COUNT; i++) for (size_t i = 0; i < GAME_PLAYER_COUNT; i++)
draw_player(&game.player[i]); drawPlayer(&game.player[i]);
for (size_t i = 0; i < GAME_BOMB_COUNT; i++) for (size_t i = 0; i < GAME_BOMB_COUNT; i++)
draw_bomb(&game.bomb[i]); draw_bomb(&game.bomb[i]);
@ -458,7 +490,7 @@ void Client::update() {
for (size_t i = 0; i < GAME_POINT_COUNT; i++) for (size_t i = 0; i < GAME_POINT_COUNT; i++)
draw_point(&game.point[i]); draw_point(&game.point[i]);
draw_box(); drawLevel();
glDisable(GL_LIGHT0); glDisable(GL_LIGHT0);
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);

View File

@ -33,6 +33,9 @@ private:
void loadConsoleFont(); void loadConsoleFont();
void onExplosion(double x, double y, double z); void onExplosion(double x, double y, double z);
void drawLevel();
void drawPlayer(player_t *player);
}; };
#endif /* CLIENT_H_ */ #endif /* CLIENT_H_ */

View File

@ -9,11 +9,11 @@ add_library( common
) )
add_dependencies( common add_dependencies( common
enet pugixml bullet enet pugixml bullet trimeshloader
) )
target_link_libraries(common target_link_libraries(common
enet pugixml bullet enet pugixml bullet trimeshloader
) )
if (WIN32) if (WIN32)

View File

@ -4,6 +4,24 @@
#include <math.h> #include <math.h>
#include <stdlib.h> #include <stdlib.h>
#include "btBulletDynamicsCommon.h"
Game::Game() :
collisionConfiguration(new btDefaultCollisionConfiguration()), dispatcher(
new btCollisionDispatcher(collisionConfiguration.get())),
overlappingPairCache(new btDbvtBroadphase), solver(
new btSequentialImpulseConstraintSolver), dynamicsWorld(
new btDiscreteDynamicsWorld(dispatcher.get(),
overlappingPairCache.get(), solver.get(),
collisionConfiguration.get())), levelMesh(0) {
}
Game::~Game() {
tlDeleteTrimesh(levelMesh);
tlDeleteTrimesh(shipMesh);
}
double rand2() { double rand2() {
float u = (float) rand() / (float) RAND_MAX; float u = (float) rand() / (float) RAND_MAX;
return 2.0 * (u - 0.5); return 2.0 * (u - 0.5);
@ -76,9 +94,61 @@ void setup_bomb(bomb_t *bomb) {
bomb->z = 0.0; bomb->z = 0.0;
} }
void Game::setupLevel() {
dynamicsWorld->setGravity(btVector3(0,-10,0));
levelMesh = tlLoadTrimesh("data/level.obj", TL_FVF_XYZ | TL_FVF_UV
| TL_FVF_NORMAL);
btIndexedMesh im;
im.m_numTriangles = levelMesh->face_count;
im.m_triangleIndexBase = (unsigned char *) levelMesh->faces;
im.m_triangleIndexStride = sizeof(unsigned short) * 3;
im.m_numVertices = levelMesh->vertex_count;
im.m_vertexBase = (unsigned char *) levelMesh->vertices;
im.m_vertexStride = levelMesh->vertex_size;
levelVertexArray.reset(new btTriangleIndexVertexArray);
levelVertexArray->addIndexedMesh(im, PHY_SHORT);
btBvhTriangleMeshShape *_levelShape = new btBvhTriangleMeshShape(
levelVertexArray.get(), true);
levelShape.reset(_levelShape);
btVector3 localInertia(0, 0, 0);
btRigidBody::btRigidBodyConstructionInfo rbInfo(0, 0, _levelShape,
localInertia);
levelBody.reset(new btRigidBody(rbInfo));
dynamicsWorld->addRigidBody(levelBody.get());
// load ship
shipMesh = tlLoadTrimesh("data/ship.obj", TL_FVF_XYZ | TL_FVF_UV
| TL_FVF_NORMAL);
btIndexedMesh sim;
sim.m_numTriangles = shipMesh->face_count;
sim.m_triangleIndexBase = (unsigned char *) shipMesh->faces;
sim.m_triangleIndexStride = sizeof(unsigned short) * 3;
sim.m_numVertices = shipMesh->vertex_count;
sim.m_vertexBase = (unsigned char *) shipMesh->vertices;
sim.m_vertexStride = shipMesh->vertex_size;
shipVertexArray.reset(new btTriangleIndexVertexArray);
shipVertexArray->addIndexedMesh(im, PHY_SHORT);
btBvhTriangleMeshShape *_shipShape = new btBvhTriangleMeshShape(
shipVertexArray.get(), true);
shipShape.reset(_shipShape);
}
void Game::setup() { void Game::setup() {
size_t i; size_t i;
setupLevel();
teams.resize(2); teams.resize(2);
for (i = 0; i < teams.size(); i++) for (i = 0; i < teams.size(); i++)
setup_team(&teams[i], i); setup_team(&teams[i], i);
@ -129,6 +199,22 @@ player_t *Game::spawn_player(Team *team) {
player->status = 1; player->status = 1;
player->id = max_player_id++; player->id = max_player_id++;
reset_player(player); reset_player(player);
if (player->body.get() == 0) {
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
startTransform.setOrigin(btVector3(player->x, player->y, player->z));
btScalar mass(1.f);
btVector3 localInertia(0, 0, 0);
shipShape->calculateLocalInertia(mass, localInertia);
player->state.reset(new btDefaultMotionState());
player->state->setWorldTransform(startTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,
player->state.get(), shipShape.get(), localInertia);
player->body.reset(new btRigidBody(rbInfo));
dynamicsWorld->addRigidBody(player->body.get());
}
return player; return player;
} }
@ -154,15 +240,20 @@ void Game::update_players(double dt) {
player_t *p = &player[i]; player_t *p = &player[i];
if (p->status == 0) if (p->status == 0)
return; return;
if (p->vx > 1000.0) // if (p->vx > 1000.0)
p->vx = 1000.0; // p->vx = 1000.0;
if (p->vy > 1000.0) // if (p->vy > 1000.0)
p->vy = 1000.0; // p->vy = 1000.0;
if (p->vz > 1000.0) // if (p->vz > 1000.0)
p->vz = 1000.0; // p->vz = 1000.0;
p->x += p->vx * dt; // p->x += p->vx * dt;
p->y += p->vy * dt; // p->y += p->vy * dt;
p->z += p->vz * dt; // p->z += p->vz * dt;
btTransform wt;
p->state->getWorldTransform(wt);
p->x = wt.getOrigin().x();
p->y = wt.getOrigin().y();
p->z = wt.getOrigin().z();
double distance2 = pow(p->x - p->team->x, 2) double distance2 = pow(p->x - p->team->x, 2)
+ pow(p->y - p->team->y, 2) + pow(p->z - p->team->z, 2); + pow(p->y - p->team->y, 2) + pow(p->z - p->team->z, 2);
@ -296,6 +387,8 @@ void Game::update_points(double dt) {
} }
void Game::update(double dt) { void Game::update(double dt) {
dynamicsWorld->stepSimulation(dt,10);
const double delta = 1. / 120.; const double delta = 1. / 120.;
updateTime += dt; updateTime += dt;
while (updateTime > delta) { while (updateTime > delta) {

View File

@ -3,8 +3,21 @@
#include "common.h" #include "common.h"
#include "sigslot.h" #include "sigslot.h"
#include "trimeshloader.h"
#include <vector> #include <vector>
#include <memory>
// bullet forward declatations
class btDefaultCollisionConfiguration;
class btCollisionDispatcher;
class btBroadphaseInterface;
class btSequentialImpulseConstraintSolver;
class btDiscreteDynamicsWorld;
class btCollisionShape;
class btTriangleIndexVertexArray;
class btRigidBody;
class btMotionState;
typedef struct Team Team; typedef struct Team Team;
typedef struct player_t player_t; typedef struct player_t player_t;
@ -22,6 +35,8 @@ struct player_t {
double vx, vy, vz; double vx, vy, vz;
Team *team; Team *team;
uint16_t points; uint16_t points;
std::auto_ptr<btMotionState> state;
std::auto_ptr<btRigidBody> body;
}; };
struct bomb_t { struct bomb_t {
@ -47,6 +62,9 @@ public:
class Game { class Game {
public: public:
Game();
~Game();
std::vector<Team> teams; std::vector<Team> teams;
player_t player[GAME_PLAYER_COUNT]; player_t player[GAME_PLAYER_COUNT];
bomb_t bomb[GAME_BOMB_COUNT]; bomb_t bomb[GAME_BOMB_COUNT];
@ -76,6 +94,25 @@ public:
void explode_bomb(bomb_t *bomb); void explode_bomb(bomb_t *bomb);
void update_point(point_t *point); void update_point(point_t *point);
size_t active_team_players(Team *team); size_t active_team_players(Team *team);
tlTrimesh *levelMesh;
tlTrimesh *shipMesh;
private:
void setupLevel();
const std::auto_ptr<btDefaultCollisionConfiguration> collisionConfiguration;
const std::auto_ptr<btCollisionDispatcher> dispatcher;
const std::auto_ptr<btBroadphaseInterface> overlappingPairCache;
const std::auto_ptr<btSequentialImpulseConstraintSolver> solver;
const std::auto_ptr<btDiscreteDynamicsWorld> dynamicsWorld;
std::auto_ptr<btTriangleIndexVertexArray> levelVertexArray;
std::auto_ptr<btCollisionShape> levelShape;
std::auto_ptr<btRigidBody> levelBody;
std::auto_ptr<btTriangleIndexVertexArray> shipVertexArray;
std::auto_ptr<btCollisionShape> shipShape;
}; };
#endif #endif