Add experimental code to load bullet mesh BVH from serialized file instead of calculating it on the fly, making it quite a bit faster

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@10583 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria 2012-01-07 22:06:40 +00:00
parent d7b12da059
commit 06d9359fa6
3 changed files with 73 additions and 8 deletions

View File

@ -21,6 +21,9 @@
#include "btBulletDynamicsCommon.h"
#include "modes/world.hpp"
#include "utils/constants.hpp"
#include "utils/time.hpp"
#include <fstream>
// -----------------------------------------------------------------------------
/** Constructor: Initialises all data structures with zero.
@ -70,8 +73,10 @@ void TriangleMesh::addTriangle(const btVector3 &t1, const btVector3 &t2,
// -----------------------------------------------------------------------------
/** Creates a collision body only, which can be used for raycasting, but
* has no physical properties.
* @param serialized_bhv if non-null, load the serialized bhv from file instead
* of builing it on the fly
*/
void TriangleMesh::createCollisionShape(bool create_collision_object)
void TriangleMesh::createCollisionShape(bool create_collision_object, const char* serialized_bhv)
{
if(m_triangleIndex2Material.size()==0)
{
@ -82,7 +87,51 @@ void TriangleMesh::createCollisionShape(bool create_collision_object)
return;
}
// Now convert the triangle mesh into a static rigid body
m_collision_shape = new btBvhTriangleMeshShape(&m_mesh, true);
btBvhTriangleMeshShape* bhv_triangle_mesh;
if (serialized_bhv != NULL)
{
FILE *f = fopen(serialized_bhv, "rb");
fseek(f, 0, SEEK_END);
long pos = ftell(f);
fseek(f, 0, SEEK_SET);
void* bytes = btAlignedAlloc(pos, 16);
fread(bytes, pos, 1, f);
fclose(f);
btOptimizedBvh* bhv = btOptimizedBvh::deSerializeInPlace(bytes, pos, !IS_LITTLE_ENDIAN);
bhv_triangle_mesh = new btBvhTriangleMeshShape(&m_mesh, true /* useQuantizedAabbCompression */,
false /* buildBvh */);
assert(bhv->isQuantized());
bhv_triangle_mesh->setOptimizedBvh( bhv );
// Do *NOT* free the bytes, 'deSerializeInPlace' makes the btOptimizedBvh object
// directly at this memory location
//free(bytes);
}
else
{
bhv_triangle_mesh = new btBvhTriangleMeshShape(&m_mesh, true /* useQuantizedAabbCompression */);
/*
// code to serialize triangle mesh
btOptimizedBvh* bvh = bhv_triangle_mesh->getOptimizedBvh();
unsigned int ssize = bvh->calculateSerializeBufferSize();
char* buffer = (char*)btAlignedAlloc(ssize, 16);
bool success = bvh->serialize(buffer, ssize, !IS_LITTLE_ENDIAN);
printf("serialization success = %i\n", success);
std::ofstream fileout("/tmp/btOptimizedBvh");
fileout.write(buffer, ssize);
fileout.close();
btAlignedFree(buffer);
*/
}
m_collision_shape = bhv_triangle_mesh;
m_collision_shape->setUserPointer(&m_user_pointer);
if(create_collision_object)
{
@ -91,6 +140,8 @@ void TriangleMesh::createCollisionShape(bool create_collision_object)
bt.setIdentity();
m_collision_object->setWorldTransform(bt);
}
} // createCollisionShape
// -----------------------------------------------------------------------------
@ -102,12 +153,15 @@ void TriangleMesh::createCollisionShape(bool create_collision_object)
* removed and all objects together with the track is converted again into
* a single rigid body. This avoids using irrlicht (or the graphics engine)
* for height of terrain detection).
* @param serializedBhv if non-NULL, the bhv is deserialized instead of
* being calculated on the fly
*/
void TriangleMesh::createPhysicalBody(btCollisionObject::CollisionFlags flags)
void TriangleMesh::createPhysicalBody(btCollisionObject::CollisionFlags flags,
const char* serializedBhv)
{
// We need the collision shape, but not the collision object (since
// this will be creates when the dynamics body is anyway).
createCollisionShape(/*create_collision_object*/false);
// this will be created when the dynamics body is anyway).
createCollisionShape(/*create_collision_object*/false, serializedBhv);
btTransform startTransform;
startTransform.setIdentity();
m_motion_state = new btDefaultMotionState(startTransform);

View File

@ -51,9 +51,10 @@ public:
const btVector3 &t3, const btVector3 &n1,
const btVector3 &n2, const btVector3 &n3,
const Material* m);
void createCollisionShape(bool create_collision_object=true);
void createCollisionShape(bool create_collision_object=true, const char* serialized_bhv=NULL);
void createPhysicalBody(btCollisionObject::CollisionFlags flags=
(btCollisionObject::CollisionFlags)0);
(btCollisionObject::CollisionFlags)0,
const char* serializedBhv = NULL);
void removeAll();
void removeCollisionObject();
btVector3 getInterpolatedNormal(unsigned int index,

View File

@ -881,7 +881,17 @@ bool Track::loadMainTrack(const XMLNode &root)
exit(-1);
}
m_track_mesh->createPhysicalBody();
bool use_serialized_bhv = false;
std::string serialized_bhv = file_manager->getDataDir() + "tracks/" + m_ident + "/" + m_ident + ".bvh";
if (file_manager->fileExists(serialized_bhv))
{
use_serialized_bhv = true;
}
m_track_mesh->createPhysicalBody((btCollisionObject::CollisionFlags)0,
(use_serialized_bhv ? serialized_bhv.c_str() : NULL));
m_gfx_effect_mesh->createCollisionShape();
scene_node->setMaterialFlag(video::EMF_LIGHTING, true);
scene_node->setMaterialFlag(video::EMF_GOURAUD_SHADING, true);