nitro-engine/include/NEPhysics.h
Antonio Niño Díaz 82171bbf69 chore: Simplify copyright years in notices
Instead of listing every individual year, keep only the first and last
years.
2024-03-09 01:42:29 +00:00

238 lines
7.8 KiB
C

// SPDX-License-Identifier: MIT
//
// Copyright (c) 2008-2022 Antonio Niño Díaz
//
// This file is part of Nitro Engine
#ifndef NE_PHYSICS_H__
#define NE_PHYSICS_H__
/// @file NEPhysics.h
/// @brief Simple physics engine.
#include "NEModel.h"
/// @defgroup physics Physics engine
///
/// A very simple physics engine. It only supports axis-aligned bounding boxes
/// at the moment.
///
/// @{
#define NE_DEFAULT_PHYSICS 64 ///< Default max number of physic objects
/// Minimun speed that an object needs to have to rebound after a collision.
///
/// If the object has less speed than this, it will stop after a collision.
#define NE_MIN_BOUNCE_SPEED (floattof32(0.01))
/// Object types supported by the physics engine.
typedef enum {
NE_BoundingBox = 1, ///< Axis-aligned bounding box.
NE_BoundingSphere = 2, ///< Bounding sphere.
NE_Dot = 3 ///< Dot. Use this for really small objects.
} NE_PhysicsTypes;
/// Possible actions that can happen to an object after a collision.
typedef enum {
NE_ColNothing = 0, ///< Ignore the collision.
NE_ColBounce, ///< ReboundBounce against the object.
NE_ColStop ///< Stop.
} NE_OnCollision;
/// Holds information of a physics object.
//
/// Values are in fixed point (f32).
///
/// The position of the object is obtained from the NE_Model object, it's not
/// stored inside the physics object.
typedef struct {
NE_Model *model; ///< Model this physics object affects.
NE_PhysicsTypes type; ///< Type of physics object (AABB, sphere, dot).
bool enabled; ///< True if this object is enabled
int xspeed; ///< X speed of model.
int yspeed; ///< Y speed of model.
int zspeed; ///< Z speed of model.
int radius; ///< Radius of a spheres
int xsize; ///< X size of an AABB
int ysize; ///< Y size of an AABB
int zsize; ///< Z size of an AABB
int gravity; ///< Intensity of gravity
int friction; ///< Intensity of friction
int keptpercent; ///< Percentage of energy remaining after a bounce.
NE_OnCollision oncollision; ///< Action to do if there is a collision.
bool iscolliding; ///< True if a collision has been detected.
int physicsgroup; ///< Objects interact with others in the same group only
} NE_Physics;
/// Creates a new physics object.
///
/// @param type Type of physics object.
/// @return Pointer to the newly created object.
NE_Physics *NE_PhysicsCreate(NE_PhysicsTypes type);
/// Deletes a physics object.
///
/// @param pointer Pointer to the object.
void NE_PhysicsDelete(NE_Physics *pointer);
/// Deletes all physic objects and frees all memory used by them.
void NE_PhysicsDeleteAll(void);
/// Resets the physics engine and sets the maximun number of objects.
///
/// @param max_objects Number of objects. If it is lower than 1, it will create
/// space for NE_DEFAULT_PHYSICS.
/// @return Returns 0 on success.
int NE_PhysicsSystemReset(int max_objects);
/// Ends physics engine and frees all memory used by it.
void NE_PhysicsSystemEnd(void);
/// Set radius of a physics object that is a bounding sphere.
///
/// @param pointer Pointer to the object.
/// @param radius Radius of the sphere (f32).
void NE_PhysicsSetRadiusI(NE_Physics *pointer, int radius);
/// Set radius of a physics object that is a bounding sphere.
///
/// @param p Pointer to the object.
/// @param r Radius of the sphere (float).
#define NE_PhysicsSetRadius(p, r) \
NE_PhysicsSetRadiusI(p, floattof32(r))
/// Set speed of a physics object.
///
/// @param pointer Pointer to the object.
/// @param x (x, y, z) Speed vector (f32).
/// @param y (x, y, z) Speed vector (f32).
/// @param z (x, y, z) Speed vector (f32).
void NE_PhysicsSetSpeedI(NE_Physics *pointer, int x, int y, int z);
/// Set speed of a physics object.
///
/// @param p Pointer to the object.
/// @param x (x, y, z) Speed vector (float).
/// @param y (x, y, z) Speed vector (float).
/// @param z (x, y, z) Speed vector (float).
#define NE_PhysicsSetSpeed(p, x, y, z) \
NE_PhysicsSetSpeedI(p, floattof32(x), floattof32(y), floattof32(z))
/// Set size of a physics object that is an bounding box.
///
/// @param pointer Pointer to the physics object.
/// @param x (x, y, z) Size (f32).
/// @param y (x, y, z) Size (f32).
/// @param z (x, y, z) Size (f32).
void NE_PhysicsSetSizeI(NE_Physics *pointer, int x, int y, int z);
/// Set size of a physics object that is an bounding box.
///
/// @param p Pointer to the physics object.
/// @param x (x, y, z) Size (float).
/// @param y (x, y, z) Size (float).
/// @param z (x, y, z) Size (float).
#define NE_PhysicsSetSize(p, x, y, z) \
NE_PhysicsSetSizeI(p, floattof32(x), floattof32(y), floattof32(z))
/// Set gravity of a physics object.
///
/// @param pointer Pointer to the physics object.
/// @param gravity Gravity on the Y axis (f32).
void NE_PhysicsSetGravityI(NE_Physics *pointer, int gravity);
/// Set gravity of a physics object.
///
/// @param p Pointer to the physics object.
/// @param g Gravity on the Y axis (float).
#define NE_PhysicsSetGravity(p, g) \
NE_PhysicsSetGravityI(p, floattof32(g))
/// Set friction of a physics object.
///
/// @param pointer Pointer to the physics object.
/// @param friction Friction (f32).
void NE_PhysicsSetFrictionI(NE_Physics *pointer, int friction);
/// Set friction of a physics object.
///
/// @param p Pointer to the physics object.
/// @param f Friction (float).
#define NE_PhysicsSetFriction(p, f) \
NE_PhysicsSetFrictionI(p, floattof32(f))
/// Set percentage of energy kept after a bounce.
///
/// @param pointer Pointer to the physics object.
/// @param percent Percentage of energy kept.
void NE_PhysicsSetBounceEnergy(NE_Physics *pointer, int percent);
/// Enable movement of a physics object.
///
/// If disabled, it will never update the position of this object. Use it for
/// objects that interact with others, but that are fixed, like the floor.
///
/// @param pointer Pointer to the physics object.
/// @param value True enables movelent, false disables it.
void NE_PhysicsEnable(NE_Physics *pointer, bool value);
/// Assign a model object to a physics object.
///
/// @param physics Pointer to the physics object.
/// @param modelpointer Pointer to the model.
void NE_PhysicsSetModel(NE_Physics *physics, NE_Model *modelpointer);
/// Sets physics group of an object.
///
/// Collisions do only work between objects with the same group. This can be
/// useful when there are two sets of objects that never interact with each
/// other. This way the engine can stop checking interactions between them.
///
/// @param physics Pointer to the object.
/// @param group New physics group number.
void NE_PhysicsSetGroup(NE_Physics *physics, int group);
/// Set action to do if this object collides with another one.
///
/// @param physics Pointer to the object.
/// @param action Action.
void NE_PhysicsOnCollision(NE_Physics *physics, NE_OnCollision action);
/// Returns true if given object is colliding.
///
/// This doesn't work with objects that have been disabled with
/// NE_PhysicsEnable().
///
/// @param pointer Pointer to the object.
/// @return True if there is a collision, false otherwise.
bool NE_PhysicsIsColliding(const NE_Physics *pointer);
/// Updates all physics objects.
void NE_PhysicsUpdateAll(void);
/// Updates the provided physics object.
///
/// @param pointer Pointer to the object.
void NE_PhysicsUpdate(NE_Physics *pointer);
/// Returns true if the given objects are colliding.
///
/// It doesn't check physic groups. Two objects in different groups can still
/// collide according to this function.
///
/// @param pointer1 Pointer to first object.
/// @param pointer2 Pointer to second object.
/// @return Returns true if two objects are colliding.
bool NE_PhysicsCheckCollision(const NE_Physics *pointer1,
const NE_Physics *pointer2);
/// @}
#endif // NE_PHYSICS_H__