Browse Source

Added Attachment/base logic with working attachment with EasyCharacterController.

Added RayCastResult & a naïve integration for EasyCharacterController.
Enjoy !
legacy
Benjamin ‘Touky’ Huet touky 12 years ago
parent
commit
11ddba1864
10 changed files with 292 additions and 71 deletions
  1. +4
    -2
      src/entity.h
  2. +3
    -2
      src/input/input.h
  3. +35
    -21
      test/BtPhysTest.cpp
  4. +0
    -8
      test/PhysicObject.h
  5. +19
    -3
      test/Physics/Include/EasyCharacterController.h
  6. +10
    -9
      test/Physics/Include/EasyPhysics.h
  7. +11
    -0
      test/Physics/Include/LolBtPhysicsIntegration.h
  8. +145
    -0
      test/Physics/Include/LolPhysics.h
  9. +39
    -2
      test/Physics/Src/EasyCharacterController.cpp
  10. +26
    -24
      test/Physics/Src/EasyPhysics.cpp

+ 4
- 2
src/entity.h View File

@@ -45,8 +45,10 @@ protected:
{ {
GAMEGROUP_BEFORE = 0, GAMEGROUP_BEFORE = 0,
GAMEGROUP_DEFAULT, GAMEGROUP_DEFAULT,
GAMEGROUP_AFTER,
// Must be the last element
GAMEGROUP_AFTER,
GAMEGROUP_AFTER_POST,

// Must be the last element
GAMEGROUP_END GAMEGROUP_END
} }
m_gamegroup; m_gamegroup;


+ 3
- 2
src/input/input.h View File

@@ -16,6 +16,7 @@
#if !defined __LOL_INPUT_INPUT_H__ #if !defined __LOL_INPUT_INPUT_H__
#define __LOL_INPUT_INPUT_H__ #define __LOL_INPUT_INPUT_H__


#include <cstring>
#include "lol/math/vector.h" #include "lol/math/vector.h"
#include "input/stick.h" #include "input/stick.h"


@@ -108,7 +109,7 @@ struct ActionSetting


ActionSetting(int NewActionId) ActionSetting(int NewActionId)
{ {
//memset(this, 0, sizeof(ActionSetting));
memset(this, 0, sizeof(ActionSetting));
ActionId = NewActionId; ActionId = NewActionId;
} }
}; };
@@ -122,7 +123,7 @@ struct ButtonSetting


ButtonSetting(int NewRawButtonId) ButtonSetting(int NewRawButtonId)
{ {
//memset(this, 0, sizeof(ButtonSetting));
memset(this, 0, sizeof(ButtonSetting));
RawButtonId = NewRawButtonId; RawButtonId = NewRawButtonId;
} }
int GetActionSettingIdx(int ActionId) int GetActionSettingIdx(int ActionId)


+ 35
- 21
test/BtPhysTest.cpp View File

@@ -51,13 +51,15 @@ int gNumObjects = 64;


#define USE_WALL 1 #define USE_WALL 1
#define USE_PLATFORM 1 #define USE_PLATFORM 1
#define USE_ROPE 1
#define USE_BODIES 1
#define USE_ROPE 0
#define USE_BODIES 0
#define USE_ROTATION 0 #define USE_ROTATION 0
#define USE_CHARACTER 1 #define USE_CHARACTER 1


BtPhysTest::BtPhysTest(bool editor) BtPhysTest::BtPhysTest(bool editor)
{ {
m_loop_value = .0f;

/* Create a camera that matches the settings of XNA BtPhysTest */ /* Create a camera that matches the settings of XNA BtPhysTest */
m_camera = new Camera(vec3(0.f, 600.f, 0.f), m_camera = new Camera(vec3(0.f, 600.f, 0.f),
vec3(0.f, 0.f, 0.f), vec3(0.f, 0.f, 0.f),
@@ -107,6 +109,7 @@ BtPhysTest::BtPhysTest(bool editor)
} }
} }


PhysicsObject* BasePhyobj = NULL;
if (USE_PLATFORM) if (USE_PLATFORM)
{ {
quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f); quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
@@ -117,16 +120,16 @@ BtPhysTest::BtPhysTest(bool editor)
m_platform_list << NewPhyobj; m_platform_list << NewPhyobj;
Ticker::Ref(NewPhyobj); Ticker::Ref(NewPhyobj);


NewPosition = pos_offset + vec3(-20.0f, -25.0f, 5.0f);
NewPosition = pos_offset + vec3(-15.0f, -25.0f, 5.0f);


NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1); NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
PhysicsObject* BasePhyobj = NewPhyobj;
BasePhyobj = NewPhyobj;


m_platform_list << NewPhyobj; m_platform_list << NewPhyobj;
Ticker::Ref(NewPhyobj); Ticker::Ref(NewPhyobj);


NewRotation = quat::fromeuler_xyz(0.f, 0.f, 90.f); NewRotation = quat::fromeuler_xyz(0.f, 0.f, 90.f);
NewPosition = pos_offset + vec3(-25.0f, -25.0f, 5.0f);
NewPosition = pos_offset + vec3(-20.0f, -25.0f, 5.0f);


NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1); NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);


@@ -134,30 +137,32 @@ BtPhysTest::BtPhysTest(bool editor)
m_platform_list << NewPhyobj; m_platform_list << NewPhyobj;
Ticker::Ref(NewPhyobj); Ticker::Ref(NewPhyobj);


NewPosition += vec3(-0.0f, .0f, .0f);
NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
//NewPosition += vec3(-0.0f, .0f, .0f);
//NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);


NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, false);
m_platform_list << NewPhyobj;
Ticker::Ref(NewPhyobj);
//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);
//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;
Ticker::Ref(NewPhyobj);
//NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), false, false);
//m_platform_list << NewPhyobj;
//Ticker::Ref(NewPhyobj);
} }


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(-15.0f, 20.0f, .0f);
vec3 NewPosition = pos_offset + vec3(-15.0f, -10.0f, .0f);


PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 2); PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 2);


m_character_list << NewPhyobj; m_character_list << NewPhyobj;
Ticker::Ref(NewPhyobj); Ticker::Ref(NewPhyobj);

//NewPhyobj->GetCharacter()->AttachTo(BasePhyobj->GetPhysic(), true, true);
} }


if (USE_BODIES) if (USE_BODIES)
@@ -280,8 +285,9 @@ void BtPhysTest::TickGame(float seconds)
} }
else if (i == 1) else if (i == 1)
{ {
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)));
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));
} }
} }
@@ -293,12 +299,20 @@ void BtPhysTest::TickGame(float seconds)
{ {
PhysicsObject* PhysObj = m_character_list[i]; PhysicsObject* PhysObj = m_character_list[i];
EasyCharacterController* Character = (EasyCharacterController*)PhysObj->GetCharacter(); EasyCharacterController* Character = (EasyCharacterController*)PhysObj->GetCharacter();
mat4 CtlrMx = Character->GetTransform();


int HMovement = Input::GetButtonState(275 /*SDLK_RIGHT*/) - Input::GetButtonState(276 /*SDLK_LEFT*/); int HMovement = Input::GetButtonState(275 /*SDLK_RIGHT*/) - Input::GetButtonState(276 /*SDLK_LEFT*/);
int VMovement = Input::GetButtonState(273 /*SDLK_UP*/) - Input::GetButtonState(274 /*SDLK_DOWN*/); int VMovement = Input::GetButtonState(273 /*SDLK_UP*/) - Input::GetButtonState(274 /*SDLK_DOWN*/);
int RMovement = Input::GetButtonState(280 /*SDLK_PAGEUP*/) - Input::GetButtonState(281 /*SDLK_PAGEDOWN*/); int RMovement = Input::GetButtonState(280 /*SDLK_PAGEUP*/) - Input::GetButtonState(281 /*SDLK_PAGEDOWN*/);
vec3 CharMove = vec3((float)VMovement * seconds * 4.f, (float)RMovement * seconds * 10.f, (float)HMovement * seconds * 4.f);

Character->SetMovementForFrame(CharMove);


Character->SetMovementForFrame(vec3((float)VMovement * seconds * 4.f, (float)RMovement * seconds * 10.f, (float)HMovement * seconds * 4.f));
RayCastResult HitResult;
if (m_simulation->RayHits(HitResult, ERT_Closest, Character->GetTransform().v3.xyz, (Character->GetTransform().v3.xyz + vec3(.0f, -1.f, .0f)), Character))
Character->AttachTo(HitResult.m_collider_list[0], true, true);
else
Character->AttachTo(NULL);
} }
} }


@@ -319,8 +333,8 @@ void BtPhysTest::TickGame(float seconds)
PhysObjBarycenter /= factor; PhysObjBarycenter /= factor;


m_camera->SetTarget(m_camera->GetTarget() + (seconds / (seconds + 0.18f)) * (PhysObjBarycenter - m_camera->GetTarget())); m_camera->SetTarget(m_camera->GetTarget() + (seconds / (seconds + 0.18f)) * (PhysObjBarycenter - m_camera->GetTarget()));
vec3 CamPosCenter = m_camera->GetTarget() + vec3(.0f, 20.0f, .0f);
m_camera->SetPosition(CamPosCenter + normalize(m_camera->GetPosition() - CamPosCenter) * 5.0f);
vec3 CamPosCenter = m_camera->GetTarget() + vec3(.0f, 5.0f, .0f);
m_camera->SetPosition(CamPosCenter + normalize(m_camera->GetPosition() - CamPosCenter) * 20.0f);
} }
else else
{ {


+ 0
- 8
test/PhysicObject.h View File

@@ -219,14 +219,6 @@ public:
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)


+ 19
- 3
test/Physics/Include/EasyCharacterController.h View File

@@ -29,7 +29,8 @@ namespace lol
namespace phys namespace phys
{ {


class EasyCharacterController : public EasyPhysic
class EasyCharacterController : public EasyPhysic,
public Entity
{ {


#ifdef HAVE_PHYS_USE_BULLET #ifdef HAVE_PHYS_USE_BULLET
@@ -37,8 +38,14 @@ class EasyCharacterController : public EasyPhysic
public: public:
EasyCharacterController(WorldEntity* NewOwnerEntity) : EasyCharacterController(WorldEntity* NewOwnerEntity) :
EasyPhysic(NewOwnerEntity), EasyPhysic(NewOwnerEntity),
m_character(NULL)
m_pair_caching_object(NULL),
m_character(NULL),
m_step_height(.0f),
m_base_is_updating(false),
m_base_cached_movement(vec3(0.f)),
m_frame_cached_movement(vec3(0.f))
{ {
m_gamegroup = GAMEGROUP_EZP_CHAR_CTRLR;
m_up_axis = 1; m_up_axis = 1;
} }
~EasyCharacterController() ~EasyCharacterController()
@@ -52,15 +59,24 @@ public:
virtual void RemoveFromSimulation(class Simulation* current_simulation); virtual void RemoveFromSimulation(class Simulation* current_simulation);
virtual void SetMovementForFrame(vec3 const &MoveQuantity); virtual void SetMovementForFrame(vec3 const &MoveQuantity);


virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation);
protected:
virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix);
public:
virtual void TickGame(float seconds);

protected: protected:


virtual btGhostObject* GetGhostObject();
virtual btGhostObject* GetGhostObjectInstance();


btPairCachingGhostObject* m_pair_caching_object; btPairCachingGhostObject* m_pair_caching_object;
btKinematicCharacterController* m_character; btKinematicCharacterController* m_character;


float m_step_height; float m_step_height;
int m_up_axis; int m_up_axis;
bool m_base_is_updating;
vec3 m_base_cached_movement;
vec3 m_frame_cached_movement;


#else // NO PHYSIC IMPLEMENTATION #else // NO PHYSIC IMPLEMENTATION




+ 10
- 9
test/Physics/Include/EasyPhysics.h View File

@@ -34,6 +34,7 @@ class EasyPhysic
{ {


friend class EasyConstraint; friend class EasyConstraint;
friend class Simulation;


#ifdef HAVE_PHYS_USE_BULLET #ifdef HAVE_PHYS_USE_BULLET


@@ -48,8 +49,9 @@ public:
virtual void SetShapeToCapsule(float radius, float height); virtual void SetShapeToCapsule(float radius, float height);


virtual bool CanChangeCollisionChannel() { return (m_rigid_body == NULL); } virtual bool CanChangeCollisionChannel() { return (m_rigid_body == NULL); }
virtual mat4 GetTransform();
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:
protected:
virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix); virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix);
public: public:
virtual void SetMass(float mass); virtual void SetMass(float mass);
@@ -57,13 +59,12 @@ public:
virtual void InitBodyToGhost(); virtual void InitBodyToGhost();
virtual void AddToSimulation(class Simulation* current_simulation); virtual void AddToSimulation(class Simulation* current_simulation);
virtual void RemoveFromSimulation(class Simulation* current_simulation); virtual void RemoveFromSimulation(class Simulation* current_simulation);
virtual mat4 GetTransform();


protected: protected:
virtual void SetLocalInertia(float mass); virtual void SetLocalInertia(float mass);
virtual void SetShapeTo(btCollisionShape* collision_shape); virtual void SetShapeTo(btCollisionShape* collision_shape);


virtual btGhostObject* GetGhostObject();
virtual btGhostObject* GetGhostObjectInstance();


btCollisionObject* m_collision_object; btCollisionObject* m_collision_object;


@@ -88,6 +89,7 @@ public:
virtual void SetShapeToCapsule(float radius, float height) { } virtual void SetShapeToCapsule(float radius, float height) { }


virtual bool CanChangeCollisionChannel() { return true; } virtual bool CanChangeCollisionChannel() { return true; }
virtual mat4 GetTransform() { return mat4(1.0f); }
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: private:
virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix) { } virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix) { }
@@ -97,7 +99,6 @@ public:
virtual void InitBodyToGhost() { } virtual void InitBodyToGhost() { }
virtual void AddToSimulation(class Simulation* current_simulation) { } virtual void AddToSimulation(class Simulation* current_simulation) { }
virtual void RemoveFromSimulation(class Simulation* current_simulation) { } virtual void RemoveFromSimulation(class Simulation* current_simulation) { }
virtual mat4 GetTransform() { return mat4(1.0f); }


virtual void InitBodyToGhost() { } virtual void InitBodyToGhost() { }


@@ -122,7 +123,7 @@ public:
//Base/Attachment logic //Base/Attachment logic
virtual void AttachTo(EasyPhysic* NewBase, bool NewBaseLockLocation = true, bool NewBaseLockRotation = true) virtual void AttachTo(EasyPhysic* NewBase, bool NewBaseLockLocation = true, bool NewBaseLockRotation = true)
{ {
if (NewBase == this || NewBase->m_base_physic == this)
if (NewBase == this || (NewBase && NewBase->m_base_physic == this))
return; return;


if (NewBase) if (NewBase)
@@ -137,11 +138,11 @@ public:
m_base_lock_location = NewBaseLockLocation; m_base_lock_location = NewBaseLockLocation;
m_base_lock_rotation = NewBaseLockRotation; m_base_lock_rotation = NewBaseLockRotation;
} }
else
else if (m_base_physic)
{ {
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--);
for (int i = 0; i < m_base_physic->m_based_physic_list.Count(); ++i)
if (m_base_physic->m_based_physic_list[i] == this)
m_base_physic->m_based_physic_list.Remove(i--);
m_base_physic = NULL; m_base_physic = NULL;
} }
} }


+ 11
- 0
test/Physics/Include/LolBtPhysicsIntegration.h View File

@@ -19,6 +19,13 @@


namespace lol namespace lol
{ {
//Override Gamegroups names for Physic-useage
//"_ENT_" means that this is a group for Entities that use EasyPhysic primitives.
//"_EZP_" means that this is a group for EasyPhysic primitives.
#define GAMEGROUP_ENT_PLATFORM GAMEGROUP_BEFORE
#define GAMEGROUP_ENT_MAIN GAMEGROUP_DEFAULT
#define GAMEGROUP_EZP_CHAR_CTRLR GAMEGROUP_AFTER
#define GAMEGROUP_SIMULATION GAMEGROUP_AFTER_POST


#ifdef HAVE_PHYS_USE_BULLET #ifdef HAVE_PHYS_USE_BULLET


@@ -31,6 +38,10 @@ namespace lol
#define LOL2BT_VEC3(ELEMENT) btVector3((ELEMENT).x, (ELEMENT).y, (ELEMENT).z) #define LOL2BT_VEC3(ELEMENT) btVector3((ELEMENT).x, (ELEMENT).y, (ELEMENT).z)
#define BT2LOL_VEC3(ELEMENT) (*(lol::vec3*)(&(ELEMENT))) #define BT2LOL_VEC3(ELEMENT) (*(lol::vec3*)(&(ELEMENT)))


//Same as above with Unit taken into account
#define LOL2BTU_VEC3(ELEMENT) btVector3((ELEMENT).x * LOL2BT_UNIT, (ELEMENT).y * LOL2BT_UNIT, (ELEMENT).z * LOL2BT_UNIT)
#define BT2LOLU_VEC3(ELEMENT) (*(lol::vec3*)(&(ELEMENT))) * BT2LOL_UNIT

#define LOL2BT_QUAT(ELEMENT) btQuaternion((ELEMENT).x, (ELEMENT).y, (ELEMENT).z, (ELEMENT).w) #define LOL2BT_QUAT(ELEMENT) btQuaternion((ELEMENT).x, (ELEMENT).y, (ELEMENT).z, (ELEMENT).w)
#define BT2LOL_QUAT(ELEMENT) lol::quat((ELEMENT).getW(), BT2LOL_VEC3((ELEMENT).getAxis()) #define BT2LOL_QUAT(ELEMENT) lol::quat((ELEMENT).getW(), BT2LOL_VEC3((ELEMENT).getAxis())




+ 145
- 0
test/Physics/Include/LolPhysics.h View File

@@ -9,8 +9,10 @@
#define __LOLPHYSICS_H__ #define __LOLPHYSICS_H__


#ifdef HAVE_PHYS_USE_BULLET #ifdef HAVE_PHYS_USE_BULLET
#include <cstring>
#include <bullet/btBulletDynamicsCommon.h> #include <bullet/btBulletDynamicsCommon.h>
#include <bullet/btBulletCollisionCommon.h> #include <bullet/btBulletCollisionCommon.h>
#include <BulletDynamics/Character/btKinematicCharacterController.h>
#include "LolBtPhysicsIntegration.h" #include "LolBtPhysicsIntegration.h"
#include "EasyPhysics.h" #include "EasyPhysics.h"
#include "EasyConstraint.h" #include "EasyConstraint.h"
@@ -22,6 +24,42 @@ namespace lol
namespace phys namespace phys
{ {


enum eRaycastType
{
ERT_Closest,
ERT_AllHit,
ERT_AnyHit, //Will stop at the first hit. Hit data are supposed to be irrelevant

ERT_MAX
};

struct RayCastResult
{
RayCastResult(int CollisionFilterGroup=1, int CollisionFilterMask=(0xFF))
{
memset(this, 0, sizeof(RayCastResult));

m_collision_filter_group = CollisionFilterGroup;
m_collision_filter_mask = CollisionFilterMask;
}
void Reset()
{
m_collider_list.Empty();
m_hit_normal_list.Empty();
m_hit_point_list.Empty();
m_hit_fraction_list.Empty();
}

Array<EasyPhysic*> m_collider_list;
Array<vec3> m_hit_normal_list;
Array<vec3> m_hit_point_list;
Array<float> m_hit_fraction_list;

short int m_collision_filter_group;
short int m_collision_filter_mask;
unsigned int m_flags; //???
};

class Simulation : public Entity class Simulation : public Entity
{ {
public: public:
@@ -33,6 +71,7 @@ public:
m_dynamics_world(0), m_dynamics_world(0),
m_timestep(1.f/60.f) m_timestep(1.f/60.f)
{ {
m_gamegroup = GAMEGROUP_SIMULATION;
} }
~Simulation() ~Simulation()
{ {
@@ -79,6 +118,111 @@ public:
} }
} }


//Reap-Off of the btKinematicClosestNotMeRayResultCallback
class LolClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
{
public:
LolClosestNotMeRayResultCallback(btCollisionObject* Me, const btVector3& rayFromWorld, const btVector3& rayToWorld) :
btCollisionWorld::ClosestRayResultCallback(rayFromWorld, rayToWorld)
{
m_me = Me;
}

virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
{
if (rayResult.m_collisionObject == m_me)
return 1.0;

return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
}
protected:
btCollisionObject* m_me;
};

//Will stop at the first hit. Hit data are supposed to be irrelevant
class AnyHitRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
{
public:
AnyHitRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld) :
btCollisionWorld::ClosestRayResultCallback(rayFromWorld, rayToWorld)
{
}

virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
{
return .0f;
}
};

//Returns true when hitting something. If SourceCaster is set, it will be ignored by Raycast.
bool RayHits(RayCastResult& HitResult, eRaycastType RaycastType, const vec3& RayFrom, const vec3& RayTo, EasyPhysic* SourceCaster=NULL)
{
bool bResult = false;

btCollisionWorld::RayResultCallback* BtRayResult = NULL;
btCollisionWorld::ClosestRayResultCallback* BtRayResult_Closest;
btCollisionWorld::AllHitsRayResultCallback* BtRayResult_AllHits;

switch (RaycastType)
{
case ERT_Closest:
{
if (SourceCaster)
BtRayResult_Closest = new LolClosestNotMeRayResultCallback(SourceCaster->m_collision_object, LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo));
else
BtRayResult_Closest = new btCollisionWorld::ClosestRayResultCallback(LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo));
BtRayResult = BtRayResult_Closest;
break;
}
case ERT_AllHit:
{
BtRayResult_AllHits = new btCollisionWorld::AllHitsRayResultCallback(LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo));
BtRayResult = BtRayResult_AllHits;
break;
}
case ERT_AnyHit:
{
BtRayResult_Closest = new AnyHitRayResultCallback(LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo));
BtRayResult = BtRayResult_Closest;
break;
}
}

m_dynamics_world->rayTest(LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo), *BtRayResult);
if (BtRayResult->hasHit())
{
bResult = true;

switch (RaycastType)
{
case ERT_Closest:
{
HitResult.m_collider_list << (EasyPhysic*)BtRayResult_Closest->m_collisionObject->getUserPointer();
HitResult.m_hit_normal_list << BT2LOLU_VEC3(BtRayResult_Closest->m_hitNormalWorld);
HitResult.m_hit_point_list << BT2LOLU_VEC3(BtRayResult_Closest->m_hitPointWorld);
HitResult.m_hit_fraction_list << BtRayResult_Closest->m_closestHitFraction;
break;
}
case ERT_AllHit:
{
for (int i = 0; i < BtRayResult_AllHits->m_collisionObjects.size(); i++)
{
HitResult.m_collider_list << (EasyPhysic*)BtRayResult_AllHits->m_collisionObjects[i]->getUserPointer();
HitResult.m_hit_normal_list << BT2LOLU_VEC3(BtRayResult_AllHits->m_hitNormalWorld[i]);
HitResult.m_hit_point_list << BT2LOLU_VEC3(BtRayResult_AllHits->m_hitPointWorld[i]);
HitResult.m_hit_fraction_list << BtRayResult_AllHits->m_hitFractions[i];
}
break;
}
}
}

delete BtRayResult;

return bResult;
}


void Exit() void Exit()
{ {
delete m_dynamics_world; delete m_dynamics_world;
@@ -128,6 +272,7 @@ private:
public: public:
void Init() { } void Init() { }
void TickGame(float seconds) { } void TickGame(float seconds) { }
bool RayHits(RayCastResult& HitResult, eRaycastType RaycastType, const vec3& RayFrom, const vec3& RayTo, EasyPhysic* SourceCaster=NULL) { return false; }
void Exit() { } void Exit() { }
private: private:
void CustomSetContinuousDetection(bool ShouldUseCCD) { } void CustomSetContinuousDetection(bool ShouldUseCCD) { }


+ 39
- 2
test/Physics/Src/EasyCharacterController.cpp View File

@@ -36,7 +36,7 @@ void EasyCharacterController::InitBodyToRigid(bool ZeroMassIsKinematic)
} }


//Return correct Ghost Object //Return correct Ghost Object
btGhostObject* EasyCharacterController::GetGhostObject()
btGhostObject* EasyCharacterController::GetGhostObjectInstance()
{ {
return new btPairCachingGhostObject(); return new btPairCachingGhostObject();
} }
@@ -63,6 +63,7 @@ void EasyCharacterController::AddToSimulation(class Simulation* current_simulati


m_character = new btKinematicCharacterController(m_pair_caching_object, m_convex_shape, m_step_height, m_up_axis); m_character = new btKinematicCharacterController(m_pair_caching_object, m_convex_shape, m_step_height, m_up_axis);
dynamics_world->addAction(m_character); dynamics_world->addAction(m_character);
Ticker::Ref(this);
} }
} }


@@ -75,14 +76,50 @@ void EasyCharacterController::RemoveFromSimulation(class Simulation* current_sim
if (dynamics_world) if (dynamics_world)
{ {
if (m_character) if (m_character)
{
dynamics_world->removeAction(m_character); dynamics_world->removeAction(m_character);
Ticker::Unref(this);
}
} }
} }


//Set movement for this frame //Set movement for this frame
void EasyCharacterController::SetMovementForFrame(vec3 const &MoveQuantity) void EasyCharacterController::SetMovementForFrame(vec3 const &MoveQuantity)
{ {
m_character->setWalkDirection(LOL2BT_VEC3(MoveQuantity));
m_frame_cached_movement = MoveQuantity;
}

//-------------------------------------------------------------------------
//Base Location/Rotation setup
//--
void EasyCharacterController::SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation)
{
if (m_base_is_updating)
{
m_base_cached_movement = base_location - m_local_to_world.v3.xyz;
m_local_to_world = lol::mat4::translate(m_local_to_world.v3.xyz) * lol::mat4(base_rotation);
if (m_ghost_object)
m_ghost_object->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(LOL2BT_UNIT * m_local_to_world.v3.xyz)));
}
else
EasyPhysic::SetTransform(base_location, base_rotation);
}

//Internal callback when Base transform has changed.
void EasyCharacterController::BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix)
{
m_base_is_updating = true;
EasyPhysic::BaseTransformChanged(PreviousMatrix, NewMatrix);
m_base_is_updating = false;
}

//Physic Tick
void EasyCharacterController::TickGame(float seconds)
{
Entity::TickGame(seconds);

m_character->setVelocityForTimeInterval(LOL2BT_VEC3(LOL2BT_UNIT * /*0.1f **/ (m_base_cached_movement + m_frame_cached_movement)) / seconds, seconds);
//m_character->setWalkDirection();
} }


#endif // HAVE_PHYS_USE_BULLET #endif // HAVE_PHYS_USE_BULLET


+ 26
- 24
test/Physics/Src/EasyPhysics.cpp View File

@@ -40,7 +40,8 @@ EasyPhysic::EasyPhysic(WorldEntity* NewOwnerEntity) :
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)
m_owner_entity(NewOwnerEntity),
m_base_physic(NULL)
{ {
} }


@@ -112,26 +113,45 @@ void EasyPhysic::SetShapeToCapsule(float radius, float height)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
//Base Location/Rotation setup //Base Location/Rotation setup
//-- //--

//Getter
mat4 EasyPhysic::GetTransform()
{
m_local_to_world = lol::mat4(1.0f);
if (m_rigid_body && m_motion_state)
{
btTransform CurTransform;
m_motion_state->getWorldTransform(CurTransform);
CurTransform.getOpenGLMatrix(&m_local_to_world[0][0]);
}
else if (m_collision_object)
m_collision_object->getWorldTransform().getOpenGLMatrix(&m_local_to_world[0][0]);
return m_local_to_world;
}

//Setter
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)
{ {
lol::mat4 PreviousMatrix = m_local_to_world; lol::mat4 PreviousMatrix = m_local_to_world;
m_local_to_world = lol::mat4::translate(base_location) * lol::mat4(base_rotation); 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(LOL2BT_UNIT * base_location)));
else else
{ {
if (m_motion_state) if (m_motion_state)
m_motion_state->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT)));
m_motion_state->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(LOL2BT_UNIT * base_location)));
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(LOL2BT_UNIT * base_location)));
} }


for (int i = 0; i < m_based_physic_list.Count(); i++) for (int i = 0; i < m_based_physic_list.Count(); i++)
{
if (m_based_physic_list[i]) if (m_based_physic_list[i])
m_based_physic_list[i]->BaseTransformChanged(PreviousMatrix, m_local_to_world); m_based_physic_list[i]->BaseTransformChanged(PreviousMatrix, m_local_to_world);
else else
m_based_physic_list.Remove(i--); m_based_physic_list.Remove(i--);
}
} }


//Internal callback when Base transform has changed. //Internal callback when Base transform has changed.
@@ -196,7 +216,7 @@ void EasyPhysic::InitBodyToRigid(bool SetToKinematic)
} }


//Return correct Ghost Object //Return correct Ghost Object
btGhostObject* EasyPhysic::GetGhostObject()
btGhostObject* EasyPhysic::GetGhostObjectInstance()
{ {
return new btGhostObject(); return new btGhostObject();
} }
@@ -207,7 +227,7 @@ void EasyPhysic::InitBodyToGhost()
if (m_collision_object) if (m_collision_object)
delete m_collision_object; delete m_collision_object;


m_ghost_object = GetGhostObject();
m_ghost_object = GetGhostObjectInstance();
m_ghost_object->setCollisionShape(m_collision_shape); m_ghost_object->setCollisionShape(m_collision_shape);
m_collision_object = m_ghost_object; m_collision_object = m_ghost_object;
m_collision_object->setUserPointer(this); m_collision_object->setUserPointer(this);
@@ -294,24 +314,6 @@ void EasyPhysic::RemoveFromSimulation(class Simulation* current_simulation)
} }
} }


//-------------------------------------------------------------------------
//Getter functons
//--

mat4 EasyPhysic::GetTransform()
{
m_local_to_world = lol::mat4(1.0f);
if (m_rigid_body && m_motion_state)
{
btTransform CurTransform;
m_motion_state->getWorldTransform(CurTransform);
CurTransform.getOpenGLMatrix(&m_local_to_world[0][0]);
}
else if (m_collision_object)
m_collision_object->getWorldTransform().getOpenGLMatrix(&m_local_to_world[0][0]);
return m_local_to_world;
}

//Set Local Inertia //Set Local Inertia
void EasyPhysic::SetLocalInertia(float mass) void EasyPhysic::SetLocalInertia(float mass)
{ {


Loading…
Cancel
Save