// 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__