Space

struct nvSpace

Space struct.

A space is the core of the physics simulation. It manages and simulates all bodies, constraints and collisions.

struct nvSpaceSettings

Space settings struct.

Public Members

nv_float baumgarte

Baumgarte stabilization factor is used to correct constraint erros by feeding them back to the velocity constraints. This can add some energy to the system. It’s a value between [0, 1]. For a game, it’s best to leave this at default.

nv_float penetration_slop

Amount of penetration error allowed in position correction. The reason we allow some error is for stability and avoid jitter. You can adjust it depending on the general size range of your game objects. But it’s best to keep it at default and respect the guidance on shape sizes explained in nvRigidBody

nvContactPositionCorrection contact_position_correction

Position correction method to use for collisions.

nv_uint32 velocity_iterations

Nova uses Sequential Impulses (or Projected Gauss-Seidel), which is an iterative method. This value defines the number of iterations done by the solver in order to solve velocity constraints. If you have high number of iterations, constraints should converge to a better solution with the cost of more load on CPU. Lower number of iterations can result in poor accuracy and the simulation may look spongy. For a game 6-10 should be sufficient.

nv_uint32 position_iterations

Iteration count for Nonlinear Gauss-Seidel solver for collisions only. For a game 3-6 should be sufficient.

Warning

Currently unused.

nv_uint32 substeps

This defines how many substeps the current simulation step is going to get divided into. This effectively increases the accuracy of the simulation but also impacts the performance greatly because the whole simulation is processed and collisions are recalculated by given amounts of times internally. In a game, you wouldn’t need this much detail. Best to leave it at 1.

nv_float linear_damping

Amount of damping applied to linear motion. It is required to remove potential energy added trough numerical instability. The final damping value is calculated as 0.99 ^ (r * d) where d is this value and r is damping ratio of a rigid body, usually 1. You can change damping ratios of individual bodies in order to have them lose energy more.

nv_float angular_damping

Same as linear_damping but for angular motion.

nv_bool warmstarting

Whether to allow warmstarting constraints or not. This is a really neat feature of Gauss-Seidel based solvers that allows to have greatly increased stability with little overhead. Warmstarting is basically using the last simulation step’s solutions for constraints as the starting guess in the solver. For a game, you don’t really have any reason to turn this off.

nvCoefficientMix restitution_mix

Mixing function used for restitution.

nvCoefficientMix friction_mix

Mixing function used for friction.

Enums

enum nvBroadPhaseAlg

Algorithm used in broad-phase collision detection.

Values:

enumerator nvBroadPhaseAlg_BRUTE_FORCE

Naive brute-force approach. Every rigid body is checked against each other. O(n^2)

enumerator nvBroadPhaseAlg_BVH

BVH (Bounding Volume Hierarchy) tree.

Methods

nvSpace *nvSpace_new()

Create new space instance.

Returns NULL on error. Use nv_get_error to get more information.

Returns:

nvSpace *

void nvSpace_free(nvSpace *space)

Free space.

It’s safe to pass NULL to this function.

Parameters:

space – Space to free

void nvSpace_set_gravity(nvSpace *space, nvVector2 gravity)

Set global gravity vector.

Parameters:
  • space – Space

  • gravity – Gravity vector

nvVector2 nvSpace_get_gravity(const nvSpace *space)

Get global gravity vector.

Parameters:

space – Space

Returns:

nvVector2 Gravity vector

void nvSpace_set_broadphase(nvSpace *space, nvBroadPhaseAlg broadphase_alg_type)

Set the current broadphase algorithm.

Broadphase is where we check for possible collided pairs of bodies. Quickly determining those pairs is important for efficiency before narrowphase.

Parameters:
  • space – Space

  • broadphase_type – Broadphase algorithm

nvBroadPhaseAlg nvSpace_get_broadphase(const nvSpace *space)

Get the current broadphase algorithm.

Parameters:

space – Space

Returns:

nvBroadPhaseAlg

nvSpaceSettings *nvSpace_get_settings(nvSpace *space)

Get the current simulation settings struct.

This returns a pointer to the current settings. So you can directly modify it.

Parameters:

space – Space

Returns:

nvSpaceSettings *

nvProfiler nvSpace_get_profiler(const nvSpace *space)

Get profiler of space.

Parameters:

space – Space

Returns:

nvProfiler

int nvSpace_set_contact_listener(nvSpace *space, nvContactListener listener, void *user_arg)

Set the current contact event listener.

Space allocates using the functions provided by listener param.

Returns non-zero on error. Use nv_get_error to get more information.

Parameters:
  • space – Space

  • listener – Contact event listener

  • user_arg – User argument

nvContactListener *nvSpace_get_contact_listener(const nvSpace *space)

Get the current contact event listener.

Parameters:

space – Space

Returns:

nvContactListener *

int nvSpace_clear(nvSpace *space, nv_bool free_all)

Clear bodies and constraints in space.

Returns non-zero on error. Use nv_get_error to get more information.

Parameters:
  • space – Space

  • free_all – Whether to free objects after removing them from space

Returns:

int Status

int nvSpace_add_rigidbody(nvSpace *space, nvRigidBody *body)

Add body to space.

Returns non-zero on error. Use nv_get_error to get more information.

Parameters:
  • space – Space

  • body – Body to add

Returns:

int Status

int nvSpace_remove_rigidbody(nvSpace *space, nvRigidBody *body)

Remove body from the space.

After removing the body, managing it’s memory belongs to user. You should use nvRigidBody_free if you are not going to add it to the space again.

This function also removes any constraints attached to the body.

Returns non-zero on error. Use nv_get_error to get more information.

Parameters:
  • space – Space

  • body – Body to remove

Returns:

int Status

int nvSpace_add_constraint(nvSpace *space, nvConstraint *cons)

Add constraint to space.

Returns non-zero on error. Use nv_get_error to get more information.

Parameters:
  • space – Space

  • cons – Constraint to add

Returns:

int Status

int nvSpace_remove_constraint(nvSpace *space, nvConstraint *cons)

Remove constraint from the space.

After removing the constraint managing it’s memory belongs to user. You should use nvConstraint_free if you are not going to add it to the space again.

Returns non-zero on error. Use nv_get_error to get more information.

Parameters:
  • space – Space

  • cons – Constraint to remove

Returns:

int

nv_bool nvSpace_iter_bodies(nvSpace *space, nvRigidBody **body, size_t *index)

Iterate over the rigid bodies in this space.

Make sure to reset the index if you alter the space in any way while iterating.

Parameters:
  • space – Space

  • body – Pointer to rigid body

  • index – Pointer to iteration index

Returns:

nv_bool

nv_bool nvSpace_iter_constraints(nvSpace *space, nvConstraint **cons, size_t *index)

Iterate over the constraints in this space.

Make sure to reset the index if you alter the space in any way while iterating.

Parameters:
  • space – Space

  • cons – Pointer to constraint

  • index – Pointer to iteration index

Returns:

nv_bool

void nvSpace_step(nvSpace *space, nv_float dt)

Advance the simulation.

Parameters:
  • space – Space instance

  • dt – Time step size (delta time)

void nvSpace_cast_ray(nvSpace *space, nvVector2 from, nvVector2 to, nvRayCastResult *results_array, size_t *num_hits, size_t capacity)

Cast a ray in space and collect intersections.

Parameters:
  • space – Space

  • from – Starting position of ray in world space

  • to – End position of ray in world space

  • results_array – Array of ray cast result structs to be filled

  • num_hits – Number of hits (size of results array)

  • capacity – Size allocated for the results array