working physics

This commit is contained in:
2026-03-04 00:18:56 +02:00
parent 02898d62c0
commit 9884006888
12 changed files with 462 additions and 53 deletions

View File

@@ -4,15 +4,20 @@
#include "tier1/utlstring.h"
CUtlString rapier_lib;
#define ROOT "../"
#define EXTERNAL ROOT"external/"
#define FUNNYSTDLIB EXTERNAL"funnystdlib/"
ADD_DEPENDENCY_BUILD_FILE(tier0, FUNNYSTDLIB"tier0/build.cpp");
ADD_DEPENDENCY_BUILD_FILE(tier1, FUNNYSTDLIB"tier1/build.cpp");
DECLARE_BUILD_STAGE(rapier)
{
Target_t target = Target_t::DefaultTarget();
target.abi = TARGET_ABI_GNU;
CUtlString rapier_lib;
CUtlString szTarget = target.GetTriplet();
if (CommandLine()->CheckParam("-norust"))
return 0;
rapier_lib = CUtlString("rapier/target/%s/release/librapier_rtt.a",szTarget.GetString());
rapier_lib = CUtlString("target/%s/release/librapier_rtt.a",szTarget.GetString());
V_printf("%s\n",rapier_lib.GetString());
CUtlVector<CUtlString> cargo_args = {
"build",
@@ -29,10 +34,29 @@ DECLARE_BUILD_STAGE(rapier)
"--crate",
"rapier_rtt",
"--output",
"../public/physics_gen.h",
"physics.h",
};
runner->Run("cbindgen", "rapier", cbindgen_args);
runner->Wait();
CProject_t cProject = {};
cProject.m_szName = "RapierPhysics";
cProject.files = {
"physics.cpp",
};
cProject.includeDirectories = {
ROOT"public",
FUNNYSTDLIB"public",
};
cProject.bFPIC = true;
LinkProject_t linkProject = ccompiler->Compile(&cProject);
linkProject.linkType = ELINK_DYNAMIC_LIBRARY;
linkProject.objects.AppendTail({rapier_lib});
linkProject.objects.AppendTail({GET_PROJECT_OBJECT(tier1, "tier1")});
CUtlString sz_libRapierPhysics = linker->Link(&linkProject);
ADD_OUTPUT_OBJECT("physics", sz_libRapierPhysics);
return 0;
};

View File

@@ -0,0 +1,115 @@
//================= Copyright kotofyt, All rights reserved ==================//
//
// Purpose: Wrap rapier bindings into C++
//
//===========================================================================//
#include "physics.h"
#define PHYSICS_OBJECT_DEFINED
#include "iphysics.h"
#include "tier1/interface.h"
class CRapierPhysicsBody: public IPhysicsBody
{
public:
virtual void SetPosition( Vector vPosition ) override
{
CRapierPhysicsBody_SetPosition(m_pBody, vPosition.x, vPosition.y, vPosition.z);
}
virtual void SetRotation( Quat vRotation ) override
{
}
virtual void SetGravityScale( float fScale ) override
{
}
RapierPhysicsBody_t *m_pBody;
};
class CRapierPhysicsWorld: public IPhysicsWorld
{
public:
virtual void Frame( float fDelta ) override
{
CRapierPhysicsWorld_Frame(m_pWorld, fDelta);
}
virtual IPhysicsBody *CreateRigidBody( HCollider hCollider, EPhysicsBodyType eType) override
{
RapierPhysicsBody_t *pBody = CRapierPhysicsWorld_CreateRigidBody(m_pWorld, (RapierCollider_t*)hCollider, eType);
if (!pBody)
return NULL;
CRapierPhysicsBody *pPhysicsBody = new CRapierPhysicsBody;
pPhysicsBody->m_pBody = pBody;
return pPhysicsBody;
}
virtual void DestroyPhysicsBody( IPhysicsBody *pBody ) override
{
}
virtual void SetGravity( float fGravity ) override
{
}
RapierWorld_t *m_pWorld;
};
class CRapierPhysics: public IPhysics
{
public:
CRapierPhysics()
{
m_pRustHandle = CRapierPhysics_New();
}
virtual HShape CreateBall( BallShape_t ball ) override
{
return CRapierPhysics_CreateBall(m_pRustHandle, ball);
}
virtual HShape CreateCube( CuboidShape_t ball ) override
{
return CRapierPhysics_CreateCube(m_pRustHandle, ball);
}
virtual void DestroyShape( HShape hShape ) override
{
}
virtual HCollider CreateCollider( HShape hShape ) override
{
return CRapierPhysics_CreateCollider(m_pRustHandle, (RapierShape_t*)hShape);
}
virtual IPhysicsWorld *CreateWorld() override
{
RapierWorld_t *pWorld = CRapierPhysics_CreateWorld(m_pRustHandle);
if (!pWorld)
return NULL;
CRapierPhysicsWorld *pPhysicsWorld = new CRapierPhysicsWorld;
pPhysicsWorld->m_pWorld = pWorld;
return pPhysicsWorld;
}
virtual void DestroyWorld( IPhysicsWorld *pWorld ) override
{
}
RapierPhysics_t *m_pRustHandle;
};
EXPOSE_INTERFACE(CRapierPhysics, IPhysics, PHYSICS_INTERFACE_VERSION)

65
rapier/physics.h Normal file
View File

@@ -0,0 +1,65 @@
#ifndef RAPIER_H
#define RAPIER_H
typedef enum EPhysicsBodyType {
k_EPhysics_Static,
k_EPhysics_Dynamic,
k_EPhysics_KinematicPositionBased,
k_EPhysics_KinematicVelocityBased,
} EPhysicsBodyType;
typedef struct RapierCollider_t RapierCollider_t;
typedef struct RapierPhysicsBody_t RapierPhysicsBody_t;
typedef struct RapierPhysics_t RapierPhysics_t;
typedef struct RapierShape_t RapierShape_t;
typedef struct RapierWorld_t RapierWorld_t;
typedef struct BallShape_t {
float m_fRadius;
} BallShape_t;
typedef struct CuboidShape_t {
float m_fExtentX;
float m_fExtentY;
float m_fExtentZ;
} CuboidShape_t;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void CRapierPhysicsBody_SetPosition(struct RapierPhysicsBody_t *this_,
float fX,
float fY,
float fZ);
struct RapierPhysicsBody_t *CRapierPhysicsWorld_CreateRigidBody(struct RapierWorld_t *this_,
struct RapierCollider_t *pCollider,
enum EPhysicsBodyType eType);
void CRapierPhysicsWorld_Frame(struct RapierWorld_t *this_, float fDelta);
struct RapierShape_t *CRapierPhysics_CreateBall(struct RapierPhysics_t *this_,
struct BallShape_t ball);
struct RapierCollider_t *CRapierPhysics_CreateCollider(struct RapierPhysics_t *this_,
struct RapierShape_t *pShape);
struct RapierShape_t *CRapierPhysics_CreateCube(struct RapierPhysics_t *this_,
struct CuboidShape_t cuboid);
struct RapierWorld_t *CRapierPhysics_CreateWorld(struct RapierPhysics_t *this_);
struct RapierPhysics_t *CRapierPhysics_New(void);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif /* RAPIER_H */

View File

@@ -1,8 +1,11 @@
//================= Copyright kotofyt, All rights reserved ==================//
//
// Purpose: Wrapper for rapier physics
//
//===========================================================================//
/*
* Rapier bindings are defined here
*/
#![allow(nonstandard_style)]
#![allow(unused)]
macro_rules! V_malloc {
($t:ty, $count:expr) => {
@@ -10,41 +13,222 @@ macro_rules! V_malloc {
};
}
use std::ptr::{self, null};
use std::mem::transmute;
use std::{default, ptr::{self, null}, sync::Arc};
use parry3d::shape::{Shape, ShapeType};
use rapier3d::geometry::Ball;
use parry3d::{glamx::vec3, shape::{Shape, ShapeType, SharedShape}};
use rapier3d::{geometry::Ball};
use rapier3d::prelude::*;
use libc::{malloc, free};
#[repr(C)]
#[derive(Clone, Copy)]
pub struct BallShape_t
{
m_fRadius: f32,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct CuboidShape_t
{
m_fExtentX: f32,
m_fExtentY: f32,
m_fExtentZ: f32,
}
#[derive(Clone)]
pub struct RapierShape_t
{
m_eType: ShapeType,
m_shape: *mut dyn Shape,
m_pShape: *mut dyn Shape,
m_sharedShape: SharedShape,
}
pub struct RapierPhysics
#[repr(C)]
pub enum EPhysicsBodyType
{
k_EPhysics_Static,
k_EPhysics_Dynamic,
k_EPhysics_KinematicPositionBased,
k_EPhysics_KinematicVelocityBased,
}
#[derive(Clone)]
pub struct RapierCollider_t
{
m_collider: Collider,
}
#[derive(Clone)]
pub struct RapierWorld_t
{
m_colliders: ColliderSet,
m_rigidBodies: RigidBodySet,
m_islandManager: IslandManager,
m_broadPhase: DefaultBroadPhase,
m_narrowPhase: NarrowPhase,
m_impulseJointSet: ImpulseJointSet,
m_multibodyJointSet: MultibodyJointSet,
m_ccdSolver: CCDSolver,
}
#[derive(Clone)]
pub struct RapierPhysicsBody_t
{
m_body: RigidBody,
m_pCollider: *mut RapierCollider_t,
m_pWorld: *mut RapierWorld_t,
m_hRigidBodyHandle: RigidBodyHandle,
m_hColliderHandle: ColliderHandle,
}
#[derive(Clone, Copy)]
pub struct RapierPhysics_t
{
}
#[no_mangle]
pub unsafe extern "C" fn CRapierPhysicsBody_SetPosition( this: *mut RapierPhysicsBody_t, fX: f32, fY: f32, fZ: f32 )
{
let world: &mut RapierWorld_t = &mut *(*this).m_pWorld;
world.m_rigidBodies[(*this).m_hRigidBodyHandle]
.set_translation(vec3(fX, fY, fZ), true);
print!("{} {} {}\n", fX, fY, fZ);
}
#[no_mangle]
pub unsafe extern "C" fn CRapierPhysicsWorld_Frame( this: *mut RapierWorld_t, fDelta: f32 )
{
let gravity = vec3(0.0, -9.81, 0.0);
let mut integrationParameters = IntegrationParameters::default();
integrationParameters.dt = fDelta;
let mut physicsPipeline = PhysicsPipeline::new();
let physicsHooks = ();
let eventHandler = ();
physicsPipeline.step(
gravity,
&integrationParameters,
&mut (*this).m_islandManager,
&mut (*this).m_broadPhase,
&mut (*this).m_narrowPhase,
&mut (*this).m_rigidBodies,
&mut (*this).m_colliders,
&mut (*this).m_impulseJointSet,
&mut (*this).m_multibodyJointSet,
&mut (*this).m_ccdSolver,
&physicsHooks,
&eventHandler,
);
for (h, b) in (*this).m_colliders.iter()
{
print!("{:?}\n",b.position())
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn CRapierPhysics_CreateBall( ball: BallShape_t ) -> *mut RapierShape_t
#[no_mangle]
pub unsafe extern "C" fn CRapierPhysicsWorld_CreateRigidBody(
this: *mut RapierWorld_t,
pCollider: *mut RapierCollider_t,
eType: EPhysicsBodyType ) -> *mut RapierPhysicsBody_t
{
let eRapierBodyType: RigidBodyType;
match eType
{
EPhysicsBodyType::k_EPhysics_Static => eRapierBodyType = RigidBodyType::Fixed,
EPhysicsBodyType::k_EPhysics_Dynamic => eRapierBodyType = RigidBodyType::Dynamic,
EPhysicsBodyType::k_EPhysics_KinematicPositionBased => eRapierBodyType = RigidBodyType::KinematicPositionBased,
EPhysicsBodyType::k_EPhysics_KinematicVelocityBased => eRapierBodyType = RigidBodyType::KinematicVelocityBased,
}
let pBody = V_malloc!(RapierPhysicsBody_t, 1);
std::ptr::write(&mut (*pBody).m_body, RigidBodyBuilder::new(eRapierBodyType).build());
(*pBody).m_pCollider = pCollider;
let hRigidBodyHandle = (*this).m_rigidBodies.insert((*pBody).m_body.clone());
let hColliderHandle = (*this).m_colliders.insert_with_parent(
(*pCollider).m_collider.clone(), hRigidBodyHandle, &mut (*this).m_rigidBodies);
(*pBody).m_hRigidBodyHandle = hRigidBodyHandle;
(*pBody).m_hColliderHandle = hColliderHandle;
(*pBody).m_pWorld = this;
pBody
}
#[no_mangle]
pub unsafe extern "C" fn CRapierPhysics_New() -> *mut RapierPhysics_t
{
let physics = RapierPhysics_t {};
let pPhysics = V_malloc!(RapierPhysics_t, 1);
*pPhysics = physics;
pPhysics
}
#[no_mangle]
pub unsafe extern "C" fn CRapierPhysics_CreateBall( this: *mut RapierPhysics_t, ball: BallShape_t ) -> *mut RapierShape_t
{
let rapierShape = Ball::new(ball.m_fRadius);
let rapierShapeMemory: *mut Ball = V_malloc!(Ball, 1);
*rapierShapeMemory = rapierShape;
let pRapierShapeMemory: *mut Ball = V_malloc!(Ball, 1);
*pRapierShapeMemory = rapierShape;
let shape: RapierShape_t = RapierShape_t { m_eType: ShapeType::Ball, m_shape: rapierShapeMemory };
let shapeMemory: *mut RapierShape_t = V_malloc!(RapierShape_t, 1);
*shapeMemory = shape;
shapeMemory
let shape: RapierShape_t = RapierShape_t {
m_eType: ShapeType::Ball,
m_pShape: pRapierShapeMemory,
m_sharedShape: SharedShape::new(rapierShape)
};
let pShapeMemory: *mut RapierShape_t = V_malloc!(RapierShape_t, 1);
*pShapeMemory = shape;
pShapeMemory
}
#[no_mangle]
pub unsafe extern "C" fn CRapierPhysics_CreateCube( this: *mut RapierPhysics_t, cuboid: CuboidShape_t ) -> *mut RapierShape_t
{
let rapierShape = Cuboid::new(vec3(cuboid.m_fExtentX, cuboid.m_fExtentY, cuboid.m_fExtentZ));
let pRapierShapeMemory: *mut Cuboid = V_malloc!(Cuboid, 1);
*pRapierShapeMemory = rapierShape;
let shape: RapierShape_t = RapierShape_t {
m_eType: ShapeType::Cuboid,
m_pShape: pRapierShapeMemory,
m_sharedShape: SharedShape::new(rapierShape)
};
let pShapeMemory: *mut RapierShape_t = V_malloc!(RapierShape_t, 1);
*pShapeMemory = shape;
pShapeMemory
}
#[no_mangle]
pub unsafe extern "C" fn CRapierPhysics_CreateCollider( this: *mut RapierPhysics_t, pShape: *mut RapierShape_t ) -> *mut RapierCollider_t
{
let pRapierShape = (*pShape).m_pShape;
let shape: &SharedShape = &(*pShape).m_sharedShape;
let rapierCollider = ColliderBuilder::new(shape.clone()).build();
let collider = RapierCollider_t {
m_collider: rapierCollider,
};
let pCollider = V_malloc!(RapierCollider_t, 1);
*pCollider = collider;
pCollider
}
#[no_mangle]
pub unsafe extern "C" fn CRapierPhysics_CreateWorld( this: *mut RapierPhysics_t ) -> *mut RapierWorld_t
{
let pWorld: *mut RapierWorld_t = V_malloc!(RapierWorld_t, 1);
let world: &mut RapierWorld_t = &mut *pWorld;
std::ptr::write(&mut (*pWorld).m_colliders, ColliderSet::new());
std::ptr::write(&mut (*pWorld).m_rigidBodies, RigidBodySet::new());
std::ptr::write(&mut (*pWorld).m_islandManager, IslandManager::new());
std::ptr::write(&mut (*pWorld).m_broadPhase, DefaultBroadPhase::new());
std::ptr::write(&mut (*pWorld).m_narrowPhase, NarrowPhase::new());
std::ptr::write(&mut (*pWorld).m_impulseJointSet, ImpulseJointSet::new());
std::ptr::write(&mut (*pWorld).m_multibodyJointSet, MultibodyJointSet::new());
std::ptr::write(&mut (*pWorld).m_ccdSolver, CCDSolver::new());
pWorld
}