initial mesh and physics support
This commit is contained in:
parent
6fcb3dbff4
commit
12153ffbea
@ -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)
|
||||||
|
|
||||||
|
7
libs/trimeshloader/CMakeLists.txt
Normal file
7
libs/trimeshloader/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
include_directories (include)
|
||||||
|
|
||||||
|
add_library (trimeshloader
|
||||||
|
src/tl3ds
|
||||||
|
src/tlobj
|
||||||
|
src/trimeshloader
|
||||||
|
)
|
36
libs/trimeshloader/Changelog.txt
Normal file
36
libs/trimeshloader/Changelog.txt
Normal 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
1252
libs/trimeshloader/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
21
libs/trimeshloader/Readme.txt
Normal file
21
libs/trimeshloader/Readme.txt
Normal 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.
|
135
libs/trimeshloader/include/tl3ds.h
Normal file
135
libs/trimeshloader/include/tl3ds.h
Normal 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
|
120
libs/trimeshloader/include/tlobj.h
Normal file
120
libs/trimeshloader/include/tlobj.h
Normal 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
|
159
libs/trimeshloader/include/trimeshloader.h
Normal file
159
libs/trimeshloader/include/trimeshloader.h
Normal 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_*/
|
909
libs/trimeshloader/src/tl3ds.c
Normal file
909
libs/trimeshloader/src/tl3ds.c
Normal 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;
|
||||||
|
}
|
1125
libs/trimeshloader/src/tlobj.c
Normal file
1125
libs/trimeshloader/src/tlobj.c
Normal file
File diff suppressed because it is too large
Load Diff
280
libs/trimeshloader/src/trimeshloader.c
Normal file
280
libs/trimeshloader/src/trimeshloader.c
Normal 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 );
|
||||||
|
}
|
@ -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);
|
||||||
|
@ -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_ */
|
||||||
|
@ -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)
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user