| @@ -10,10 +10,13 @@ | |||
| // | |||
| // | |||
| // The EasyPhysic class | |||
| // The EasyCharacterController class | |||
| // ------------------ | |||
| // | |||
| //Should try to to make a btKinematicCharacterController for real. | |||
| // | |||
| #if !defined __EASYCHARACTERCONTROLLER_EASYCHARACTERCONTROLLER_H__ | |||
| #define __EASYCHARACTERCONTROLLER_EASYCHARACTERCONTROLLER_H__ | |||
| @@ -33,6 +36,9 @@ class EasyCharacterController : public EasyPhysic, | |||
| public Entity | |||
| { | |||
| friend class Simulation; | |||
| friend class EasyPhysic; | |||
| #ifdef HAVE_PHYS_USE_BULLET | |||
| public: | |||
| @@ -47,6 +53,7 @@ public: | |||
| { | |||
| m_gamegroup = GAMEGROUP_EZP_CHAR_CTRLR; | |||
| m_up_axis = 1; | |||
| m_gravity = vec3(.0f, -9.81f, .0f); | |||
| } | |||
| ~EasyCharacterController() | |||
| { | |||
| @@ -77,6 +84,8 @@ protected: | |||
| bool m_base_is_updating; | |||
| vec3 m_base_cached_movement; | |||
| vec3 m_frame_cached_movement; | |||
| vec3 m_gravity; | |||
| vec3 m_velocity; | |||
| #else // NO PHYSIC IMPLEMENTATION | |||
| @@ -30,6 +30,10 @@ namespace phys | |||
| class EasyConstraint | |||
| { | |||
| friend class Simulation; | |||
| friend class EasyPhysic; | |||
| #ifdef HAVE_PHYS_USE_BULLET | |||
| public: | |||
| @@ -40,6 +44,7 @@ public: | |||
| m_slider_constraint(NULL), | |||
| m_cone_twist_constraint(NULL), | |||
| m_6dof_constraint(NULL), | |||
| m_owner_simulation(NULL), | |||
| m_a_physobj(NULL), | |||
| m_b_physobj(NULL), | |||
| m_a_transform(lol::mat4(1.f)), | |||
| @@ -193,6 +198,7 @@ public: | |||
| } | |||
| private: | |||
| Simulation* m_owner_simulation; | |||
| EasyPhysic* m_a_physobj; | |||
| EasyPhysic* m_b_physobj; | |||
| lol::mat4 m_a_transform; | |||
| @@ -33,8 +33,8 @@ namespace phys | |||
| class EasyPhysic | |||
| { | |||
| friend class EasyConstraint; | |||
| friend class Simulation; | |||
| friend class EasyConstraint; | |||
| #ifdef HAVE_PHYS_USE_BULLET | |||
| @@ -153,6 +153,7 @@ protected: | |||
| int m_collision_group; | |||
| int m_collision_mask; | |||
| WorldEntity* m_owner_entity; | |||
| Simulation* m_owner_simulation; | |||
| //Base/Attachment logic | |||
| Array<EasyPhysic*> m_based_physic_list; //List of objects based on this : this object moves, its based object move with it. | |||
| @@ -320,19 +320,104 @@ public: | |||
| } | |||
| private: | |||
| friend class EasyPhysic; | |||
| friend class EasyCharacterController; | |||
| friend class EasyConstraint; | |||
| enum eEasyPhysicType | |||
| { | |||
| EEPT_Dynamic, | |||
| EEPT_Static, | |||
| EEPT_Ghost, | |||
| EEPT_CollisionObject, | |||
| EEPT_CharacterController, | |||
| EEPT_MAX | |||
| }; | |||
| //m_owner_simulation | |||
| //Adds the given EasyPhysic to the correct list. | |||
| void AddToDynamic(EasyPhysic* NewEPDynamic) { m_dynamic_list << NewEPDynamic; } | |||
| void AddToStatic(EasyPhysic* NewEPStatic) { m_static_list << NewEPStatic; } | |||
| void AddToGhost(EasyPhysic* NewEPGhost) { m_ghost_list << NewEPGhost; } | |||
| void AddToConstraint(EasyConstraint* NewEC) { m_constraint_list << NewEC; } | |||
| void ObjectRegistration(bool AddObject, EasyPhysic* NewEP, eEasyPhysicType CurType) | |||
| { | |||
| Array<EasyPhysic*>* SearchList = NULL; | |||
| switch(CurType) | |||
| { | |||
| case EEPT_Dynamic: | |||
| { | |||
| SearchList = &m_dynamic_list; | |||
| break; | |||
| } | |||
| case EEPT_Static: | |||
| { | |||
| SearchList = &m_static_list; | |||
| break; | |||
| } | |||
| case EEPT_Ghost: | |||
| { | |||
| SearchList = &m_ghost_list; | |||
| break; | |||
| } | |||
| case EEPT_CollisionObject: | |||
| { | |||
| SearchList = &m_collision_object_list; | |||
| break; | |||
| } | |||
| case EEPT_CharacterController: | |||
| { | |||
| SearchList = &m_character_controller_list; | |||
| break; | |||
| } | |||
| } | |||
| if (AddObject) | |||
| { | |||
| NewEP->m_owner_simulation = this; | |||
| (*SearchList) << NewEP; | |||
| } | |||
| else | |||
| { | |||
| NewEP->m_owner_simulation = NULL; | |||
| for (int i = 0; i < SearchList->Count(); ++i) | |||
| { | |||
| if ((*SearchList)[i] == NewEP) | |||
| { | |||
| SearchList->Remove(i--); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| void ObjectRegistration(bool AddObject, EasyConstraint* NewEC) | |||
| { | |||
| Array<EasyConstraint*>* SearchList = NULL; | |||
| SearchList = &m_constraint_list; | |||
| if (AddObject) | |||
| { | |||
| NewEC->m_owner_simulation = this; | |||
| (*SearchList) << NewEC; | |||
| } | |||
| else | |||
| { | |||
| NewEC->m_owner_simulation = NULL; | |||
| for (int i = 0; i < SearchList->Count(); ++i) | |||
| { | |||
| if ((*SearchList)[i] == NewEC) | |||
| { | |||
| SearchList->Remove(i--); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| //Easy Physics body List | |||
| Array<EasyPhysic*> m_dynamic_list; | |||
| Array<EasyPhysic*> m_static_list; | |||
| Array<EasyPhysic*> m_ghost_list; | |||
| Array<EasyPhysic*> m_collision_object_list; | |||
| Array<EasyPhysic*> m_character_controller_list; | |||
| Array<EasyConstraint*> m_constraint_list; | |||
| //Easy Physics data storage | |||
| @@ -62,7 +62,13 @@ void EasyCharacterController::AddToSimulation(class Simulation* current_simulati | |||
| delete m_character; | |||
| m_character = new btKinematicCharacterController(m_pair_caching_object, m_convex_shape, m_step_height, m_up_axis); | |||
| //Deactivate Character controller basic behaviour. | |||
| //m_character->setGravity(.0f); | |||
| //m_character->setFallSpeed(.0f); | |||
| dynamics_world->addAction(m_character); | |||
| current_simulation->ObjectRegistration(true, this, Simulation::EEPT_CharacterController); | |||
| Ticker::Ref(this); | |||
| } | |||
| } | |||
| @@ -78,6 +84,7 @@ void EasyCharacterController::RemoveFromSimulation(class Simulation* current_sim | |||
| if (m_character) | |||
| { | |||
| dynamics_world->removeAction(m_character); | |||
| current_simulation->ObjectRegistration(false, this, Simulation::EEPT_CharacterController); | |||
| Ticker::Unref(this); | |||
| } | |||
| } | |||
| @@ -118,7 +125,9 @@ void EasyCharacterController::TickGame(float seconds) | |||
| { | |||
| Entity::TickGame(seconds); | |||
| m_character->setVelocityForTimeInterval(LOL2BT_VEC3(LOL2BT_UNIT * (m_base_cached_movement + m_frame_cached_movement)) / seconds, seconds); | |||
| int IterationsNb = (int)(seconds / m_owner_simulation->m_timestep); | |||
| float NewSeconds = IterationsNb * m_owner_simulation->m_timestep; | |||
| m_character->setVelocityForTimeInterval(LOL2BT_VEC3(LOL2BT_UNIT * (m_base_cached_movement + m_frame_cached_movement)) / NewSeconds, NewSeconds); | |||
| m_base_cached_movement = vec3(.0f); | |||
| } | |||
| @@ -25,7 +25,7 @@ void EasyConstraint::AddToSimulation(class Simulation* current_simulation) | |||
| if (dynamics_world && m_typed_constraint) | |||
| { | |||
| dynamics_world->addConstraint(m_typed_constraint, m_disable_a2b_collision); | |||
| current_simulation->AddToConstraint(this); | |||
| current_simulation->ObjectRegistration(true, this); | |||
| } | |||
| } | |||
| @@ -33,7 +33,10 @@ 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); | |||
| current_simulation->ObjectRegistration(false, this); | |||
| } | |||
| } | |||
| #endif // HAVE_PHYS_USE_BULLET | |||
| @@ -41,6 +41,7 @@ EasyPhysic::EasyPhysic(WorldEntity* NewOwnerEntity) : | |||
| m_collision_group(1), | |||
| m_collision_mask(1), | |||
| m_owner_entity(NewOwnerEntity), | |||
| m_owner_simulation(NULL), | |||
| m_base_physic(NULL) | |||
| { | |||
| } | |||
| @@ -286,18 +287,21 @@ void EasyPhysic::AddToSimulation(class Simulation* current_simulation) | |||
| if (m_ghost_object) | |||
| { | |||
| dynamics_world->addCollisionObject(m_ghost_object, m_collision_group, m_collision_mask); | |||
| current_simulation->AddToGhost(this); | |||
| current_simulation->ObjectRegistration(true, this, Simulation::EEPT_Ghost); | |||
| } | |||
| else if (m_rigid_body) | |||
| { | |||
| dynamics_world->addRigidBody(m_rigid_body, m_collision_group, m_collision_mask); | |||
| if (m_mass != .0f) | |||
| current_simulation->AddToDynamic(this); | |||
| current_simulation->ObjectRegistration(true, this, Simulation::EEPT_Dynamic); | |||
| else | |||
| current_simulation->AddToStatic(this); | |||
| current_simulation->ObjectRegistration(true, this, Simulation::EEPT_Static); | |||
| } | |||
| else | |||
| { | |||
| dynamics_world->addCollisionObject(m_collision_object, m_collision_group, m_collision_mask); | |||
| current_simulation->ObjectRegistration(true, this, Simulation::EEPT_CollisionObject); | |||
| } | |||
| } | |||
| } | |||
| @@ -308,9 +312,20 @@ void EasyPhysic::RemoveFromSimulation(class Simulation* current_simulation) | |||
| if (dynamics_world) | |||
| { | |||
| if (m_rigid_body) | |||
| { | |||
| dynamics_world->removeRigidBody(m_rigid_body); | |||
| else if (m_collision_object) | |||
| if (m_mass != .0f) | |||
| current_simulation->ObjectRegistration(false, this, Simulation::EEPT_Dynamic); | |||
| else | |||
| current_simulation->ObjectRegistration(false, this, Simulation::EEPT_Static); | |||
| } | |||
| else | |||
| { | |||
| dynamics_world->removeCollisionObject(m_collision_object); | |||
| if (m_ghost_object) | |||
| current_simulation->ObjectRegistration(false, this, Simulation::EEPT_Ghost); | |||
| current_simulation->ObjectRegistration(false, this, Simulation::EEPT_CollisionObject); | |||
| } | |||
| } | |||
| } | |||