diff --git a/legacy/ephysics/src/lib/EPhysics.h b/legacy/ephysics/src/lib/EPhysics.h index a4c9cf7a61..bcce72d6a9 100644 --- a/legacy/ephysics/src/lib/EPhysics.h +++ b/legacy/ephysics/src/lib/EPhysics.h @@ -270,6 +270,26 @@ typedef enum _EPhysics_Callback_World_Type EPHYSICS_CALLBACK_WORLD_LAST, /**< kept as sentinel, not really an event */ } EPhysics_Callback_World_Type; +/** + * @enum _EPhysics_World_Constraint_Solver_Mode + * typedef EPhysics_World_Constraint_Solver_Mode + * + * Identifies the worlds contact and joint constraint solver mode. By default + * EPHYSICS_WORLD_SOLVER_USE_WARMSTARTING is the only enabled solver mode. + * + * @see ephysics_world_constraint_solver_mode_enable_set() + * @see ephysics_world_constraint_solver_mode_enable_get() + * + * @ingroup EPhysics_World + */ +typedef enum _EPhysics_World_Constraint_Solver_Mode +{ + EPHYSICS_WORLD_SOLVER_RANDMIZE_ORDER = 1, /**< Randomize the order of solving the constraint rows*/ + EPHYSICS_WORLD_SOLVER_USE_WARMSTARTING = 4, /**< The PGS is an iterative algorithm where each iteration is based on the solution of previous iteration, if no warmstarting is used, the initial solution for PGS is set to zero each frame (by default this mode is enabled, disabling this mode the user can face a better performance depending on the amount of objects in the simulation)*/ + EPHYSICS_WORLD_SOLVER_USE_2_FRICTION_DIRECTIONS = 16, /**< While calculating a friction impulse consider this should be applied on both bodies (this mode cause a better stacking stabilization)*/ + EPHYSICS_WORLD_SOLVER_SIMD = 256, /**< Use a SSE optimized innerloop, using assembly intrinsics, this is implemented and can be enabled/disabled for Windows and Mac OSX versions, single-precision floating point, 32bit(disabled by default)*/ +} EPhysics_World_Solver_Mode; + /** * @typedef EPhysics_World_Event_Cb * @@ -478,6 +498,33 @@ EAPI void ephysics_world_constraint_solver_iterations_set(EPhysics_World *world, */ EAPI int ephysics_world_constraint_solver_iterations_get(EPhysics_World *world); +/** + * @brief + * Enable or disable a constraint solver mode to @p world. A world can operate + * on several constraint solver modes. + * + * @param world The world to be set. + * @param solver_mode The solver mode to set. + * + * @see EPhysics_World_Solver_Mode for supported solver modes. + * @see ephysics_world_constraint_solver_mode_enable_get() + * @ingroup EPhysics_World + */ +EAPI void ephysics_world_constraint_solver_mode_enable_set(EPhysics_World *world, EPhysics_World_Solver_Mode solver_mode, Eina_Bool enable); + +/** + * @brief + * Get the @p solver_mode status on @p world. + * + * @param world The world to be queried. + * @param solver_mode The solver mode of interest. + * @return EINA_TRUE if @p solver_mode is enabled, EINA_FALSE otherwise + * + * @see ephysics_world_constraint_solver_mode_enable_set() + * @ingroup EPhysics_World + */ +EAPI Eina_Bool ephysics_world_constraint_solver_mode_enable_get(EPhysics_World *world, EPhysics_World_Solver_Mode solver_mode); + /** * @brief * Get world gravity values for axis x and y. diff --git a/legacy/ephysics/src/lib/ephysics_world.cpp b/legacy/ephysics/src/lib/ephysics_world.cpp index 235f60e15d..be1e9d83c0 100644 --- a/legacy/ephysics/src/lib/ephysics_world.cpp +++ b/legacy/ephysics/src/lib/ephysics_world.cpp @@ -290,6 +290,8 @@ ephysics_world_new(void) goto no_list; } + world->dynamics_world->getSolverInfo().m_solverMode ^= + EPHYSICS_WORLD_SOLVER_SIMD; world->dynamics_world->setGravity(btVector3(0, -9.8, 0)); world->rate = 30; world->dynamics_world->setInternalTickCallback(_ephysics_world_tick_cb, @@ -495,6 +497,34 @@ ephysics_world_constraint_solver_iterations_get(EPhysics_World *world) return world->dynamics_world->getSolverInfo().m_numIterations; } +EAPI void +ephysics_world_constraint_solver_mode_enable_set(EPhysics_World *world, EPhysics_World_Solver_Mode solver_mode, Eina_Bool enable) +{ + int current_solver_mode; + if (!world) + { + ERR("Can't enable/disable constraint solver mode, world is null."); + return; + } + + current_solver_mode = world->dynamics_world->getSolverInfo().m_solverMode; + if ((enable && !(current_solver_mode & solver_mode)) || + (!enable && (current_solver_mode & solver_mode))) + world->dynamics_world->getSolverInfo().m_solverMode ^= solver_mode; +} + +EAPI Eina_Bool +ephysics_world_constraint_solver_mode_enable_get(EPhysics_World *world, EPhysics_World_Solver_Mode solver_mode) +{ + if (!world) + { + ERR("Can't get constraint solver mode status, world is null."); + return EINA_FALSE; + } + + return world->dynamics_world->getSolverInfo().m_solverMode & solver_mode; +} + EAPI void ephysics_world_gravity_get(const EPhysics_World *world, double *gx, double *gy) {