@@ -109,7 +109,7 @@ BtPhysTest::BtPhysTest(bool editor) | |||||
if (USE_PLATFORM) | if (USE_PLATFORM) | ||||
{ | { | ||||
quat NewRotation = quat::fromeuler_xyz(5.f, 0.f, 0.f); | |||||
quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f); | |||||
vec3 NewPosition = pos_offset + vec3(5.0f, -25.0f, -15.0f); | vec3 NewPosition = pos_offset + vec3(5.0f, -25.0f, -15.0f); | ||||
PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1); | PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1); | ||||
@@ -119,8 +119,32 @@ BtPhysTest::BtPhysTest(bool editor) | |||||
NewPosition = pos_offset + vec3(-20.0f, -25.0f, 5.0f); | NewPosition = pos_offset + vec3(-20.0f, -25.0f, 5.0f); | ||||
NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1); | |||||
PhysicsObject* BasePhyobj = NewPhyobj; | |||||
m_platform_list << NewPhyobj; | |||||
Ticker::Ref(NewPhyobj); | |||||
NewRotation = quat::fromeuler_xyz(0.f, 0.f, 90.f); | |||||
NewPosition = pos_offset + vec3(-25.0f, -25.0f, 5.0f); | |||||
NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1); | |||||
NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, true); | |||||
m_platform_list << NewPhyobj; | |||||
Ticker::Ref(NewPhyobj); | |||||
NewPosition += vec3(-0.0f, .0f, .0f); | |||||
NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1); | NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1); | ||||
NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, false); | |||||
m_platform_list << NewPhyobj; | |||||
Ticker::Ref(NewPhyobj); | |||||
NewPosition += vec3(-2.0f, .0f, .0f); | |||||
NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1); | |||||
NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), false, false); | |||||
m_platform_list << NewPhyobj; | m_platform_list << NewPhyobj; | ||||
Ticker::Ref(NewPhyobj); | Ticker::Ref(NewPhyobj); | ||||
} | } | ||||
@@ -128,7 +152,7 @@ BtPhysTest::BtPhysTest(bool editor) | |||||
if (USE_CHARACTER) | if (USE_CHARACTER) | ||||
{ | { | ||||
quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f); | quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f); | ||||
vec3 NewPosition = pos_offset + vec3(.0f, 20.0f, .0f); | |||||
vec3 NewPosition = pos_offset + vec3(-15.0f, 20.0f, .0f); | |||||
PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 2); | PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 2); | ||||
@@ -180,151 +204,6 @@ BtPhysTest::BtPhysTest(bool editor) | |||||
} | } | ||||
} | } | ||||
} | } | ||||
#if 0 | |||||
//init Physics | |||||
{ | |||||
m_bt_ccd_mode = USE_CCD; | |||||
//collision configuration contains default setup for memory, collision setup | |||||
m_bt_collision_config = new btDefaultCollisionConfiguration(); | |||||
//use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) | |||||
m_bt_dispatcher = new btCollisionDispatcher(m_bt_collision_config); | |||||
m_bt_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE, | |||||
BOX_SHAPE_PROXYTYPE, | |||||
m_bt_collision_config->getCollisionAlgorithmCreateFunc(CONVEX_SHAPE_PROXYTYPE, | |||||
CONVEX_SHAPE_PROXYTYPE)); | |||||
m_bt_broadphase = new btDbvtBroadphase(); | |||||
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) | |||||
m_bt_solver = new btSequentialImpulseConstraintSolver; | |||||
m_bt_world = new btDiscreteDynamicsWorld(m_bt_dispatcher, m_bt_broadphase, m_bt_solver, m_bt_collision_config); | |||||
//m_bt_world->setDebugDrawer(&sDebugDrawer); | |||||
m_bt_world->getSolverInfo().m_splitImpulse = true; | |||||
m_bt_world->getSolverInfo().m_numIterations = 20; | |||||
m_bt_world->getDispatchInfo().m_useContinuous = (m_bt_ccd_mode == USE_CCD); | |||||
m_bt_world->setGravity(btVector3(0,-10,0)); | |||||
///create a few basic rigid bodies | |||||
btBoxShape* box = new btBoxShape(btVector3(btScalar(110.),btScalar(1.),btScalar(110.))); | |||||
btCollisionShape* groundShape = box; | |||||
m_bt_collision_shapes << groundShape; | |||||
m_ground_mesh.Compile("[sc#ddd afcb220 2 220 -1]"); | |||||
//m_bt_collision_shapes << new btCylinderShape(btVector3(.5f,.5f,.5f)); | |||||
btTransform groundTransform; | |||||
groundTransform.setIdentity(); | |||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: | |||||
{ | |||||
btScalar mass(0.); | |||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static | |||||
bool isDynamic = (mass != 0.f); | |||||
btVector3 localInertia(0,0,0); | |||||
if (isDynamic) | |||||
groundShape->calculateLocalInertia(mass,localInertia); | |||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects | |||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); | |||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); | |||||
btRigidBody* body = new btRigidBody(rbInfo); | |||||
//add the body to the dynamics world | |||||
m_bt_world->addRigidBody(body); | |||||
} | |||||
//Adding Shapes | |||||
{ | |||||
//create a few dynamic rigidbodies | |||||
// Re-using the same collision is better for memory usage and performance | |||||
btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1)); | |||||
m_rigid_mesh[0].Compile("[sc#add afcb2 2 2 -.1]"); | |||||
m_rigid_mesh[1].Compile("[sc#dad afcb2 2 2 -.1]"); | |||||
m_rigid_mesh[2].Compile("[sc#dda afcb2 2 2 -.1]"); | |||||
m_rigid_mesh[3].Compile("[sc#daa afcb2 2 2 -.1]"); | |||||
m_rigid_mesh[4].Compile("[sc#ada afcb2 2 2 -.1]"); | |||||
m_rigid_mesh[5].Compile("[sc#aad afcb2 2 2 -.1]"); | |||||
m_bt_collision_shapes << colShape; | |||||
m_bt_dynamic_shapes << colShape; | |||||
/// Create Dynamic Objects | |||||
btTransform startTransform; | |||||
startTransform.setIdentity(); | |||||
btScalar mass(1.f); | |||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static | |||||
bool isDynamic = (mass != 0.f); | |||||
btVector3 localInertia(0,0,0); | |||||
if (isDynamic) | |||||
colShape->calculateLocalInertia(mass,localInertia); | |||||
int i; | |||||
for (i=0;i<gNumObjects;i++) | |||||
{ | |||||
btCollisionShape* shape = colShape; | |||||
btTransform trans; | |||||
trans.setIdentity(); | |||||
//stack them | |||||
int colsize = 10; | |||||
int row = int(((float)i*CUBE_HALF_EXTENTS*2.0f)/((float)colsize*2.0f*CUBE_HALF_EXTENTS)); | |||||
int row2 = row; | |||||
int col = (i)%(colsize)-colsize/2; | |||||
if (col>3) | |||||
{ | |||||
col=11; | |||||
row2 |=1; | |||||
} | |||||
btVector3 pos(((row+col+row2) % 4)*CUBE_HALF_EXTENTS, | |||||
20.0f + row*8*CUBE_HALF_EXTENTS+CUBE_HALF_EXTENTS+EXTRA_HEIGHT, | |||||
col*8*CUBE_HALF_EXTENTS + 2 * (row2%2)*CUBE_HALF_EXTENTS); | |||||
trans.setOrigin(pos); | |||||
float mass = 1.f; | |||||
btAssert((!shape || shape->getShapeType() != INVALID_SHAPE_PROXYTYPE)); | |||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static | |||||
bool isDynamic = (mass != 0.f); | |||||
btVector3 localInertia(0,0,0); | |||||
if (isDynamic) | |||||
shape->calculateLocalInertia(mass,localInertia); | |||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects | |||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(trans); | |||||
btRigidBody::btRigidBodyConstructionInfo cInfo(mass,myMotionState,shape,localInertia); | |||||
btRigidBody* body = new btRigidBody(cInfo); | |||||
body->setContactProcessingThreshold(BT_LARGE_FLOAT); | |||||
m_bt_world->addRigidBody(body); | |||||
///when using m_ccdMode | |||||
if (m_bt_ccd_mode == USE_CCD) | |||||
{ | |||||
body->setCcdMotionThreshold(CUBE_HALF_EXTENTS); | |||||
body->setCcdSweptSphereRadius(0.9*CUBE_HALF_EXTENTS); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
#endif | |||||
} | } | ||||
void BtPhysTest::TickGame(float seconds) | void BtPhysTest::TickGame(float seconds) | ||||
@@ -334,6 +213,10 @@ void BtPhysTest::TickGame(float seconds) | |||||
if (Input::GetButtonState(27 /*SDLK_ESCAPE*/)) | if (Input::GetButtonState(27 /*SDLK_ESCAPE*/)) | ||||
Ticker::Shutdown(); | Ticker::Shutdown(); | ||||
m_loop_value += seconds; | |||||
if (m_loop_value > M_PI * 2.0f) | |||||
m_loop_value -= M_PI * 2.0f; | |||||
vec3 GroundBarycenter = vec3(.0f); | vec3 GroundBarycenter = vec3(.0f); | ||||
vec3 PhysObjBarycenter = vec3(.0f); | vec3 PhysObjBarycenter = vec3(.0f); | ||||
float factor = .0f; | float factor = .0f; | ||||
@@ -395,11 +278,10 @@ void BtPhysTest::TickGame(float seconds) | |||||
GroundMat = GroundMat * mat4(quat::fromeuler_xyz(vec3(20.f, .0f, .0f) * seconds)); | GroundMat = GroundMat * mat4(quat::fromeuler_xyz(vec3(20.f, .0f, .0f) * seconds)); | ||||
PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat)); | PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat)); | ||||
} | } | ||||
else | |||||
else if (i == 1) | |||||
{ | { | ||||
GroundMat = GroundMat * mat4::translate(vec3(.0f, .0f, 10.0f) * seconds); | |||||
if (GroundMat.v3.z > 40.0f) | |||||
GroundMat = GroundMat * mat4::translate(vec3(.0f, .0f, -80.0f)); | |||||
GroundMat = mat4::translate(vec3(-15.0f, 5.0f, lol::cos(m_loop_value) * 8.f)) * | |||||
mat4(quat::fromeuler_xyz(vec3(.0f, lol::cos(m_loop_value) * 20.f, .0f))); | |||||
PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat)); | PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat)); | ||||
} | } | ||||
} | } | ||||
@@ -458,17 +340,6 @@ void BtPhysTest::TickGame(float seconds) | |||||
m_camera->SetPosition(GroundBarycenter + normalize(GroundBarycenter - PhysObjBarycenter) * 60.0f); | m_camera->SetPosition(GroundBarycenter + normalize(GroundBarycenter - PhysObjBarycenter) * 60.0f); | ||||
} | } | ||||
#if 0 | |||||
///step the simulation | |||||
if (m_bt_world) | |||||
{ | |||||
//int steps = (int)(seconds / 0.005f); | |||||
//for (int i = 0; i < steps; i++) | |||||
m_bt_world->stepSimulation(seconds /*/ steps*/); | |||||
//optional but useful: debug drawing | |||||
//m_bt_world->debugDrawWorld(); | |||||
} | |||||
#endif | |||||
} | } | ||||
void BtPhysTest::TickDraw(float seconds) | void BtPhysTest::TickDraw(float seconds) | ||||
@@ -477,59 +348,12 @@ void BtPhysTest::TickDraw(float seconds) | |||||
if (!m_ready) | if (!m_ready) | ||||
{ | { | ||||
#if 0 | |||||
m_ground_mesh.MeshConvert(); | |||||
m_rigid_mesh[0].MeshConvert(); | |||||
m_rigid_mesh[1].MeshConvert(); | |||||
m_rigid_mesh[2].MeshConvert(); | |||||
m_rigid_mesh[3].MeshConvert(); | |||||
m_rigid_mesh[4].MeshConvert(); | |||||
m_rigid_mesh[5].MeshConvert(); | |||||
#endif | |||||
/* FIXME: this object never cleans up */ | /* FIXME: this object never cleans up */ | ||||
m_ready = true; | m_ready = true; | ||||
} | } | ||||
//Video::SetClearColor(vec4(0.0f, 0.0f, 0.12f, 1.0f)); | //Video::SetClearColor(vec4(0.0f, 0.0f, 0.12f, 1.0f)); | ||||
#if 0 | |||||
vec3 BarycenterLocation = vec3(.0f); | |||||
float BarycenterFactor = 0.0f; | |||||
for(int i=0;i<gNumObjects;i++) | |||||
{ | |||||
mat4 m(1.0f); | |||||
btMatrix3x3 rot; rot.setIdentity(); | |||||
btCollisionObject* colObj = m_bt_world->getCollisionObjectArray()[i]; | |||||
btRigidBody* body = btRigidBody::upcast(colObj); | |||||
if(body && body->getMotionState()) | |||||
{ | |||||
btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState(); | |||||
myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(&m[0][0]); | |||||
rot = myMotionState->m_graphicsWorldTrans.getBasis(); | |||||
} | |||||
else | |||||
{ | |||||
colObj->getWorldTransform().getOpenGLMatrix(&m[0][0]); | |||||
rot = colObj->getWorldTransform().getBasis(); | |||||
} | |||||
if (i > 0) | |||||
{ | |||||
BarycenterLocation += m.v3.xyz; | |||||
BarycenterFactor += 1.0f; | |||||
} | |||||
if (i == 0) | |||||
m_ground_mesh.Render(m); | |||||
else | |||||
m_rigid_mesh[i % 6].Render(m); | |||||
} | |||||
if (BarycenterFactor > .0f) | |||||
{ | |||||
BarycenterLocation /= BarycenterFactor; | |||||
m_camera->SetTarget(BarycenterLocation); | |||||
m_camera->SetPosition(BarycenterLocation + vec3(-20.0f, 8.0f, .0f)); | |||||
} | |||||
#endif | |||||
} | } | ||||
BtPhysTest::~BtPhysTest() | BtPhysTest::~BtPhysTest() | ||||
@@ -573,37 +397,6 @@ BtPhysTest::~BtPhysTest() | |||||
} | } | ||||
Ticker::Unref(m_simulation); | Ticker::Unref(m_simulation); | ||||
#if 0 | |||||
//Exit Physics | |||||
{ | |||||
//cleanup in the reverse order of creation/initialization | |||||
//remove the rigidbodies from the dynamics world and delete them | |||||
for (int i = m_bt_world->getNumCollisionObjects() - 1; i >= 0 ;i--) | |||||
{ | |||||
btCollisionObject* obj = m_bt_world->getCollisionObjectArray()[i]; | |||||
btRigidBody* body = btRigidBody::upcast(obj); | |||||
if (body && body->getMotionState()) | |||||
delete body->getMotionState(); | |||||
m_bt_world->removeCollisionObject(obj); | |||||
delete obj; | |||||
} | |||||
//delete collision shapes | |||||
for (int j = 0; j < m_bt_collision_shapes.Count(); j++) | |||||
{ | |||||
btCollisionShape* shape = m_bt_collision_shapes[j]; | |||||
delete shape; | |||||
} | |||||
m_bt_collision_shapes.Empty(); | |||||
delete m_bt_world; | |||||
delete m_bt_solver; | |||||
delete m_bt_broadphase; | |||||
delete m_bt_dispatcher; | |||||
delete m_bt_collision_config; | |||||
} | |||||
#endif | |||||
} | } | ||||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||||
@@ -31,25 +31,7 @@ private: | |||||
Array<PhysicsObject*> m_platform_list; | Array<PhysicsObject*> m_platform_list; | ||||
Array<PhysicsObject*> m_character_list; | Array<PhysicsObject*> m_character_list; | ||||
#if 0 | |||||
EasyMesh m_ground_mesh; | |||||
EasyMesh m_rigid_mesh[6]; | |||||
//Bullet Physics Datas | |||||
enum | |||||
{ | |||||
USE_CCD=1, | |||||
USE_NO_CCD | |||||
}; | |||||
int m_bt_ccd_mode; | |||||
btDefaultCollisionConfiguration* m_bt_collision_config; | |||||
btCollisionDispatcher* m_bt_dispatcher; | |||||
btDbvtBroadphase* m_bt_broadphase; | |||||
btSequentialImpulseConstraintSolver* m_bt_solver; | |||||
btDiscreteDynamicsWorld* m_bt_world; | |||||
Array<btCollisionShape*> m_bt_collision_shapes; | |||||
Array<btCollisionShape*> m_bt_dynamic_shapes; | |||||
#endif | |||||
float m_loop_value; | |||||
}; | }; | ||||
#endif // __BTPHYSTEST_H__ | #endif // __BTPHYSTEST_H__ | ||||
@@ -26,32 +26,37 @@ public: | |||||
PhysicsObject(Simulation* new_sim, const vec3 &base_location, const quat &base_rotation) | PhysicsObject(Simulation* new_sim, const vec3 &base_location, const quat &base_rotation) | ||||
: m_ready(false), m_should_render(true), m_is_character(false) | : m_ready(false), m_should_render(true), m_is_character(false) | ||||
{ | { | ||||
m_physics = new EasyPhysic(this); | |||||
m_mesh.Compile("[sc#ddd afcb60 1 60 -.1]"); | m_mesh.Compile("[sc#ddd afcb60 1 60 -.1]"); | ||||
vec3 BoxSize = vec3(60.f, 1.f, 60.f); | vec3 BoxSize = vec3(60.f, 1.f, 60.f); | ||||
m_physics.SetCollisionChannel(0, 0xFF); | |||||
m_physics.SetShapeToBox(BoxSize); | |||||
m_physics.SetMass(.0f); | |||||
m_physics.SetTransform(base_location, base_rotation); | |||||
m_physics.InitBodyToRigid(true); | |||||
m_physics.AddToSimulation(new_sim); | |||||
m_physics->SetCollisionChannel(0, 0xFF); | |||||
m_physics->SetShapeToBox(BoxSize); | |||||
m_physics->SetMass(.0f); | |||||
m_physics->SetTransform(base_location, base_rotation); | |||||
m_physics->InitBodyToRigid(true); | |||||
m_physics->AddToSimulation(new_sim); | |||||
} | } | ||||
PhysicsObject(Simulation* new_sim, const vec3 &base_location, const quat &base_rotation, int dummy) | PhysicsObject(Simulation* new_sim, const vec3 &base_location, const quat &base_rotation, int dummy) | ||||
: m_ready(false), m_should_render(true), m_is_character(false) | : m_ready(false), m_should_render(true), m_is_character(false) | ||||
{ | { | ||||
if (dummy == 1) //for Rope purpose | |||||
if (dummy == 1) //for platform purpose | |||||
{ | { | ||||
m_physics = new EasyPhysic(this); | |||||
m_mesh.Compile("[sc#ddd afcb20 1 20 -.1]"); | m_mesh.Compile("[sc#ddd afcb20 1 20 -.1]"); | ||||
vec3 BoxSize = vec3(20.f, 1.f, 20.f); | vec3 BoxSize = vec3(20.f, 1.f, 20.f); | ||||
m_physics.SetCollisionChannel(0, 0xFF); | |||||
m_physics.SetShapeToBox(BoxSize); | |||||
m_physics.SetMass(.0f); | |||||
m_physics.SetTransform(base_location, base_rotation); | |||||
m_physics.InitBodyToRigid(true); | |||||
m_physics.AddToSimulation(new_sim); | |||||
m_physics->SetCollisionChannel(0, 0xFF); | |||||
m_physics->SetShapeToBox(BoxSize); | |||||
m_physics->SetMass(.0f); | |||||
m_physics->SetTransform(base_location, base_rotation); | |||||
m_physics->InitBodyToRigid(true); | |||||
m_physics->AddToSimulation(new_sim); | |||||
} | } | ||||
else if (dummy == 2) //for character purpose | else if (dummy == 2) //for character purpose | ||||
{ | { | ||||
m_character = new EasyCharacterController(this); | |||||
m_is_character = true; | m_is_character = true; | ||||
//m_mesh.Compile("[sc#f00 afcb10 10 10 -.1]"); | //m_mesh.Compile("[sc#f00 afcb10 10 10 -.1]"); | ||||
m_mesh.Compile( | m_mesh.Compile( | ||||
@@ -77,12 +82,12 @@ public: | |||||
" ty-.1 tx.05]" | " ty-.1 tx.05]" | ||||
); | ); | ||||
vec3 BoxSize = vec3(.5f, 2.f, .5f); | vec3 BoxSize = vec3(.5f, 2.f, .5f); | ||||
m_character.SetCollisionChannel(0, 0xFF); | |||||
m_character.SetShapeToCapsule(BoxSize.x, BoxSize.y); | |||||
m_character.SetMass(.0f); | |||||
m_character.SetTransform(base_location, base_rotation); | |||||
m_character.InitBodyToGhost(); | |||||
m_character.AddToSimulation(new_sim); | |||||
m_character->SetCollisionChannel(0, 0xFF); | |||||
m_character->SetShapeToCapsule(BoxSize.x, BoxSize.y); | |||||
m_character->SetMass(.0f); | |||||
m_character->SetTransform(base_location, base_rotation); | |||||
m_character->InitBodyToGhost(); | |||||
m_character->AddToSimulation(new_sim); | |||||
} | } | ||||
} | } | ||||
@@ -167,57 +172,67 @@ public: | |||||
} | } | ||||
} | } | ||||
m_physics = new EasyPhysic(this); | |||||
m_mesh.Compile(MeshRand[RandValue]); | m_mesh.Compile(MeshRand[RandValue]); | ||||
vec3 BoxSize = vec3(2.0f); | vec3 BoxSize = vec3(2.0f); | ||||
int ColGroup = 1; | int ColGroup = 1; | ||||
if (RandValue < SphereLimit) | if (RandValue < SphereLimit) | ||||
{ | { | ||||
m_physics.SetShapeToBox(BoxSize); | |||||
m_physics->SetShapeToBox(BoxSize); | |||||
ColGroup += 0; | ColGroup += 0; | ||||
} | } | ||||
else if (RandValue < ConeLimit) | else if (RandValue < ConeLimit) | ||||
{ | { | ||||
m_physics.SetShapeToSphere(BoxSize.x * 2.f); | |||||
m_physics->SetShapeToSphere(BoxSize.x * 2.f); | |||||
ColGroup += 1; | ColGroup += 1; | ||||
} | } | ||||
else if (RandValue < CylLimit) | else if (RandValue < CylLimit) | ||||
{ | { | ||||
m_physics.SetShapeToCone(BoxSize.x, BoxSize.y); | |||||
m_physics->SetShapeToCone(BoxSize.x, BoxSize.y); | |||||
ColGroup += 2; | ColGroup += 2; | ||||
} | } | ||||
else if (RandValue < CapsLimit) | else if (RandValue < CapsLimit) | ||||
{ | { | ||||
m_physics.SetShapeToCylinder(BoxSize); | |||||
m_physics->SetShapeToCylinder(BoxSize); | |||||
ColGroup += 3; | ColGroup += 3; | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
m_physics.SetShapeToCapsule(BoxSize.x, BoxSize.y); | |||||
m_physics->SetShapeToCapsule(BoxSize.x, BoxSize.y); | |||||
ColGroup += 4; | ColGroup += 4; | ||||
} | } | ||||
m_physics.SetCollisionChannel(0, 0xFF); | |||||
//m_physics.SetCollisionChannel(ColGroup, (1<<ColGroup)|(1)); | |||||
m_physics.SetMass(base_mass); | |||||
m_physics.SetTransform(base_location); | |||||
m_physics.InitBodyToRigid(); | |||||
m_physics.AddToSimulation(new_sim); | |||||
m_physics->SetCollisionChannel(0, 0xFF); | |||||
//m_physics->SetCollisionChannel(ColGroup, (1<<ColGroup)|(1)); | |||||
m_physics->SetMass(base_mass); | |||||
m_physics->SetTransform(base_location); | |||||
m_physics->InitBodyToRigid(); | |||||
m_physics->AddToSimulation(new_sim); | |||||
} | } | ||||
void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f))) | void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f))) | ||||
{ | { | ||||
if (m_is_character) | if (m_is_character) | ||||
m_character.SetTransform(base_location, base_rotation); | |||||
m_character->SetTransform(base_location, base_rotation); | |||||
else | else | ||||
m_physics.SetTransform(base_location, base_rotation); | |||||
m_physics->SetTransform(base_location, base_rotation); | |||||
} | |||||
void SetLinearVelocity(const lol::vec3& NewVelocity, bool bIsLocal=false) | |||||
{ | |||||
//if (m_is_character) | |||||
// m_character->SetLinearVelocity(NewVelocity); | |||||
//else | |||||
// m_physics->SetLinearVelocity(NewVelocity); | |||||
} | } | ||||
lol::mat4 GetTransform() | lol::mat4 GetTransform() | ||||
{ | { | ||||
if (m_is_character) | if (m_is_character) | ||||
return m_character.GetTransform(); | |||||
return m_character->GetTransform(); | |||||
else | else | ||||
return m_physics.GetTransform(); | |||||
return m_physics->GetTransform(); | |||||
} | } | ||||
void SetRender(bool should_render) | void SetRender(bool should_render) | ||||
@@ -226,8 +241,8 @@ public: | |||||
} | } | ||||
EasyMesh *GetMesh() { return &m_mesh; } | EasyMesh *GetMesh() { return &m_mesh; } | ||||
EasyPhysic *GetPhysic() { return &m_physics; } | |||||
EasyPhysic *GetCharacter() { return &m_character; } | |||||
EasyPhysic *GetPhysic() { return m_physics; } | |||||
EasyPhysic *GetCharacter() { return m_character; } | |||||
~PhysicsObject() | ~PhysicsObject() | ||||
{ | { | ||||
@@ -254,21 +269,21 @@ protected: | |||||
if (m_should_render) | if (m_should_render) | ||||
{ | { | ||||
if (m_is_character) | if (m_is_character) | ||||
m_mesh.Render(m_character.GetTransform()); | |||||
m_mesh.Render(m_character->GetTransform()); | |||||
else | else | ||||
m_mesh.Render(m_physics.GetTransform()); | |||||
m_mesh.Render(m_physics->GetTransform()); | |||||
} | } | ||||
} | } | ||||
private: | private: | ||||
//Base datas | //Base datas | ||||
EasyMesh m_mesh; | |||||
EasyPhysic m_physics; | |||||
EasyCharacterController m_character; | |||||
EasyMesh m_mesh; | |||||
EasyPhysic* m_physics; | |||||
EasyCharacterController* m_character; | |||||
bool m_ready; | |||||
bool m_should_render; | |||||
bool m_is_character; | |||||
bool m_ready; | |||||
bool m_should_render; | |||||
bool m_is_character; | |||||
}; | }; | ||||
#endif /* __PHYSICOBJECT_H__ */ | #endif /* __PHYSICOBJECT_H__ */ | ||||
@@ -35,8 +35,8 @@ class EasyCharacterController : public EasyPhysic | |||||
#ifdef HAVE_PHYS_USE_BULLET | #ifdef HAVE_PHYS_USE_BULLET | ||||
public: | public: | ||||
EasyCharacterController() : | |||||
EasyPhysic(), | |||||
EasyCharacterController(WorldEntity* NewOwnerEntity) : | |||||
EasyPhysic(NewOwnerEntity), | |||||
m_character(NULL) | m_character(NULL) | ||||
{ | { | ||||
m_up_axis = 1; | m_up_axis = 1; | ||||
@@ -38,7 +38,7 @@ class EasyPhysic | |||||
#ifdef HAVE_PHYS_USE_BULLET | #ifdef HAVE_PHYS_USE_BULLET | ||||
public: | public: | ||||
EasyPhysic(); | |||||
EasyPhysic(WorldEntity* NewOwnerEntity); | |||||
~EasyPhysic(); | ~EasyPhysic(); | ||||
virtual void SetShapeToBox(lol::vec3& box_size); | virtual void SetShapeToBox(lol::vec3& box_size); | ||||
@@ -49,6 +49,9 @@ public: | |||||
virtual bool CanChangeCollisionChannel() { return (m_rigid_body == NULL); } | virtual bool CanChangeCollisionChannel() { return (m_rigid_body == NULL); } | ||||
virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f))); | virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f))); | ||||
private: | |||||
virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix); | |||||
public: | |||||
virtual void SetMass(float mass); | virtual void SetMass(float mass); | ||||
virtual void InitBodyToRigid(bool ZeroMassIsKinematic=false); | virtual void InitBodyToRigid(bool ZeroMassIsKinematic=false); | ||||
virtual void InitBodyToGhost(); | virtual void InitBodyToGhost(); | ||||
@@ -76,7 +79,7 @@ protected: | |||||
#else // NO PHYSIC IMPLEMENTATION | #else // NO PHYSIC IMPLEMENTATION | ||||
public: | public: | ||||
EasyPhysic() { } | |||||
EasyPhysic(WorldEntity* NewOwnerEntity) { m_owner_entity = NewOwnerEntity; } | |||||
virtual void SetShapeToBox(lol::vec3& BoxSize) { } | virtual void SetShapeToBox(lol::vec3& BoxSize) { } | ||||
virtual void SetShapeToSphere(float radius) { } | virtual void SetShapeToSphere(float radius) { } | ||||
@@ -86,6 +89,9 @@ public: | |||||
virtual bool CanChangeCollisionChannel() { return true; } | virtual bool CanChangeCollisionChannel() { return true; } | ||||
virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f))) { } | virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f))) { } | ||||
private: | |||||
virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix) { } | |||||
public: | |||||
virtual void SetMass(float mass) { } | virtual void SetMass(float mass) { } | ||||
virtual void InitBodyToRigid() { } | virtual void InitBodyToRigid() { } | ||||
virtual void InitBodyToGhost() { } | virtual void InitBodyToGhost() { } | ||||
@@ -113,11 +119,48 @@ public: | |||||
int GetCollisionGroup() { return m_collision_group; } | int GetCollisionGroup() { return m_collision_group; } | ||||
int GetCollisionMask() { return m_collision_mask; } | int GetCollisionMask() { return m_collision_mask; } | ||||
//Base/Attachment logic | |||||
virtual void AttachTo(EasyPhysic* NewBase, bool NewBaseLockLocation = true, bool NewBaseLockRotation = true) | |||||
{ | |||||
if (NewBase == this || NewBase->m_base_physic == this) | |||||
return; | |||||
if (NewBase) | |||||
{ | |||||
bool bAlreadyExists = false; | |||||
for (int i = 0; i < NewBase->m_based_physic_list.Count(); ++i) | |||||
if (NewBase->m_based_physic_list[i] == this) | |||||
bAlreadyExists = true; | |||||
if (!bAlreadyExists) | |||||
NewBase->m_based_physic_list << this; | |||||
m_base_physic = NewBase; | |||||
m_base_lock_location = NewBaseLockLocation; | |||||
m_base_lock_rotation = NewBaseLockRotation; | |||||
} | |||||
else | |||||
{ | |||||
for (int i = 0; i < NewBase->m_based_physic_list.Count(); ++i) | |||||
if (NewBase->m_based_physic_list[i] == this) | |||||
NewBase->m_based_physic_list.Remove(i--); | |||||
m_base_physic = NULL; | |||||
} | |||||
} | |||||
protected: | protected: | ||||
lol::mat4 m_local_to_world; | lol::mat4 m_local_to_world; | ||||
float m_mass; | float m_mass; | ||||
int m_collision_group; | int m_collision_group; | ||||
int m_collision_mask; | int m_collision_mask; | ||||
WorldEntity* m_owner_entity; | |||||
//Base/Attachment logic | |||||
Array<EasyPhysic*> m_based_physic_list; //List of objects based on this : this object moves, its based object move with it. | |||||
EasyPhysic* m_base_physic; //Base for this object : The base moves, the object moves with it. | |||||
bool m_base_lock_location; //when this is TRUE, location moves with rotation change. | |||||
bool m_base_lock_rotation; //when this is TRUE, rotation moves with rotation change. | |||||
//Touch logic | |||||
Array<EasyPhysic*> m_touching_physic; //Maintained by ghost objects | |||||
}; | }; | ||||
} /* namespace phys */ | } /* namespace phys */ | ||||
@@ -29,7 +29,7 @@ namespace phys | |||||
//EASY_PHYSIC | //EASY_PHYSIC | ||||
//-- | //-- | ||||
EasyPhysic::EasyPhysic() : | |||||
EasyPhysic::EasyPhysic(WorldEntity* NewOwnerEntity) : | |||||
m_collision_object(NULL), | m_collision_object(NULL), | ||||
m_ghost_object(NULL), | m_ghost_object(NULL), | ||||
m_rigid_body(NULL), | m_rigid_body(NULL), | ||||
@@ -39,7 +39,8 @@ EasyPhysic::EasyPhysic() : | |||||
m_motion_state(NULL), | m_motion_state(NULL), | ||||
m_mass(.0f), | m_mass(.0f), | ||||
m_collision_group(1), | m_collision_group(1), | ||||
m_collision_mask(1) | |||||
m_collision_mask(1), | |||||
m_owner_entity(NewOwnerEntity) | |||||
{ | { | ||||
} | } | ||||
@@ -113,7 +114,8 @@ void EasyPhysic::SetShapeToCapsule(float radius, float height) | |||||
//-- | //-- | ||||
void EasyPhysic::SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation) | void EasyPhysic::SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation) | ||||
{ | { | ||||
m_local_to_world = lol::mat4::translate(base_location) * mat4(base_rotation); | |||||
lol::mat4 PreviousMatrix = m_local_to_world; | |||||
m_local_to_world = lol::mat4::translate(base_location) * lol::mat4(base_rotation); | |||||
if (m_ghost_object) | if (m_ghost_object) | ||||
m_ghost_object->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT))); | m_ghost_object->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT))); | ||||
@@ -124,6 +126,28 @@ void EasyPhysic::SetTransform(const lol::vec3& base_location, const lol::quat& b | |||||
else | else | ||||
m_motion_state = new btDefaultMotionState(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT))); | m_motion_state = new btDefaultMotionState(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT))); | ||||
} | } | ||||
for (int i = 0; i < m_based_physic_list.Count(); i++) | |||||
if (m_based_physic_list[i]) | |||||
m_based_physic_list[i]->BaseTransformChanged(PreviousMatrix, m_local_to_world); | |||||
else | |||||
m_based_physic_list.Remove(i--); | |||||
} | |||||
//Internal callback when Base transform has changed. | |||||
void EasyPhysic::BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix) | |||||
{ | |||||
mat4 PreviousMatrixLoc = ((m_base_lock_location)?(PreviousMatrix):(lol::mat4::translate(PreviousMatrix.v3.xyz))); | |||||
mat4 PreviousMatrixRot = ((m_base_lock_rotation)?(lol::mat4(lol::quat(PreviousMatrix))):(lol::mat4(1.f))); | |||||
mat4 NewMatrixLoc = ((m_base_lock_location)?(NewMatrix):(lol::mat4::translate(NewMatrix.v3.xyz))); | |||||
mat4 NewMatrixRot = ((m_base_lock_rotation)?(lol::mat4(lol::quat(NewMatrix))):(lol::mat4(1.f))); | |||||
if (m_ghost_object || (m_rigid_body->getCollisionFlags() & btCollisionObject::CF_KINEMATIC_OBJECT)) | |||||
{ | |||||
mat4 ThisMatrixLoc = NewMatrixLoc * inverse(PreviousMatrixLoc) * lol::mat4::translate(m_local_to_world.v3.xyz); | |||||
mat4 ThisMatrixRot = NewMatrixRot * inverse(PreviousMatrixRot) * lol::mat4(lol::quat(m_local_to_world)); | |||||
SetTransform(ThisMatrixLoc.v3.xyz, lol::mat4(lol::quat(ThisMatrixRot))); | |||||
} | |||||
} | } | ||||
//------------------------------------------------------------------------- | //------------------------------------------------------------------------- | ||||