From 79ceac1005a7cbef42f36dbe378592215506c4df Mon Sep 17 00:00:00 2001 From: kotofyt Date: Wed, 18 Mar 2026 18:41:28 +0200 Subject: [PATCH] different stuff in physics --- game/client/milmoba/player.cpp | 20 +++++- game/client/worldrender.cpp | 7 ++ game/server/milmoba/player.cpp | 32 +++++++++ game/server/milmoba/player.h | 4 ++ public/iphysics.h | 25 ++++++- rapier/physics.cpp | 12 ++++ rapier/physics.h | 18 +++++ rapier/physics.rs | 123 +++++++++++++++++++++++++++++---- 8 files changed, 223 insertions(+), 18 deletions(-) diff --git a/game/client/milmoba/player.cpp b/game/client/milmoba/player.cpp index 0223b3f..1659fa2 100644 --- a/game/client/milmoba/player.cpp +++ b/game/client/milmoba/player.cpp @@ -13,19 +13,37 @@ void C_MOBAPlayer::Spawn() BaseClass::Spawn(); SetThink(Think); SetScale(1); - vCameraPos = {0,0,-20}; }; void C_MOBAPlayer::Think( float fDelta ) { +<<<<<<< HEAD C_MOBAPlayer *pEntity = (C_MOBAPlayer*)UTIL_GetLocalPlayer(); +<<<<<<< HEAD +======= +======= + C_MOBAPlayer *pPlayerEntity = (C_MOBAPlayer*)UTIL_GetLocalPlayer(); + +<<<<<<< HEAD +>>>>>>> c251089 (different stuff in physics) +>>>>>>> a2652ed (merges) m_vMovementVector.z = m_bIsForward - m_bIsBack; m_vMovementVector.x = m_bIsLeft - m_bIsRight; if (pEntity == this) +======= + m_vMovementVector.z = m_bIsBack - m_bIsForward; + m_vMovementVector.x = m_bIsRight - m_bIsLeft; + + if (pPlayerEntity == this) +>>>>>>> 83e8198 (different stuff in physics) { + Vector vCameraPos; + vCameraPos = GetAbsOrigin(); + vCameraPos.z = 20; + vCameraPos.y+=3; g_pWorldRenderer->SetCameraPosition(vCameraPos); } BaseClass::Think(fDelta); diff --git a/game/client/worldrender.cpp b/game/client/worldrender.cpp index 4f1236d..88fd6b5 100644 --- a/game/client/worldrender.cpp +++ b/game/client/worldrender.cpp @@ -228,6 +228,13 @@ void CFunnyWorldRenderer::Frame( float fDelta ) glm_mat4_identity(matCamera); glm_mat4_identity(matCamera2); glm_translate(matCamera2, m_vPos); +<<<<<<< HEAD +======= +<<<<<<< HEAD +======= + glm_mat4_inv(matCamera2, matCamera2); +>>>>>>> c251089 (different stuff in physics) +>>>>>>> a2652ed (merges) glm_perspective(glm_rad(75), uWidth/(float)uHeight, 0.01, 10000, matCamera); glm_mul(matCamera, matCamera2, matCamera); m_pViewBufferData = (ViewBuffer_t*)m_pViewBuffer->Map(); diff --git a/game/server/milmoba/player.cpp b/game/server/milmoba/player.cpp index 0ed6cf4..05a6ca4 100644 --- a/game/server/milmoba/player.cpp +++ b/game/server/milmoba/player.cpp @@ -3,14 +3,35 @@ #include "entitysystem.h" +CMOBAPlayer::CMOBAPlayer() +{ + m_hCuboid = g_pPhysics->CreateBall({1}); +} + +CMOBAPlayer::~CMOBAPlayer() +{ + +} void CMOBAPlayer::Spawn() { CBaseEntity::Spawn(); +<<<<<<< HEAD +======= +<<<<<<< HEAD +>>>>>>> a2652ed (merges) SetPhysics(k_EPhysics_Static); SetModel("game/core/models/sphere.fmdl"); SetScale(1); SetAbsOrigin({0,-14.5, 0}); +<<<<<<< HEAD +======= +======= + SetModel("game/core/models/sphere.fmdl"); + SetScale(1); + SetAbsOrigin({0,-11.5, 0}); +>>>>>>> c251089 (different stuff in physics) +>>>>>>> a2652ed (merges) SetThink(Think); }; @@ -26,7 +47,18 @@ void CMOBAPlayer::Think( float fDelta ) vPosition.x += m_vMovementVector.x*fDelta*5; vPosition.z += m_vMovementVector.z*fDelta*5; +<<<<<<< HEAD SetAbsOrigin(vPosition); +<<<<<<< HEAD +======= +======= + CastResult_t result = g_pPhysicsWorld->ShapeCast(m_hCuboid, {0,0,0,1}, vPosition, {vPosition.x, vPosition.y, -100}); + if (result.m_bIsHit) + SetAbsOrigin(result.m_vCollisionPoint); + else + SetAbsOrigin(vPosition); +>>>>>>> c251089 (different stuff in physics) +>>>>>>> a2652ed (merges) }; LINK_ENTITY_TO_CLASS(player, CMOBAPlayer) diff --git a/game/server/milmoba/player.h b/game/server/milmoba/player.h index f578bc9..6f3e12d 100644 --- a/game/server/milmoba/player.h +++ b/game/server/milmoba/player.h @@ -10,10 +10,14 @@ public: DECLARE_DATADESC(); DECLARE_SERVERCLASS() + CMOBAPlayer(); + virtual ~CMOBAPlayer(); virtual void Spawn( void ) override; void Think( float fDelta ); private: Vector m_vMovementVector = {}; + + HShape m_hCuboid = NULL; }; #endif diff --git a/public/iphysics.h b/public/iphysics.h index 3bb1883..e4c87c5 100644 --- a/public/iphysics.h +++ b/public/iphysics.h @@ -4,6 +4,10 @@ #include "tier0/platform.h" #include "trig.h" + +typedef void *HShape; +typedef void *HCollider; + #ifndef PHYSICS_OBJECT_DEFINED struct BallShape_t { @@ -25,6 +29,19 @@ struct TriangleMeshShape_t uint32_t m_nIndiciesCount; }; +struct CastResult_t +{ + bool m_bIsHit; + HCollider m_hCollider; + + Vector m_vCollisionPoint; + + // 0 to 1 + float m_fTime; + // 0 to lenght + float m_fDistance; +}; + enum EPhysicsBodyType { k_EPhysics_Static, @@ -34,17 +51,16 @@ enum EPhysicsBodyType }; #endif -typedef void *HShape; -typedef void *HCollider; - abstract_class IPhysicsBody { public: virtual void SetPosition( Vector vPosition ) = 0; virtual void SetRotation( Quat vRotation ) = 0; + virtual Vector GetPosition() = 0; virtual Quat GetRotation() = 0; + virtual void SetType( EPhysicsBodyType eType ) = 0; virtual void SetGravityScale( float fScale ) = 0; }; @@ -58,6 +74,9 @@ public: virtual void DestroyPhysicsBody( IPhysicsBody *pBody ) = 0; virtual void SetGravity( float fGravity ) = 0; + + virtual CastResult_t RayCast( Vector vBegin, Vector vEnd ) = 0; + virtual CastResult_t ShapeCast( HShape hShape, Quat vOrientation, Vector vBegin, Vector vEnd ) = 0; }; diff --git a/rapier/physics.cpp b/rapier/physics.cpp index 5949dfc..ad80392 100644 --- a/rapier/physics.cpp +++ b/rapier/physics.cpp @@ -80,6 +80,18 @@ public: } + virtual CastResult_t RayCast( Vector vBegin, Vector vEnd ) override + { + return CRapierPhysicsWorld_RayCast(m_pWorld, vBegin, vEnd); + } + + virtual CastResult_t ShapeCast( HShape hShape, Quat vOrientation, Vector vBegin, Vector vEnd ) override + { + return CRapierPhysicsWorld_ShapeCast(m_pWorld, (RapierShape_t*)hShape, vOrientation, vBegin, vEnd ); + + } + + RapierWorld_t *m_pWorld = NULL; }; diff --git a/rapier/physics.h b/rapier/physics.h index 580c8e3..d9d6326 100644 --- a/rapier/physics.h +++ b/rapier/physics.h @@ -33,6 +33,14 @@ typedef struct Quat { float w; } Quat; +typedef struct CastResult_t { + bool m_bIsHit; + const struct RapierCollider_t *m_hCollider; + struct Vector m_vCollisionPoint; + float m_fTime; + float m_fDistance; +} CastResult_t; + typedef struct BallShape_t { float m_fRadius; } BallShape_t; @@ -77,6 +85,16 @@ struct RapierPhysicsBody_t *CRapierPhysicsWorld_CreateRigidBody(struct RapierWor void CRapierPhysicsWorld_Frame(struct RapierWorld_t *this_, float fDelta); +struct CastResult_t CRapierPhysicsWorld_RayCast(struct RapierWorld_t *this_, + struct Vector vBegin, + struct Vector vEnd); + +struct CastResult_t CRapierPhysicsWorld_ShapeCast(struct RapierWorld_t *this_, + struct RapierShape_t *pShape, + struct Quat vOrientation, + struct Vector vBegin, + struct Vector vEnd); + struct RapierShape_t *CRapierPhysics_CreateBall(struct RapierPhysics_t *this_, struct BallShape_t ball); diff --git a/rapier/physics.rs b/rapier/physics.rs index 0cad87b..bf7cc89 100644 --- a/rapier/physics.rs +++ b/rapier/physics.rs @@ -16,10 +16,29 @@ macro_rules! V_malloc { use std::{default, ops::Index, ptr::{self, null, null_mut}, slice::from_raw_parts, sync::Arc}; use parry3d::{glamx::vec3, shape::{Shape, ShapeType, SharedShape}}; +use parry3d::{glamx::{Pose3A}, query::ShapeCastOptions}; use rapier3d::{geometry::Ball, na::{UnitQuaternion, Vector4, coordinates::XYZ}}; use rapier3d::prelude::*; use libc::{malloc, free}; +#[repr(C)] +#[derive(Default, Debug)] +pub struct Vector { + x: f32, + y: f32, + z: f32, +} +#[repr(C)] +#[derive(Default, Debug)] +pub struct Quat { + x: f32, + y: f32, + z: f32, + w: f32, +} + + + #[repr(C)] #[derive(Clone, Copy)] pub struct BallShape_t @@ -67,6 +86,17 @@ pub enum EPhysicsBodyType +#[repr(C)] +#[derive(Debug, Default)] +pub struct CastResult_t +{ + m_bIsHit: bool, + m_hCollider: *const RapierCollider_t, + m_vCollisionPoint: Vector, + m_fTime: f32, + m_fDistance: f32, +} + #[derive(Clone)] #[derive(Debug)] pub struct RapierCollider_t @@ -124,12 +154,6 @@ pub unsafe extern "C" fn CRapierPhysicsBody_SetRotation( this: *mut RapierPhysic } -#[repr(C)] -pub struct Vector { - x: f32, - y: f32, - z: f32, -} #[no_mangle] pub unsafe extern "C" fn CRapierPhysicsBody_GetPosition( this: *mut RapierPhysicsBody_t ) -> Vector @@ -140,14 +164,6 @@ pub unsafe extern "C" fn CRapierPhysicsBody_GetPosition( this: *mut RapierPhysic return Vector { x: position[0], y: position[1], z: position[2]} } -#[repr(C)] -pub struct Quat { - x: f32, - y: f32, - z: f32, - w: f32, -} - #[no_mangle] pub unsafe extern "C" fn CRapierPhysicsBody_GetRotation( this: *mut RapierPhysicsBody_t ) -> Quat { @@ -226,6 +242,85 @@ pub unsafe extern "C" fn CRapierPhysicsWorld_CreateRigidBody( pBody } +#[no_mangle] +pub unsafe extern "C" fn CRapierPhysicsWorld_RayCast( this: *mut RapierWorld_t, vBegin: Vector, vEnd: Vector ) -> CastResult_t +{ + let mut cast = CastResult_t::default(); + let vDir = Vector{ x: vEnd.x-vBegin.x, y:vEnd.y-vBegin.y, z:vEnd.z-vBegin.z}; + let fMaxDistance = f32::sqrt(vDir.x*vDir.x+vDir.y*vDir.y+vDir.z*vDir.z); + let vNormalizedDir = Vector{ x: vDir.x/fMaxDistance, y:vDir.y/fMaxDistance, z:vDir.z/fMaxDistance}; + let ray = Ray::new( + Vec3 { x: vBegin.x, y: vBegin.y, z: vBegin.z }, + Vec3 { x: vNormalizedDir.x, y: vNormalizedDir.y, z: vNormalizedDir.z }); + let queryPipeline = (*this).m_broadPhase.as_query_pipeline( + (*this).m_narrowPhase.query_dispatcher(), + &(*this).m_rigidBodies, + &(*this).m_colliders, + QueryFilter::default(), + ); + if let Some((handle, intersection)) = queryPipeline.cast_ray_and_get_normal(&ray, fMaxDistance, true) + { + cast.m_bIsHit = true; + cast.m_fDistance = intersection.time_of_impact; + cast.m_fTime = intersection.time_of_impact/fMaxDistance; + cast.m_vCollisionPoint = Vector{ + x: vBegin.x + vNormalizedDir.x * intersection.time_of_impact, + y: vBegin.y + vNormalizedDir.y * intersection.time_of_impact, + z: vBegin.z + vNormalizedDir.z * intersection.time_of_impact, + }; + + } + cast +} + +#[no_mangle] +pub unsafe extern "C" fn CRapierPhysicsWorld_ShapeCast( this: *mut RapierWorld_t, pShape: *mut RapierShape_t, vOrientation: Quat, vBegin: Vector, vEnd: Vector ) -> CastResult_t +{ + let mut cast = CastResult_t::default(); + let vDir = Vector{ x: vEnd.x-vBegin.x, y:vEnd.y-vBegin.y, z:vEnd.z-vBegin.z}; + let fMaxDistance = f32::sqrt(vDir.x*vDir.x+vDir.y*vDir.y+vDir.z*vDir.z); + let vNormalizedDir = Vector{ x: vDir.x/fMaxDistance, y:vDir.y/fMaxDistance, z:vDir.z/fMaxDistance}; + let queryPipeline = (*this).m_broadPhase.as_query_pipeline( + (*this).m_narrowPhase.query_dispatcher(), + &(*this).m_rigidBodies, + &(*this).m_colliders, + QueryFilter::default(), + ); + let vRustDir = Vector{ x: vNormalizedDir.x, y: vNormalizedDir.y, z: vNormalizedDir.z }; + let mut castOptions = ShapeCastOptions::default(); + castOptions.stop_at_penetration = true; + castOptions.max_time_of_impact = fMaxDistance; + let shapeStats = Pose3::from_parts(Vec3::from_array([vBegin.x, vBegin.y, vBegin.z]),glamx::Quat::from_xyzw(vOrientation.x, vOrientation.y, vOrientation.z, vOrientation.w)); + let shape: &dyn Shape; + match (*pShape).m_sharedShape.as_typed_shape() + { + TypedShape::Ball(s) => { shape = s; } + TypedShape::Cuboid(s) => { shape = s; } + TypedShape::TriMesh(s) => { shape = s; } + default => { + return cast; + } + } + if let Some((handle, intersection)) = queryPipeline.cast_shape( + &shapeStats, + Vec3 { x: vNormalizedDir.x, y: vNormalizedDir.y, z: vNormalizedDir.z }, + shape, + castOptions) + { + cast.m_bIsHit = true; + cast.m_fDistance = intersection.time_of_impact; + cast.m_fTime = intersection.time_of_impact/fMaxDistance; + cast.m_vCollisionPoint = Vector{ + x: vBegin.x + vNormalizedDir.x * intersection.time_of_impact, + y: vBegin.y + vNormalizedDir.y * intersection.time_of_impact, + z: vBegin.z + vNormalizedDir.z * intersection.time_of_impact, + }; + + } + cast +} + + #[no_mangle] pub unsafe extern "C" fn CRapierPhysics_New() -> *mut RapierPhysics_t {