Browse Source

Correct integration of EasyConstraint + TestDemo.

legacy
Benjamin ‘Touky’ Huet touky 12 years ago
parent
commit
4a31a63b77
5 changed files with 313 additions and 42 deletions
  1. +61
    -18
      test/BtPhysTest.cpp
  2. +1
    -0
      test/BtPhysTest.h
  3. +38
    -3
      test/PhysicObject.h
  4. +49
    -14
      test/Physics/EasyPhysics.cpp
  5. +164
    -7
      test/Physics/EasyPhysics.h

+ 61
- 18
test/BtPhysTest.cpp View File

@@ -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);


+ 1
- 0
test/BtPhysTest.h View File

@@ -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;



+ 38
- 3
test/PhysicObject.h View File

@@ -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()
{
}


+ 49
- 14
test/Physics/EasyPhysics.cpp View File

@@ -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 */


+ 164
- 7
test/Physics/EasyPhysics.h View File

@@ -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 */


Loading…
Cancel
Save