From 58ff2f3a725c70c35fae6b499ba4ae3cf7eaa058 Mon Sep 17 00:00:00 2001 From: nillerusr Date: Tue, 17 Oct 2023 20:49:22 +0300 Subject: [PATCH] improve collision loading, fix wrong axes --- vphysics-physx/physics_collide.cpp | 67 +++++++++++++++++++++++------- vphysics-physx/physics_collide.h | 0 vphysics-physx/physics_object.cpp | 36 +++++++++++++--- vphysics-physx/physics_trace.h | 3 ++ 4 files changed, 84 insertions(+), 22 deletions(-) create mode 100644 vphysics-physx/physics_collide.h diff --git a/vphysics-physx/physics_collide.cpp b/vphysics-physx/physics_collide.cpp index 42c174c9..04d6011d 100644 --- a/vphysics-physx/physics_collide.cpp +++ b/vphysics-physx/physics_collide.cpp @@ -320,6 +320,32 @@ struct moppheader_t : public physcollideheader_t }; #endif +class CPhysCollidePx : public CPhysCollide +{ +public: + CPhysCollidePx(PxShape *shape) + { + m_pPxShape = shape; + } + + virtual PxShape *GetPxShape() + { + return m_pPxShape; + } + + IVP_SurfaceManager *CreateSurfaceManager( short & ) const { return NULL; } + virtual void GetAllLedges( IVP_U_BigVector &ledges ) const {} + unsigned int GetSerializationSize() { return 0; } + int GetVCollideIndex() const { return 0; } + Vector GetMassCenter() const { return Vector(0, 0, 0); } + void SetMassCenter( const Vector &massCenter ) {} + void OutputDebugInfo() const {} + unsigned int GetSerializationSize() const { return 0; } + unsigned int SerializeToBuffer( char *pDest, bool bSwap = false ) const { return 0; } +private: + PxShape *m_pPxShape; +}; + class CPhysCollideCompactSurface : public CPhysCollide { public: @@ -1829,7 +1855,7 @@ float CPhysicsCollision::CollideSurfaceArea( CPhysCollide *pCollide ) return area; } -PxConvexMesh *IVPLedgeToConvexShape( const ivp_compat::compactledge_t *pLedge ) +PxShape *IVPLedgeToConvexShape( const ivp_compat::compactledge_t *pLedge ) { if ( !pLedge->n_triangles ) return nullptr; @@ -1852,7 +1878,7 @@ PxConvexMesh *IVPLedgeToConvexShape( const ivp_compat::compactledge_t *pLedge ) const int nIndex = pTriangles[ i ].c_three_edges[ j ].start_point_index; const float *pVertex = reinterpret_cast< const float * >( pVertices + ( nIndex * IVPAlignedVectorSize ) ); - convexVerts[ ( i * 3 ) + j ] = PxVec3( IVP2HL(pVertex[0]), IVP2HL(pVertex[1]), IVP2HL(pVertex[2]) ); + convexVerts[ ( i * 3 ) + j ] = PxVec3( IVP2HL(pVertex[0]), IVP2HL(pVertex[2]), -IVP2HL(pVertex[1]) ); } } @@ -1870,19 +1896,19 @@ PxConvexMesh *IVPLedgeToConvexShape( const ivp_compat::compactledge_t *pLedge ) PxDefaultMemoryInputData input(buf.getData(), buf.getSize()); PxConvexMesh* convexMesh = gPxPhysics->createConvexMesh(input); - + PxMaterial *mat = gPxPhysics->createMaterial(0.5f, 0.5f, 0.6f); + PxShape *shape = gPxPhysics->createShape( PxConvexMeshGeometry(convexMesh), *mat ); - Msg("Cooking success %u!\n", convexMesh->getNbVertices()); + if( shape ) + Msg("Cooking success %u!\n", convexMesh->getNbVertices()); //pConvexShape->SetUserData( pLedge->client_data ); - return convexMesh; + return shape; } static void GetAllIVPEdges(const ivp_compat::compactledgenode_t *pNode, CUtlVector *vecOut) { - - if (!pNode || !vecOut) return; if ( !pNode->IsTerminal() ) @@ -1902,20 +1928,27 @@ CPhysCollide *DeserializeIVP_Poly( const ivp_compat::compactsurface_t* pSurface CUtlVector< const ivp_compat::compactledge_t * > ledges; GetAllIVPEdges( pFirstLedgeNode, &ledges ); - Msg("ledge count - %d\n", ledges.Count()); +// if( ledges.Count() <= 5 ) +// return NULL; + + PxShape *mesh = IVPLedgeToConvexShape( ledges[0] ); + mesh->userData = NULL; if( ledges.Count() == 1 ) - { - PxConvexMesh *mesh = IVPLedgeToConvexShape( ledges[0] ); - return (CPhysCollide*)mesh; - } + return new CPhysCollidePx( mesh ); + +// if( ledges.Count() > 5 ) +// return NULL; - for( int i = 0; ledges.Count(); i++ ) + PxShape *prevMesh = mesh; + for( int i = 1; i < ledges.Count(); i++ ) { - + PxShape *nextMesh = IVPLedgeToConvexShape( ledges[i] ); + prevMesh->userData = nextMesh; + prevMesh = nextMesh; } - return NULL; + return new CPhysCollidePx( mesh ); } CPhysCollide *DeserializeIVP_Poly( const ivp_compat::collideheader_t *pCollideHeader ) @@ -1953,10 +1986,12 @@ void CPhysicsCollision::VCollideLoad( vcollide_t *pOutput, int solidCount, const if ( pCollideHeader->version != VPHYSICS_COLLISION_VERSION ) Warning( "Solid with unknown version: 0x%x, may crash!\n", pCollideHeader->version ); + CPhysCollide *collide; switch ( pCollideHeader->modelType ) { case COLLIDE_POLY: - pOutput->solids[ i ] = DeserializeIVP_Poly( pCollideHeader ); + collide = DeserializeIVP_Poly( pCollideHeader ); + pOutput->solids[ i ] = collide; break; default: Warning( "Unsupported solid type 0x%x on solid %d. Skipping...\n", (int)pCollideHeader->modelType, i ); diff --git a/vphysics-physx/physics_collide.h b/vphysics-physx/physics_collide.h new file mode 100644 index 00000000..e69de29b diff --git a/vphysics-physx/physics_object.cpp b/vphysics-physx/physics_object.cpp index 66009b00..26cc869b 100644 --- a/vphysics-physx/physics_object.cpp +++ b/vphysics-physx/physics_object.cpp @@ -1062,9 +1062,12 @@ CPhysicsObject *CreatePhysicsObject( CPhysicsEnvironment *pEnvironment, const CP CPhysicsObject *pObject = new CPhysicsObject(); short collideType; - IVP_SurfaceManager *pSurman = CreateSurfaceManager( pCollisionModel, collideType ); - if ( !pSurman ) - return NULL; + +// IVP_SurfaceManager *pSurman = CreateSurfaceManager( pCollisionModel, collideType ); + +// if ( !pSurman ) +// return NULL; + pObject->m_collideType = collideType; pObject->m_asleepSinceCreation = true; @@ -1072,9 +1075,31 @@ CPhysicsObject *CreatePhysicsObject( CPhysicsEnvironment *pEnvironment, const CP // IVP_Polygon *realObject = pEnvironment->GetIVPEnvironment()->create_polygon(pSurman, &objectTemplate, &rotation, &pos); + if( !pCollisionModel ) + return NULL; + PxScene *scene = pEnvironment->GetPxScene(); - PxConvexMesh *mesh = (PxConvexMesh*)pCollisionModel; + PxShape *shape = pCollisionModel->GetPxShape(); + + if( shape ) + { + RadianEuler radian(angles); + Quaternion qw(radian); + PxQuat q( qw.x, qw.y, qw.z, qw.w ); + + PxTransform t(PxVec3(position.x, position.y, position.z), q); + PxRigidStatic* body = gPxPhysics->createRigidStatic(t); + + while( shape ) + { + body->attachShape( *shape ); + shape = (PxShape*)shape->userData; + } + + scene->addActor(*body); + } +#if 0 if( pCollisionModel && mesh->getNbVertices() != 0 ) { RadianEuler radian(angles); @@ -1094,9 +1119,8 @@ CPhysicsObject *CreatePhysicsObject( CPhysicsEnvironment *pEnvironment, const CP scene->addActor(*body); } -//PxRigidActorExt::createExclusiveShape(*aConvexActor, -// PxConvexMeshGeometry(mesh), aMaterial); } +#endif pObject->Init( pCollisionModel, NULL, materialIndex, pParams->volume, pParams->dragCoefficient, pParams->dragCoefficient ); pObject->SetGameData( pParams->pGameData ); diff --git a/vphysics-physx/physics_trace.h b/vphysics-physx/physics_trace.h index ca24d76e..f59f3214 100644 --- a/vphysics-physx/physics_trace.h +++ b/vphysics-physx/physics_trace.h @@ -11,6 +11,7 @@ #pragma once #endif +#include "physics_globals.h" class Vector; class QAngle; @@ -49,6 +50,7 @@ public: virtual void SetOrthographicAreas( const Vector &areas ) = 0; virtual float GetSphereRadius() const = 0; virtual void OutputDebugInfo() const = 0; + virtual PxShape *GetPxShape() = 0; }; #define LEAFMAP_HAS_CUBEMAP 0x0001 @@ -138,6 +140,7 @@ public: virtual void ComputeOrthographicAreas( float epsilon ) {} virtual void SetOrthographicAreas( const Vector &areas ) {} virtual const collidemap_t *GetCollideMap() const { return NULL; } + virtual PxShape *GetPxShape() { return NULL; } }; class ITraceObject