@@ -100,17 +100,47 @@ BtPhysTest::BtPhysTest(bool editor) | |||
m_ground_list << NewPhyobj; | |||
} | |||
for (int x=0; x < 6; x++) | |||
if (1) | |||
{ | |||
for (int y=0; y < 6; y++) | |||
for (int x=0; x < 6; x++) | |||
{ | |||
for (int z=0; z < 5; z++) | |||
for (int y=0; y < 6; y++) | |||
{ | |||
PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f, | |||
vec3(-20.f, 15.f, -20.f) + | |||
vec3(8.f * (float)x, 8.f * (float)y, 8.f * (float)z)); | |||
m_physobj_list << new_physobj; | |||
Ticker::Ref(new_physobj); | |||
for (int z=0; z < 5; z++) | |||
{ | |||
PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f, | |||
vec3(-20.f, 15.f, -20.f) + | |||
vec3(8.f * (float)x, 8.f * (float)y, 8.f * (float)z)); | |||
m_physobj_list << new_physobj; | |||
Ticker::Ref(new_physobj); | |||
} | |||
} | |||
} | |||
} | |||
if (1) | |||
{ | |||
Array<PhysicsObject*> RopeElements; | |||
for (int i = 0; i < 14; i++) | |||
{ | |||
PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f, | |||
vec3(0.f, 15.f, -20.f) + | |||
vec3(0.f, 0.f, 2.f * (float)i), 1); | |||
RopeElements << new_physobj; | |||
m_physobj_list << new_physobj; | |||
Ticker::Ref(new_physobj); | |||
if (RopeElements.Count() > 1) | |||
{ | |||
EasyConstraint* new_constraint = new EasyConstraint(); | |||
vec3 A2B = .5f * (RopeElements[i]->GetPhysic()->GetTransform().v3.xyz - | |||
RopeElements[i - 1]->GetPhysic()->GetTransform().v3.xyz); | |||
new_constraint->SetPhysObjA(RopeElements[i - 1]->GetPhysic(), lol::mat4::translate(A2B)); | |||
new_constraint->SetPhysObjB(RopeElements[i]->GetPhysic(), lol::mat4::translate(-A2B)); | |||
new_constraint->InitConstraintToPoint2Point(); | |||
new_constraint->DisableCollisionBetweenObjs(true); | |||
new_constraint->AddToSimulation(m_simulation); | |||
m_constraint_list << new_constraint; | |||
} | |||
} | |||
} | |||
@@ -298,17 +328,20 @@ void BtPhysTest::TickGame(float seconds) | |||
PhysObj->SetRender(true); | |||
} | |||
for (int i = 0; i < m_ground_list.Count(); i++) | |||
if (1) | |||
{ | |||
PhysicsObject* PhysObj = m_ground_list[i]; | |||
mat4 GroundMat = PhysObj->GetTransform(); | |||
mat4 CenterMx = mat4::translate(GroundBarycenter); | |||
GroundMat = inverse(CenterMx) * GroundMat; | |||
GroundMat = CenterMx * | |||
mat4(quat::fromeuler_xyz(vec3(.0f, 20.f, 20.0f) * seconds)) | |||
* GroundMat; | |||
PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat)); | |||
for (int i = 0; i < m_ground_list.Count(); i++) | |||
{ | |||
PhysicsObject* PhysObj = m_ground_list[i]; | |||
mat4 GroundMat = PhysObj->GetTransform(); | |||
mat4 CenterMx = mat4::translate(GroundBarycenter); | |||
GroundMat = inverse(CenterMx) * GroundMat; | |||
GroundMat = CenterMx * | |||
mat4(quat::fromeuler_xyz(vec3(.0f, 20.f, 20.0f) * seconds)) | |||
* GroundMat; | |||
PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat)); | |||
} | |||
} | |||
PhysObjBarycenter = vec3(.0f); | |||
@@ -403,16 +436,26 @@ void BtPhysTest::TickDraw(float seconds) | |||
BtPhysTest::~BtPhysTest() | |||
{ | |||
Ticker::Unref(m_camera); | |||
while (m_constraint_list.Count()) | |||
{ | |||
EasyConstraint* CurPop = m_constraint_list.Last(); | |||
m_constraint_list.Pop(); | |||
CurPop->RemoveFromSimulation(m_simulation); | |||
delete CurPop; | |||
} | |||
while (m_ground_list.Count()) | |||
{ | |||
PhysicsObject* CurPop = m_ground_list.Last(); | |||
m_ground_list.Pop(); | |||
CurPop->GetPhysic()->RemoveFromSimulation(m_simulation); | |||
Ticker::Unref(CurPop); | |||
} | |||
while (m_physobj_list.Count()) | |||
{ | |||
PhysicsObject* CurPop = m_physobj_list.Last(); | |||
m_physobj_list.Pop(); | |||
CurPop->GetPhysic()->RemoveFromSimulation(m_simulation); | |||
Ticker::Unref(CurPop); | |||
} | |||
Ticker::Unref(m_simulation); | |||
@@ -25,6 +25,7 @@ private: | |||
bool m_ready; | |||
lol::phys::Simulation* m_simulation; | |||
Array<EasyConstraint*> m_constraint_list; | |||
Array<PhysicsObject*> m_physobj_list; | |||
Array<PhysicsObject*> m_ground_list; | |||
@@ -34,7 +34,7 @@ public: | |||
m_physics.AddToSimulation(new_sim); | |||
} | |||
PhysicsObject(Simulation* new_sim, float base_mass, const vec3 &base_location) | |||
PhysicsObject(Simulation* new_sim, float base_mass, const vec3 &base_location, int RandValue = -1) | |||
: m_ready(false), m_should_render(true) | |||
{ | |||
Array<char *> MeshRand; | |||
@@ -82,7 +82,38 @@ public: | |||
MeshRand << "[sc#ada scb#ada acap3 2 1]"; | |||
MeshRand << "[sc#aad scb#aad acap3 2 1]"; | |||
int RandValue = (int)(lol::RandF() * (MeshRand.Count() - 1)); | |||
switch (RandValue) | |||
{ | |||
case 0: | |||
{ | |||
RandValue = (int)(lol::RandF() * (SphereLimit - 1)); | |||
break; | |||
} | |||
case 1: | |||
{ | |||
RandValue = SphereLimit + (int)(lol::RandF() * ((ConeLimit - SphereLimit) - 1)); | |||
break; | |||
} | |||
case 2: | |||
{ | |||
RandValue = ConeLimit + (int)(lol::RandF() * ((CylLimit - ConeLimit) - 1)); | |||
break; | |||
} | |||
case 3: | |||
{ | |||
RandValue = CylLimit + (int)(lol::RandF() * ((CapsLimit - CylLimit) - 1)); | |||
break; | |||
} | |||
case 4: | |||
{ | |||
RandValue = CapsLimit + (int)(lol::RandF() * ((MeshRand.Count() - CapsLimit) - 1)); | |||
break; | |||
} | |||
default: | |||
{ | |||
RandValue = (int)(lol::RandF() * (MeshRand.Count() - 1)); | |||
} | |||
} | |||
m_mesh.Compile(MeshRand[RandValue]); | |||
vec3 BoxSize = vec3(2.0f); | |||
@@ -113,7 +144,8 @@ public: | |||
ColGroup += 4; | |||
} | |||
m_physics.SetCollisionChannel(ColGroup, (1<<ColGroup)|(1)); | |||
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(); | |||
@@ -135,6 +167,9 @@ public: | |||
m_should_render = should_render; | |||
} | |||
EasyMesh *GetMesh() { return &m_mesh; } | |||
EasyPhysic *GetPhysic() { return &m_physics; } | |||
~PhysicsObject() | |||
{ | |||
} | |||
@@ -10,11 +10,6 @@ | |||
// http://sam.zoy.org/projects/COPYING.WTFPL for more details. | |||
// | |||
// | |||
// The EasyMesh class | |||
// ------------------ | |||
// | |||
#if defined HAVE_CONFIG_H | |||
# include "config.h" | |||
#endif | |||
@@ -30,6 +25,10 @@ namespace phys | |||
#ifdef HAVE_PHYS_USE_BULLET | |||
//------------------------------------------------------------------------- | |||
//EASY_PHYSIC | |||
//-- | |||
EasyPhysic::EasyPhysic() : | |||
m_collision_object(NULL), | |||
m_rigid_body(NULL), | |||
@@ -108,9 +107,9 @@ void EasyPhysic::SetShapeToCapsule(float radius, float height) | |||
void EasyPhysic::SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation) | |||
{ | |||
if (m_motion_state) | |||
m_motion_state->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location))); | |||
m_motion_state->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT))); | |||
else | |||
m_motion_state = new btDefaultMotionState(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location))); | |||
m_motion_state = new btDefaultMotionState(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT))); | |||
} | |||
//------------------------------------------------------------------------- | |||
@@ -156,16 +155,31 @@ void EasyPhysic::InitBodyToRigid(bool SetToKinematic) | |||
void EasyPhysic::AddToSimulation(class Simulation* current_simulation) | |||
{ | |||
btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld(); | |||
if (m_rigid_body) | |||
if (dynamics_world) | |||
{ | |||
dynamics_world->addRigidBody(m_rigid_body, m_collision_group, m_collision_mask); | |||
if (m_mass != .0f) | |||
current_simulation->AddToDynamic(this); | |||
if (m_rigid_body) | |||
{ | |||
dynamics_world->addRigidBody(m_rigid_body, m_collision_group, m_collision_mask); | |||
if (m_mass != .0f) | |||
current_simulation->AddToDynamic(this); | |||
else | |||
current_simulation->AddToStatic(this); | |||
} | |||
else | |||
current_simulation->AddToStatic(this); | |||
dynamics_world->addCollisionObject(m_collision_object, m_collision_group, m_collision_mask); | |||
} | |||
} | |||
void EasyPhysic::RemoveFromSimulation(class Simulation* current_simulation) | |||
{ | |||
btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld(); | |||
if (dynamics_world) | |||
{ | |||
if (m_rigid_body) | |||
dynamics_world->removeRigidBody(m_rigid_body); | |||
else | |||
dynamics_world->removeCollisionObject(m_collision_object); | |||
} | |||
else | |||
dynamics_world->addCollisionObject(m_collision_object, m_collision_group, m_collision_mask); | |||
} | |||
//------------------------------------------------------------------------- | |||
@@ -195,6 +209,27 @@ void EasyPhysic::SetLocalInertia(float mass) | |||
m_local_inertia = btVector3(.0f, .0f, .0f); | |||
} | |||
//------------------------------------------------------------------------- | |||
//EASY_CONSTRAINT | |||
//-- | |||
void EasyConstraint::AddToSimulation(class Simulation* current_simulation) | |||
{ | |||
btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld(); | |||
if (dynamics_world && m_typed_constraint) | |||
{ | |||
dynamics_world->addConstraint(m_typed_constraint, m_disable_a2b_collision); | |||
current_simulation->AddToConstraint(this); | |||
} | |||
} | |||
void EasyConstraint::RemoveFromSimulation(class Simulation* current_simulation) | |||
{ | |||
btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld(); | |||
if (dynamics_world, m_typed_constraint) | |||
dynamics_world->removeConstraint(m_typed_constraint); | |||
} | |||
#endif // HAVE_PHYS_USE_BULLET | |||
} /* namespace phys */ | |||
@@ -32,6 +32,8 @@ namespace phys | |||
class EasyPhysic | |||
{ | |||
friend class EasyConstraint; | |||
#ifdef HAVE_PHYS_USE_BULLET | |||
public: | |||
@@ -49,6 +51,7 @@ public: | |||
void SetMass(float mass); | |||
void InitBodyToRigid(bool ZeroMassIsKinematic=false); | |||
void AddToSimulation(class Simulation* current_simulation); | |||
void RemoveFromSimulation(class Simulation* current_simulation); | |||
mat4 GetTransform(); | |||
protected: | |||
@@ -79,6 +82,7 @@ public: | |||
void SetMass(float mass) { } | |||
void InitBodyToRigid() { } | |||
void AddToSimulation(class Simulation* current_simulation) { } | |||
void RemoveFromSimulation(class Simulation* current_simulation) { } | |||
mat4 GetTransform() { return mat4(1.0f); } | |||
#endif // PHYSIC IMPLEMENTATION | |||
@@ -108,23 +112,176 @@ protected: | |||
class EasyConstraint | |||
{ | |||
EasyConstraint() | |||
#ifdef HAVE_PHYS_USE_BULLET | |||
public: | |||
EasyConstraint() : | |||
m_typed_constraint(NULL), | |||
m_p2p_constraint(NULL), | |||
m_hinge_constraint(NULL), | |||
m_slider_constraint(NULL), | |||
m_cone_twist_constraint(NULL), | |||
m_6dof_constraint(NULL), | |||
m_a_physobj(NULL), | |||
m_b_physobj(NULL), | |||
m_a_transform(lol::mat4(1.f)), | |||
m_b_transform(lol::mat4(1.f)), | |||
m_using_ref_a(false), | |||
m_disable_a2b_collision(false) | |||
{ | |||
} | |||
~EasyConstraint() | |||
{ | |||
//btPoint2PointConstraint(bA, bB, PivotA, PivotB) | |||
//btHingeConstraint(bA, bB, TransfA, TransfB, UseRefA) | |||
//btSliderConstraint(bA, bB, TransfA, TransfB, UseRefA) | |||
//btConeTwistConstraint(bA, bB, TransfA, TransfB) | |||
//btGeneric6DofConstraint(bA, bB, TransfA, TransfB, UseRefA) | |||
delete m_typed_constraint; | |||
m_p2p_constraint = NULL; | |||
m_hinge_constraint = NULL; | |||
m_slider_constraint = NULL; | |||
m_cone_twist_constraint = NULL; | |||
m_6dof_constraint = NULL; | |||
} | |||
#ifdef HAVE_PHYS_USE_BULLET | |||
void AddToSimulation(class Simulation* current_simulation); | |||
void RemoveFromSimulation(class Simulation* current_simulation); | |||
private: | |||
//check if Init can be done | |||
bool CanProceedWithInit() | |||
{ | |||
if (!m_a_physobj || !m_b_physobj) | |||
return false; | |||
if (!m_a_physobj->m_rigid_body || !m_b_physobj->m_rigid_body) | |||
return false; | |||
return true; | |||
} | |||
//------------------------------------------------------------------------- | |||
//Init constraint functions | |||
//-- | |||
void CustomInitConstraintToPoint2Point() | |||
{ | |||
m_p2p_constraint = new btPoint2PointConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body, | |||
LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)); | |||
m_typed_constraint = m_p2p_constraint; | |||
} | |||
void CustomInitConstraintToHinge() | |||
{ | |||
m_hinge_constraint = new btHingeConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body, | |||
btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)), | |||
btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)), | |||
m_using_ref_a); | |||
m_typed_constraint = m_hinge_constraint; | |||
} | |||
void CustomInitConstraintToSlider() | |||
{ | |||
m_slider_constraint = new btSliderConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body, | |||
btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)), | |||
btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)), | |||
m_using_ref_a); | |||
m_typed_constraint = m_slider_constraint; | |||
} | |||
void CustomInitConstraintToConeTwist() | |||
{ | |||
m_cone_twist_constraint = new btConeTwistConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body, | |||
btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)), | |||
btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT))); | |||
m_typed_constraint = m_cone_twist_constraint; | |||
} | |||
void CustomInitConstraintTo6Dof() | |||
{ | |||
m_6dof_constraint = new btGeneric6DofConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body, | |||
btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)), | |||
btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)), | |||
m_using_ref_a); | |||
m_typed_constraint = m_6dof_constraint; | |||
} | |||
btTypedConstraint* m_typed_constraint; | |||
btPoint2PointConstraint* m_p2p_constraint; | |||
btHingeConstraint* m_hinge_constraint; | |||
btSliderConstraint* m_slider_constraint; | |||
btConeTwistConstraint* m_cone_twist_constraint; | |||
btGeneric6DofConstraint* m_6dof_constraint; | |||
#else // NO PHYSIC IMPLEMENTATION | |||
public: | |||
EasyConstraint() : | |||
m_a_physobj(NULL), | |||
m_b_physobj(NULL), | |||
m_a_transform(lol::mat4(1.f)), | |||
m_b_transform(lol::mat4(1.f)), | |||
m_using_ref_a(false), | |||
m_disable_a2b_collision(false) | |||
{ | |||
} | |||
private: | |||
void AddToSimulation(class Simulation* current_simulation) { } | |||
void RemoveFromSimulation(class Simulation* current_simulation) { } | |||
//check if Init can be done | |||
bool CanProceedWithInit() { return false; } | |||
void CustomInitConstraintToPoint2Point() { } | |||
void CustomInitConstraintToHinge() { } | |||
void CustomInitConstraintToSlider() { } | |||
void CustomInitConstraintToConeTwist() { } | |||
void CustomInitConstraintTo6Dof() { } | |||
#endif // PHYSIC IMPLEMENTATION | |||
public: | |||
void InitConstraintToPoint2Point() { if (CanProceedWithInit()) CustomInitConstraintToPoint2Point(); } | |||
void InitConstraintToHinge() { if (CanProceedWithInit()) CustomInitConstraintToHinge(); } | |||
void InitConstraintToSlider() { if (CanProceedWithInit()) CustomInitConstraintToSlider(); } | |||
void InitConstraintToConeTwist() { if (CanProceedWithInit()) CustomInitConstraintToConeTwist(); } | |||
void InitConstraintTo6Dof() { if (CanProceedWithInit()) CustomInitConstraintTo6Dof(); } | |||
//Set given physic object to the proper slot. | |||
void SetPhysObjA(EasyPhysic* NewPhysObj, lol::mat4 NewTransform) { SetPhysObj(false, NewPhysObj, NewTransform); } | |||
void SetPhysObjB(EasyPhysic* NewPhysObj, lol::mat4 NewTransform) { SetPhysObj(true, NewPhysObj, NewTransform); } | |||
void SetPhysObj(bool SetToB, EasyPhysic* NewPhysObj, lol::mat4 NewTransform) | |||
{ | |||
if (SetToB) | |||
{ | |||
m_b_physobj = NewPhysObj; | |||
m_b_transform = NewTransform; | |||
} | |||
else | |||
{ | |||
m_a_physobj = NewPhysObj; | |||
m_a_transform = NewTransform; | |||
} | |||
} | |||
//Set whether or not the physic engine should use the A object as the reference (most constraint transform are local). | |||
void SetRefAsA(bool NewUseRefA) | |||
{ | |||
m_using_ref_a = NewUseRefA; | |||
} | |||
//Set whether or not to disable the collision between the bodies | |||
void DisableCollisionBetweenObjs(bool DisableCollision) | |||
{ | |||
m_disable_a2b_collision = DisableCollision; | |||
} | |||
private: | |||
EasyPhysic* m_a_physobj; | |||
EasyPhysic* m_b_physobj; | |||
lol::mat4 m_a_transform; | |||
lol::mat4 m_b_transform; | |||
bool m_using_ref_a; | |||
bool m_disable_a2b_collision; | |||
}; | |||
} /* namespace phys */ | |||