mirror of
https://github.com/raylib-cs/raylib-cs
synced 2025-04-05 11:19:39 -04:00
- Matrix in raylib is column major whereas in numerics it is row major. The type marshals and works but it needs to be transposed before it can be used. At first I looked into keeping the matrix type and converting between the 2 as that made sense but I think using just the on type and documenting the difference is a better tradeoff. It may be easy to create bugs by forgetting to transpose but with good documentation I think this is better than having to deal with the 2 types. I may be wrong about this so we will see how it goes.
242 lines
10 KiB
C#
242 lines
10 KiB
C#
/* Physac.cs
|
|
*
|
|
* Copyright 2020 Chris Dill
|
|
*
|
|
* Release under zLib License.
|
|
* See LICENSE for details.
|
|
*/
|
|
|
|
using System;
|
|
using System.Numerics;
|
|
using System.Runtime.InteropServices;
|
|
using System.Security;
|
|
using Raylib_cs;
|
|
|
|
namespace Physac_cs
|
|
{
|
|
public enum PhysicsShapeType
|
|
{
|
|
PHYSICS_CIRCLE,
|
|
PHYSICS_POLYGON
|
|
}
|
|
|
|
// Mat2 type (used for polygon shape rotation matrix)
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
|
public struct Mat2
|
|
{
|
|
public float m00;
|
|
public float m01;
|
|
public float m10;
|
|
public float m11;
|
|
}
|
|
|
|
// @TODO Custom array marshall issue https://github.com/ChrisDill/Raylib-cs/issues/9
|
|
// Hack same as raylib.cs _MaterialMap_e_FixedBuffer
|
|
// No easy way to marshall arrays of custom types. no idea why?
|
|
public unsafe struct _Polygon_e_FixedBuffer
|
|
{
|
|
public Vector2 v0;
|
|
public Vector2 v1;
|
|
public Vector2 v2;
|
|
public Vector2 v3;
|
|
public Vector2 v4;
|
|
public Vector2 v5;
|
|
public Vector2 v6;
|
|
public Vector2 v7;
|
|
public Vector2 v8;
|
|
public Vector2 v9;
|
|
public Vector2 v10;
|
|
public Vector2 v11;
|
|
public Vector2 v12;
|
|
public Vector2 v13;
|
|
public Vector2 v14;
|
|
public Vector2 v15;
|
|
public Vector2 v16;
|
|
public Vector2 v17;
|
|
public Vector2 v18;
|
|
public Vector2 v19;
|
|
public Vector2 v20;
|
|
public Vector2 v21;
|
|
public Vector2 v22;
|
|
public Vector2 v23;
|
|
public Vector2 v24;
|
|
|
|
public Vector2 this[int index]
|
|
{
|
|
get
|
|
{
|
|
fixed (Vector2* e = &v0)
|
|
return e[index];
|
|
}
|
|
}
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
|
public struct PolygonData
|
|
{
|
|
public uint vertexCount; // Current used vertex and normals count
|
|
public _Polygon_e_FixedBuffer positions; // Polygon vertex positions vectors
|
|
public _Polygon_e_FixedBuffer normals; // Polygon vertex normals vectors
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
|
public struct PhysicsShape
|
|
{
|
|
public PhysicsShapeType type; // Physics shape type (circle or polygon)
|
|
public IntPtr body; // Shape physics body reference
|
|
public float radius; // Circle shape radius (used for circle shapes)
|
|
public Mat2 transform; // Vertices transform matrix 2x2
|
|
public PolygonData vertexData; // Polygon shape vertices position and normals data (just used for polygon shapes)
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
|
public partial struct PhysicsBodyData
|
|
{
|
|
public uint id;
|
|
|
|
[MarshalAs(UnmanagedType.Bool)]
|
|
public bool enabled;
|
|
|
|
public Vector2 position;
|
|
public Vector2 velocity;
|
|
public Vector2 force;
|
|
public float angularVelocity;
|
|
public float torque;
|
|
public float orient;
|
|
public float inertia;
|
|
public float inverseInertia;
|
|
public float mass;
|
|
public float inverseMass;
|
|
public float staticFriction;
|
|
public float dynamicFriction;
|
|
public float restitution;
|
|
|
|
[MarshalAs(UnmanagedType.Bool)]
|
|
public bool useGravity;
|
|
|
|
[MarshalAs(UnmanagedType.Bool)]
|
|
public bool isGrounded;
|
|
|
|
[MarshalAs(UnmanagedType.Bool)]
|
|
public bool freezeOrient;
|
|
|
|
public PhysicsShape shape;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
|
public struct PhysicsManifoldData
|
|
{
|
|
public uint id; // Reference unique identifier
|
|
public IntPtr bodyA; // Manifold first physics body reference
|
|
public IntPtr bodyB; // Manifold second physics body reference
|
|
public float penetration; // Depth of penetration from collision
|
|
public Vector2 normal; // Normal direction vector from 'a' to 'b'
|
|
public Vector2 contactsA; // Points of contact during collision
|
|
public Vector2 contactsB; // Points of contact during collision
|
|
public uint contactsCount; // Current collision number of contacts
|
|
public float restitution; // Mixed restitution during collision
|
|
public float dynamicFriction; // Mixed dynamic friction during collision
|
|
public float staticFriction; // Mixed static friction during collision
|
|
}
|
|
|
|
[SuppressUnmanagedCodeSecurity]
|
|
public static class Physac
|
|
{
|
|
// Used by DllImport to load the native library.
|
|
public const string nativeLibName = "physac";
|
|
|
|
public const int PHYSAC_MAX_BODIES = 64;
|
|
public const int PHYSAC_MAX_MANIFOLDS = 4096;
|
|
public const int PHYSAC_MAX_VERTICES = 24;
|
|
public const int PHYSAC_CIRCLE_VERTICES = 24;
|
|
|
|
public const int PHYSAC_COLLISION_ITERATIONS = 100;
|
|
public const float PHYSAC_PENETRATION_ALLOWANCE = 0.05f;
|
|
public const float PHYSAC_PENETRATION_CORRECTION = 0.4f;
|
|
|
|
// Initializes physics values, pointers and creates physics loop thread
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern void InitPhysics();
|
|
|
|
// Run physics step, to be used if PHYSICS_NO_THREADS is set in your main loop
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern void RunPhysicsStep();
|
|
|
|
// Sets physics fixed time step in milliseconds. 1.666666 by default
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern void SetPhysicsTimeStep(double delta);
|
|
|
|
// Returns true if physics thread is currently enabled
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern bool IsPhysicsEnabled();
|
|
|
|
// Sets physics global gravity force
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern void SetPhysicsGravity(float x, float y);
|
|
|
|
// Creates a new circle physics body with generic parameters
|
|
// IntPtr refers to a PhysicsBodyData *
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern IntPtr CreatePhysicsBodyCircle(Vector2 pos, float radius, float density);
|
|
|
|
// Creates a new rectangle physics body with generic parameters
|
|
// IntPtr refers to a PhysicsBodyData *
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern IntPtr CreatePhysicsBodyRectangle(Vector2 pos, float width, float height, float density);
|
|
|
|
// Creates a new polygon physics body with generic parameters
|
|
// IntPtr refers to a PhysicsBodyData *
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern IntPtr CreatePhysicsBodyPolygon(Vector2 pos, float radius, int sides, float density);
|
|
|
|
// Adds a force to a physics body
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern void PhysicsAddForce(PhysicsBodyData body, Vector2 force);
|
|
|
|
// Adds an angular force to a physics body
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern void PhysicsAddTorque(PhysicsBodyData body, float amount);
|
|
|
|
// Shatters a polygon shape physics body to little physics bodies with explosion force
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern void PhysicsShatter(PhysicsBodyData body, Vector2 position, float force);
|
|
|
|
// Returns the current amount of created physics bodies
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern int GetPhysicsBodiesCount();
|
|
|
|
// Returns a physics body of the bodies pool at a specific index
|
|
// IntPtr refers to a PhysicsBodyData *
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern IntPtr GetPhysicsBody(int index);
|
|
|
|
// Returns the physics body shape type (PHYSICS_CIRCLE or PHYSICS_POLYGON)
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern int GetPhysicsShapeType(int index);
|
|
|
|
// Returns the amount of vertices of a physics body shape
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern int GetPhysicsShapeVerticesCount(int index);
|
|
|
|
// Returns transformed position of a body shape (body position + vertex transformed position)
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern Vector2 GetPhysicsShapeVertex(PhysicsBodyData body, int vertex);
|
|
|
|
// Sets physics body shape transform based on radians parameter
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern void SetPhysicsBodyRotation(PhysicsBodyData body, float radians);
|
|
|
|
// Unitializes and destroy a physics body
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern void DestroyPhysicsBody(PhysicsBodyData body);
|
|
|
|
// Destroys created physics bodies and manifolds and resets global values
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern void ResetPhysics();
|
|
|
|
// Unitializes physics pointers and closes physics loop thread
|
|
[DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern void ClosePhysics();
|
|
}
|
|
}
|