Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
18051fd0de | |||
|
29985681a1 | ||
|
53cb673849 | ||
|
f72cf388aa | ||
|
87150cc028 | ||
|
704b8aa98e | ||
|
c4f13f04a8 | ||
|
f402495b24 | ||
|
b45295ef7c | ||
|
327ea9dee7 | ||
|
ade05ab153 | ||
|
bfe1baf323 | ||
|
a84ee9062c | ||
|
7c863a351b | ||
|
8fcac9c164 | ||
|
97f6cdfbe2 | ||
|
7a3b3cd96f | ||
|
90e2937b32 | ||
|
23204fcc73 | ||
|
abb470a471 | ||
|
ab527be41a | ||
|
cd1c5bd397 | ||
|
8f8c2556b7 | ||
|
b8558de63e |
7
.github/workflows/build.yml
vendored
7
.github/workflows/build.yml
vendored
@ -2,6 +2,7 @@ name: Build
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
|
||||
jobs:
|
||||
build-linux-i386:
|
||||
runs-on: ubuntu-latest
|
||||
@ -38,7 +39,7 @@ jobs:
|
||||
- name: Build windows-i386
|
||||
run: |
|
||||
git submodule init && git submodule update
|
||||
./waf.bat configure -T debug
|
||||
./waf.bat configure -T debug --32bits
|
||||
./waf.bat build
|
||||
|
||||
build-windows-amd64:
|
||||
@ -49,7 +50,7 @@ jobs:
|
||||
- name: Build windows-amd64
|
||||
run: |
|
||||
git submodule init && git submodule update
|
||||
./waf.bat configure -T debug -8
|
||||
./waf.bat configure -T debug
|
||||
./waf.bat build
|
||||
|
||||
build-dedicated-windows-i386:
|
||||
@ -71,7 +72,7 @@ jobs:
|
||||
- name: Build dedicated windows-amd64
|
||||
run: |
|
||||
git submodule init && git submodule update
|
||||
./waf.bat configure -T debug -d -8
|
||||
./waf.bat configure -T debug -d
|
||||
./waf.bat build
|
||||
|
||||
build-dedicated-linux-i386:
|
||||
|
4
.github/workflows/tests.yml
vendored
4
.github/workflows/tests.yml
vendored
@ -38,7 +38,7 @@ jobs:
|
||||
- name: Run tests windows-i386
|
||||
run: |
|
||||
git submodule init && git submodule update
|
||||
./waf.bat configure -T release --tests --prefix=out/
|
||||
./waf.bat configure -T release --tests --prefix=out/ --32bits
|
||||
./waf.bat install
|
||||
cd out
|
||||
$env:Path = "bin";
|
||||
@ -52,7 +52,7 @@ jobs:
|
||||
- name: Run tests windows-amd64
|
||||
run: |
|
||||
git submodule init && git submodule update
|
||||
./waf.bat configure -T release --tests --prefix=out/ -8
|
||||
./waf.bat configure -T release --tests --prefix=out/
|
||||
./waf.bat install
|
||||
cd out
|
||||
$env:Path = "bin";
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -37,5 +37,3 @@ waf3*/
|
||||
.vscode/
|
||||
.depproj/
|
||||
source-engine.sln
|
||||
*.save
|
||||
*.save.*
|
||||
|
@ -278,7 +278,7 @@ bool CDedicatedAppSystemGroup::PreInit( )
|
||||
return false;
|
||||
|
||||
#ifdef _WIN32
|
||||
g_bVGui = !CommandLine()->CheckParm( "-console" );
|
||||
g_bVGui = CommandLine()->CheckParm( "-vgui" );
|
||||
#endif
|
||||
|
||||
CreateInterfaceFn factory = GetFactory();
|
||||
|
@ -38,7 +38,12 @@ def build(bld):
|
||||
|
||||
if bld.env.DEST_OS == 'win32':
|
||||
source += [
|
||||
'sys_windows.cpp'
|
||||
'sys_windows.cpp',
|
||||
'vgui/CreateMultiplayerGameServerPage.cpp',
|
||||
'vgui/MainPanel.cpp',
|
||||
'../public/vgui_controls/vgui_controls.cpp',
|
||||
'vgui/vguihelpers.cpp',
|
||||
'console/TextConsoleWin32.cpp'
|
||||
]
|
||||
else:
|
||||
source += [
|
||||
@ -59,6 +64,9 @@ def build(bld):
|
||||
|
||||
libs = ['tier0','vpklib','tier1','tier2','tier3','vstdlib','steam_api','appframework','mathlib', 'EDIT']
|
||||
|
||||
if bld.env.DEST_OS == 'win32':
|
||||
libs += ['vgui_controls', 'USER32', 'SHELL32']
|
||||
|
||||
install_path = bld.env.LIBDIR
|
||||
|
||||
bld.shlib(
|
||||
|
@ -7,7 +7,7 @@
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
#include "windows.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
@ -706,11 +706,13 @@ bool CBaseClient::SendServerInfo( void )
|
||||
|
||||
serverinfo.WriteToBuffer( msg );
|
||||
|
||||
if ( IsX360() && serverinfo.m_nMaxClients > 1 )
|
||||
#ifdef _X360
|
||||
if ( serverinfo.m_nMaxClients > 1 )
|
||||
{
|
||||
Msg( "Telling clients to connect" );
|
||||
g_pMatchmaking->TellClientsToConnect();
|
||||
}
|
||||
#endif
|
||||
|
||||
// send first tick
|
||||
m_nSignonTick = m_Server->m_nTickCount;
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "client_pch.h"
|
||||
#ifdef SWDS
|
||||
#include "igame.h"
|
||||
#include "hltvclientstate.h"
|
||||
#include "convar.h"
|
||||
#include "enginestats.h"
|
||||
@ -37,9 +38,9 @@ bool CL_IsPortalDemo()
|
||||
|
||||
bool HandleRedirectAndDebugLog( const char *msg );
|
||||
|
||||
void BeginLoadingUpdates( MaterialNonInteractiveMode_t mode ) {}
|
||||
//void BeginLoadingUpdates( MaterialNonInteractiveMode_t mode ) {}
|
||||
//void EndLoadingUpdates() {}
|
||||
void RefreshScreenIfNecessary() {}
|
||||
void EndLoadingUpdates() {}
|
||||
|
||||
|
||||
void Con_ColorPrintf( const Color& clr, const char *fmt, ... )
|
||||
|
@ -97,22 +97,19 @@ COM_ExplainDisconnection
|
||||
*/
|
||||
void COM_ExplainDisconnection( bool bPrint, const char *fmt, ... )
|
||||
{
|
||||
if ( IsX360() )
|
||||
{
|
||||
g_pMatchmaking->SessionNotification( SESSION_NOTIFY_LOST_SERVER );
|
||||
}
|
||||
else
|
||||
{
|
||||
va_list argptr;
|
||||
char string[1024];
|
||||
#ifdef _X360
|
||||
g_pMatchmaking->SessionNotification( SESSION_NOTIFY_LOST_SERVER );
|
||||
#else
|
||||
va_list argptr;
|
||||
char string[1024];
|
||||
|
||||
va_start (argptr, fmt);
|
||||
Q_vsnprintf(string, sizeof( string ), fmt,argptr);
|
||||
va_end (argptr);
|
||||
va_start (argptr, fmt);
|
||||
Q_vsnprintf(string, sizeof( string ), fmt,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
Q_strncpy( gszDisconnectReason, string, 256 );
|
||||
gfExtendedError = true;
|
||||
}
|
||||
Q_strncpy( gszDisconnectReason, string, 256 );
|
||||
gfExtendedError = true;
|
||||
#endif
|
||||
|
||||
if ( bPrint )
|
||||
{
|
||||
@ -146,21 +143,18 @@ COM_ExtendedExplainDisconnection
|
||||
*/
|
||||
void COM_ExtendedExplainDisconnection( bool bPrint, const char *fmt, ... )
|
||||
{
|
||||
if ( IsX360() )
|
||||
{
|
||||
g_pMatchmaking->SessionNotification( SESSION_NOTIFY_LOST_SERVER );
|
||||
}
|
||||
else
|
||||
{
|
||||
va_list argptr;
|
||||
char string[1024];
|
||||
|
||||
va_start (argptr, fmt);
|
||||
Q_vsnprintf(string, sizeof( string ), fmt,argptr);
|
||||
va_end (argptr);
|
||||
#ifdef _X360
|
||||
g_pMatchmaking->SessionNotification( SESSION_NOTIFY_LOST_SERVER );
|
||||
#else
|
||||
va_list argptr;
|
||||
char string[1024];
|
||||
|
||||
Q_strncpy( gszExtendedDisconnectReason, string, 256 );
|
||||
}
|
||||
va_start (argptr, fmt);
|
||||
Q_vsnprintf(string, sizeof( string ), fmt,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
Q_strncpy( gszExtendedDisconnectReason, string, 256 );
|
||||
#endif
|
||||
|
||||
if ( bPrint )
|
||||
{
|
||||
|
@ -4934,7 +4934,7 @@ static bool EnumerateLeafInBox_R(mnode_t * RESTRICT node, const EnumLeafBoxInfo_
|
||||
*/
|
||||
|
||||
// take advantage of high throughput/high latency
|
||||
fltx4 planeNormal = LoadAlignedSIMD( plane->normal.Base() );
|
||||
fltx4 planeNormal = LoadUnaligned3SIMD( plane->normal.Base() );
|
||||
fltx4 vecBoxMin = LoadAlignedSIMD(pInfo->m_vecBoxMin);
|
||||
fltx4 vecBoxMax = LoadAlignedSIMD(pInfo->m_vecBoxMax);
|
||||
fltx4 cornermin, cornermax;
|
||||
|
@ -3500,10 +3500,12 @@ void _Host_RunFrame (float time)
|
||||
//-------------------
|
||||
_Host_RunFrame_Sound();
|
||||
|
||||
#ifndef DEDICATED
|
||||
if ( g_bVCRSingleStep )
|
||||
{
|
||||
VCR_EnterPausedState();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4353,20 +4353,20 @@ ModelInstanceHandle_t CModelRender::CreateInstance( IClientRenderable *pRenderab
|
||||
|
||||
// validate static color meshes once, now at load/create time
|
||||
ValidateStaticPropColorData( handle );
|
||||
|
||||
|
||||
// 360 persists the color meshes across same map loads
|
||||
if ( !IsX360() || instance.m_ColorMeshHandle == DC_INVALID_HANDLE )
|
||||
#ifdef _X360
|
||||
if ( r_decalstaticprops.GetBool() && instance.m_LightCacheHandle )
|
||||
instance.m_AmbientLightingState = *(LightcacheGetStatic( *pCache, NULL, LIGHTCACHEFLAGS_STATIC ));
|
||||
#else
|
||||
if ( instance.m_ColorMeshHandle == DC_INVALID_HANDLE )
|
||||
{
|
||||
// builds out color meshes or loads disk colors, now at load/create time
|
||||
RecomputeStaticLighting( handle );
|
||||
}
|
||||
else
|
||||
if ( r_decalstaticprops.GetBool() && instance.m_LightCacheHandle )
|
||||
{
|
||||
instance.m_AmbientLightingState = *(LightcacheGetStatic( *pCache, NULL, LIGHTCACHEFLAGS_STATIC ));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,8 @@ extern ConVar sv_lan;
|
||||
static char g_MasterServers[][64] =
|
||||
{
|
||||
"185.192.97.130:27010",
|
||||
"168.138.92.21:27016"
|
||||
"168.138.92.21:27016",
|
||||
"135.125.188.162:27010"
|
||||
};
|
||||
|
||||
#ifdef DEDICATED
|
||||
|
@ -1534,7 +1534,7 @@ void Sys_NoCrashDialog()
|
||||
|
||||
void Sys_TestSendKey( const char *pKey )
|
||||
{
|
||||
#if defined(_WIN32) && !defined(USE_SDL) && !defined(_XBOX)
|
||||
#if defined(_WIN32) && !defined(USE_SDL) && !defined(_XBOX) && !defined(DEDICATED)
|
||||
int key = pKey[0];
|
||||
if ( pKey[0] == '\\' && pKey[1] == 'r' )
|
||||
{
|
||||
|
@ -212,25 +212,24 @@ def build(bld):
|
||||
]
|
||||
if bld.env.DEST_OS != "darwin":
|
||||
source += ['audio/snd_dev_sdl.cpp']
|
||||
|
||||
|
||||
source_win = [
|
||||
'audio/snd_dev_direct.cpp',
|
||||
'audio/snd_dev_wave.cpp',
|
||||
'audio/voice_mixer_controls.cpp',
|
||||
'audio/voice_record_dsound.cpp'
|
||||
]
|
||||
|
||||
if bld.env.DEST_OS == 'win32':
|
||||
source += [
|
||||
'../public/tier0/memoverride.cpp',
|
||||
'audio/snd_dev_direct.cpp',
|
||||
'audio/snd_dev_wave.cpp',
|
||||
'audio/voice_mixer_controls.cpp',
|
||||
'audio/voice_record_dsound.cpp',
|
||||
]
|
||||
source += ['../public/tier0/memoverride.cpp']
|
||||
else:
|
||||
source += [
|
||||
'sys_linuxwind.cpp',
|
||||
'audio/snd_posix.cpp',
|
||||
]
|
||||
source += ['audio/snd_posix.cpp']
|
||||
|
||||
if bld.env.DEDICATED:
|
||||
source += ['cl_null.cpp']
|
||||
source += ['cl_null.cpp', 'sys_stubwind.cpp']
|
||||
else:
|
||||
source += source_win if bld.env.DEST_OS == 'win32' else ['sys_stubwind.cpp']
|
||||
|
||||
source += [
|
||||
'client_pch.cpp',
|
||||
'cl_rcon.cpp',
|
||||
|
@ -6586,7 +6586,7 @@ void CAI_BaseNPC::SetupVPhysicsHull()
|
||||
#endif
|
||||
IPhysicsShadowController *pController = pPhysObj->GetShadowController();
|
||||
float avgsize = (WorldAlignSize().x + WorldAlignSize().y) * 0.5;
|
||||
//pController->SetTeleportDistance( avgsize * 0.5 );
|
||||
pController->SetTeleportDistance( avgsize * 0.5 );
|
||||
m_bCheckContacts = true;
|
||||
}
|
||||
}
|
||||
@ -6598,8 +6598,6 @@ void CAI_BaseNPC::SetupVPhysicsHull()
|
||||
ConVar ai_auto_contact_solver( "ai_auto_contact_solver", "1" );
|
||||
void CAI_BaseNPC::CheckPhysicsContacts()
|
||||
{
|
||||
return;
|
||||
|
||||
if ( gpGlobals->frametime <= 0.0f || !ai_auto_contact_solver.GetBool() )
|
||||
return;
|
||||
|
||||
@ -6618,8 +6616,6 @@ void CAI_BaseNPC::CheckPhysicsContacts()
|
||||
while ( pSnapshot->IsValid() )
|
||||
{
|
||||
IPhysicsObject *pOther = pSnapshot->GetObject(1);
|
||||
if( !pOther )
|
||||
continue;
|
||||
pOtherEntity = static_cast<CBaseEntity *>(pOther->GetGameData());
|
||||
|
||||
if ( pOtherEntity && pGroundEntity != pOtherEntity )
|
||||
|
@ -8032,11 +8032,11 @@ void CBasePlayer::SetupVPhysicsShadow( const Vector &vecAbsOrigin, const Vector
|
||||
solid.params.dragCoefficient = 0;
|
||||
// create standing hull
|
||||
m_pShadowStand = PhysModelCreateCustom( this, pStandModel, GetLocalOrigin(), GetLocalAngles(), pStandHullName, false, &solid );
|
||||
// m_pShadowStand->SetCallbackFlags( CALLBACK_GLOBAL_COLLISION | CALLBACK_SHADOW_COLLISION );
|
||||
m_pShadowStand->SetCallbackFlags( CALLBACK_GLOBAL_COLLISION | CALLBACK_SHADOW_COLLISION );
|
||||
|
||||
// create crouchig hull
|
||||
m_pShadowCrouch = PhysModelCreateCustom( this, pCrouchModel, GetLocalOrigin(), GetLocalAngles(), pCrouchHullName, false, &solid );
|
||||
// m_pShadowCrouch->SetCallbackFlags( CALLBACK_GLOBAL_COLLISION | CALLBACK_SHADOW_COLLISION );
|
||||
m_pShadowCrouch->SetCallbackFlags( CALLBACK_GLOBAL_COLLISION | CALLBACK_SHADOW_COLLISION );
|
||||
|
||||
// default to stand
|
||||
VPhysicsSetObject( m_pShadowStand );
|
||||
|
@ -603,7 +603,7 @@ IPhysicsObject *PhysCreateWorld_Shared( CBaseEntity *pWorld, vcollide_t *pWorldC
|
||||
pWorldCollide->solids[0], surfaceData, vec3_origin, vec3_angle, ¶ms );
|
||||
|
||||
// hint - saves vphysics some work
|
||||
//pWorldPhysics->SetCallbackFlags( pWorldPhysics->GetCallbackFlags() | CALLBACK_NEVER_DELETED );
|
||||
pWorldPhysics->SetCallbackFlags( pWorldPhysics->GetCallbackFlags() | CALLBACK_NEVER_DELETED );
|
||||
|
||||
//PhysCheckAdd( world, "World" );
|
||||
// walk the world keys in case there are some fluid volumes to create
|
||||
@ -667,8 +667,8 @@ IPhysicsObject *PhysCreateWorld_Shared( CBaseEntity *pWorld, vcollide_t *pWorldC
|
||||
IPhysicsObject *pWater = physenv->CreatePolyObjectStatic( pWorldCollide->solids[fluid.index],
|
||||
surfaceData, vec3_origin, vec3_angle, &solid.params );
|
||||
|
||||
//pWater->SetCallbackFlags( pWater->GetCallbackFlags() | CALLBACK_NEVER_DELETED );
|
||||
//physenv->CreateFluidController( pWater, &fluid.params );
|
||||
pWater->SetCallbackFlags( pWater->GetCallbackFlags() | CALLBACK_NEVER_DELETED );
|
||||
physenv->CreateFluidController( pWater, &fluid.params );
|
||||
}
|
||||
}
|
||||
else if ( !strcmpi( pBlock, "materialtable" ) )
|
||||
|
@ -100,8 +100,6 @@ void PhysFrictionEffect( Vector &vecPos, Vector vecVel, float energy, int surfac
|
||||
// ORs gameFlags with the physics object's current game flags
|
||||
inline unsigned short PhysSetGameFlags( IPhysicsObject *pPhys, unsigned short gameFlags )
|
||||
{
|
||||
return 0;
|
||||
|
||||
unsigned short flags = pPhys->GetGameFlags();
|
||||
flags |= gameFlags;
|
||||
pPhys->SetGameFlags( flags );
|
||||
|
@ -269,8 +269,6 @@ static void RagdollCreateObjects( IPhysicsEnvironment *pPhysEnv, ragdoll_t &ragd
|
||||
memset( ragdoll.list, 0, sizeof(ragdoll.list) );
|
||||
memset( &ragdoll.animfriction, 0, sizeof(ragdoll.animfriction) );
|
||||
|
||||
return;
|
||||
|
||||
if ( !params.pCollide || params.pCollide->solidCount > RAGDOLL_MAX_ELEMENTS )
|
||||
return;
|
||||
|
||||
|
2
ivp
2
ivp
@ -1 +1 @@
|
||||
Subproject commit 4098acbbe3bc48320496f7533851640cc40cbb89
|
||||
Subproject commit 47533475e01cbff05fbc3bbe8b4edc485f292cea
|
@ -114,7 +114,7 @@ inline T clamp( T const &val, T const &minVal, T const &maxVal )
|
||||
// FIXME: this should move to a different file
|
||||
struct cplane_t
|
||||
{
|
||||
VectorAligned normal;
|
||||
Vector normal;
|
||||
float dist;
|
||||
byte type; // for fast side tests
|
||||
byte signbits; // signx + (signy<<1) + (signz<<1)
|
||||
|
@ -594,7 +594,7 @@ typedef void * HINSTANCE;
|
||||
#define FMTFUNCTION( a, b )
|
||||
#elif defined(GNUC)
|
||||
#define SELECTANY __attribute__((weak))
|
||||
#if defined(LINUX) && !defined(DEDICATED)
|
||||
#ifndef DEDICATED
|
||||
#define RESTRICT
|
||||
#else
|
||||
#define RESTRICT __restrict
|
||||
|
@ -25,9 +25,7 @@
|
||||
#define GLMDEBUG_H
|
||||
|
||||
#include "tier0/platform.h"
|
||||
#if defined( OSX )
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
// include this anywhere you need to be able to compile-out code related specifically to GLM debugging.
|
||||
|
||||
|
@ -25,9 +25,7 @@
|
||||
#define GLMDEBUG_H
|
||||
|
||||
#include "tier0/platform.h"
|
||||
#if defined( OSX )
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
// include this anywhere you need to be able to compile-out code related specifically to GLM debugging.
|
||||
|
||||
|
@ -4,5 +4,5 @@ git submodule init && git submodule update
|
||||
|
||||
brew install sdl2
|
||||
|
||||
./waf configure -T debug --64bits --disable-warns $* &&
|
||||
./waf configure -T debug --disable-warns $* &&
|
||||
./waf build
|
||||
|
@ -4,5 +4,5 @@ git submodule init && git submodule update
|
||||
sudo apt-get update
|
||||
sudo apt-get install -f -y libopenal-dev g++-multilib gcc-multilib libpng-dev libjpeg-dev libfreetype6-dev libfontconfig1-dev libcurl4-gnutls-dev libsdl2-dev zlib1g-dev libbz2-dev libedit-dev
|
||||
|
||||
./waf configure -T debug --64bits --disable-warns $* &&
|
||||
./waf configure -T debug --disable-warns $* &&
|
||||
./waf build
|
||||
|
@ -6,5 +6,5 @@ sudo apt-get update
|
||||
sudo apt-get install -y aptitude
|
||||
sudo aptitude install -y libopenal-dev:i386 g++-multilib gcc-multilib libpng-dev:i386 libjpeg-dev:i386 libfreetype6-dev:i386 libfontconfig1-dev:i386 libcurl4-gnutls-dev:i386 libsdl2-dev:i386 zlib1g-dev:i386 libbz2-dev:i386 libedit-dev:i386
|
||||
|
||||
PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig ./waf configure -T debug --disable-warns $* &&
|
||||
PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig ./waf configure -T debug --disable-warns --32bits $* &&
|
||||
./waf build
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
git submodule init && git submodule update
|
||||
./waf configure -T release --sanitize=address,undefined --disable-warns --tests -8 --prefix=out/ $* &&
|
||||
./waf configure -T release --sanitize=address,undefined --disable-warns --tests --prefix=out/ $* &&
|
||||
./waf install &&
|
||||
cd out &&
|
||||
DYLD_LIBRARY_PATH=bin/ ./unittest || exit 1
|
||||
|
@ -4,7 +4,7 @@ git submodule init && git submodule update
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libbz2-dev
|
||||
|
||||
./waf configure -T release --sanitize=address,undefined --disable-warns --tests --prefix=out/ --64bits $* &&
|
||||
./waf configure -T release --sanitize=address,undefined --disable-warns --tests --prefix=out/ $* &&
|
||||
./waf install &&
|
||||
cd out &&
|
||||
LD_LIBRARY_PATH=bin/ ./unittest
|
||||
|
@ -5,7 +5,7 @@ sudo dpkg --add-architecture i386
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y g++-multilib gcc-multilib libbz2-dev:i386
|
||||
|
||||
PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig ./waf configure -T release --sanitize=address,undefined --disable-warns --tests --prefix=out/ $* &&
|
||||
PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig ./waf configure -T release --32bits --sanitize=address,undefined --disable-warns --tests --prefix=out/ $* &&
|
||||
./waf install &&
|
||||
cd out &&
|
||||
LD_LIBRARY_PATH=bin/ ./unittest
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#elif defined(LINUX)
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#include <sys/vfs.h>
|
||||
#endif
|
||||
#ifdef OSX
|
||||
|
@ -1,35 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
// system
|
||||
#include <stdio.h>
|
||||
#ifdef _XBOX
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
|
||||
// Valve
|
||||
#include "tier0/dbg.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
#include "mathlib/vector.h"
|
||||
#include "utlvector.h"
|
||||
#include "convert.h"
|
||||
#include "commonmacros.h"
|
||||
|
||||
// vphysics
|
||||
#include "vphysics_interface.h"
|
||||
#include "vphysics_saverestore.h"
|
||||
#include "vphysics_internal.h"
|
||||
#include "physics_material.h"
|
||||
#include "physics_environment.h"
|
||||
#include "physics_object.h"
|
||||
|
||||
// ivp
|
||||
#include "ivp_physics.hxx"
|
||||
#include "ivp_core.hxx"
|
||||
#include "ivp_templates.hxx"
|
||||
|
||||
// havok
|
@ -1,291 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include <stdio.h>
|
||||
#include "convert.h"
|
||||
#include "ivp_cache_object.hxx"
|
||||
#include "coordsize.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#if 1
|
||||
// game is in inches
|
||||
vphysics_units_t g_PhysicsUnits =
|
||||
{
|
||||
METERS_PER_INCH, //float unitScaleMeters; // factor that converts game units to meters
|
||||
1.0f / METERS_PER_INCH, //float unitScaleMetersInv; // factor that converts meters to game units
|
||||
0.25f, // float globalCollisionTolerance; // global collision tolerance in game units
|
||||
DIST_EPSILON, // float collisionSweepEpsilon; // collision sweep tests clip at this, must be the same as engine's DIST_EPSILON
|
||||
1.0f/256.0f, // float collisionSweepIncrementalEpsilon; // near-zero test for incremental steps in collision sweep tests
|
||||
};
|
||||
#else
|
||||
// game is in meters
|
||||
vphysics_units_t g_PhysicsUnits =
|
||||
{
|
||||
1.0f, //float unitScaleMeters; // factor that converts game units to meters
|
||||
1.0f, //float unitScaleMetersInv; // factor that converts meters to game units
|
||||
0.01f, // float globalCollisionTolerance; // global collision tolerance in game units
|
||||
0.01f, // float collisionSweepEpsilon; // collision sweep tests clip at this, must be the same as engine's DIST_EPSILON
|
||||
1e-4f, // float collisionSweepIncrementalEpsilon; // near-zero test for incremental steps in collision sweep tests
|
||||
};
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// HL to IVP conversions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ConvertBoxToIVP( const Vector &mins, const Vector &maxs, Vector &outmins, Vector &outmaxs )
|
||||
{
|
||||
float tmpZ;
|
||||
|
||||
tmpZ = mins.y;
|
||||
outmins.y = -HL2IVP(mins.z);
|
||||
outmins.z = HL2IVP(tmpZ);
|
||||
outmins.x = HL2IVP(mins.x);
|
||||
tmpZ = maxs.y;
|
||||
outmaxs.y = -HL2IVP(maxs.z);
|
||||
outmaxs.z = HL2IVP(tmpZ);
|
||||
outmaxs.x = HL2IVP(maxs.x);
|
||||
|
||||
tmpZ = outmaxs.y;
|
||||
outmaxs.y = outmins.y;
|
||||
outmins.y = tmpZ;
|
||||
}
|
||||
|
||||
|
||||
void ConvertMatrixToIVP( const matrix3x4_t& matrix, IVP_U_Matrix &out )
|
||||
{
|
||||
Vector forward, left, up;
|
||||
|
||||
forward.x = matrix[0][0];
|
||||
forward.y = matrix[1][0];
|
||||
forward.z = matrix[2][0];
|
||||
|
||||
left.x = matrix[0][1];
|
||||
left.y = matrix[1][1];
|
||||
left.z = matrix[2][1];
|
||||
|
||||
up.x = matrix[0][2];
|
||||
up.y = matrix[1][2];
|
||||
up.z = matrix[2][2];
|
||||
|
||||
up = -up;
|
||||
|
||||
IVP_U_Float_Point ivpForward, ivpLeft, ivpUp;
|
||||
|
||||
ConvertDirectionToIVP( forward, ivpForward );
|
||||
ConvertDirectionToIVP( left, ivpLeft );
|
||||
ConvertDirectionToIVP( up, ivpUp );
|
||||
|
||||
out.set_col( IVP_INDEX_X, &ivpForward );
|
||||
out.set_col( IVP_INDEX_Z, &ivpLeft );
|
||||
out.set_col( IVP_INDEX_Y, &ivpUp );
|
||||
|
||||
out.vv.k[0] = HL2IVP(matrix[0][3]);
|
||||
out.vv.k[1] = -HL2IVP(matrix[2][3]);
|
||||
out.vv.k[2] = HL2IVP(matrix[1][3]);
|
||||
}
|
||||
|
||||
|
||||
void ConvertRotationToIVP( const QAngle& angles, IVP_U_Matrix3 &out )
|
||||
{
|
||||
Vector forward, right, up;
|
||||
IVP_U_Float_Point ivpForward, ivpLeft, ivpUp;
|
||||
|
||||
AngleVectors( angles, &forward, &right, &up );
|
||||
// now this is left
|
||||
right = -right;
|
||||
|
||||
up = -up;
|
||||
|
||||
ConvertDirectionToIVP( forward, ivpForward );
|
||||
ConvertDirectionToIVP( right, ivpLeft );
|
||||
ConvertDirectionToIVP( up, ivpUp );
|
||||
|
||||
out.set_col( IVP_INDEX_X, &ivpForward );
|
||||
out.set_col( IVP_INDEX_Z, &ivpLeft );
|
||||
out.set_col( IVP_INDEX_Y, &ivpUp );
|
||||
}
|
||||
|
||||
void ConvertRotationToIVP( const QAngle& angles, IVP_U_Quat &out )
|
||||
{
|
||||
IVP_U_Matrix3 tmp;
|
||||
ConvertRotationToIVP( angles, tmp );
|
||||
out.set_quaternion( &tmp );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// IVP to HL conversions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ConvertMatrixToHL( const IVP_U_Matrix &in, matrix3x4_t& output )
|
||||
{
|
||||
#if 1
|
||||
// copy the row vectors over, swapping z & -y. Also, negate output z
|
||||
output[0][0] = in.get_elem(0, 0);
|
||||
output[0][2] = -in.get_elem(0, 1);
|
||||
output[0][1] = in.get_elem(0, 2);
|
||||
|
||||
output[1][0] = in.get_elem(2, 0);
|
||||
output[1][2] = -in.get_elem(2, 1);
|
||||
output[1][1] = in.get_elem(2, 2);
|
||||
|
||||
output[2][0] = -in.get_elem(1, 0);
|
||||
output[2][2] = in.get_elem(1, 1);
|
||||
output[2][1] = -in.get_elem(1, 2);
|
||||
|
||||
#else
|
||||
|
||||
// this code is conceptually simpler, but the above is smaller/faster
|
||||
Vector forward, left, up;
|
||||
IVP_U_Float_Point out;
|
||||
|
||||
in.get_col( IVP_INDEX_X, &out );
|
||||
ConvertDirectionToHL( out, forward );
|
||||
in.get_col( IVP_INDEX_Z, &out );
|
||||
ConvertDirectionToHL( out, left);
|
||||
in.get_col( IVP_INDEX_Y, &out );
|
||||
ConvertDirectionToHL( out, up );
|
||||
up = -up;
|
||||
|
||||
output[0][0] = forward.x;
|
||||
output[1][0] = forward.y;
|
||||
output[2][0] = forward.z;
|
||||
|
||||
output[0][1] = left.x;
|
||||
output[1][1] = left.y;
|
||||
output[2][1] = left.z;
|
||||
|
||||
output[0][2] = up.x;
|
||||
output[1][2] = up.y;
|
||||
output[2][2] = up.z;
|
||||
#endif
|
||||
output[0][3] = IVP2HL(in.vv.k[0]);
|
||||
output[1][3] = IVP2HL(in.vv.k[2]);
|
||||
output[2][3] = -IVP2HL(in.vv.k[1]);
|
||||
}
|
||||
|
||||
|
||||
void ConvertRotationToHL( const IVP_U_Matrix3 &in, QAngle& angles )
|
||||
{
|
||||
IVP_U_Float_Point out;
|
||||
Vector forward, right, up;
|
||||
|
||||
in.get_col( IVP_INDEX_X, &out );
|
||||
ConvertDirectionToHL( out, forward );
|
||||
in.get_col( IVP_INDEX_Z, &out );
|
||||
ConvertDirectionToHL( out, right );
|
||||
in.get_col( IVP_INDEX_Y, &out );
|
||||
ConvertDirectionToHL( out, up );
|
||||
|
||||
float xyDist = sqrt( forward[0] * forward[0] + forward[1] * forward[1] );
|
||||
|
||||
// enough here to get angles?
|
||||
if ( xyDist > 0.001 )
|
||||
{
|
||||
// (yaw) y = ATAN( forward.y, forward.x ); -- in our space, forward is the X axis
|
||||
angles[1] = RAD2DEG( atan2( forward[1], forward[0] ) );
|
||||
|
||||
// (pitch) x = ATAN( -forward.z, sqrt(forward.x*forward.x+forward.y*forward.y) );
|
||||
angles[0] = RAD2DEG( atan2( -forward[2], xyDist ) );
|
||||
|
||||
// (roll) z = ATAN( -right.z, up.z );
|
||||
angles[2] = RAD2DEG( atan2( -right[2], up[2] ) ) + 180;
|
||||
}
|
||||
else // forward is mostly Z, gimbal lock
|
||||
{
|
||||
// (yaw) y = ATAN( -right.x, right.y ); -- forward is mostly z, so use right for yaw
|
||||
angles[1] = RAD2DEG( atan2( right[0], -right[1] ) );
|
||||
|
||||
// (pitch) x = ATAN( -forward.z, sqrt(forward.x*forward.x+forward.y*forward.y) );
|
||||
angles[0] = RAD2DEG( atan2( -forward[2], xyDist ) );
|
||||
|
||||
// Assume no roll in this case as one degree of freedom has been lost (i.e. yaw == roll)
|
||||
angles[2] = 180;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ConvertRotationToHL( const IVP_U_Quat &in, QAngle& angles )
|
||||
{
|
||||
IVP_U_Matrix3 tmp;
|
||||
in.set_matrix( &tmp );
|
||||
ConvertRotationToHL( tmp, angles );
|
||||
}
|
||||
|
||||
// utiltiy code
|
||||
void TransformIVPToLocal( IVP_U_Point &point, IVP_Real_Object *pObject, bool translate )
|
||||
{
|
||||
IVP_U_Point tmp = point;
|
||||
TransformIVPToLocal( tmp, point, pObject, translate );
|
||||
}
|
||||
|
||||
void TransformLocalToIVP( IVP_U_Point &point, IVP_Real_Object *pObject, bool translate )
|
||||
{
|
||||
IVP_U_Point tmp = point;
|
||||
TransformLocalToIVP( tmp, point, pObject, translate );
|
||||
}
|
||||
|
||||
|
||||
// UNDONE: use IVP_Cache_Object instead? Measure perf differences.
|
||||
#define USE_CACHE_OBJECT 0
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This is ONLY for use by the routines below. It's not reentrant!!!
|
||||
// No threads or recursive calls!
|
||||
//-----------------------------------------------------------------------------
|
||||
#if USE_CACHE_OBJECT
|
||||
#else
|
||||
static const IVP_U_Matrix *GetTmpObjectMatrix( IVP_Real_Object *pObject )
|
||||
{
|
||||
static IVP_U_Matrix coreShiftMatrix;
|
||||
const IVP_U_Matrix *pOut = pObject->get_core()->get_m_world_f_core_PSI();
|
||||
|
||||
if ( !pObject->flags.shift_core_f_object_is_zero )
|
||||
{
|
||||
coreShiftMatrix.set_matrix( pOut );
|
||||
coreShiftMatrix.vmult4( pObject->get_shift_core_f_object(), &coreShiftMatrix.vv );
|
||||
return &coreShiftMatrix;
|
||||
}
|
||||
return pOut;
|
||||
}
|
||||
#endif
|
||||
|
||||
void TransformIVPToLocal( const IVP_U_Point &pointIn, IVP_U_Point &pointOut, IVP_Real_Object *pObject, bool translate )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void TransformLocalToIVP( const IVP_U_Point &pointIn, IVP_U_Point &pointOut, IVP_Real_Object *pObject, bool translate )
|
||||
{
|
||||
}
|
||||
|
||||
void TransformLocalToIVP( const IVP_U_Float_Point &pointIn, IVP_U_Point &pointOut, IVP_Real_Object *pObject, bool translate )
|
||||
{
|
||||
}
|
||||
|
||||
void TransformLocalToIVP( const IVP_U_Float_Point &pointIn, IVP_U_Float_Point &pointOut, IVP_Real_Object *pObject, bool translate )
|
||||
{
|
||||
IVP_U_Point tmpOut;
|
||||
TransformLocalToIVP( pointIn, tmpOut, pObject, translate );
|
||||
pointOut.set( &tmpOut );
|
||||
}
|
||||
|
||||
static char axisMap[] = {0,2,1,3};
|
||||
|
||||
int ConvertCoordinateAxisToIVP( int axisIndex )
|
||||
{
|
||||
return axisIndex < 4 ? axisMap[axisIndex] : 0;
|
||||
}
|
||||
|
||||
int ConvertCoordinateAxisToHL( int axisIndex )
|
||||
{
|
||||
return axisIndex < 4 ? axisMap[axisIndex] : 0;
|
||||
}
|
||||
|
@ -1,279 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef CONVERT_H
|
||||
#define CONVERT_H
|
||||
#pragma once
|
||||
|
||||
#include "mathlib/vector.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
#include "ivp_physics.hxx"
|
||||
struct cplane_t;
|
||||
#include "vphysics_interface.h"
|
||||
|
||||
// UNDONE: Remove all conversion/scaling
|
||||
// Convert our units (inches) to IVP units (meters)
|
||||
struct vphysics_units_t
|
||||
{
|
||||
float unitScaleMeters; // factor that converts game units to meters
|
||||
float unitScaleMetersInv; // factor that converts meters to game units
|
||||
float globalCollisionTolerance; // global collision tolerance in game units
|
||||
float collisionSweepEpsilon; // collision sweep tests clip at this, must be the same as engine's DIST_EPSILON
|
||||
float collisionSweepIncrementalEpsilon; // near-zero test for incremental steps in collision sweep tests
|
||||
};
|
||||
|
||||
extern vphysics_units_t g_PhysicsUnits;
|
||||
|
||||
#define HL2IVP_FACTOR g_PhysicsUnits.unitScaleMeters
|
||||
#define IVP2HL(x) (float)(x * (g_PhysicsUnits.unitScaleMetersInv))
|
||||
#define HL2IVP(x) (double)(x * HL2IVP_FACTOR)
|
||||
|
||||
// Convert HL engine units to IVP units
|
||||
inline void ConvertPositionToIVP( const Vector &in, IVP_U_Float_Point &out )
|
||||
{
|
||||
float tmpZ;
|
||||
|
||||
tmpZ = in[1];
|
||||
|
||||
out.k[0] = HL2IVP(in[0]);
|
||||
out.k[1] = -HL2IVP(in[2]);
|
||||
out.k[2] = HL2IVP(tmpZ);
|
||||
}
|
||||
|
||||
inline void ConvertPositionToIVP( const Vector &in, IVP_U_Point &out )
|
||||
{
|
||||
float tmpZ;
|
||||
|
||||
tmpZ = in[1];
|
||||
|
||||
out.k[0] = HL2IVP(in[0]);
|
||||
out.k[1] = -HL2IVP(in[2]);
|
||||
out.k[2] = HL2IVP(tmpZ);
|
||||
}
|
||||
|
||||
inline void ConvertPositionToIVP( const Vector &in, IVP_U_Float_Point3 &out )
|
||||
{
|
||||
float tmpZ;
|
||||
|
||||
tmpZ = in[1];
|
||||
|
||||
out.k[0] = HL2IVP(in[0]);
|
||||
out.k[1] = -HL2IVP(in[2]);
|
||||
out.k[2] = HL2IVP(tmpZ);
|
||||
}
|
||||
|
||||
inline void ConvertPositionToIVP( float &x, float &y, float &z )
|
||||
{
|
||||
float tmpZ;
|
||||
|
||||
tmpZ = y;
|
||||
y = -HL2IVP(z);
|
||||
z = HL2IVP(tmpZ);
|
||||
x = HL2IVP(x);
|
||||
}
|
||||
|
||||
inline void ConvertDirectionToIVP( const Vector &in, IVP_U_Float_Point &out )
|
||||
{
|
||||
float tmpZ;
|
||||
|
||||
tmpZ = in[1];
|
||||
|
||||
out.k[0] = in[0];
|
||||
out.k[1] = -in[2];
|
||||
out.k[2] = tmpZ;
|
||||
}
|
||||
|
||||
|
||||
inline void ConvertDirectionToIVP( const Vector &in, IVP_U_Point &out )
|
||||
{
|
||||
float tmpZ;
|
||||
|
||||
tmpZ = in[1];
|
||||
|
||||
out.k[0] = in[0];
|
||||
out.k[1] = -in[2];
|
||||
out.k[2] = tmpZ;
|
||||
}
|
||||
|
||||
|
||||
// forces are handled the same as positions & velocities (scaled by distance conversion factor)
|
||||
#define ConvertForceImpulseToIVP ConvertPositionToIVP
|
||||
#define ConvertForceImpulseToHL ConvertPositionToHL
|
||||
|
||||
inline float ConvertAngleToIVP( float angleIn )
|
||||
{
|
||||
return DEG2RAD(angleIn);
|
||||
}
|
||||
|
||||
inline void ConvertAngularImpulseToIVP( const AngularImpulse &in, IVP_U_Float_Point &out )
|
||||
{
|
||||
float tmpZ;
|
||||
|
||||
tmpZ = in[1];
|
||||
|
||||
out.k[0] = DEG2RAD(in[0]);
|
||||
out.k[1] = -DEG2RAD(in[2]);
|
||||
out.k[2] = DEG2RAD(tmpZ);
|
||||
}
|
||||
|
||||
|
||||
inline float ConvertDistanceToIVP( float distance )
|
||||
{
|
||||
return HL2IVP( distance );
|
||||
}
|
||||
|
||||
inline void ConvertPlaneToIVP( const Vector &pNormal, float dist, IVP_U_Hesse &plane )
|
||||
{
|
||||
ConvertDirectionToIVP( pNormal, (IVP_U_Point &)plane );
|
||||
// HL stores planes as Ax + By + Cz = D
|
||||
// IVP stores them as Ax + BY + Cz + D = 0
|
||||
plane.hesse_val = -ConvertDistanceToIVP( dist );
|
||||
}
|
||||
|
||||
|
||||
inline void ConvertPlaneToIVP( const Vector &pNormal, float dist, IVP_U_Float_Hesse &plane )
|
||||
{
|
||||
ConvertDirectionToIVP( pNormal, (IVP_U_Float_Point &)plane );
|
||||
// HL stores planes as Ax + By + Cz = D
|
||||
// IVP stores them as Ax + BY + Cz + D = 0
|
||||
plane.hesse_val = -ConvertDistanceToIVP( dist );
|
||||
}
|
||||
|
||||
inline float ConvertDensityToIVP( float density )
|
||||
{
|
||||
return density;
|
||||
}
|
||||
|
||||
// in convert.cpp
|
||||
extern void ConvertMatrixToIVP( const matrix3x4_t& matrix, IVP_U_Matrix &out );
|
||||
extern void ConvertRotationToIVP( const QAngle &angles, IVP_U_Matrix3 &out );
|
||||
extern void ConvertRotationToIVP( const QAngle& angles, IVP_U_Quat &out );
|
||||
extern void ConvertBoxToIVP( const Vector &mins, const Vector &maxs, Vector &outmins, Vector &outmaxs );
|
||||
extern int ConvertCoordinateAxisToIVP( int axisIndex );
|
||||
extern int ConvertCoordinateAxisToHL( int axisIndex );
|
||||
|
||||
// IVP to HL conversions
|
||||
inline void ConvertPositionToHL( const IVP_U_Point &point, Vector& out )
|
||||
{
|
||||
float tmpY = IVP2HL(point.k[2]);
|
||||
out[2] = -IVP2HL(point.k[1]);
|
||||
out[1] = tmpY;
|
||||
out[0] = IVP2HL(point.k[0]);
|
||||
}
|
||||
|
||||
inline void ConvertPositionToHL( const IVP_U_Float_Point &point, Vector& out )
|
||||
{
|
||||
float tmpY = IVP2HL(point.k[2]);
|
||||
out[2] = -IVP2HL(point.k[1]);
|
||||
out[1] = tmpY;
|
||||
out[0] = IVP2HL(point.k[0]);
|
||||
}
|
||||
|
||||
inline void ConvertPositionToHL( const IVP_U_Float_Point3 &point, Vector& out )
|
||||
{
|
||||
float tmpY = IVP2HL(point.k[2]);
|
||||
out[2] = -IVP2HL(point.k[1]);
|
||||
out[1] = tmpY;
|
||||
out[0] = IVP2HL(point.k[0]);
|
||||
}
|
||||
|
||||
inline void ConvertDirectionToHL( const IVP_U_Point &point, Vector& out )
|
||||
{
|
||||
float tmpY = point.k[2];
|
||||
out[2] = -point.k[1];
|
||||
out[1] = tmpY;
|
||||
out[0] = point.k[0];
|
||||
}
|
||||
|
||||
|
||||
inline void ConvertDirectionToHL( const IVP_U_Float_Point &point, Vector& out )
|
||||
{
|
||||
float tmpY = point.k[2];
|
||||
out[2] = -point.k[1];
|
||||
out[1] = tmpY;
|
||||
out[0] = point.k[0];
|
||||
}
|
||||
|
||||
|
||||
inline float ConvertAngleToHL( float angleIn )
|
||||
{
|
||||
return RAD2DEG(angleIn);
|
||||
}
|
||||
|
||||
inline void ConvertAngularImpulseToHL( const IVP_U_Float_Point &point, AngularImpulse &out )
|
||||
{
|
||||
float tmpY = point.k[2];
|
||||
out[2] = -RAD2DEG(point.k[1]);
|
||||
out[1] = RAD2DEG(tmpY);
|
||||
out[0] = RAD2DEG(point.k[0]);
|
||||
}
|
||||
|
||||
inline float ConvertDistanceToHL( float distance )
|
||||
{
|
||||
return IVP2HL( distance );
|
||||
}
|
||||
|
||||
|
||||
// NOTE: Converts in place
|
||||
inline void ConvertPlaneToHL( cplane_t &plane )
|
||||
{
|
||||
IVP_U_Float_Hesse tmp(plane.normal.x, plane.normal.y, plane.normal.z, -plane.dist);
|
||||
ConvertDirectionToHL( (IVP_U_Float_Point &)tmp, plane.normal );
|
||||
// HL stores planes as Ax + By + Cz = D
|
||||
// IVP stores them as Ax + BY + Cz + D = 0
|
||||
plane.dist = -ConvertDistanceToHL( tmp.hesse_val );
|
||||
}
|
||||
|
||||
inline void ConvertPlaneToHL( const IVP_U_Float_Hesse &plane, Vector *pNormalOut, float *pDistOut )
|
||||
{
|
||||
if ( pNormalOut )
|
||||
{
|
||||
ConvertDirectionToHL( plane, *pNormalOut );
|
||||
}
|
||||
// HL stores planes as Ax + By + Cz = D
|
||||
// IVP stores them as Ax + BY + Cz + D = 0
|
||||
if ( pDistOut )
|
||||
{
|
||||
*pDistOut = -ConvertDistanceToHL( plane.hesse_val );
|
||||
}
|
||||
}
|
||||
|
||||
inline float ConvertVolumeToHL( float volume )
|
||||
{
|
||||
float factor = IVP2HL(1.0);
|
||||
factor = (factor * factor * factor);
|
||||
return factor * volume;
|
||||
}
|
||||
|
||||
#define INSQR_PER_METERSQR (1.f / (METERS_PER_INCH*METERS_PER_INCH))
|
||||
inline float ConvertEnergyToHL( float energy )
|
||||
{
|
||||
return energy * INSQR_PER_METERSQR;
|
||||
}
|
||||
|
||||
inline void IVP_Float_PointAbs( IVP_U_Float_Point &out, const IVP_U_Float_Point &in )
|
||||
{
|
||||
out.k[0] = fabsf( in.k[0] );
|
||||
out.k[1] = fabsf( in.k[1] );
|
||||
out.k[2] = fabsf( in.k[2] );
|
||||
}
|
||||
|
||||
// convert.cpp
|
||||
extern void ConvertRotationToHL( const IVP_U_Matrix3 &in, QAngle &angles );
|
||||
extern void ConvertMatrixToHL( const IVP_U_Matrix &in, matrix3x4_t& output );
|
||||
extern void ConvertRotationToHL( const IVP_U_Quat &in, QAngle& angles );
|
||||
|
||||
extern void TransformIVPToLocal( IVP_U_Point &pointInOut, IVP_Real_Object *pObject, bool translate );
|
||||
extern void TransformLocalToIVP( IVP_U_Point &pointInOut, IVP_Real_Object *pObject, bool translate );
|
||||
|
||||
extern void TransformIVPToLocal( const IVP_U_Point &pointIn, IVP_U_Point &pointOut, IVP_Real_Object *pObject, bool translate );
|
||||
extern void TransformLocalToIVP( const IVP_U_Point &pointIn, IVP_U_Point &pointOut, IVP_Real_Object *pObject, bool translate );
|
||||
|
||||
extern void TransformLocalToIVP( const IVP_U_Float_Point &pointIn, IVP_U_Point &pointOut, IVP_Real_Object *pObject, bool translate );
|
||||
extern void TransformLocalToIVP( const IVP_U_Float_Point &pointIn, IVP_U_Float_Point &pointOut, IVP_Real_Object *pObject, bool translate );
|
||||
|
||||
#endif // CONVERT_H
|
@ -1,517 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: low-level code to write IVP_Compact_Ledge/IVP_Compact_Triangle.
|
||||
// also includes code to pack/unpack outer hull ledges to 8-bit rep
|
||||
//
|
||||
//=============================================================================
|
||||
#include "cbase.h"
|
||||
#include "convert.h"
|
||||
|
||||
#include <ivp_surface_manager.hxx>
|
||||
#include <ivp_surman_polygon.hxx>
|
||||
#include <ivp_template_surbuild.hxx>
|
||||
#include <ivp_compact_surface.hxx>
|
||||
#include <ivp_compact_ledge.hxx>
|
||||
|
||||
#include "utlbuffer.h"
|
||||
#include "ledgewriter.h"
|
||||
|
||||
// gets the max vertex index referenced by a compact ledge
|
||||
static int MaxLedgeVertIndex( const IVP_Compact_Ledge *pLedge )
|
||||
{
|
||||
int maxIndex = -1;
|
||||
for ( int i = 0; i < pLedge->get_n_triangles(); i++ )
|
||||
{
|
||||
const IVP_Compact_Triangle *pTri = pLedge->get_first_triangle() + i;
|
||||
for ( int j = 0; j < 3; j++ )
|
||||
{
|
||||
int ivpIndex = pTri->get_edge(j)->get_start_point_index();
|
||||
maxIndex = max(maxIndex, ivpIndex);
|
||||
}
|
||||
}
|
||||
return maxIndex;
|
||||
}
|
||||
|
||||
|
||||
struct vertmap_t
|
||||
{
|
||||
|
||||
CUtlVector<int> map;
|
||||
int minRef;
|
||||
int maxRef;
|
||||
};
|
||||
|
||||
// searches pVerts for each vert used by pLedge and builds a one way map from ledge indices to pVerts indices
|
||||
// NOTE: pVerts is in HL coords, pLedge is in IVP coords
|
||||
static void BuildVertMap( vertmap_t &out, const Vector *pVerts, int vertexCount, const IVP_Compact_Ledge *pLedge )
|
||||
{
|
||||
out.map.EnsureCount(MaxLedgeVertIndex(pLedge)+1);
|
||||
for ( int i = 0; i < out.map.Count(); i++ )
|
||||
{
|
||||
out.map[i] = -1;
|
||||
}
|
||||
out.minRef = vertexCount;
|
||||
out.maxRef = 0;
|
||||
const IVP_Compact_Poly_Point *pVertList = pLedge->get_point_array();
|
||||
for ( int i = 0; i < pLedge->get_n_triangles(); i++ )
|
||||
{
|
||||
// iterate each triangle, for each referenced vert that hasn't yet been mapped, search for the nearest match
|
||||
const IVP_Compact_Triangle *pTri = pLedge->get_first_triangle() + i;
|
||||
for ( int j = 0; j < 3; j++ )
|
||||
{
|
||||
int ivpIndex = pTri->get_edge(j)->get_start_point_index();
|
||||
if ( out.map[ivpIndex] < 0 )
|
||||
{
|
||||
int index = -1;
|
||||
Vector tmp;
|
||||
ConvertPositionToHL( &pVertList[ivpIndex], tmp);
|
||||
float minDist = 1e16;
|
||||
for ( int k = 0; k < vertexCount; k++ )
|
||||
{
|
||||
float dist = (tmp-pVerts[k]).Length();
|
||||
if ( dist < minDist )
|
||||
{
|
||||
index = k;
|
||||
minDist = dist;
|
||||
}
|
||||
}
|
||||
Assert(minDist<0.1f);
|
||||
out.map[ivpIndex] = index;
|
||||
out.minRef = min(out.minRef, index);
|
||||
out.maxRef = max(out.maxRef, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Each IVP_Compact_Triangle and IVP_Compact_Edge occupies an index
|
||||
// 0,1,2,3 is tri, edge, edge, edge (tris and edges are both 16 bytes)
|
||||
// So you can just add the index to get_first_triangle to get a pointer
|
||||
inline int EdgeIndex( const IVP_Compact_Ledge *pLedge, const IVP_Compact_Edge *pEdge )
|
||||
{
|
||||
return pEdge - (const IVP_Compact_Edge *)pLedge->get_first_triangle();
|
||||
}
|
||||
|
||||
// Builds a packedhull_t from a IVP_Compact_Ledge. Assumes that the utlbuffer points at the memory following pHull (pHull is the header, utlbuffer is the body)
|
||||
void PackLedgeIntoBuffer( packedhull_t *pHull, CUtlBuffer &buf, const IVP_Compact_Ledge *pLedge, const virtualmeshlist_t &list )
|
||||
{
|
||||
if ( !pLedge )
|
||||
return;
|
||||
|
||||
// The lists store the ivp index of each element to be written out
|
||||
// The maps store the output packed index for each ivp index
|
||||
CUtlVector<int> triangleList, triangleMap;
|
||||
CUtlVector<int> edgeList, edgeMap;
|
||||
vertmap_t vertMap;
|
||||
BuildVertMap( vertMap, list.pVerts, list.vertexCount, pLedge );
|
||||
pHull->baseVert = vertMap.minRef;
|
||||
// clear the maps
|
||||
triangleMap.EnsureCount(pLedge->get_n_triangles());
|
||||
for ( int i = 0; i < triangleMap.Count(); i++ )
|
||||
{
|
||||
triangleMap[i] = -1;
|
||||
}
|
||||
edgeMap.EnsureCount(pLedge->get_n_triangles()*4); // each triangle also occupies an edge index
|
||||
for ( int i = 0; i < edgeMap.Count(); i++ )
|
||||
{
|
||||
edgeMap[i] = -1;
|
||||
}
|
||||
|
||||
// we're going to reorder the triangles and edges so that the ones marked virtual
|
||||
// appear first in the list. This way we only need a virtual count, not a per-item
|
||||
// flag.
|
||||
|
||||
// also, the edges are stored relative to the first triangle that references them
|
||||
// so an edge from 0->1 means that the first triangle that references the edge is 0->1 and the
|
||||
// second triangle is 1->0. This way we store half the edges and the winged edge pointers are implicit
|
||||
|
||||
// sort triangles in two passes
|
||||
for ( int i = 0; i < pLedge->get_n_triangles(); i++ )
|
||||
{
|
||||
const IVP_Compact_Triangle *pTri = pLedge->get_first_triangle() + i;
|
||||
if ( pTri->get_is_virtual() )
|
||||
{
|
||||
triangleMap[i] = triangleList.AddToTail(i);
|
||||
}
|
||||
}
|
||||
pHull->vtriCount = triangleList.Count();
|
||||
for ( int i = 0; i < pLedge->get_n_triangles(); i++ )
|
||||
{
|
||||
const IVP_Compact_Triangle *pTri = pLedge->get_first_triangle() + i;
|
||||
if ( !pTri->get_is_virtual() )
|
||||
{
|
||||
triangleMap[i] = triangleList.AddToTail(i);
|
||||
}
|
||||
}
|
||||
// sort edges in two passes
|
||||
for ( int i = 0; i < pLedge->get_n_triangles(); i++ )
|
||||
{
|
||||
const IVP_Compact_Triangle *pTri = pLedge->get_first_triangle() + triangleList[i];
|
||||
for ( int j = 0; j < 3; j++ )
|
||||
{
|
||||
const IVP_Compact_Edge *pEdge = pTri->get_edge(j);
|
||||
if ( pEdge->get_is_virtual() && edgeMap[EdgeIndex(pLedge, pEdge->get_opposite())] < 0 )
|
||||
{
|
||||
edgeMap[EdgeIndex(pLedge, pEdge)] = edgeList.AddToTail(EdgeIndex(pLedge, pEdge));
|
||||
}
|
||||
}
|
||||
}
|
||||
pHull->vedgeCount = edgeList.Count();
|
||||
|
||||
for ( int i = 0; i < pLedge->get_n_triangles(); i++ )
|
||||
{
|
||||
const IVP_Compact_Triangle *pTri = pLedge->get_first_triangle() + triangleList[i];
|
||||
for ( int j = 0; j < 3; j++ )
|
||||
{
|
||||
const IVP_Compact_Edge *pEdge = pTri->get_edge(j);
|
||||
int index = EdgeIndex(pLedge, pEdge);
|
||||
int oppositeIndex = EdgeIndex(pLedge, pEdge->get_opposite());
|
||||
if ( !pEdge->get_is_virtual() && edgeMap[oppositeIndex] < 0 )
|
||||
{
|
||||
edgeMap[index] = edgeList.AddToTail(index);
|
||||
}
|
||||
if ( edgeMap[index] < 0 )
|
||||
{
|
||||
Assert(edgeMap[oppositeIndex] >= 0);
|
||||
edgeMap[index] = edgeMap[oppositeIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
Assert( edgeList.Count() == pHull->edgeCount );
|
||||
|
||||
// now write the packed triangles
|
||||
for ( int i = 0; i < pHull->triangleCount; i++ )
|
||||
{
|
||||
packedtriangle_t tri;
|
||||
const IVP_Compact_Triangle *pTri = pLedge->get_first_triangle() + triangleList[i];
|
||||
const IVP_Compact_Edge *pEdge;
|
||||
pEdge = pTri->get_edge(0);
|
||||
tri.opposite = triangleMap[pTri->get_pierce_index()];
|
||||
Assert(tri.opposite<pHull->triangleCount);
|
||||
tri.e0 = edgeMap[EdgeIndex(pLedge, pEdge)];
|
||||
pEdge = pTri->get_edge(1);
|
||||
tri.e1 = edgeMap[EdgeIndex(pLedge, pEdge)];
|
||||
pEdge = pTri->get_edge(2);
|
||||
tri.e2 = edgeMap[EdgeIndex(pLedge, pEdge)];
|
||||
Assert(tri.e0<pHull->edgeCount);
|
||||
Assert(tri.e1<pHull->edgeCount);
|
||||
Assert(tri.e2<pHull->edgeCount);
|
||||
buf.Put(&tri, sizeof(tri));
|
||||
}
|
||||
// now write the packed edges
|
||||
for ( int i = 0; i < pHull->edgeCount; i++ )
|
||||
{
|
||||
packededge_t edge;
|
||||
const IVP_Compact_Edge *pEdge = (const IVP_Compact_Edge *)pLedge->get_first_triangle() + edgeList[i];
|
||||
Assert((edgeList[i]&3) != 0); // must not be a triangle
|
||||
|
||||
int v0 = vertMap.map[pEdge->get_start_point_index()] - pHull->baseVert;
|
||||
int v1 = vertMap.map[pEdge->get_next()->get_start_point_index()] - pHull->baseVert;
|
||||
Assert(v0>=0 && v0<256);
|
||||
Assert(v1>=0 && v1<256);
|
||||
edge.v0 = v0;
|
||||
edge.v1 = v1;
|
||||
buf.Put(&edge, sizeof(edge));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// decompress packed hull into a compact ledge
|
||||
void CVPhysicsVirtualMeshWriter::UnpackCompactLedgeFromHull( IVP_Compact_Ledge *pLedge, int materialIndex, const IVP_Compact_Poly_Point *pPointList, const virtualmeshhull_t *pHullHeader, int hullIndex, bool isVirtualLedge )
|
||||
{
|
||||
const packedhull_t *pHull = pHullHeader->GetPackedHull(hullIndex);
|
||||
const packedtriangle_t *pPackedTris = pHullHeader->GetPackedTriangles(hullIndex);
|
||||
// write the ledge
|
||||
pLedge->set_offset_ledge_points( (int)((char *)pPointList - (char *)pLedge) ); // byte offset from 'this' to (ledge) point array
|
||||
pLedge->set_is_compact( IVP_TRUE );
|
||||
pLedge->set_size(sizeof(IVP_Compact_Ledge) + sizeof(IVP_Compact_Triangle)*pHull->triangleCount); // <0 indicates a non compact compact ledge
|
||||
pLedge->n_triangles = pHull->triangleCount;
|
||||
pLedge->has_chilren_flag = isVirtualLedge ? IVP_TRUE : IVP_FALSE;
|
||||
|
||||
// Make the offset -pLedge so the result is a NULL ledgetree node - we haven't needed to create one of these as of yet
|
||||
//pLedge->ledgetree_node_offset = -((int)pLedge);
|
||||
|
||||
// keep track of which triangle edge referenced this edge (so the next one can swap the order and point to the first one)
|
||||
int forwardEdgeIndex[255];
|
||||
for ( int i = 0; i < pHull->edgeCount; i++ )
|
||||
{
|
||||
forwardEdgeIndex[i] = -1;
|
||||
}
|
||||
packededge_t *pPackedEdges = (packededge_t *)(pPackedTris + pHull->triangleCount);
|
||||
IVP_Compact_Triangle *pOut = pLedge->get_first_triangle();
|
||||
// now write the compact triangles and their edges
|
||||
int baseVert = pHull->baseVert;
|
||||
for ( int i = 0; i < pHull->triangleCount; i++ )
|
||||
{
|
||||
pOut[i].set_tri_index(i);
|
||||
pOut[i].set_material_index(materialIndex);
|
||||
pOut[i].set_is_virtual( i < pHull->vtriCount ? IVP_TRUE : IVP_FALSE );
|
||||
pOut[i].set_pierce_index(pPackedTris[i].opposite);
|
||||
Assert(pPackedTris[i].opposite<pHull->triangleCount);
|
||||
int edges[3] = {pPackedTris[i].e0, pPackedTris[i].e1, pPackedTris[i].e2};
|
||||
for ( int j = 0; j < 3; j++ )
|
||||
{
|
||||
Assert(edges[j]<pHull->edgeCount);
|
||||
if ( forwardEdgeIndex[edges[j]] < 0 )
|
||||
{
|
||||
// this is the first triangle to use this edge, so it's forward (and the other triangle sharing (opposite edge pointer) is unknown)
|
||||
int startVert = pPackedEdges[edges[j]].v0 + baseVert;
|
||||
pOut[i].c_three_edges[j].set_start_point_index(startVert);
|
||||
pOut[i].c_three_edges[j].set_is_virtual( edges[j] < pHull->vedgeCount ? IVP_TRUE : IVP_FALSE );
|
||||
forwardEdgeIndex[edges[j]] = EdgeIndex(pLedge, &pOut[i].c_three_edges[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is the second triangle to use this edge, so it's reversed (and the other triangle sharing is in the forward edge table)
|
||||
int oppositeIndex = forwardEdgeIndex[edges[j]];
|
||||
|
||||
int startVert = pPackedEdges[edges[j]].v1 + baseVert;
|
||||
pOut[i].c_three_edges[j].set_start_point_index(startVert);
|
||||
pOut[i].c_three_edges[j].set_is_virtual( edges[j] < pHull->vedgeCount ? IVP_TRUE : IVP_FALSE );
|
||||
// now build the links between the triangles sharing this edge
|
||||
int thisEdgeIndex = EdgeIndex( pLedge, &pOut[i].c_three_edges[j] );
|
||||
pOut[i].c_three_edges[j].set_opposite_index( oppositeIndex - thisEdgeIndex );
|
||||
pOut[i].c_three_edges[j].get_opposite()->set_opposite_index( thisEdgeIndex - oppositeIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// low-level code to initialize a 2-sided triangle
|
||||
static void InitTriangle( IVP_Compact_Triangle *pTri, int index, int materialIndex, int v0, int v1, int v2, int opp0, int opp1, int opp2 )
|
||||
{
|
||||
pTri->set_tri_index(index);
|
||||
pTri->set_material_index(materialIndex);
|
||||
|
||||
pTri->c_three_edges[0].set_start_point_index(v0);
|
||||
pTri->c_three_edges[1].set_start_point_index(v1);
|
||||
pTri->c_three_edges[2].set_start_point_index(v2);
|
||||
|
||||
pTri->c_three_edges[0].set_opposite_index(opp0);
|
||||
pTri->c_three_edges[1].set_opposite_index(opp1);
|
||||
pTri->c_three_edges[2].set_opposite_index(opp2);
|
||||
}
|
||||
|
||||
void CVPhysicsVirtualMeshWriter::InitTwoSidedTriangleLege( triangleledge_t *pOut, const IVP_Compact_Poly_Point *pPoints, int v0, int v1, int v2, int materialIndex )
|
||||
{
|
||||
IVP_Compact_Ledge *pLedge = &pOut->ledge;
|
||||
pLedge->set_offset_ledge_points( (int)((char *)pPoints - (char *)pLedge) ); // byte offset from 'this' to (ledge) point array
|
||||
pLedge->set_is_compact( IVP_TRUE );
|
||||
pLedge->set_size(sizeof(triangleledge_t)); // <0 indicates a non compact compact ledge
|
||||
pLedge->n_triangles = 2;
|
||||
pLedge->has_chilren_flag = IVP_FALSE;
|
||||
// triangles
|
||||
InitTriangle( &pOut->faces[0], 0, materialIndex, v0, v1, v2, 6, 4, 2 );
|
||||
InitTriangle( &pOut->faces[1], 1, materialIndex, v0, v2, v1, -2, -4, -6);
|
||||
pOut->faces[0].set_pierce_index(1);
|
||||
pOut->faces[1].set_pierce_index(0);
|
||||
}
|
||||
|
||||
bool CVPhysicsVirtualMeshWriter::LedgeCanBePacked(const IVP_Compact_Ledge *pLedge, const virtualmeshlist_t &list)
|
||||
{
|
||||
int edgeCount = pLedge->get_n_triangles() * 3;
|
||||
if ( edgeCount > 512 )
|
||||
return false;
|
||||
vertmap_t vertMap;
|
||||
BuildVertMap( vertMap, list.pVerts, list.vertexCount, pLedge );
|
||||
if ( (vertMap.maxRef - vertMap.minRef) > 255 )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// this builds a packed hull array from a compact ledge array (needs the virtualmeshlist for reference)
|
||||
virtualmeshhull_t *CVPhysicsVirtualMeshWriter::CreatePackedHullFromLedges( const virtualmeshlist_t &list, const IVP_Compact_Ledge **pLedges, int ledgeCount )
|
||||
{
|
||||
int triCount = 0;
|
||||
int edgeCount = 0;
|
||||
for ( int i = 0; i < ledgeCount; i++ )
|
||||
{
|
||||
triCount += pLedges[i]->get_n_triangles();
|
||||
edgeCount += (pLedges[i]->get_n_triangles() * 3)/2;
|
||||
Assert(LedgeCanBePacked(pLedges[i], list));
|
||||
}
|
||||
|
||||
unsigned int totalSize = sizeof(packedtriangle_t)*triCount + sizeof(packededge_t)*edgeCount + sizeof(packedhull_t)*ledgeCount + sizeof(virtualmeshhull_t);
|
||||
byte *pBuf = new byte[totalSize];
|
||||
|
||||
CUtlBuffer buf;
|
||||
buf.SetExternalBuffer( pBuf, totalSize, 0, 0 );
|
||||
|
||||
if ( 1 )
|
||||
{
|
||||
virtualmeshhull_t tmp;
|
||||
Q_memset( &tmp, 0, sizeof(tmp) );
|
||||
tmp.hullCount = ledgeCount;
|
||||
buf.Put(&tmp, sizeof(tmp));
|
||||
}
|
||||
|
||||
// write the headers
|
||||
Assert(ledgeCount < 16);
|
||||
packedhull_t *pHulls[16];
|
||||
for ( int i = 0; i < ledgeCount; i++ )
|
||||
{
|
||||
pHulls[i] = (packedhull_t *)buf.PeekPut();
|
||||
packedhull_t hull;
|
||||
hull.triangleCount = pLedges[i]->get_n_triangles();
|
||||
hull.edgeCount = (hull.triangleCount * 3) / 2;
|
||||
buf.Put(&hull, sizeof(hull));
|
||||
}
|
||||
|
||||
// write the data itself
|
||||
for ( int i = 0; i < ledgeCount; i++ )
|
||||
{
|
||||
PackLedgeIntoBuffer( pHulls[i], buf, pLedges[i], list );
|
||||
}
|
||||
|
||||
return (virtualmeshhull_t *)pBuf;
|
||||
}
|
||||
|
||||
// frees the memory associated with this packed hull
|
||||
void CVPhysicsVirtualMeshWriter::DestroyPackedHull( virtualmeshhull_t *pHull )
|
||||
{
|
||||
byte *pData = (byte *)pHull;
|
||||
delete[] pData;
|
||||
}
|
||||
|
||||
|
||||
unsigned int CVPhysicsVirtualMeshWriter::UnpackLedgeListFromHull( byte *pOut, virtualmeshhull_t *pHull, IVP_Compact_Poly_Point *pPoints )
|
||||
{
|
||||
unsigned int memOffset = 0;
|
||||
for ( int i = 0; i < pHull->hullCount; i++ )
|
||||
{
|
||||
IVP_Compact_Ledge *pHullLedge = (IVP_Compact_Ledge *)(pOut + memOffset);
|
||||
CVPhysicsVirtualMeshWriter::UnpackCompactLedgeFromHull( pHullLedge, 0, pPoints, pHull, i, true );
|
||||
memOffset += pHullLedge->get_size();
|
||||
}
|
||||
return memOffset;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
#define DUMP_FILES 1
|
||||
static bool DumpListToGLView( const char *pFilename, const virtualmeshlist_t &list )
|
||||
{
|
||||
#if DUMP_FILES
|
||||
FILE *fp = fopen( pFilename, "a+" );
|
||||
for ( int i = 0; i < list.triangleCount; i++ )
|
||||
{
|
||||
fprintf( fp, "3\n" );
|
||||
fprintf( fp, "%6.3f %6.3f %6.3f 1 0 0\n", list.pVerts[list.indices[i*3+0]].x, list.pVerts[list.indices[i*3+0]].y, list.pVerts[list.indices[i*3+0]].z );
|
||||
fprintf( fp, "%6.3f %6.3f %6.3f 0 1 0\n", list.pVerts[list.indices[i*3+1]].x, list.pVerts[list.indices[i*3+1]].y, list.pVerts[list.indices[i*3+1]].z );
|
||||
fprintf( fp, "%6.3f %6.3f %6.3f 0 0 1\n", list.pVerts[list.indices[i*3+2]].x, list.pVerts[list.indices[i*3+2]].y, list.pVerts[list.indices[i*3+2]].z );
|
||||
}
|
||||
fclose(fp);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool DumpLedgeToGLView( const char *pFilename, const IVP_Compact_Ledge *pLedge, float r=1.0f, float g=1.0f, float b=1.0f, float offset=0.0f )
|
||||
{
|
||||
#if DUMP_FILES
|
||||
FILE *fp = fopen( pFilename, "a+" );
|
||||
int ivpIndex;
|
||||
Vector tmp[3];
|
||||
const IVP_Compact_Poly_Point *pPoints = pLedge->get_point_array();
|
||||
for ( int i = 0; i < pLedge->get_n_triangles(); i++ )
|
||||
{
|
||||
// iterate each triangle, for each referenced vert that hasn't yet been mapped, search for the nearest match
|
||||
const IVP_Compact_Triangle *pTri = pLedge->get_first_triangle() + i;
|
||||
ivpIndex = pTri->get_edge(2)->get_start_point_index();
|
||||
ConvertPositionToHL( &pPoints[ivpIndex], tmp[0] );
|
||||
ivpIndex = pTri->get_edge(1)->get_start_point_index();
|
||||
ConvertPositionToHL( &pPoints[ivpIndex], tmp[1] );
|
||||
ivpIndex = pTri->get_edge(0)->get_start_point_index();
|
||||
ConvertPositionToHL( &pPoints[ivpIndex], tmp[2] );
|
||||
tmp[0].x += offset;
|
||||
tmp[1].x += offset;
|
||||
tmp[2].x += offset;
|
||||
fprintf( fp, "2\n" );
|
||||
fprintf( fp, "%6.3f %6.3f %6.3f %.1f %.1f %.1f\n", tmp[0].x, tmp[0].y, tmp[0].z, r, g, b );
|
||||
fprintf( fp, "%6.3f %6.3f %6.3f %.1f %.1f %.1f\n", tmp[1].x, tmp[1].y, tmp[1].z, r, g, b );
|
||||
fprintf( fp, "2\n" );
|
||||
fprintf( fp, "%6.3f %6.3f %6.3f %.1f %.1f %.1f\n", tmp[1].x, tmp[1].y, tmp[1].z, r, g, b );
|
||||
fprintf( fp, "%6.3f %6.3f %6.3f %.1f %.1f %.1f\n", tmp[2].x, tmp[2].y, tmp[2].z, r, g, b );
|
||||
fprintf( fp, "2\n" );
|
||||
fprintf( fp, "%6.3f %6.3f %6.3f %.1f %.1f %.1f\n", tmp[2].x, tmp[2].y, tmp[2].z, r, g, b );
|
||||
fprintf( fp, "%6.3f %6.3f %6.3f %.1f %.1f %.1f\n", tmp[0].x, tmp[0].y, tmp[0].z, r, g, b );
|
||||
}
|
||||
fclose( fp );
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ComputeSize( virtualmeshhull_t *pHeader )
|
||||
{
|
||||
packedhull_t *pHull = (packedhull_t *)(pHeader+1);
|
||||
unsigned int size = pHeader->hullCount * sizeof(IVP_Compact_Ledge);
|
||||
for ( int i = 0; i < pHeader->hullCount; i++ )
|
||||
{
|
||||
size += sizeof(IVP_Compact_Triangle) * pHull[i].triangleCount;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool CVPhysicsVirtualMeshWriter::CheckHulls( virtualmeshhull_t *pHull0, virtualmeshhull_t *pHull1, const virtualmeshlist_t &list )
|
||||
{
|
||||
for ( int i = 0; i < pHull0->hullCount; i++ )
|
||||
{
|
||||
const packedhull_t *pP0 = pHull0->GetPackedHull(i);
|
||||
const packedhull_t *pP1 = pHull1->GetPackedHull(i);
|
||||
Assert(pP0->triangleCount == pP1->triangleCount);
|
||||
Assert(pP0->vtriCount == pP1->vtriCount);
|
||||
Assert(pP0->edgeCount == pP1->edgeCount);
|
||||
Assert(pP0->vedgeCount == pP1->vedgeCount);
|
||||
Assert(pP0->baseVert == pP1->baseVert);
|
||||
const packedtriangle_t *pTri0 = pHull0->GetPackedTriangles( i );
|
||||
const packedtriangle_t *pTri1 = pHull1->GetPackedTriangles( i );
|
||||
for ( int j = 0; j < pP0->triangleCount; j++ )
|
||||
{
|
||||
Assert(pTri0[j].e0 == pTri1[j].e0);
|
||||
Assert(pTri0[j].e1 == pTri1[j].e1);
|
||||
Assert(pTri0[j].e2 == pTri1[j].e2);
|
||||
Assert(pTri0[j].opposite == pTri1[j].opposite);
|
||||
}
|
||||
}
|
||||
{
|
||||
int size0 = ComputeSize(pHull0);
|
||||
int pointSize0 = sizeof(IVP_Compact_Poly_Point) * list.vertexCount;
|
||||
byte *pMem0 = (byte *)ivp_malloc_aligned( size0+pointSize0, 16 );
|
||||
IVP_Compact_Poly_Point *pPoints = (IVP_Compact_Poly_Point *)pMem0;
|
||||
IVP_Compact_Ledge *pLedge0 = (IVP_Compact_Ledge *)(pPoints + list.vertexCount);
|
||||
for ( int i = 0; i < list.vertexCount; i++ )
|
||||
{
|
||||
ConvertPositionToIVP( list.pVerts[i], pPoints[i] );
|
||||
}
|
||||
UnpackLedgeListFromHull( (byte *)pLedge0, pHull0, pPoints );
|
||||
for ( int i = 0; i < pHull0->hullCount; i++ )
|
||||
{
|
||||
if ( i == i ) DumpLedgeToGLView( "c:\\jay.txt", pLedge0, 1, 0, 0, 0 );
|
||||
pLedge0 = (IVP_Compact_Ledge *)( ((byte *)pLedge0 ) + pLedge0->get_size() );
|
||||
}
|
||||
ivp_free_aligned(pMem0);
|
||||
}
|
||||
|
||||
{
|
||||
int size1 = ComputeSize(pHull1);
|
||||
int pointSize1 = sizeof(IVP_Compact_Poly_Point) * list.vertexCount;
|
||||
byte *pMem1 = (byte *)ivp_malloc_aligned( size1+pointSize1, 16 );
|
||||
IVP_Compact_Poly_Point *pPoints = (IVP_Compact_Poly_Point *)pMem1;
|
||||
IVP_Compact_Ledge *pLedge1 = (IVP_Compact_Ledge *)(pPoints + list.vertexCount);
|
||||
for ( int i = 0; i < list.vertexCount; i++ )
|
||||
{
|
||||
ConvertPositionToIVP( list.pVerts[i], pPoints[i] );
|
||||
}
|
||||
UnpackLedgeListFromHull( (byte *)pLedge1, pHull1, pPoints );
|
||||
for ( int i = 0; i < pHull1->hullCount; i++ )
|
||||
{
|
||||
if ( i == i ) DumpLedgeToGLView( "c:\\jay.txt", pLedge1, 0, 1, 0, 1024 );
|
||||
pLedge1 = (IVP_Compact_Ledge *)( ((byte *)pLedge1 ) + pLedge1->get_size() );
|
||||
}
|
||||
ivp_free_aligned(pMem1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
*/
|
@ -1,110 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef LEDGEWRITER_H
|
||||
#define LEDGEWRITER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "vphysics/virtualmesh.h"
|
||||
|
||||
// 2-sided triangle ledge rep
|
||||
struct triangleledge_t
|
||||
{
|
||||
IVP_Compact_Ledge ledge;
|
||||
IVP_Compact_Triangle faces[2];
|
||||
};
|
||||
|
||||
// minimum footprint convex hull rep. Assume 8-bits of index space per edge/triangle/vert
|
||||
// NOTE: EACH ELEMENT OF THESE STRUCTS MUST BE 8-bits OR YOU HAVE TO WRITE SWAPPING CODE FOR
|
||||
// THE X360 IMPLEMENTATION. THERE IS NO SUCH CODE AS OF NOW.
|
||||
#pragma pack(1)
|
||||
struct packedtriangle_t
|
||||
{
|
||||
byte e0; // only bytes allowed see above
|
||||
byte e1;
|
||||
byte e2;
|
||||
byte opposite;
|
||||
};
|
||||
|
||||
struct packededge_t
|
||||
{
|
||||
byte v0; // only bytes allowed see above
|
||||
byte v1;
|
||||
};
|
||||
|
||||
struct packedhull_t
|
||||
{
|
||||
byte triangleCount; // only bytes allowed see above
|
||||
byte vtriCount;
|
||||
byte edgeCount;
|
||||
byte vedgeCount;
|
||||
byte baseVert;
|
||||
inline size_t DataSize() const
|
||||
{
|
||||
return (sizeof(packedtriangle_t) * triangleCount) + (sizeof(packededge_t)*edgeCount);
|
||||
}
|
||||
};
|
||||
|
||||
struct virtualmeshhull_t
|
||||
{
|
||||
byte hullCount; // only bytes allowed see above
|
||||
byte pad[3];
|
||||
|
||||
inline const packedhull_t *GetPackedHull( int hullIndex ) const
|
||||
{
|
||||
Assert(hullIndex<hullCount);
|
||||
return ((const packedhull_t *)(this+1)) + hullIndex;
|
||||
}
|
||||
inline const packedtriangle_t *GetPackedTriangles( int hullIndex ) const
|
||||
{
|
||||
const packedhull_t *pHull = GetPackedHull(0);
|
||||
// the first triangle is immediately following the memory for the packed hulls
|
||||
const byte *pStart = reinterpret_cast<const byte *>(GetPackedHull(0) + hullCount);
|
||||
for ( int i = 0; i < hullIndex; i++ )
|
||||
{
|
||||
pStart += pHull[i].DataSize();
|
||||
}
|
||||
return reinterpret_cast<const packedtriangle_t *>(pStart);
|
||||
}
|
||||
inline const packededge_t *GetPackedEdges( int hullIndex ) const
|
||||
{
|
||||
return reinterpret_cast<const packededge_t *>(GetPackedTriangles(hullIndex) + GetPackedHull(hullIndex)->triangleCount);
|
||||
}
|
||||
inline size_t TotalSize() const
|
||||
{
|
||||
size_t size = sizeof(*this) + sizeof(packedhull_t) * hullCount;
|
||||
for ( int i = 0; i < hullCount; i++ )
|
||||
{
|
||||
size += GetPackedHull(i)->DataSize();
|
||||
}
|
||||
return size;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
// end
|
||||
// NOTE: EACH ELEMENT OF THE ABOVE STRUCTS MUST BE 8-bits OR YOU HAVE TO WRITE SWAPPING CODE FOR
|
||||
// THE X360 IMPLEMENTATION. THERE IS NO SUCH CODE AS OF NOW.
|
||||
|
||||
|
||||
// These statics are grouped in a class so they can be friends of IVP_Compact_Ledge and access its private data
|
||||
class CVPhysicsVirtualMeshWriter
|
||||
{
|
||||
public:
|
||||
// init a 2-sided triangle ledge
|
||||
static void InitTwoSidedTriangleLege( triangleledge_t *pOut, const IVP_Compact_Poly_Point *pPoints, int v0, int v1, int v2, int materialIndex );
|
||||
|
||||
static virtualmeshhull_t *CreatePackedHullFromLedges( const virtualmeshlist_t &list, const IVP_Compact_Ledge **pLedges, int ledgeCount );
|
||||
static void UnpackCompactLedgeFromHull( IVP_Compact_Ledge *pLedge, int materialIndex, const IVP_Compact_Poly_Point *pPointList, const virtualmeshhull_t *pHullHeader, int hullIndex, bool isVirtualLedge );
|
||||
static void DestroyPackedHull( virtualmeshhull_t *pHull );
|
||||
static bool LedgeCanBePacked(const IVP_Compact_Ledge *pLedge, const virtualmeshlist_t &list);
|
||||
static unsigned int UnpackLedgeListFromHull( byte *pOut, virtualmeshhull_t *pHull, IVP_Compact_Poly_Point *pPoints );
|
||||
};
|
||||
|
||||
#endif // LEDGEWRITER_H
|
@ -1,113 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "tier0/platform.h"
|
||||
#include "linear_solver.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
// BUGBUG: Remove/tune this number somehow!!!
|
||||
#define DET_EPSILON 1e-6f
|
||||
|
||||
|
||||
// assumes square matrix!
|
||||
// ONLY SUPPORTS 2x2, 3x3, and 4x4
|
||||
float Det( float *matrix, int rows )
|
||||
{
|
||||
if ( rows == 2 )
|
||||
{
|
||||
return matrix[0]*matrix[3] - matrix[1]*matrix[2];
|
||||
}
|
||||
if ( rows == 3 )
|
||||
{
|
||||
return matrix[0]*matrix[4]*matrix[8] - matrix[0]*matrix[7]*matrix[5] - matrix[1]*matrix[3]*matrix[8] +
|
||||
matrix[1]*matrix[5]*matrix[6] + matrix[2]*matrix[3]*matrix[7] - matrix[2]*matrix[4]*matrix[6];
|
||||
}
|
||||
|
||||
// ERROR no more than 4x4
|
||||
if ( rows != 4 )
|
||||
return 0;
|
||||
|
||||
// UNDONE: Generalize this to NxN
|
||||
float tmp[9];
|
||||
float det = 0.f;
|
||||
// do 4 3x3 dets
|
||||
for ( int i = 0; i < 4; i++ )
|
||||
{
|
||||
// develop on row 0
|
||||
int out = 0;
|
||||
for ( int j = 1; j < 4; j++ )
|
||||
{
|
||||
// iterate each column and
|
||||
for ( int k = 0; k < 4; k++ )
|
||||
{
|
||||
if ( k == i )
|
||||
continue;
|
||||
tmp[out] = matrix[(j*rows)+k];
|
||||
out++;
|
||||
}
|
||||
}
|
||||
if ( i & 1 )
|
||||
{
|
||||
det -= matrix[i]*Det(tmp,3);
|
||||
}
|
||||
else
|
||||
{
|
||||
det += matrix[i]*Det(tmp,3);
|
||||
}
|
||||
}
|
||||
|
||||
return det;
|
||||
}
|
||||
|
||||
float *SolveCramer( const float *matrix, int rows, int columns )
|
||||
{
|
||||
// max 4 equations, 4 unknowns (until determinant routine is more general)
|
||||
float tmpMain[16*16], tmpSub[16*16];
|
||||
static float solution[16];
|
||||
|
||||
int i, j;
|
||||
|
||||
if ( rows > 4 || columns > 5 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int outCol = columns - 1;
|
||||
// copy out the square matrix
|
||||
for ( i = 0; i < rows; i++ )
|
||||
{
|
||||
memcpy( tmpMain + (i*outCol), matrix + i*columns, sizeof(float)*outCol );
|
||||
}
|
||||
|
||||
float detMain = Det( tmpMain, rows );
|
||||
|
||||
// probably degenerate!
|
||||
if ( fabs(detMain) < DET_EPSILON )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for ( i = 0; i < rows; i++ )
|
||||
{
|
||||
// copy the square matrix
|
||||
memcpy( tmpSub, tmpMain, sizeof(float)*rows*rows );
|
||||
|
||||
// copy the column of constants over the row
|
||||
for ( j = 0; j < rows; j++ )
|
||||
{
|
||||
tmpSub[i+j*outCol] = matrix[j*columns+columns-1];
|
||||
}
|
||||
float det = Det( tmpSub, rows );
|
||||
solution[i] = det / detMain;
|
||||
}
|
||||
|
||||
return solution;
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef LINEAR_SOLVER_H
|
||||
#define LINEAR_SOLVER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
// Take the determinant of a matrix.
|
||||
// NOTE: ONLY SUPPORTS 2x2, 3x3, and 4x4
|
||||
extern float Det( float *matrix, int rows );
|
||||
|
||||
// solve a system of linear equations using Cramer's rule (only supports up to 4 variables due to limits on Det())
|
||||
extern float *SolveCramer( const float *matrix, int rows, int columns );
|
||||
|
||||
#endif // LINEAR_SOLVER_H
|
@ -1,269 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "interface.h"
|
||||
#include "vphysics/object_hash.h"
|
||||
#include "vphysics/collision_set.h"
|
||||
#include "tier1/tier1.h"
|
||||
#include "ivu_vhash.hxx"
|
||||
#include "PxPhysicsAPI.h"
|
||||
#include "convert.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
#if defined(_WIN32) && !defined(_X360)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif // _WIN32 && !_X360
|
||||
|
||||
#include "vphysics_interfaceV30.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
static void ivu_string_print_function( const char *str )
|
||||
{
|
||||
Msg("%s", str);
|
||||
}
|
||||
|
||||
class PhysErrorCallback : public PxErrorCallback
|
||||
{
|
||||
public:
|
||||
virtual void reportError(PxErrorCode::Enum code, const char* message, const char* file,
|
||||
int line)
|
||||
{
|
||||
// error processing implementation
|
||||
Warning("Px: %s %s:%d\n", message, file, line);
|
||||
}
|
||||
};
|
||||
|
||||
PhysErrorCallback gPxErrorCallback;
|
||||
PxDefaultAllocator gPxAllocatorCallback;
|
||||
|
||||
PxFoundation *gPxFoundation = NULL;
|
||||
PxPvd *gPxPvd = NULL;
|
||||
PxPhysics *gPxPhysics = NULL;
|
||||
PxCooking *gPxCooking = NULL;
|
||||
|
||||
// simple 32x32 bit array
|
||||
class CPhysicsCollisionSet : public IPhysicsCollisionSet
|
||||
{
|
||||
public:
|
||||
~CPhysicsCollisionSet() {}
|
||||
CPhysicsCollisionSet()
|
||||
{
|
||||
memset( m_bits, 0, sizeof(m_bits) );
|
||||
}
|
||||
void EnableCollisions( int index0, int index1 )
|
||||
{
|
||||
Assert(index0<32&&index1<32);
|
||||
m_bits[index0] |= 1<<index1;
|
||||
m_bits[index1] |= 1<<index0;
|
||||
}
|
||||
void DisableCollisions( int index0, int index1 )
|
||||
{
|
||||
Assert(index0<32&&index1<32);
|
||||
m_bits[index0] &= ~(1<<index1);
|
||||
m_bits[index1] &= ~(1<<index0);
|
||||
}
|
||||
|
||||
bool ShouldCollide( int index0, int index1 )
|
||||
{
|
||||
Assert(index0<32&&index1<32);
|
||||
return (m_bits[index0] & (1<<index1)) ? true : false;
|
||||
}
|
||||
private:
|
||||
unsigned int m_bits[32];
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main physics interface
|
||||
//-----------------------------------------------------------------------------
|
||||
class CPhysicsInterface : public CTier1AppSystem<IPhysics>
|
||||
{
|
||||
public:
|
||||
CPhysicsInterface() : m_pCollisionSetHash(NULL) {}
|
||||
virtual InitReturnVal_t Init();
|
||||
virtual void Shutdown();
|
||||
virtual void *QueryInterface( const char *pInterfaceName );
|
||||
virtual IPhysicsEnvironment *CreateEnvironment( void );
|
||||
virtual void DestroyEnvironment( IPhysicsEnvironment *pEnvironment );
|
||||
virtual IPhysicsEnvironment *GetActiveEnvironmentByIndex( int index );
|
||||
virtual IPhysicsObjectPairHash *CreateObjectPairHash();
|
||||
virtual void DestroyObjectPairHash( IPhysicsObjectPairHash *pHash );
|
||||
virtual IPhysicsCollisionSet *FindOrCreateCollisionSet( unsigned int id, int maxElementCount );
|
||||
virtual IPhysicsCollisionSet *FindCollisionSet( unsigned int id );
|
||||
virtual void DestroyAllCollisionSets();
|
||||
|
||||
typedef CTier1AppSystem<IPhysics> BaseClass;
|
||||
private:
|
||||
CUtlVector<IPhysicsEnvironment *> m_envList;
|
||||
CUtlVector<CPhysicsCollisionSet> m_collisionSets;
|
||||
IVP_VHash_Store *m_pCollisionSetHash;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Expose singleton
|
||||
//-----------------------------------------------------------------------------
|
||||
static CPhysicsInterface g_MainDLLInterface;
|
||||
IPhysics *g_PhysicsInternal = &g_MainDLLInterface;
|
||||
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CPhysicsInterface, IPhysics, VPHYSICS_INTERFACE_VERSION, g_MainDLLInterface );
|
||||
|
||||
#define PVD_HOST "localhost"
|
||||
|
||||
InitReturnVal_t CPhysicsInterface::Init()
|
||||
{
|
||||
InitReturnVal_t nRetVal = BaseClass::Init();
|
||||
if ( nRetVal != INIT_OK )
|
||||
return nRetVal;
|
||||
|
||||
bool recordMemoryAllocations = true;
|
||||
|
||||
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f, false, false, false, false );
|
||||
|
||||
gPxFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gPxAllocatorCallback, gPxErrorCallback);
|
||||
|
||||
if( !gPxFoundation )
|
||||
{
|
||||
Error("PxCreateFoundation failed!\n");
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
gPxPvd = PxCreatePvd(*gPxFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10000);
|
||||
if(transport)
|
||||
Msg("PxDefaultPvdSocketTransportCreate success\n");
|
||||
|
||||
gPxPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
PxTolerancesScale scale;
|
||||
|
||||
scale.length = g_PhysicsUnits.unitScaleMetersInv;
|
||||
scale.speed *= g_PhysicsUnits.unitScaleMetersInv;
|
||||
|
||||
gPxPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gPxFoundation, scale, recordMemoryAllocations, gPxPvd);
|
||||
|
||||
if( !gPxPhysics )
|
||||
{
|
||||
Error("PxCreatePhysics failed!\n");
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
gPxCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gPxFoundation, PxCookingParams(scale));
|
||||
return INIT_OK;
|
||||
}
|
||||
|
||||
|
||||
void CPhysicsInterface::Shutdown()
|
||||
{
|
||||
if( gPxCooking )
|
||||
gPxCooking->release();
|
||||
|
||||
if( gPxPhysics )
|
||||
gPxPhysics->release();
|
||||
|
||||
if( gPxFoundation )
|
||||
gPxFoundation->release();
|
||||
|
||||
|
||||
BaseClass::Shutdown( );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Query interface
|
||||
//-----------------------------------------------------------------------------
|
||||
void *CPhysicsInterface::QueryInterface( const char *pInterfaceName )
|
||||
{
|
||||
// Loading the datacache DLL mounts *all* interfaces
|
||||
// This includes the backward-compatible interfaces + other vphysics interfaces
|
||||
CreateInterfaceFn factory = Sys_GetFactoryThis(); // This silly construction is necessary
|
||||
return factory( pInterfaceName, NULL ); // to prevent the LTCG compiler from crashing.
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Implementation of IPhysics
|
||||
//-----------------------------------------------------------------------------
|
||||
IPhysicsEnvironment *CPhysicsInterface::CreateEnvironment( void )
|
||||
{
|
||||
IPhysicsEnvironment *pEnvironment = CreatePhysicsEnvironment();
|
||||
m_envList.AddToTail( pEnvironment );
|
||||
return pEnvironment;
|
||||
}
|
||||
|
||||
void CPhysicsInterface::DestroyEnvironment( IPhysicsEnvironment *pEnvironment )
|
||||
{
|
||||
m_envList.FindAndRemove( pEnvironment );
|
||||
delete pEnvironment;
|
||||
}
|
||||
|
||||
IPhysicsEnvironment *CPhysicsInterface::GetActiveEnvironmentByIndex( int index )
|
||||
{
|
||||
if ( index < 0 || index >= m_envList.Count() )
|
||||
return NULL;
|
||||
|
||||
return m_envList[index];
|
||||
}
|
||||
|
||||
IPhysicsObjectPairHash *CPhysicsInterface::CreateObjectPairHash()
|
||||
{
|
||||
return ::CreateObjectPairHash();
|
||||
}
|
||||
|
||||
void CPhysicsInterface::DestroyObjectPairHash( IPhysicsObjectPairHash *pHash )
|
||||
{
|
||||
delete pHash;
|
||||
}
|
||||
// holds a cache of these by id.
|
||||
// NOTE: This is stuffed into vphysics.dll as a sneaky way of sharing the memory between
|
||||
// client and server in single player. So you can't have different client/server rules.
|
||||
IPhysicsCollisionSet *CPhysicsInterface::FindOrCreateCollisionSet( unsigned int id, int maxElementCount )
|
||||
{
|
||||
if ( !m_pCollisionSetHash )
|
||||
{
|
||||
m_pCollisionSetHash = new IVP_VHash_Store(256);
|
||||
}
|
||||
Assert( id != 0 );
|
||||
Assert( maxElementCount <= 32 );
|
||||
if ( maxElementCount > 32 )
|
||||
return NULL;
|
||||
|
||||
IPhysicsCollisionSet *pSet = FindCollisionSet( id );
|
||||
if ( pSet )
|
||||
return pSet;
|
||||
intp index = m_collisionSets.AddToTail();
|
||||
m_pCollisionSetHash->add_elem( (void *)(intp)id, (void *)(intp)(index+1) );
|
||||
return &m_collisionSets[index];
|
||||
}
|
||||
|
||||
IPhysicsCollisionSet *CPhysicsInterface::FindCollisionSet( unsigned int id )
|
||||
{
|
||||
if ( m_pCollisionSetHash )
|
||||
{
|
||||
intp index = (intp)m_pCollisionSetHash->find_elem( (void *)(intp)id );
|
||||
if ( index > 0 )
|
||||
{
|
||||
Assert( index <= m_collisionSets.Count() );
|
||||
if ( index <= m_collisionSets.Count() )
|
||||
{
|
||||
return &m_collisionSets[index-1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CPhysicsInterface::DestroyAllCollisionSets()
|
||||
{
|
||||
m_collisionSets.Purge();
|
||||
delete m_pCollisionSetHash;
|
||||
m_pCollisionSetHash = NULL;
|
||||
}
|
||||
|
@ -1,342 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "stdafx.h"
|
||||
#include "filesystem_tools.h"
|
||||
#include "KeyValues.h"
|
||||
#include "physdll.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "utlvector.h"
|
||||
|
||||
char g_szAppName[] = "VPhysics perf test";
|
||||
bool g_bCaptureOnFocus = false;
|
||||
|
||||
IPhysics *physics = NULL;
|
||||
IPhysicsCollision *physcollision = NULL;
|
||||
IPhysicsSurfaceProps *physprops = NULL;
|
||||
IMaterial *g_materialFlatshaded = NULL;
|
||||
IMaterial *g_pWireframeMaterial = NULL;
|
||||
int gKeys[256];
|
||||
|
||||
const objectparams_t g_PhysDefaultObjectParams =
|
||||
{
|
||||
NULL,
|
||||
1.0f, //mass
|
||||
1.0f, // inertia
|
||||
0.0f, // damping
|
||||
0.0f, // rotdamping
|
||||
0.05f, // rotIntertiaLimit
|
||||
"DEFAULT",
|
||||
NULL,// game data
|
||||
0.f, // volume (leave 0 if you don't have one or call physcollision->CollideVolume() to compute it)
|
||||
1.0f, // drag coefficient
|
||||
true,// enable collisions?
|
||||
};
|
||||
|
||||
|
||||
void AddSurfacepropFile( const char *pFileName, IPhysicsSurfaceProps *pProps, IFileSystem *pFileSystem )
|
||||
{
|
||||
// Load file into memory
|
||||
FileHandle_t file = pFileSystem->Open( pFileName, "rb" );
|
||||
|
||||
if ( file )
|
||||
{
|
||||
int len = pFileSystem->Size( file );
|
||||
|
||||
// read the file
|
||||
char *buffer = (char *)stackalloc( len+1 );
|
||||
pFileSystem->Read( buffer, len, file );
|
||||
pFileSystem->Close( file );
|
||||
buffer[len] = 0;
|
||||
pProps->ParseSurfaceData( pFileName, buffer );
|
||||
// buffer is on the stack, no need to free
|
||||
}
|
||||
}
|
||||
|
||||
void PhysParseSurfaceData( IPhysicsSurfaceProps *pProps, IFileSystem *pFileSystem )
|
||||
{
|
||||
const char *SURFACEPROP_MANIFEST_FILE = "scripts/surfaceproperties_manifest.txt";
|
||||
KeyValues *manifest = new KeyValues( SURFACEPROP_MANIFEST_FILE );
|
||||
if ( manifest->LoadFromFile( pFileSystem, SURFACEPROP_MANIFEST_FILE, "GAME" ) )
|
||||
{
|
||||
for ( KeyValues *sub = manifest->GetFirstSubKey(); sub != NULL; sub = sub->GetNextKey() )
|
||||
{
|
||||
if ( !Q_stricmp( sub->GetName(), "file" ) )
|
||||
{
|
||||
// Add
|
||||
AddSurfacepropFile( sub->GetString(), pProps, pFileSystem );
|
||||
continue;
|
||||
}
|
||||
|
||||
Warning( "surfaceprops::Init: Manifest '%s' with bogus file type '%s', expecting 'file'\n",
|
||||
SURFACEPROP_MANIFEST_FILE, sub->GetName() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Error( "Unable to load manifest file '%s'\n", SURFACEPROP_MANIFEST_FILE );
|
||||
}
|
||||
|
||||
manifest->deleteThis();
|
||||
}
|
||||
|
||||
struct physics_test_object_t
|
||||
{
|
||||
IPhysicsObject *pPhysics;
|
||||
ICollisionQuery *pModel;
|
||||
};
|
||||
|
||||
struct physicstest_t
|
||||
{
|
||||
IPhysicsEnvironment *physenv;
|
||||
CUtlVector<physics_test_object_t> list;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
physenv->SetQuickDelete( true );
|
||||
for ( int i = 0; i < list.Count(); i++ )
|
||||
{
|
||||
physcollision->DestroyQueryModel( list[i].pModel );
|
||||
physenv->DestroyObject( list[i].pPhysics );
|
||||
}
|
||||
list.Purge();
|
||||
physics->DestroyEnvironment( physenv );
|
||||
}
|
||||
void InitEnvironment()
|
||||
{
|
||||
physenv = physics->CreateEnvironment();
|
||||
//g_EntityCollisionHash = physics->CreateObjectPairHash();
|
||||
physenv->EnableDeleteQueue( true );
|
||||
|
||||
//physenv->SetCollisionSolver( &g_Collisions );
|
||||
//physenv->SetCollisionEventHandler( &g_Collisions );
|
||||
//physenv->SetConstraintEventHandler( g_pConstraintEvents );
|
||||
//physenv->SetObjectEventHandler( &g_Objects );
|
||||
|
||||
physenv->SetSimulationTimestep( DEFAULT_TICK_INTERVAL ); // 15 ms per tick
|
||||
// HL Game gravity, not real-world gravity
|
||||
physenv->SetGravity( Vector( 0, 0, -600.0f ) );
|
||||
physenv->SetAirDensity( 0.5f );
|
||||
}
|
||||
|
||||
int AddObject( IPhysicsObject *pObject )
|
||||
{
|
||||
int index = list.AddToTail();
|
||||
list[index].pPhysics = pObject;
|
||||
list[index].pModel = physcollision->CreateQueryModel( (CPhysCollide *)pObject->GetCollide() );
|
||||
return index;
|
||||
}
|
||||
|
||||
void CreateGround( float size )
|
||||
{
|
||||
{
|
||||
CPhysCollide *pCollide = physcollision->BBoxToCollide( Vector(-size,-size,-24), Vector(size,size,0) );
|
||||
objectparams_t params = g_PhysDefaultObjectParams;
|
||||
IPhysicsObject *pGround = physenv->CreatePolyObjectStatic( pCollide, physprops->GetSurfaceIndex( "default" ), vec3_origin, vec3_angle, ¶ms );
|
||||
AddObject( pGround );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < 20; i++ )
|
||||
{
|
||||
CPhysCollide *pCollide = physcollision->BBoxToCollide( Vector(-24,-24,-24), Vector(24,24,24) );
|
||||
objectparams_t params = g_PhysDefaultObjectParams;
|
||||
params.mass = 150.0f;
|
||||
IPhysicsObject *pGround = physenv->CreatePolyObject( pCollide, physprops->GetSurfaceIndex( "default" ), Vector(64*(i%4),64 * (i%5),1024), vec3_angle, ¶ms );
|
||||
AddObject( pGround );
|
||||
pGround->Wake();
|
||||
}
|
||||
}
|
||||
|
||||
void Explode( const Vector &origin, float force )
|
||||
{
|
||||
for ( int i = 0; i < list.Count(); i++ )
|
||||
{
|
||||
if ( !list[i].pPhysics->IsMoveable() )
|
||||
continue;
|
||||
|
||||
Vector pos, dir;
|
||||
list[i].pPhysics->GetPosition( &pos, NULL );
|
||||
dir = pos - origin;
|
||||
dir.z += 10;
|
||||
VectorNormalize( dir );
|
||||
list[i].pPhysics->ApplyForceCenter( dir * force );
|
||||
}
|
||||
}
|
||||
void RandomColor( float *color, int key )
|
||||
{
|
||||
static bool first = true;
|
||||
static colorVec colors[256];
|
||||
|
||||
if ( first )
|
||||
{
|
||||
int r, g, b;
|
||||
first = false;
|
||||
for ( int i = 0; i < 256; i++ )
|
||||
{
|
||||
do
|
||||
{
|
||||
r = rand()&255;
|
||||
g = rand()&255;
|
||||
b = rand()&255;
|
||||
} while ( (r+g+b)<256 );
|
||||
colors[i].r = r;
|
||||
colors[i].g = g;
|
||||
colors[i].b = b;
|
||||
colors[i].a = 255;
|
||||
}
|
||||
}
|
||||
|
||||
int index = key & 255;
|
||||
color[0] = colors[index].r * (1.f / 255.f);
|
||||
color[1] = colors[index].g * (1.f / 255.f);
|
||||
color[2] = colors[index].b * (1.f / 255.f);
|
||||
color[3] = colors[index].a * (1.f / 255.f);
|
||||
}
|
||||
|
||||
void DrawObject( ICollisionQuery *pModel, IMaterial *pMaterial, IPhysicsObject *pObject )
|
||||
{
|
||||
matrix3x4_t matrix;
|
||||
pObject->GetPositionMatrix( &matrix );
|
||||
CMatRenderContextPtr pRenderContext(g_MaterialSystemApp.m_pMaterialSystem);
|
||||
pRenderContext->Bind( pMaterial );
|
||||
|
||||
int vertIndex = 0;
|
||||
for ( int i = 0; i < pModel->ConvexCount(); i++ )
|
||||
{
|
||||
float color[4];
|
||||
RandomColor( color, i + (int)pObject );
|
||||
IMesh* pMatMesh = pRenderContext->GetDynamicMesh( );
|
||||
CMeshBuilder meshBuilder;
|
||||
int triCount = pModel->TriangleCount( i );
|
||||
meshBuilder.Begin( pMatMesh, MATERIAL_TRIANGLES, triCount );
|
||||
|
||||
for ( int j = 0; j < triCount; j++ )
|
||||
{
|
||||
Vector objectSpaceVerts[3];
|
||||
pModel->GetTriangleVerts( i, j, objectSpaceVerts );
|
||||
|
||||
for ( int k = 0; k < 3; k++ )
|
||||
{
|
||||
Vector v;
|
||||
|
||||
VectorTransform (objectSpaceVerts[k], matrix, v);
|
||||
meshBuilder.Position3fv( v.Base() );
|
||||
meshBuilder.Color4fv( color );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
}
|
||||
meshBuilder.End( false, true );
|
||||
}
|
||||
}
|
||||
|
||||
void Draw()
|
||||
{
|
||||
for ( int i = 0; i < list.Count(); i++ )
|
||||
{
|
||||
DrawObject( list[i].pModel, g_materialFlatshaded, list[i].pPhysics );
|
||||
}
|
||||
}
|
||||
void Simulate( float frametime )
|
||||
{
|
||||
physenv->Simulate( frametime );
|
||||
}
|
||||
};
|
||||
|
||||
physicstest_t staticTest;
|
||||
|
||||
void AppInit( void )
|
||||
{
|
||||
memset( gKeys, 0, sizeof(gKeys) );
|
||||
CreateInterfaceFn physicsFactory = GetPhysicsFactory();
|
||||
if (!(physics = (IPhysics *)physicsFactory( VPHYSICS_INTERFACE_VERSION, NULL )) ||
|
||||
!(physcollision = (IPhysicsCollision *)physicsFactory( VPHYSICS_COLLISION_INTERFACE_VERSION, NULL )) ||
|
||||
!(physprops = (IPhysicsSurfaceProps *)physicsFactory( VPHYSICS_SURFACEPROPS_INTERFACE_VERSION, NULL )) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PhysParseSurfaceData( physprops, g_pFullFileSystem );
|
||||
g_materialFlatshaded = g_MaterialSystemApp.m_pMaterialSystem->FindMaterial("debug/debugdrawflatpolygons", TEXTURE_GROUP_OTHER, true);
|
||||
g_pWireframeMaterial = g_MaterialSystemApp.m_pMaterialSystem->FindMaterial("shadertest/wireframevertexcolor", TEXTURE_GROUP_OTHER);
|
||||
staticTest.InitEnvironment();
|
||||
staticTest.CreateGround( 1024 );
|
||||
}
|
||||
|
||||
void FPSControls( float frametime, float mouseDeltaX, float mouseDeltaY, Vector& cameraPosition, QAngle& cameraAngles, float speed )
|
||||
{
|
||||
cameraAngles[1] -= mouseDeltaX;
|
||||
cameraAngles[0] -= mouseDeltaY;
|
||||
|
||||
if ( cameraAngles[0] < -85 )
|
||||
cameraAngles[0] = -85;
|
||||
if ( cameraAngles[0] > 85 )
|
||||
cameraAngles[0] = 85;
|
||||
|
||||
Vector forward, right, up;
|
||||
AngleVectors( cameraAngles, &forward, &right, &up );
|
||||
|
||||
if ( gKeys[ 'W' ] )
|
||||
VectorMA( cameraPosition, frametime * speed, forward, cameraPosition );
|
||||
if ( gKeys[ 'S' ] )
|
||||
VectorMA( cameraPosition, -frametime * speed, forward, cameraPosition );
|
||||
if ( gKeys[ 'A' ] )
|
||||
VectorMA( cameraPosition, -frametime * speed, right, cameraPosition );
|
||||
if ( gKeys[ 'D' ] )
|
||||
VectorMA( cameraPosition, frametime * speed, right, cameraPosition );
|
||||
}
|
||||
|
||||
|
||||
void SetupCamera( Vector& cameraPosition, QAngle& cameraAngles )
|
||||
{
|
||||
CMatRenderContextPtr pRenderContext(g_MaterialSystemApp.m_pMaterialSystem);
|
||||
pRenderContext->MatrixMode( MATERIAL_VIEW );
|
||||
pRenderContext->LoadIdentity( );
|
||||
pRenderContext->Rotate( -90, 1, 0, 0 ); // put Z going up
|
||||
pRenderContext->Rotate( 90, 0, 0, 1 );
|
||||
|
||||
pRenderContext->Rotate( -cameraAngles[2], 1, 0, 0); // roll
|
||||
pRenderContext->Rotate( -cameraAngles[0], 0, 1, 0); // pitch
|
||||
pRenderContext->Rotate( -cameraAngles[1], 0, 0, 1); // yaw
|
||||
|
||||
pRenderContext->Translate( -cameraPosition[0], -cameraPosition[1], -cameraPosition[2] );
|
||||
}
|
||||
|
||||
static Vector cameraPosition = Vector(0,0,128);
|
||||
static QAngle cameraAngles = vec3_angle;
|
||||
|
||||
void AppRender( float frametime, float mouseDeltaX, float mouseDeltaY )
|
||||
{
|
||||
FPSControls( frametime, mouseDeltaX, mouseDeltaY, cameraPosition, cameraAngles, 300 );
|
||||
SetupCamera( cameraPosition, cameraAngles );
|
||||
|
||||
staticTest.Simulate( frametime );
|
||||
staticTest.Draw();
|
||||
}
|
||||
|
||||
void AppExit( void )
|
||||
{
|
||||
staticTest.Clear();
|
||||
|
||||
//physics->DestroyObjectPairHash( g_EntityCollisionHash );
|
||||
//g_EntityCollisionHash = NULL;
|
||||
physics->DestroyAllCollisionSets();
|
||||
}
|
||||
|
||||
void AppKey( int key, int down )
|
||||
{
|
||||
gKeys[ key & 255 ] = down;
|
||||
}
|
||||
|
||||
|
||||
void AppChar( int key )
|
||||
{
|
||||
if ( key == ' ' )
|
||||
{
|
||||
staticTest.Explode( cameraPosition, 150 * 100 );
|
||||
}
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// PERFTEST.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_win_win32_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE,..\..\utils\common,..\..\utils\matsysapp,."
|
||||
$PreprocessorDefinitions "$BASE;VECTOR;PROTECTED_THINGS_DISABLE"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
// $AdditionalDependencies "comctl32.lib winmm.lib"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "perftest"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "..\..\utils\matsysapp\matsysapp.cpp"
|
||||
$File "perftest.cpp"
|
||||
|
||||
$Folder "common files"
|
||||
{
|
||||
// $File "..\..\utils\common\bsplib.cpp"
|
||||
$File "..\..\utils\common\cmdlib.cpp"
|
||||
$File "$SRCDIR\public\filesystem_helpers.cpp"
|
||||
$File "$SRCDIR\public\filesystem_init.cpp"
|
||||
$File "..\..\utils\common\filesystem_tools.cpp"
|
||||
$File "..\..\utils\common\physdll.cpp"
|
||||
$File "..\..\utils\common\scriplib.cpp"
|
||||
}
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\vphysics_interface.h"
|
||||
$File "stdafx.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
// $DynamicFile "$SRCDIR\lib\public\appframework.lib"
|
||||
$DynamicFile "$SRCDIR\lib\public\mathlib.lib"
|
||||
$DynamicFile "$SRCDIR\lib\public\tier2.lib"
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "matsysapp.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
#include "const.h"
|
||||
#include "vphysics_interface.h"
|
File diff suppressed because it is too large
Load Diff
@ -1,303 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PHYSICS_AIRBOAT_H
|
||||
#define PHYSICS_AIRBOAT_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "ivp_controller.hxx"
|
||||
#include "ivp_car_system.hxx"
|
||||
|
||||
|
||||
class IPhysicsObject;
|
||||
class IVP_Ray_Solver_Template;
|
||||
class IVP_Ray_Hit;
|
||||
class IVP_Event_Sim;
|
||||
|
||||
|
||||
#define IVP_RAYCAST_AIRBOAT_MAX_WHEELS 4
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class IVP_Raycast_Airboat_Wheel
|
||||
{
|
||||
public:
|
||||
|
||||
// static section
|
||||
IVP_U_Float_Point hp_cs; // hard point core system projected on y plane
|
||||
IVP_U_Float_Point raycast_start_cs; // ray cast start position
|
||||
IVP_U_Float_Point raycast_dir_cs;
|
||||
IVP_FLOAT raycast_length;
|
||||
|
||||
IVP_U_Float_Point spring_direction_cs; // spring direction in core-space
|
||||
IVP_FLOAT distance_orig_hp_to_hp; // distance hp is moved by projecting it onto the y - plane
|
||||
IVP_FLOAT spring_len; // == pretension + distance_orig_hp_to_hp
|
||||
IVP_FLOAT spring_constant; // shock at wheel spring constant
|
||||
IVP_FLOAT spring_damp_relax; // shock at wheel spring dampening during relaxation
|
||||
IVP_FLOAT spring_damp_compress; // shock at wheel spring dampening during compression
|
||||
|
||||
IVP_FLOAT max_rotation_speed; // max rotational speed of the wheel
|
||||
|
||||
IVP_FLOAT wheel_radius; // wheel radius
|
||||
IVP_FLOAT inv_wheel_radius; // inverse wheel radius
|
||||
IVP_FLOAT friction_of_wheel; // wheel friction
|
||||
|
||||
// dynamic section
|
||||
IVP_FLOAT torque; // torque applied to wheel
|
||||
IVP_BOOL wheel_is_fixed; // eg. handbrake (fixed = stationary)
|
||||
IVP_U_Float_Point axis_direction_cs; // axle direction in core-space
|
||||
IVP_FLOAT angle_wheel; // wheel angle
|
||||
IVP_FLOAT wheel_angular_velocity; // angular velocity of wheel
|
||||
|
||||
// out
|
||||
IVP_U_Float_Point surface_speed_of_wheel_on_ground_ws; // actual speed in world-space
|
||||
IVP_FLOAT pressure; // force from gravity, mass of car, stabilizers, etc. on wheel
|
||||
IVP_FLOAT raycast_dist; // raycast distance to impact for wheel
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class IVP_Raycast_Airboat_Impact
|
||||
{
|
||||
public:
|
||||
|
||||
IVP_FLOAT friction_value; // combined (multiply) frictional value of impact surface and wheel
|
||||
IVP_FLOAT stabilizer_force; // force on wheel due to axle stabilization
|
||||
IVP_Real_Object *moveable_object_hit_by_ray; // moveable physics object hit by raycast
|
||||
|
||||
IVP_U_Float_Point raycast_dir_ws; // raycast direction in world-space
|
||||
IVP_U_Float_Point spring_direction_ws; // spring direction (raycast for impact direction) in world-space
|
||||
IVP_U_Float_Point surface_speed_wheel_ws; // wheel speed in world-space
|
||||
IVP_U_Float_Point projected_surface_speed_wheel_ws; // ???
|
||||
IVP_U_Float_Point axis_direction_ws; // axle direction in world-space
|
||||
IVP_U_Float_Point projected_axis_direction_ws; // ???
|
||||
|
||||
IVP_FLOAT forces_needed_to_drive_straight; // forces need to keep the vehicle driving straight (attempt and directional wheel friction)
|
||||
IVP_FLOAT inv_normal_dot_dir; // ???
|
||||
|
||||
// Impact information.
|
||||
IVP_BOOL bImpact; // Had an impact?
|
||||
IVP_BOOL bImpactWater; // Impact with water?
|
||||
IVP_BOOL bInWater; // Point in water?
|
||||
IVP_U_Point vecImpactPointWS; // Impact point in world-space.
|
||||
IVP_U_Float_Point vecImpactNormalWS; // Impact normal in world-space.
|
||||
IVP_FLOAT flDepth; // Distance to water surface.
|
||||
IVP_FLOAT flFriction; // Friction at impact point.
|
||||
IVP_FLOAT flDampening; // Dampening at surface.
|
||||
int nSurfaceProps; // Surface property!
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class IVP_Raycast_Airboat_Axle
|
||||
{
|
||||
public:
|
||||
|
||||
IVP_FLOAT stabilizer_constant; // axle (for wheels) stabilizer constant
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class IVP_Controller_Raycast_Airboat_Vector_of_Cores_1: public IVP_U_Vector<IVP_Core>
|
||||
{
|
||||
void *elem_buffer[1];
|
||||
|
||||
public:
|
||||
|
||||
IVP_Controller_Raycast_Airboat_Vector_of_Cores_1();
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
class CPhysics_Airboat : public IVP_Car_System, protected IVP_Controller_Dependent
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
CPhysics_Airboat( IVP_Environment *env, const IVP_Template_Car_System *t, IPhysicsGameTrace *pGameTrace );
|
||||
virtual ~CPhysics_Airboat();
|
||||
|
||||
void update_wheel_positions( void ) {}
|
||||
void SetWheelFriction( int iWheel, float flFriction );
|
||||
|
||||
IPhysicsObject *GetWheel( int index );
|
||||
|
||||
virtual const char *get_controller_name() { return "sys:airboat"; }
|
||||
|
||||
protected:
|
||||
|
||||
void InitAirboat( const IVP_Template_Car_System *pCarSystem );
|
||||
float GetWaterDepth( Ray_t *pGameRay, IPhysicsObject *pPhysAirboat );
|
||||
|
||||
// Purpose: Deconstructor
|
||||
void PerformFrictionNotification( float flEliminatedEnergy, float dt, int nSurfaceProp, IPhysicsCollisionData *pCollisionData );
|
||||
|
||||
void do_raycasts_gameside( int nRaycastCount, IVP_Ray_Solver_Template *pRays, IVP_Raycast_Airboat_Impact *pImpacts );
|
||||
void pre_raycasts_gameside( int nRaycastCount, IVP_Ray_Solver_Template *pRays, Ray_t *pGameRays, IVP_Raycast_Airboat_Impact *pImpacts );
|
||||
|
||||
IVP_Real_Object *m_pWheels[IVP_RAYCAST_AIRBOAT_MAX_WHEELS];
|
||||
IPhysicsGameTrace *m_pGameTrace;
|
||||
|
||||
public:
|
||||
|
||||
// Steering
|
||||
void do_steering_wheel(IVP_POS_WHEEL wheel_pos, IVP_FLOAT s_angle); // called by do_steering()
|
||||
|
||||
// Car Adjustment
|
||||
void change_spring_constant(IVP_POS_WHEEL pos, IVP_FLOAT spring_constant); // [Newton/meter]
|
||||
void change_spring_dampening(IVP_POS_WHEEL pos, IVP_FLOAT spring_dampening); // when spring is relaxing spring
|
||||
void change_spring_dampening_compression(IVP_POS_WHEEL pos, IVP_FLOAT spring_dampening); // [Newton/meter] for compressing spring
|
||||
void change_max_body_force(IVP_POS_WHEEL , IVP_FLOAT mforce) {}
|
||||
void change_spring_pre_tension(IVP_POS_WHEEL pos, IVP_FLOAT pre_tension_length);
|
||||
void change_spring_length(IVP_POS_WHEEL pos, IVP_FLOAT spring_length);
|
||||
|
||||
void change_stabilizer_constant(IVP_POS_AXIS pos, IVP_FLOAT stabi_constant); // [Newton/meter]
|
||||
void change_fast_turn_factor( IVP_FLOAT fast_turn_factor_ ); // not implemented for raycasts
|
||||
void change_wheel_torque(IVP_POS_WHEEL pos, IVP_FLOAT torque);
|
||||
IVP_FLOAT get_wheel_torque(IVP_POS_WHEEL wheel_nr);
|
||||
|
||||
void update_throttle( IVP_FLOAT flThrottle );
|
||||
|
||||
void update_body_countertorque() {}
|
||||
|
||||
void change_body_downforce(IVP_FLOAT force); // extra force to keep flipped objects flipped over
|
||||
|
||||
void fix_wheel( IVP_POS_WHEEL, IVP_BOOL stop_wheel ); // stop wheel completely (e.g. handbrake )
|
||||
void change_friction_of_wheel( IVP_POS_WHEEL pos, IVP_FLOAT friction );
|
||||
void set_powerslide( float frontAccel, float rearAccel ) {}
|
||||
|
||||
// Car Info
|
||||
IVP_DOUBLE get_body_speed(IVP_COORDINATE_INDEX idx_z = IVP_INDEX_Z); // km/h in 'z' direction
|
||||
IVP_DOUBLE get_wheel_angular_velocity(IVP_POS_WHEEL);
|
||||
IVP_DOUBLE get_orig_front_wheel_distance();
|
||||
IVP_DOUBLE get_orig_axles_distance();
|
||||
void get_skid_info( IVP_Wheel_Skid_Info *array_of_skid_info_out);
|
||||
|
||||
void get_wheel_position(IVP_U_Point *position_ws_out, IVP_U_Quat *direction_ws_out);
|
||||
|
||||
// Methods: 2nd Level, based on primitives
|
||||
virtual void do_steering(IVP_FLOAT steering_angle_in, bool bAnalog); // default implementation updates this->steering_angle
|
||||
|
||||
//
|
||||
// Booster (the airboat has no booster).
|
||||
//
|
||||
virtual bool IsBoosting(void) { return false; }
|
||||
virtual void set_booster_acceleration( IVP_FLOAT acceleration) {}
|
||||
virtual void activate_booster(IVP_FLOAT thrust, IVP_FLOAT duration, IVP_FLOAT delay) {}
|
||||
virtual void update_booster(IVP_FLOAT delta_time) {}
|
||||
virtual IVP_FLOAT get_booster_delay() { return 0; }
|
||||
virtual IVP_FLOAT get_booster_time_to_go() { return 0; }
|
||||
|
||||
// Debug
|
||||
void SetCarSystemDebugData( const IVP_CarSystemDebugData_t &carSystemDebugData );
|
||||
void GetCarSystemDebugData( IVP_CarSystemDebugData_t &carSystemDebugData );
|
||||
|
||||
protected:
|
||||
|
||||
IVP_Core *m_pCore;
|
||||
IVP_U_Float_Point m_vecLocalVelocity;
|
||||
float m_flSpeed;
|
||||
IVP_Real_Object *m_pAirboatBody; // *car_body
|
||||
|
||||
// Wheels/Axles.
|
||||
short n_wheels;
|
||||
short n_axis;
|
||||
short wheels_per_axis;
|
||||
IVP_Raycast_Airboat_Wheel m_aAirboatWheels[IVP_RAYCAST_AIRBOAT_MAX_WHEELS]; // wheel_of_car
|
||||
IVP_Raycast_Airboat_Axle m_aAirboatAxles[IVP_RAYCAST_AIRBOAT_MAX_WHEELS/2]; // axis_of_car
|
||||
|
||||
// Gravity.
|
||||
IVP_FLOAT gravity_y_direction; // +/-1
|
||||
IVP_U_Float_Point normized_gravity_ws;
|
||||
IVP_FLOAT extra_gravity;
|
||||
|
||||
// Orientation.
|
||||
IVP_COORDINATE_INDEX index_x;
|
||||
IVP_COORDINATE_INDEX index_y;
|
||||
IVP_COORDINATE_INDEX index_z;
|
||||
IVP_BOOL is_left_handed;
|
||||
|
||||
// Speed.
|
||||
IVP_FLOAT max_speed;
|
||||
|
||||
//
|
||||
IVP_FLOAT down_force;
|
||||
IVP_FLOAT down_force_vertical_offset;
|
||||
|
||||
// Steering
|
||||
IVP_FLOAT m_SteeringAngle;
|
||||
bool m_bSteeringReversed;
|
||||
bool m_bAnalogSteering;
|
||||
IVP_FLOAT m_flPrevSteeringAngle;
|
||||
IVP_FLOAT m_flSteerTime; // Number of seconds we've steered in this direction.
|
||||
|
||||
// Thrust.
|
||||
IVP_FLOAT m_flThrust;
|
||||
|
||||
bool m_bAirborne; // Whether we are airborne or not.
|
||||
IVP_FLOAT m_flAirTime; // How long we've been airborne (if we are).
|
||||
bool m_bWeakJump; // Set when we become airborne while going slow.
|
||||
|
||||
// Pitch and roll stabilizers.
|
||||
IVP_FLOAT m_flPitchErrorPrev;
|
||||
IVP_FLOAT m_flRollErrorPrev;
|
||||
|
||||
// Debugging!
|
||||
IVP_CarSystemDebugData_t m_CarSystemDebugData;
|
||||
|
||||
protected:
|
||||
|
||||
IVP_Raycast_Airboat_Wheel *get_wheel( IVP_POS_WHEEL i );
|
||||
IVP_Raycast_Airboat_Axle *get_axle( IVP_POS_AXIS i );
|
||||
|
||||
virtual void core_is_going_to_be_deleted_event( IVP_Core * );
|
||||
virtual IVP_U_Vector<IVP_Core> *get_associated_controlled_cores( void );
|
||||
|
||||
virtual void do_simulation_controller(IVP_Event_Sim *,IVP_U_Vector<IVP_Core> *core_list);
|
||||
virtual IVP_CONTROLLER_PRIORITY get_controller_priority();
|
||||
|
||||
private:
|
||||
|
||||
// Initialization.
|
||||
void InitRaycastCarEnvironment( IVP_Environment *pEnvironment, const IVP_Template_Car_System *pCarSystemTemplate );
|
||||
void InitRaycastCarBody( const IVP_Template_Car_System *pCarSystemTemplate );
|
||||
void InitRaycastCarWheels( const IVP_Template_Car_System *pCarSystemTemplate );
|
||||
void InitRaycastCarAxes( const IVP_Template_Car_System *pCarSystemTemplate );
|
||||
|
||||
// Raycasts for simulation.
|
||||
void PreRaycasts( IVP_Ray_Solver_Template *pRaySolverTemplates, const IVP_U_Matrix *m_world_f_core, IVP_Raycast_Airboat_Impact *pImpacts );
|
||||
bool PostRaycasts( IVP_Ray_Solver_Template *pRaySolverTemplates, const IVP_U_Matrix *matWorldFromCore, IVP_Raycast_Airboat_Impact *pImpacts );
|
||||
|
||||
// Simulation.
|
||||
void DoSimulationPontoons( IVP_Raycast_Airboat_Impact *pImpacts, IVP_Event_Sim *pEventSim );
|
||||
void DoSimulationPontoonsGround( IVP_Raycast_Airboat_Wheel *pPontoonPoint, IVP_Raycast_Airboat_Impact *pImpact, IVP_Event_Sim *pEventSim );
|
||||
void DoSimulationPontoonsWater( IVP_Raycast_Airboat_Wheel *pPontoonPoint, IVP_Raycast_Airboat_Impact *pImpact, IVP_Event_Sim *pEventSim );
|
||||
void DoSimulationDrag( IVP_Raycast_Airboat_Impact *pImpacts, IVP_Event_Sim *pEventSim );
|
||||
void DoSimulationTurbine( IVP_Event_Sim *pEventSim );
|
||||
void DoSimulationSteering( IVP_Event_Sim *pEventSim );
|
||||
void DoSimulationKeepUprightPitch( IVP_Raycast_Airboat_Impact *pImpacts, IVP_Event_Sim *pEventSim );
|
||||
void DoSimulationKeepUprightRoll( IVP_Raycast_Airboat_Impact *pImpacts, IVP_Event_Sim *pEventSim );
|
||||
void DoSimulationGravity( IVP_Event_Sim *pEventSim );
|
||||
|
||||
int CountSurfaceContactPoints( IVP_Raycast_Airboat_Impact *pImpacts );
|
||||
void UpdateAirborneState( IVP_Raycast_Airboat_Impact *pImpacts, IVP_Event_Sim *pEventSim );
|
||||
|
||||
float ComputeFrontPontoonWaveNoise( int nPontoonIndex, float flSpeedRatio );
|
||||
|
||||
void CalcImpactPosition( IVP_Ray_Solver_Template *pRaySolver, IVP_Raycast_Airboat_Wheel *pPontoonPoint,
|
||||
IVP_Raycast_Airboat_Impact *pImpacts );
|
||||
|
||||
IVP_Controller_Raycast_Airboat_Vector_of_Cores_1 vector_of_cores;
|
||||
};
|
||||
|
||||
#endif // PHYSICS_AIRBOAT_H
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,32 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PHYSICS_CONSTRAINT_H
|
||||
#define PHYSICS_CONSTRAINT_H
|
||||
#pragma once
|
||||
|
||||
class IVP_Environment;
|
||||
|
||||
class CPhysicsObject;
|
||||
class IPhysicsConstraint;
|
||||
class IPhysicsConstraintGroup;
|
||||
|
||||
extern IPhysicsConstraint *CreateRagdollConstraint( IVP_Environment *pEnvironment, CPhysicsObject *pReferenceObject, CPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_ragdollparams_t &ragdoll );
|
||||
extern IPhysicsConstraint *CreateHingeConstraint( IVP_Environment *pEnvironment, CPhysicsObject *pReferenceObject, CPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_limitedhingeparams_t &ragdoll );
|
||||
extern IPhysicsConstraint *CreateFixedConstraint( IVP_Environment *pEnvironment, CPhysicsObject *pReferenceObject, CPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_fixedparams_t &fixed );
|
||||
extern IPhysicsConstraint *CreateBallsocketConstraint( IVP_Environment *pEnvironment, CPhysicsObject *pReferenceObject, CPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_ballsocketparams_t &ballsocket );
|
||||
extern IPhysicsConstraint *CreateSlidingConstraint( IVP_Environment *pEnvironment, CPhysicsObject *pReferenceObject, CPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_slidingparams_t &slide );
|
||||
extern IPhysicsConstraint *CreatePulleyConstraint( IVP_Environment *pEnvironment, CPhysicsObject *pReferenceObject, CPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_pulleyparams_t &pulley );
|
||||
extern IPhysicsConstraint *CreateLengthConstraint( IVP_Environment *pEnvironment, CPhysicsObject *pReferenceObject, CPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_lengthparams_t &length );
|
||||
|
||||
extern IPhysicsConstraintGroup *CreatePhysicsConstraintGroup( IVP_Environment *pEnvironment, const constraint_groupparams_t &group );
|
||||
|
||||
extern IPhysicsConstraint *GetClientDataForHkConstraint( class hk_Breakable_Constraint *pHkConstraint );
|
||||
|
||||
extern bool IsExternalConstraint( IVP_Controller *pLCS, void *pGameData );
|
||||
|
||||
#endif // PHYSICS_CONSTRAINT_H
|
@ -1,171 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "physics_controller_raycast_vehicle.h"
|
||||
#include "ivp_material.hxx"
|
||||
#include "ivp_ray_solver.hxx"
|
||||
#include "ivp_cache_object.hxx"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CPhysics_Car_System_Raycast_Wheels::CPhysics_Car_System_Raycast_Wheels( IVP_Environment *pEnv,
|
||||
const IVP_Template_Car_System *pCarSystem )
|
||||
: IVP_Controller_Raycast_Car( pEnv, pCarSystem )
|
||||
{
|
||||
InitCarSystemWheels( pCarSystem );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Deconstructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CPhysics_Car_System_Raycast_Wheels::~CPhysics_Car_System_Raycast_Wheels()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Setup the car system wheels.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPhysics_Car_System_Raycast_Wheels::InitCarSystemWheels( const IVP_Template_Car_System *pCarSystem )
|
||||
{
|
||||
for ( int iWheel = 0; iWheel < pCarSystem->n_wheels; ++iWheel )
|
||||
{
|
||||
m_pWheels[iWheel] = pCarSystem->car_wheel[iWheel];
|
||||
m_pWheels[iWheel]->enable_collision_detection( IVP_FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Get the raycast wheel.
|
||||
//-----------------------------------------------------------------------------
|
||||
IPhysicsObject *CPhysics_Car_System_Raycast_Wheels::GetWheel( int index )
|
||||
{
|
||||
Assert( index >= 0 );
|
||||
Assert( index < n_wheels );
|
||||
|
||||
return ( IPhysicsObject* )m_pWheels[index]->client_data;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Setup the car system wheels.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPhysics_Car_System_Raycast_Wheels::do_raycasts( IVP_Event_Sim *es,
|
||||
int n_wheels,
|
||||
class IVP_Ray_Solver_Template *t_in,
|
||||
class IVP_Ray_Hit *hits_out,
|
||||
IVP_FLOAT *friction_of_object_out )
|
||||
{
|
||||
t_in[0].ray_flags = IVP_RAY_SOLVER_ALL;
|
||||
|
||||
int j = 0;
|
||||
IVP_Ray_Solver_Min ray_solver0(&t_in[j]);
|
||||
j++; if ( j >= n_wheels) j--;
|
||||
IVP_Ray_Solver_Min ray_solver1(&t_in[j]);
|
||||
j++; if ( j >= n_wheels) j--;
|
||||
IVP_Ray_Solver_Min ray_solver2(&t_in[j]);
|
||||
j++; if ( j >= n_wheels) j--;
|
||||
IVP_Ray_Solver_Min ray_solver3(&t_in[j]);
|
||||
|
||||
IVP_Ray_Solver_Min *solvers[4] = { &ray_solver0, &ray_solver1, &ray_solver2, &ray_solver3 };
|
||||
IVP_Ray_Solver_Group rs_group( n_wheels, (IVP_Ray_Solver **)solvers );
|
||||
|
||||
#if 0
|
||||
// Debug!
|
||||
IVP_CarSystemDebugData_t carSystemDebugData;
|
||||
GetCarSystemDebugData( carSystemDebugData );
|
||||
carSystemDebugData.wheelRaycasts[0][0] = ray_solver0.ray_start_point;
|
||||
carSystemDebugData.wheelRaycasts[0][1] = ray_solver0.ray_end_point;
|
||||
carSystemDebugData.wheelRaycasts[1][0] = ray_solver1.ray_start_point;
|
||||
carSystemDebugData.wheelRaycasts[1][1] = ray_solver1.ray_end_point;
|
||||
carSystemDebugData.wheelRaycasts[2][0] = ray_solver2.ray_start_point;
|
||||
carSystemDebugData.wheelRaycasts[2][1] = ray_solver2.ray_end_point;
|
||||
carSystemDebugData.wheelRaycasts[3][0] = ray_solver3.ray_start_point;
|
||||
carSystemDebugData.wheelRaycasts[3][1] = ray_solver3.ray_end_point;
|
||||
#endif
|
||||
|
||||
// check which objects are hit
|
||||
rs_group.check_ray_group_against_all_objects_in_sim(es->environment);
|
||||
|
||||
for ( int i = 0; i < n_wheels; i++ )
|
||||
{
|
||||
IVP_Ray_Hit *hit = solvers[i]->get_ray_hit();
|
||||
if (hit)
|
||||
{
|
||||
hits_out[i] = *hit;
|
||||
friction_of_object_out[i] = hit->hit_real_object->l_default_material->get_friction_factor();
|
||||
|
||||
#if 0
|
||||
// Debug!
|
||||
carSystemDebugData.wheelRaycastImpacts[i] = ( hit->hit_distance / solvers[i]->ray_length );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
memset( &hits_out[i], 0, sizeof(IVP_Ray_Hit) );
|
||||
friction_of_object_out[i] = 0;
|
||||
|
||||
#if 0
|
||||
// Debug!
|
||||
carSystemDebugData.wheelRaycastImpacts[i] = 0.0f;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Debug!
|
||||
SetCarSystemDebugData( carSystemDebugData );
|
||||
#endif
|
||||
}
|
||||
|
||||
void CPhysics_Car_System_Raycast_Wheels::update_wheel_positions( void )
|
||||
{
|
||||
// Get the car body object.
|
||||
IVP_Cache_Object *pCacheObject = car_body->get_cache_object();
|
||||
|
||||
// Get the core (vehicle) matrix.
|
||||
IVP_U_Matrix m_core_f_object;
|
||||
car_body->calc_m_core_f_object( &m_core_f_object );
|
||||
|
||||
for ( int iWheel = 0; iWheel < n_wheels; ++iWheel )
|
||||
{
|
||||
// Get the current raycast wheel.
|
||||
IVP_Raycast_Car_Wheel *pRaycastWheel = get_wheel( IVP_POS_WHEEL( iWheel ) );
|
||||
|
||||
// Get the position of the wheel in vehicle core space.
|
||||
IVP_U_Float_Point hp_cs;
|
||||
hp_cs.add_multiple( &pRaycastWheel->hp_cs, &pRaycastWheel->spring_direction_cs, pRaycastWheel->raycast_dist - pRaycastWheel->wheel_radius );
|
||||
|
||||
// Get the position on vehicle object space (inverse transform).
|
||||
IVP_U_Float_Point hp_os;
|
||||
m_core_f_object.vimult4( &hp_cs, &hp_os );
|
||||
|
||||
// Transform the wheel position from object space into world space.
|
||||
IVP_U_Point hp_ws;
|
||||
pCacheObject->transform_position_to_world_coords( &hp_os, &hp_ws );
|
||||
|
||||
// Apply rotational component.
|
||||
IVP_U_Point wheel_cs( &pRaycastWheel->axis_direction_cs );
|
||||
IVP_U_Point wheel2_cs( 0 ,0 ,0 );
|
||||
wheel2_cs.k[index_y] = -1.0;
|
||||
wheel2_cs.rotate( IVP_COORDINATE_INDEX( index_x ), pRaycastWheel->angle_wheel );
|
||||
|
||||
IVP_U_Matrix3 m_core_f_wheel;
|
||||
m_core_f_wheel.init_normized3_col( &wheel_cs, IVP_COORDINATE_INDEX( index_x ), &wheel2_cs );
|
||||
|
||||
IVP_U_Matrix3 m_world_f_wheel;
|
||||
pCacheObject->m_world_f_object.mmult3( &m_core_f_wheel, &m_world_f_wheel ); // bid hack, assumes cs = os (for rotation);
|
||||
|
||||
IVP_U_Quat rot_ws;
|
||||
rot_ws.set_quaternion( &m_world_f_wheel );
|
||||
m_pWheels[iWheel]->beam_object_to_new_position( &rot_ws, &hp_ws );
|
||||
}
|
||||
|
||||
pCacheObject->remove_reference();
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PHYSICS_CONTROLLER_RAYCAST_VEHICLE_H
|
||||
#define PHYSICS_CONTROLLER_RAYCAST_VEHICLE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "ivp_controller.hxx"
|
||||
#include "ivp_car_system.hxx"
|
||||
#include "ivp_controller_raycast_car.hxx"
|
||||
|
||||
class IPhysicsObject;
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Raycast Car System
|
||||
//
|
||||
class CPhysics_Car_System_Raycast_Wheels : public IVP_Controller_Raycast_Car
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
CPhysics_Car_System_Raycast_Wheels( IVP_Environment *env, const IVP_Template_Car_System *t );
|
||||
virtual ~CPhysics_Car_System_Raycast_Wheels();
|
||||
|
||||
virtual void do_raycasts( IVP_Event_Sim *, int n_wheels, IVP_Ray_Solver_Template *t_in,
|
||||
IVP_Ray_Hit *hits_out, IVP_FLOAT *friction_of_object_out );
|
||||
|
||||
void update_wheel_positions( void );
|
||||
|
||||
IPhysicsObject *GetWheel( int index );
|
||||
|
||||
virtual const char *get_controller_name() { return "sys:vehicle"; }
|
||||
protected:
|
||||
|
||||
void InitCarSystemWheels( const IVP_Template_Car_System *pCarSystem );
|
||||
|
||||
IVP_Real_Object *m_pWheels[IVP_RAYCAST_CAR_MAX_WHEELS];
|
||||
};
|
||||
|
||||
#endif // PHYSICS_CONTROLLER_RAYCAST_VEHICLE_H
|
File diff suppressed because it is too large
Load Diff
@ -1,181 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PHYSICS_WORLD_H
|
||||
#define PHYSICS_WORLD_H
|
||||
#pragma once
|
||||
|
||||
#include "vphysics_interface.h"
|
||||
#include "ivu_types.hxx"
|
||||
#include "utlvector.h"
|
||||
#include "physics_globals.h"
|
||||
|
||||
class IVP_Environment;
|
||||
class CSleepObjects;
|
||||
class CPhysicsListenerCollision;
|
||||
class CPhysicsListenerConstraint;
|
||||
class IVP_Listener_Collision;
|
||||
class IVP_Listener_Constraint;
|
||||
class IVP_Listener_Object;
|
||||
class IVP_Controller;
|
||||
class CPhysicsFluidController;
|
||||
class CCollisionSolver;
|
||||
class CPhysicsObject;
|
||||
class CDeleteQueue;
|
||||
class IVPhysicsDebugOverlay;
|
||||
struct constraint_limitedhingeparams_t;
|
||||
struct vphysics_save_iphysicsobject_t;
|
||||
|
||||
class CPhysicsEnvironment : public IPhysicsEnvironment
|
||||
{
|
||||
public:
|
||||
CPhysicsEnvironment( void );
|
||||
~CPhysicsEnvironment( void );
|
||||
|
||||
virtual void SetDebugOverlay( CreateInterfaceFn debugOverlayFactory );
|
||||
virtual IVPhysicsDebugOverlay *GetDebugOverlay( void );
|
||||
|
||||
void SetGravity( const Vector& gravityVector );
|
||||
IPhysicsObject *CreatePolyObject( const CPhysCollide *pCollisionModel, int materialIndex, const Vector& position, const QAngle& angles, objectparams_t *pParams );
|
||||
IPhysicsObject *CreatePolyObjectStatic( const CPhysCollide *pCollisionModel, int materialIndex, const Vector& position, const QAngle& angles, objectparams_t *pParams );
|
||||
virtual unsigned int GetObjectSerializeSize( IPhysicsObject *pObject ) const;
|
||||
virtual void SerializeObjectToBuffer( IPhysicsObject *pObject, unsigned char *pBuffer, unsigned int bufferSize );
|
||||
virtual IPhysicsObject *UnserializeObjectFromBuffer( void *pGameData, unsigned char *pBuffer, unsigned int bufferSize, bool enableCollisions );
|
||||
|
||||
|
||||
PxScene *GetPxScene() { return m_pPxScene; }
|
||||
|
||||
IPhysicsSpring *CreateSpring( IPhysicsObject *pObjectStart, IPhysicsObject *pObjectEnd, springparams_t *pParams );
|
||||
IPhysicsFluidController *CreateFluidController( IPhysicsObject *pFluidObject, fluidparams_t *pParams );
|
||||
IPhysicsConstraint *CreateRagdollConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_ragdollparams_t &ragdoll );
|
||||
|
||||
virtual IPhysicsConstraint *CreateHingeConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_hingeparams_t &hinge );
|
||||
virtual IPhysicsConstraint *CreateLimitedHingeConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_limitedhingeparams_t &hinge );
|
||||
virtual IPhysicsConstraint *CreateFixedConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_fixedparams_t &fixed );
|
||||
virtual IPhysicsConstraint *CreateSlidingConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_slidingparams_t &sliding );
|
||||
virtual IPhysicsConstraint *CreateBallsocketConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_ballsocketparams_t &ballsocket );
|
||||
virtual IPhysicsConstraint *CreatePulleyConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_pulleyparams_t &pulley );
|
||||
virtual IPhysicsConstraint *CreateLengthConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_lengthparams_t &length );
|
||||
|
||||
virtual IPhysicsConstraintGroup *CreateConstraintGroup( const constraint_groupparams_t &group );
|
||||
virtual void DestroyConstraintGroup( IPhysicsConstraintGroup *pGroup );
|
||||
|
||||
void Simulate( float deltaTime );
|
||||
float GetSimulationTimestep() const;
|
||||
void SetSimulationTimestep( float timestep );
|
||||
float GetSimulationTime() const;
|
||||
float GetNextFrameTime() const;
|
||||
bool IsInSimulation() const;
|
||||
|
||||
virtual void DestroyObject( IPhysicsObject * );
|
||||
virtual void DestroySpring( IPhysicsSpring * );
|
||||
virtual void DestroyFluidController( IPhysicsFluidController * );
|
||||
virtual void DestroyConstraint( IPhysicsConstraint * );
|
||||
|
||||
virtual void SetCollisionEventHandler( IPhysicsCollisionEvent *pCollisionEvents );
|
||||
virtual void SetObjectEventHandler( IPhysicsObjectEvent *pObjectEvents );
|
||||
virtual void SetConstraintEventHandler( IPhysicsConstraintEvent *pConstraintEvents );
|
||||
|
||||
virtual IPhysicsShadowController *CreateShadowController( IPhysicsObject *pObject, bool allowTranslation, bool allowRotation );
|
||||
virtual void DestroyShadowController( IPhysicsShadowController * );
|
||||
virtual IPhysicsMotionController *CreateMotionController( IMotionEvent *pHandler );
|
||||
virtual void DestroyMotionController( IPhysicsMotionController *pController );
|
||||
virtual IPhysicsPlayerController *CreatePlayerController( IPhysicsObject *pObject );
|
||||
virtual void DestroyPlayerController( IPhysicsPlayerController *pController );
|
||||
virtual IPhysicsVehicleController *CreateVehicleController( IPhysicsObject *pVehicleBodyObject, const vehicleparams_t ¶ms, unsigned int nVehicleType, IPhysicsGameTrace *pGameTrace );
|
||||
virtual void DestroyVehicleController( IPhysicsVehicleController *pController );
|
||||
|
||||
virtual void SetQuickDelete( bool bQuick )
|
||||
{
|
||||
m_deleteQuick = bQuick;
|
||||
}
|
||||
virtual bool ShouldQuickDelete() const { return m_deleteQuick; }
|
||||
virtual void TraceBox( trace_t *ptr, const Vector &mins, const Vector &maxs, const Vector &start, const Vector &end );
|
||||
virtual void SetCollisionSolver( IPhysicsCollisionSolver *pCollisionSolver );
|
||||
virtual void GetGravity( Vector *pGravityVector ) const;
|
||||
virtual int GetActiveObjectCount() const;
|
||||
virtual void GetActiveObjects( IPhysicsObject **pOutputObjectList ) const;
|
||||
virtual const IPhysicsObject **GetObjectList( int *pOutputObjectCount ) const;
|
||||
virtual bool TransferObject( IPhysicsObject *pObject, IPhysicsEnvironment *pDestinationEnvironment );
|
||||
|
||||
IVP_Environment *GetIVPEnvironment( void ) { return m_pPhysEnv; }
|
||||
void ClearDeadObjects( void );
|
||||
IVP_Controller *GetDragController() { return m_pDragController; }
|
||||
const IVP_Controller *GetDragController() const { return m_pDragController; }
|
||||
virtual void SetAirDensity( float density );
|
||||
virtual float GetAirDensity( void ) const;
|
||||
virtual void ResetSimulationClock( void );
|
||||
virtual IPhysicsObject *CreateSphereObject( float radius, int materialIndex, const Vector &position, const QAngle &angles, objectparams_t *pParams, bool isStatic );
|
||||
virtual void CleanupDeleteList();
|
||||
virtual void EnableDeleteQueue( bool enable ) { m_queueDeleteObject = enable; }
|
||||
// debug
|
||||
virtual bool IsCollisionModelUsed( CPhysCollide *pCollide ) const;
|
||||
|
||||
// trace against the physics world
|
||||
virtual void TraceRay( const Ray_t &ray, unsigned int fMask, IPhysicsTraceFilter *pTraceFilter, trace_t *pTrace );
|
||||
virtual void SweepCollideable( const CPhysCollide *pCollide, const Vector &vecAbsStart, const Vector &vecAbsEnd,
|
||||
const QAngle &vecAngles, unsigned int fMask, IPhysicsTraceFilter *pTraceFilter, trace_t *pTrace );
|
||||
|
||||
// performance tuning
|
||||
virtual void GetPerformanceSettings( physics_performanceparams_t *pOutput ) const;
|
||||
virtual void SetPerformanceSettings( const physics_performanceparams_t *pSettings );
|
||||
|
||||
// perf/cost statistics
|
||||
virtual void ReadStats( physics_stats_t *pOutput );
|
||||
virtual void ClearStats();
|
||||
virtual void EnableConstraintNotify( bool bEnable );
|
||||
// debug
|
||||
virtual void DebugCheckContacts(void);
|
||||
|
||||
// Save/restore
|
||||
bool Save( const physsaveparams_t ¶ms );
|
||||
void PreRestore( const physprerestoreparams_t ¶ms );
|
||||
bool Restore( const physrestoreparams_t ¶ms );
|
||||
void PostRestore();
|
||||
void PhantomAdd( CPhysicsObject *pObject );
|
||||
void PhantomRemove( CPhysicsObject *pObject );
|
||||
|
||||
void AddPlayerController( IPhysicsPlayerController *pController );
|
||||
void RemovePlayerController( IPhysicsPlayerController *pController );
|
||||
IPhysicsPlayerController *FindPlayerController( IPhysicsObject *pObject );
|
||||
|
||||
IPhysicsCollisionEvent *GetCollisionEventHandler();
|
||||
// a constraint is being disabled - report the game DLL as "broken"
|
||||
void NotifyConstraintDisabled( IPhysicsConstraint *pConstraint );
|
||||
|
||||
private:
|
||||
IVP_Environment *m_pPhysEnv;
|
||||
IVP_Controller *m_pDragController;
|
||||
IVPhysicsDebugOverlay *m_pDebugOverlay; // Interface to use for drawing debug overlays.
|
||||
CUtlVector<IPhysicsObject *> m_objects;
|
||||
CUtlVector<IPhysicsObject *> m_deadObjects;
|
||||
CUtlVector<CPhysicsFluidController *> m_fluids;
|
||||
CUtlVector<IPhysicsPlayerController *> m_playerControllers;
|
||||
CSleepObjects *m_pSleepEvents;
|
||||
CPhysicsListenerCollision *m_pCollisionListener;
|
||||
CCollisionSolver *m_pCollisionSolver;
|
||||
CPhysicsListenerConstraint *m_pConstraintListener;
|
||||
CDeleteQueue *m_pDeleteQueue;
|
||||
int m_lastObjectThisTick;
|
||||
bool m_deleteQuick;
|
||||
bool m_inSimulation;
|
||||
bool m_queueDeleteObject;
|
||||
bool m_fixedTimestep;
|
||||
bool m_enableConstraintNotify;
|
||||
|
||||
PxDefaultCpuDispatcher *m_pPxDispatcher;
|
||||
PxScene *m_pPxScene;
|
||||
};
|
||||
|
||||
extern IPhysicsEnvironment *CreatePhysicsEnvironment( void );
|
||||
|
||||
class IVP_Synapse_Friction;
|
||||
class IVP_Real_Object;
|
||||
extern IVP_Real_Object *GetOppositeSynapseObject( IVP_Synapse_Friction *pfriction );
|
||||
extern IPhysicsObjectPairHash *CreateObjectPairHash();
|
||||
|
||||
#endif // PHYSICS_WORLD_H
|
@ -1,233 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "physics_fluid.h"
|
||||
|
||||
|
||||
#include "ivp_compact_surface.hxx"
|
||||
#include "ivp_surman_polygon.hxx"
|
||||
#include "ivp_phantom.hxx"
|
||||
#include "ivp_controller_buoyancy.hxx"
|
||||
#include "ivp_liquid_surface_descript.hxx"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// NOTE: This is auto-deleted by the phantom controller
|
||||
class CBuoyancyAttacher : public IVP_Attacher_To_Cores_Buoyancy
|
||||
{
|
||||
public:
|
||||
virtual IVP_Template_Buoyancy *get_parameters_per_core( IVP_Core *pCore );
|
||||
CBuoyancyAttacher(IVP_Template_Buoyancy &templ, IVP_U_Set_Active<IVP_Core> *set_of_cores_, IVP_Liquid_Surface_Descriptor *liquid_surface_descriptor_);
|
||||
|
||||
float m_density;
|
||||
};
|
||||
|
||||
CPhysicsFluidController::CPhysicsFluidController( CBuoyancyAttacher *pBuoy, IVP_Liquid_Surface_Descriptor *pLiquid, CPhysicsObject *pObject, int nContents )
|
||||
{
|
||||
m_pBuoyancy = pBuoy;
|
||||
m_pLiquidSurface = pLiquid;
|
||||
m_pObject = pObject;
|
||||
m_nContents = nContents;
|
||||
}
|
||||
|
||||
CPhysicsFluidController::~CPhysicsFluidController( void )
|
||||
{
|
||||
delete m_pLiquidSurface;
|
||||
}
|
||||
|
||||
void CPhysicsFluidController::SetGameData( void *pGameData )
|
||||
{
|
||||
m_pGameData = pGameData;
|
||||
}
|
||||
|
||||
void *CPhysicsFluidController::GetGameData( void ) const
|
||||
{
|
||||
return m_pGameData;
|
||||
}
|
||||
|
||||
void CPhysicsFluidController::GetSurfacePlane( Vector *pNormal, float *pDist ) const
|
||||
{
|
||||
IVP_U_Float_Hesse surface;
|
||||
IVP_U_Float_Point abs_speed_of_current;
|
||||
|
||||
m_pLiquidSurface->calc_liquid_surface( GetIVPObject()->get_core()->environment,
|
||||
GetIVPObject()->get_core(), &surface, &abs_speed_of_current );
|
||||
ConvertPlaneToHL( surface, pNormal, pDist );
|
||||
if ( pNormal )
|
||||
{
|
||||
*pNormal *= -1;
|
||||
}
|
||||
if ( pDist )
|
||||
{
|
||||
*pDist *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
IVP_Real_Object *CPhysicsFluidController::GetIVPObject()
|
||||
{
|
||||
return m_pObject->GetObject();
|
||||
}
|
||||
|
||||
const IVP_Real_Object *CPhysicsFluidController::GetIVPObject() const
|
||||
{
|
||||
return m_pObject->GetObject();
|
||||
}
|
||||
|
||||
float CPhysicsFluidController::GetDensity() const
|
||||
{
|
||||
return m_pBuoyancy->m_density;
|
||||
}
|
||||
|
||||
void CPhysicsFluidController::WakeAllSleepingObjects()
|
||||
{
|
||||
GetIVPObject()->get_controller_phantom()->wake_all_sleeping_objects();
|
||||
}
|
||||
|
||||
int CPhysicsFluidController::GetContents() const
|
||||
{
|
||||
return m_nContents;
|
||||
}
|
||||
|
||||
IVP_Template_Buoyancy *CBuoyancyAttacher::get_parameters_per_core( IVP_Core *pCore )
|
||||
{
|
||||
if ( pCore )
|
||||
{
|
||||
IVP_Real_Object *pivp = pCore->objects.element_at(0);
|
||||
CPhysicsObject *pPhys = static_cast<CPhysicsObject *>(pivp->client_data);
|
||||
|
||||
// This ratio is for objects whose mass / (collision model) volume is not equal to their density.
|
||||
// Keep the fluid pressure/friction solution for the volume, but scale the buoyant force calculations
|
||||
// to be in line with the object's real density. This is accompilshed by changing the fluid's density
|
||||
// on a per-object basis.
|
||||
float ratio = pPhys->GetBuoyancyRatio();
|
||||
|
||||
if ( pPhys->GetShadowController() || !(pPhys->CallbackFlags() & CALLBACK_DO_FLUID_SIMULATION) )
|
||||
{
|
||||
// NOTE: don't do buoyancy on these guys for now!
|
||||
template_buoyancy.medium_density = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
template_buoyancy.medium_density = m_density * ratio;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
template_buoyancy.medium_density = m_density;
|
||||
}
|
||||
|
||||
return &template_buoyancy;
|
||||
}
|
||||
|
||||
CBuoyancyAttacher::CBuoyancyAttacher(IVP_Template_Buoyancy &templ, IVP_U_Set_Active<IVP_Core> *set_of_cores_, IVP_Liquid_Surface_Descriptor *liquid_surface_descriptor_)
|
||||
:IVP_Attacher_To_Cores_Buoyancy(templ, set_of_cores_, liquid_surface_descriptor_)
|
||||
{
|
||||
m_density = templ.medium_density;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defines the surface descriptor in local space
|
||||
//-----------------------------------------------------------------------------
|
||||
class CLiquidSurfaceDescriptor : public IVP_Liquid_Surface_Descriptor
|
||||
{
|
||||
public:
|
||||
CLiquidSurfaceDescriptor( CPhysicsObject *pFluidObject, const Vector4D &plane, const Vector ¤t )
|
||||
{
|
||||
cplane_t worldPlane;
|
||||
worldPlane.normal = plane.AsVector3D();
|
||||
worldPlane.dist = plane[3];
|
||||
|
||||
matrix3x4_t matObjectToWorld;
|
||||
pFluidObject->GetPositionMatrix( &matObjectToWorld );
|
||||
MatrixITransformPlane( matObjectToWorld, worldPlane, m_objectSpacePlane );
|
||||
|
||||
VectorIRotate( current, matObjectToWorld, m_vecObjectSpaceCurrent );
|
||||
m_pFluidObject = pFluidObject;
|
||||
}
|
||||
|
||||
virtual void calc_liquid_surface( IVP_Environment * /*environment*/,
|
||||
IVP_Core * /*core*/,
|
||||
IVP_U_Float_Hesse *surface_normal_out,
|
||||
IVP_U_Float_Point *abs_speed_of_current_out)
|
||||
{
|
||||
cplane_t worldPlane;
|
||||
matrix3x4_t matObjectToWorld;
|
||||
m_pFluidObject->GetPositionMatrix( &matObjectToWorld );
|
||||
MatrixTransformPlane( matObjectToWorld, m_objectSpacePlane, worldPlane );
|
||||
|
||||
worldPlane.normal *= -1.0f;
|
||||
worldPlane.dist *= -1.0f;
|
||||
|
||||
IVP_U_Float_Hesse worldSurface;
|
||||
ConvertPlaneToIVP( worldPlane.normal, worldPlane.dist, worldSurface );
|
||||
surface_normal_out->set(&worldSurface);
|
||||
surface_normal_out->hesse_val = worldSurface.hesse_val;
|
||||
|
||||
Vector worldSpaceCurrent;
|
||||
VectorRotate( m_vecObjectSpaceCurrent, matObjectToWorld, worldSpaceCurrent );
|
||||
|
||||
IVP_U_Float_Point ivpWorldSpaceCurrent;
|
||||
ConvertDirectionToIVP( worldSpaceCurrent, ivpWorldSpaceCurrent );
|
||||
abs_speed_of_current_out->set( &ivpWorldSpaceCurrent );
|
||||
}
|
||||
|
||||
private:
|
||||
Vector m_vecObjectSpaceCurrent;
|
||||
cplane_t m_objectSpacePlane;
|
||||
CPhysicsObject *m_pFluidObject;
|
||||
};
|
||||
|
||||
|
||||
CPhysicsFluidController *CreateFluidController( IVP_Environment *pEnvironment, CPhysicsObject *pFluidObject, fluidparams_t *pParams )
|
||||
{
|
||||
pFluidObject->BecomeTrigger();
|
||||
|
||||
return NULL;
|
||||
|
||||
IVP_Controller_Phantom *pPhantom = pFluidObject->GetObject()->get_controller_phantom();
|
||||
if ( !pPhantom )
|
||||
return NULL;
|
||||
|
||||
IVP_Liquid_Surface_Descriptor *lsd = new CLiquidSurfaceDescriptor( pFluidObject, pParams->surfacePlane, pParams->currentVelocity );
|
||||
int surfaceprops = pFluidObject->GetMaterialIndex();
|
||||
float density = physprops->GetSurfaceData( surfaceprops )->physics.density;
|
||||
// ---------------------------------------------
|
||||
// create parameter template for Buoyancy_Solver
|
||||
// ---------------------------------------------
|
||||
// UNDONE: Expose these other parametersd
|
||||
IVP_Template_Buoyancy buoyancy_input;
|
||||
buoyancy_input.medium_density = ConvertDensityToIVP(density); // density of water (unit: kg/m^3)
|
||||
buoyancy_input.pressure_damp_factor = pParams->damping;
|
||||
buoyancy_input.viscosity_factor = 0.0f;
|
||||
buoyancy_input.torque_factor = 0.01f;
|
||||
buoyancy_input.viscosity_input_factor = 0.1f;
|
||||
// -------------------------------------------------------------------------------
|
||||
// create "water" (i.e. buoyancy solver) and attach a dynamic list of object cores
|
||||
// -------------------------------------------------------------------------------
|
||||
CBuoyancyAttacher *attacher_to_cores_buoyancy = new CBuoyancyAttacher( buoyancy_input, pPhantom->get_intruding_cores(), lsd );
|
||||
|
||||
CPhysicsFluidController *pFluid = new CPhysicsFluidController( attacher_to_cores_buoyancy, lsd, pFluidObject, pParams->contents );
|
||||
pFluid->SetGameData( pParams->pGameData );
|
||||
pPhantom->client_data = static_cast<void *>(pFluid);
|
||||
|
||||
return pFluid;
|
||||
}
|
||||
|
||||
|
||||
bool SavePhysicsFluidController( const physsaveparams_t ¶ms, CPhysicsFluidController *pFluidObject )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RestorePhysicsFluidController( const physrestoreparams_t ¶ms, CPhysicsFluidController **ppFluidObject )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -1,49 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PHYSICS_FLUID_H
|
||||
#define PHYSICS_FLUID_H
|
||||
#pragma once
|
||||
|
||||
#include "vphysics_interface.h"
|
||||
|
||||
class IVP_Compact_Surface;
|
||||
class IVP_Environment;
|
||||
class IVP_Listener_Phantom;
|
||||
class CBuoyancyAttacher;
|
||||
class IVP_Liquid_Surface_Descriptor;
|
||||
class CPhysicsObject;
|
||||
class CPhysicsObject;
|
||||
|
||||
class CPhysicsFluidController : public IPhysicsFluidController
|
||||
{
|
||||
public:
|
||||
CPhysicsFluidController( CBuoyancyAttacher *pBuoy, IVP_Liquid_Surface_Descriptor *pLiquid, CPhysicsObject *pObject, int nContents );
|
||||
~CPhysicsFluidController( void );
|
||||
|
||||
virtual void SetGameData( void *pGameData );
|
||||
virtual void *GetGameData( void ) const;
|
||||
virtual void GetSurfacePlane( Vector *pNormal, float *pDist ) const;
|
||||
virtual float GetDensity() const;
|
||||
virtual void WakeAllSleepingObjects();
|
||||
virtual int GetContents() const;
|
||||
|
||||
class IVP_Real_Object *GetIVPObject();
|
||||
const class IVP_Real_Object *GetIVPObject() const;
|
||||
|
||||
private:
|
||||
CBuoyancyAttacher *m_pBuoyancy;
|
||||
IVP_Liquid_Surface_Descriptor *m_pLiquidSurface;
|
||||
CPhysicsObject *m_pObject;
|
||||
int m_nContents;
|
||||
void *m_pGameData;
|
||||
};
|
||||
|
||||
extern CPhysicsFluidController *CreateFluidController( IVP_Environment *pEnvironment, CPhysicsObject *pFluidObject, fluidparams_t *pParams );
|
||||
|
||||
|
||||
#endif // PHYSICS_FLUID_H
|
@ -1,194 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
#include "physics_friction.h"
|
||||
#include "vphysics/friction.h"
|
||||
|
||||
#include "ivp_mindist.hxx"
|
||||
#include "ivp_mindist_intern.hxx"
|
||||
#include "ivp_listener_collision.hxx"
|
||||
#include "ivp_friction.hxx"
|
||||
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class CFrictionSnapshot : public IPhysicsFrictionSnapshot
|
||||
{
|
||||
public:
|
||||
CFrictionSnapshot( IVP_Real_Object *pObject );
|
||||
~CFrictionSnapshot();
|
||||
|
||||
bool IsValid();
|
||||
|
||||
// Object 0 is this object, Object 1 is the other object
|
||||
IPhysicsObject *GetObject( int index );
|
||||
int GetMaterial( int index );
|
||||
|
||||
void GetContactPoint( Vector &out );
|
||||
void GetSurfaceNormal( Vector &out );
|
||||
float GetNormalForce();
|
||||
float GetEnergyAbsorbed();
|
||||
void RecomputeFriction();
|
||||
void ClearFrictionForce();
|
||||
|
||||
void MarkContactForDelete();
|
||||
void DeleteAllMarkedContacts( bool wakeObjects );
|
||||
void NextFrictionData();
|
||||
float GetFrictionCoefficient();
|
||||
|
||||
|
||||
private:
|
||||
void SetFrictionSynapse( IVP_Synapse_Friction *pSet );
|
||||
CUtlVector<IVP_Real_Object *> *m_pDeleteList;
|
||||
IVP_Real_Object *m_pObject;
|
||||
IVP_Synapse_Friction *m_pFriction;
|
||||
IVP_Contact_Point *m_pContactPoint;
|
||||
int m_synapseIndex;
|
||||
};
|
||||
|
||||
CFrictionSnapshot::CFrictionSnapshot( IVP_Real_Object *pObject ) : m_pObject(pObject)
|
||||
{
|
||||
m_pDeleteList = NULL;
|
||||
//SetFrictionSynapse( pObject->get_first_friction_synapse() );
|
||||
}
|
||||
|
||||
CFrictionSnapshot::~CFrictionSnapshot()
|
||||
{
|
||||
delete m_pDeleteList;
|
||||
}
|
||||
|
||||
void CFrictionSnapshot::DeleteAllMarkedContacts( bool wakeObjects )
|
||||
{
|
||||
if ( !m_pDeleteList )
|
||||
return;
|
||||
|
||||
for ( int i = 0; i < m_pDeleteList->Count(); i++ )
|
||||
{
|
||||
if ( wakeObjects )
|
||||
{
|
||||
m_pDeleteList->Element(i)->ensure_in_simulation();
|
||||
}
|
||||
DeleteAllFrictionPairs( m_pObject, m_pDeleteList->Element(i) );
|
||||
}
|
||||
m_pFriction = NULL;
|
||||
}
|
||||
|
||||
void CFrictionSnapshot::SetFrictionSynapse( IVP_Synapse_Friction *pSet )
|
||||
{
|
||||
if ( pSet )
|
||||
{
|
||||
m_pFriction = pSet;
|
||||
m_pContactPoint = pSet->get_contact_point();
|
||||
m_synapseIndex = (pSet == m_pContactPoint->get_synapse(0)) ? 0 : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pFriction = NULL;
|
||||
m_pContactPoint = NULL;
|
||||
m_synapseIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool CFrictionSnapshot::IsValid()
|
||||
{
|
||||
return m_pFriction != NULL ? true : false;
|
||||
}
|
||||
|
||||
IPhysicsObject *CFrictionSnapshot::GetObject( int index )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CFrictionSnapshot::MarkContactForDelete()
|
||||
{
|
||||
IVP_Synapse_Friction *pFriction = m_pContactPoint->get_synapse(!m_synapseIndex);
|
||||
IVP_Real_Object *pObject = pFriction->get_object();
|
||||
Assert(pObject != m_pObject);
|
||||
if ( pObject != m_pObject )
|
||||
{
|
||||
if ( !m_pDeleteList )
|
||||
{
|
||||
m_pDeleteList = new CUtlVector<IVP_Real_Object *>;
|
||||
}
|
||||
m_pDeleteList->AddToTail( pObject );
|
||||
}
|
||||
}
|
||||
|
||||
int CFrictionSnapshot::GetMaterial( int index )
|
||||
{
|
||||
IVP_Material *ivpMats[2];
|
||||
|
||||
m_pContactPoint->get_material_info(ivpMats);
|
||||
|
||||
// index 1 is the other one
|
||||
index ^= m_synapseIndex;
|
||||
|
||||
return physprops->GetIVPMaterialIndex( ivpMats[index] );
|
||||
}
|
||||
|
||||
void CFrictionSnapshot::GetContactPoint( Vector &out )
|
||||
{
|
||||
ConvertPositionToHL( *m_pContactPoint->get_contact_point_ws(), out );
|
||||
}
|
||||
|
||||
void CFrictionSnapshot::GetSurfaceNormal( Vector &out )
|
||||
{
|
||||
float sign[2] = {1,-1};
|
||||
IVP_U_Float_Point normal;
|
||||
IVP_Contact_Point_API::get_surface_normal_ws(const_cast<IVP_Contact_Point *>(m_pContactPoint), &normal );
|
||||
ConvertDirectionToHL( normal, out );
|
||||
out *= sign[m_synapseIndex];
|
||||
VectorNormalize(out);
|
||||
}
|
||||
|
||||
float CFrictionSnapshot::GetFrictionCoefficient()
|
||||
{
|
||||
return m_pContactPoint->get_friction_factor();
|
||||
}
|
||||
|
||||
float CFrictionSnapshot::GetNormalForce()
|
||||
{
|
||||
return ConvertDistanceToHL( IVP_Contact_Point_API::get_vert_force( m_pContactPoint ) );
|
||||
}
|
||||
|
||||
float CFrictionSnapshot::GetEnergyAbsorbed()
|
||||
{
|
||||
return ConvertEnergyToHL( IVP_Contact_Point_API::get_eliminated_energy( m_pContactPoint ) );
|
||||
}
|
||||
|
||||
void CFrictionSnapshot::RecomputeFriction()
|
||||
{
|
||||
m_pContactPoint->recompute_friction();
|
||||
}
|
||||
|
||||
void CFrictionSnapshot::ClearFrictionForce()
|
||||
{
|
||||
m_pContactPoint->set_friction_to_neutral();
|
||||
}
|
||||
|
||||
void CFrictionSnapshot::NextFrictionData()
|
||||
{
|
||||
SetFrictionSynapse( m_pFriction->get_next() );
|
||||
}
|
||||
|
||||
IPhysicsFrictionSnapshot *CreateFrictionSnapshot( IVP_Real_Object *pObject )
|
||||
{
|
||||
return new CFrictionSnapshot( pObject );
|
||||
}
|
||||
|
||||
void DestroyFrictionSnapshot( IPhysicsFrictionSnapshot *pSnapshot )
|
||||
{
|
||||
delete pSnapshot;
|
||||
}
|
||||
|
||||
|
||||
void DeleteAllFrictionPairs( IVP_Real_Object *pObject0, IVP_Real_Object *pObject1 )
|
||||
{
|
||||
pObject0->unlink_contact_points_for_object( pObject1 );
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PHYSICS_FRICTION_H
|
||||
#define PHYSICS_FRICTION_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
class IVP_Real_Object;
|
||||
class IPhysicsFrictionSnapshot;
|
||||
|
||||
IPhysicsFrictionSnapshot *CreateFrictionSnapshot( IVP_Real_Object *pObject );
|
||||
void DestroyFrictionSnapshot( IPhysicsFrictionSnapshot *pSnapshot );
|
||||
void DeleteAllFrictionPairs( IVP_Real_Object *pObject0, IVP_Real_Object *pObject1 );
|
||||
|
||||
#endif // PHYSICS_FRICTION_H
|
@ -1,8 +0,0 @@
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern PxFoundation *gPxFoundation;
|
||||
extern PxPvd *gPxPvd;
|
||||
extern PxPhysics *gPxPhysics;
|
||||
extern PxCooking *gPxCooking;
|
@ -1,643 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "physics_vehicle.h"
|
||||
|
||||
#include "ivp_material.hxx"
|
||||
#include <ctype.h>
|
||||
#include "utlsymbol.h"
|
||||
#include "tier1/strtools.h"
|
||||
#include "vcollide_parse_private.h"
|
||||
#include "ctype.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This is the data stored for each material/surface propery list
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSurface : public IVP_Material
|
||||
{
|
||||
public:
|
||||
|
||||
// IVP_Material
|
||||
virtual IVP_DOUBLE get_friction_factor()
|
||||
{
|
||||
return data.physics.friction;
|
||||
}
|
||||
|
||||
virtual IVP_DOUBLE get_elasticity()
|
||||
{
|
||||
return data.physics.elasticity;
|
||||
}
|
||||
virtual const char *get_name();
|
||||
// UNDONE: not implemented here.
|
||||
virtual IVP_DOUBLE get_second_friction_factor()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
virtual IVP_DOUBLE get_adhesion()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual IVP_DOUBLE get_damping()
|
||||
{
|
||||
return data.physics.dampening;
|
||||
}
|
||||
|
||||
// strings
|
||||
CUtlSymbol m_name;
|
||||
unsigned short m_pad;
|
||||
|
||||
// physics properties
|
||||
surfacedata_t data;
|
||||
};
|
||||
|
||||
|
||||
class CPhysicsSurfaceProps;
|
||||
|
||||
class CIVPMaterialManager : public IVP_Material_Manager
|
||||
{
|
||||
typedef IVP_Material_Manager BaseClass;
|
||||
public:
|
||||
CIVPMaterialManager( void );
|
||||
void Init( CPhysicsSurfaceProps *pProps ) { m_props = pProps; }
|
||||
void SetPropMap( int *map, int mapSize );
|
||||
int RemapIVPMaterialIndex( int ivpMaterialIndex ) const;
|
||||
|
||||
// IVP_Material_Manager
|
||||
virtual IVP_Material *get_material_by_index(IVP_Real_Object *pObject, const IVP_U_Point *world_position, int index);
|
||||
|
||||
virtual IVP_DOUBLE get_friction_factor(IVP_Contact_Situation *situation) // returns values >0, value of 1.0f means object stands on a 45 degres hill
|
||||
{
|
||||
// vehicle wheels get no friction with stuff that isn't ground
|
||||
// helps keep control of the car
|
||||
// traction on less than 60 degree slopes.
|
||||
float wheelFriction = 1.0f;
|
||||
if ( ShouldOverrideWheelContactFriction( &wheelFriction, situation->objects[0], situation->objects[1], &situation->surf_normal ) )
|
||||
{
|
||||
return wheelFriction;
|
||||
}
|
||||
|
||||
IVP_DOUBLE factor = BaseClass::get_friction_factor( situation );
|
||||
factor = clamp(factor,0.0,1.0);
|
||||
|
||||
return factor;
|
||||
}
|
||||
|
||||
virtual IVP_DOUBLE get_elasticity(IVP_Contact_Situation *situation) // range [0, 1.0f[, the relative speed after a collision compared to the speed before
|
||||
{
|
||||
IVP_DOUBLE flElasticity = BaseClass::get_elasticity( situation );
|
||||
if ( flElasticity > 1.0f )
|
||||
{
|
||||
flElasticity = 1.0f;
|
||||
}
|
||||
else if ( flElasticity < 0 )
|
||||
{
|
||||
flElasticity = 0;
|
||||
}
|
||||
return flElasticity;
|
||||
}
|
||||
|
||||
private:
|
||||
CPhysicsSurfaceProps *m_props;
|
||||
unsigned short m_propMap[128];
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This is the main database of materials
|
||||
//-----------------------------------------------------------------------------
|
||||
class CPhysicsSurfaceProps : public IPhysicsSurfacePropsInternal
|
||||
{
|
||||
public:
|
||||
CPhysicsSurfaceProps( void );
|
||||
~CPhysicsSurfaceProps( void );
|
||||
|
||||
virtual int ParseSurfaceData( const char *pFilename, const char *pTextfile );
|
||||
virtual int SurfacePropCount( void ) const;
|
||||
virtual int GetSurfaceIndex( const char *pPropertyName ) const;
|
||||
virtual void GetPhysicsProperties( int surfaceDataIndex, float *density, float *thickness, float *friction, float *elasticity ) const;
|
||||
virtual void GetPhysicsParameters( int surfaceDataIndex, surfacephysicsparams_t *pParamsOut ) const;
|
||||
virtual surfacedata_t *GetSurfaceData( int surfaceDataIndex );
|
||||
virtual const char *GetString( unsigned short stringTableIndex ) const;
|
||||
virtual const char *GetPropName( int surfaceDataIndex ) const;
|
||||
virtual void SetWorldMaterialIndexTable( int *pMapArray, int mapSize );
|
||||
virtual int RemapIVPMaterialIndex( int ivpMaterialIndex ) const
|
||||
{
|
||||
return m_ivpManager.RemapIVPMaterialIndex( ivpMaterialIndex );
|
||||
}
|
||||
bool IsReservedMaterialIndex( int materialIndex ) const;
|
||||
virtual const char *GetReservedMaterialName( int materialIndex ) const;
|
||||
int GetReservedFallBack( int materialIndex ) const;
|
||||
|
||||
int GetReservedSurfaceIndex( const char *pPropertyName ) const;
|
||||
|
||||
// The database is derived from the IVP material class
|
||||
const IVP_Material *GetIVPMaterial( int materialIndex ) const;
|
||||
IVP_Material *GetIVPMaterial( int materialIndex );
|
||||
virtual int GetIVPMaterialIndex( const IVP_Material *pIVP ) const;
|
||||
IVP_Material_Manager *GetIVPManager( void ) { return &m_ivpManager; }
|
||||
|
||||
const char *GetNameString( CUtlSymbol name ) const
|
||||
{
|
||||
return m_strings.String(name);
|
||||
}
|
||||
|
||||
private:
|
||||
const CSurface *GetInternalSurface( int materialIndex ) const;
|
||||
CSurface *GetInternalSurface( int materialIndex );
|
||||
|
||||
void CopyPhysicsProperties( CSurface *pOut, int baseIndex );
|
||||
bool AddFileToDatabase( const char *pFilename );
|
||||
|
||||
private:
|
||||
CUtlSymbolTableMT m_strings;
|
||||
CUtlVector<CSurface> m_props;
|
||||
CUtlVector<CUtlSymbol> m_fileList;
|
||||
CIVPMaterialManager m_ivpManager;
|
||||
bool m_init;
|
||||
int m_shadowFallback;
|
||||
};
|
||||
|
||||
|
||||
// Singleton database object
|
||||
CPhysicsSurfaceProps g_SurfaceDatabase;
|
||||
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CPhysicsSurfaceProps, IPhysicsSurfaceProps, VPHYSICS_SURFACEPROPS_INTERFACE_VERSION, g_SurfaceDatabase);
|
||||
|
||||
|
||||
// Global pointer to singleton for VPHYSICS.DLL internal access
|
||||
IPhysicsSurfacePropsInternal *physprops = &g_SurfaceDatabase;
|
||||
|
||||
|
||||
const char *CSurface::get_name()
|
||||
{
|
||||
return g_SurfaceDatabase.GetNameString( m_name );
|
||||
}
|
||||
|
||||
CPhysicsSurfaceProps::CPhysicsSurfaceProps( void ) : m_fileList(8,8), m_strings( 0, 32, true )
|
||||
{
|
||||
m_ivpManager.Init( this );
|
||||
// Force index 0 to be the empty string. Allows game code to check for zero, but
|
||||
// still resolve to a string
|
||||
m_strings.AddString("");
|
||||
m_init = false;
|
||||
m_shadowFallback = 0;
|
||||
}
|
||||
|
||||
|
||||
CPhysicsSurfaceProps::~CPhysicsSurfaceProps( void )
|
||||
{
|
||||
}
|
||||
|
||||
int CPhysicsSurfaceProps::SurfacePropCount( void ) const
|
||||
{
|
||||
return m_props.Size();
|
||||
}
|
||||
|
||||
// Add the filename to a list to make sure each file is only processed once
|
||||
bool CPhysicsSurfaceProps::AddFileToDatabase( const char *pFilename )
|
||||
{
|
||||
CUtlSymbol id = m_strings.AddString( pFilename );
|
||||
|
||||
for ( int i = 0; i < m_fileList.Size(); i++ )
|
||||
{
|
||||
if ( m_fileList[i] == id )
|
||||
return false;
|
||||
}
|
||||
|
||||
m_fileList.AddToTail( id );
|
||||
return true;
|
||||
}
|
||||
|
||||
int CPhysicsSurfaceProps::GetSurfaceIndex( const char *pPropertyName ) const
|
||||
{
|
||||
if ( pPropertyName[0] == '$' )
|
||||
{
|
||||
int index = GetReservedSurfaceIndex( pPropertyName );
|
||||
if ( index >= 0 )
|
||||
return index;
|
||||
}
|
||||
|
||||
CUtlSymbol id = m_strings.Find( pPropertyName );
|
||||
if ( id.IsValid() )
|
||||
{
|
||||
// BUGBUG: Linear search is slow!!!
|
||||
for ( int i = 0; i < m_props.Size(); i++ )
|
||||
{
|
||||
// NOTE: Just comparing strings by index is pretty fast though
|
||||
if ( m_props[i].m_name == id )
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
const char *CPhysicsSurfaceProps::GetPropName( int surfaceDataIndex ) const
|
||||
{
|
||||
const CSurface *pSurface = GetInternalSurface( surfaceDataIndex );
|
||||
if ( pSurface )
|
||||
{
|
||||
return GetNameString( pSurface->m_name );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// UNDONE: move reserved materials into this table, or into a parallel table
|
||||
// that gets hooked out here.
|
||||
CSurface *CPhysicsSurfaceProps::GetInternalSurface( int materialIndex )
|
||||
{
|
||||
if ( IsReservedMaterialIndex( materialIndex ) )
|
||||
{
|
||||
materialIndex = GetReservedFallBack( materialIndex );
|
||||
}
|
||||
if ( materialIndex < 0 || materialIndex > m_props.Size()-1 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return &m_props[materialIndex];
|
||||
}
|
||||
|
||||
// this function is actually const except for the return type, so this is safe
|
||||
const CSurface *CPhysicsSurfaceProps::GetInternalSurface( int materialIndex ) const
|
||||
{
|
||||
return const_cast<CPhysicsSurfaceProps *>(this)->GetInternalSurface(materialIndex);
|
||||
}
|
||||
|
||||
void CPhysicsSurfaceProps::GetPhysicsProperties( int materialIndex, float *density, float *thickness, float *friction, float *elasticity ) const
|
||||
{
|
||||
const CSurface *pSurface = GetInternalSurface( materialIndex );
|
||||
if ( !pSurface )
|
||||
{
|
||||
pSurface = GetInternalSurface( GetSurfaceIndex( "default" ) );
|
||||
Assert ( pSurface );
|
||||
}
|
||||
if ( pSurface )
|
||||
{
|
||||
if ( friction )
|
||||
{
|
||||
*friction = (float)pSurface->data.physics.friction;
|
||||
}
|
||||
if ( elasticity )
|
||||
{
|
||||
*elasticity = (float)pSurface->data.physics.elasticity;
|
||||
}
|
||||
if ( density )
|
||||
{
|
||||
*density = pSurface->data.physics.density;
|
||||
}
|
||||
if ( thickness )
|
||||
{
|
||||
*thickness = pSurface->data.physics.thickness;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPhysicsSurfaceProps::GetPhysicsParameters( int surfaceDataIndex, surfacephysicsparams_t *pParamsOut ) const
|
||||
{
|
||||
if ( !pParamsOut )
|
||||
return;
|
||||
|
||||
const CSurface *pSurface = GetInternalSurface( surfaceDataIndex );
|
||||
if ( pSurface )
|
||||
{
|
||||
*pParamsOut = pSurface->data.physics;
|
||||
}
|
||||
}
|
||||
|
||||
surfacedata_t *CPhysicsSurfaceProps::GetSurfaceData( int materialIndex )
|
||||
{
|
||||
CSurface *pSurface = GetInternalSurface( materialIndex );
|
||||
if (!pSurface)
|
||||
pSurface = GetInternalSurface( 0 ); // Zero is always the "default" property
|
||||
|
||||
Assert ( pSurface );
|
||||
return &pSurface->data;
|
||||
}
|
||||
|
||||
const char *CPhysicsSurfaceProps::GetString( unsigned short stringTableIndex ) const
|
||||
{
|
||||
return m_strings.String( stringTableIndex );
|
||||
}
|
||||
|
||||
|
||||
bool CPhysicsSurfaceProps::IsReservedMaterialIndex( int materialIndex ) const
|
||||
{
|
||||
return (materialIndex > 127) ? true : false;
|
||||
}
|
||||
|
||||
const char *CPhysicsSurfaceProps::GetReservedMaterialName( int materialIndex ) const
|
||||
{
|
||||
// NOTE: All of these must start with '$'
|
||||
switch( materialIndex )
|
||||
{
|
||||
case MATERIAL_INDEX_SHADOW:
|
||||
return "$MATERIAL_INDEX_SHADOW";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int CPhysicsSurfaceProps::GetReservedSurfaceIndex( const char *pPropertyName ) const
|
||||
{
|
||||
if ( !Q_stricmp( pPropertyName, "$MATERIAL_INDEX_SHADOW" ) )
|
||||
{
|
||||
return MATERIAL_INDEX_SHADOW;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
const IVP_Material *CPhysicsSurfaceProps::GetIVPMaterial( int materialIndex ) const
|
||||
{
|
||||
return GetInternalSurface(materialIndex);
|
||||
}
|
||||
|
||||
IVP_Material *CPhysicsSurfaceProps::GetIVPMaterial( int materialIndex )
|
||||
{
|
||||
return GetInternalSurface(materialIndex);
|
||||
}
|
||||
|
||||
|
||||
int CPhysicsSurfaceProps::GetReservedFallBack( int materialIndex ) const
|
||||
{
|
||||
switch( materialIndex )
|
||||
{
|
||||
case MATERIAL_INDEX_SHADOW:
|
||||
return m_shadowFallback;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CPhysicsSurfaceProps::GetIVPMaterialIndex( const IVP_Material *pIVP ) const
|
||||
{
|
||||
int index = (const CSurface *)pIVP - m_props.Base();
|
||||
if ( index >= 0 && index < m_props.Size() )
|
||||
return index;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void CPhysicsSurfaceProps::CopyPhysicsProperties( CSurface *pOut, int baseIndex )
|
||||
{
|
||||
const CSurface *pSurface = GetInternalSurface( baseIndex );
|
||||
if ( pSurface )
|
||||
{
|
||||
pOut->data = pSurface->data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int CPhysicsSurfaceProps::ParseSurfaceData( const char *pFileName, const char *pTextfile )
|
||||
{
|
||||
if ( !AddFileToDatabase( pFileName ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *pText = pTextfile;
|
||||
|
||||
do
|
||||
{
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
|
||||
pText = ParseKeyvalue( pText, key, value );
|
||||
if ( !strcmp(value, "{") )
|
||||
{
|
||||
CSurface prop;
|
||||
memset( &prop.data, 0, sizeof(prop.data) );
|
||||
prop.m_name = m_strings.AddString( key );
|
||||
int baseMaterial = GetSurfaceIndex( key );
|
||||
if ( baseMaterial < 0 )
|
||||
{
|
||||
baseMaterial = GetSurfaceIndex( "default" );
|
||||
}
|
||||
|
||||
CopyPhysicsProperties( &prop, baseMaterial );
|
||||
|
||||
do
|
||||
{
|
||||
pText = ParseKeyvalue( pText, key, value );
|
||||
if ( !strcmpi( key, "}" ) )
|
||||
{
|
||||
// already in the database, don't add again, override values instead
|
||||
const char *pOverride = m_strings.String(prop.m_name);
|
||||
int propIndex = GetSurfaceIndex( pOverride );
|
||||
if ( propIndex >= 0 )
|
||||
{
|
||||
CSurface *pSurface = GetInternalSurface( propIndex );
|
||||
pSurface->data = prop.data;
|
||||
break;
|
||||
}
|
||||
|
||||
m_props.AddToTail( prop );
|
||||
break;
|
||||
}
|
||||
else if ( !strcmpi( key, "base" ) )
|
||||
{
|
||||
baseMaterial = GetSurfaceIndex( value );
|
||||
CopyPhysicsProperties( &prop, baseMaterial );
|
||||
}
|
||||
else if ( !strcmpi( key, "thickness" ) )
|
||||
{
|
||||
prop.data.physics.thickness = atof(value);
|
||||
}
|
||||
else if ( !strcmpi( key, "density" ) )
|
||||
{
|
||||
prop.data.physics.density = atof(value);
|
||||
}
|
||||
else if ( !strcmpi( key, "elasticity" ) )
|
||||
{
|
||||
prop.data.physics.elasticity = atof(value);
|
||||
}
|
||||
else if ( !strcmpi( key, "friction" ) )
|
||||
{
|
||||
prop.data.physics.friction = atof(value);
|
||||
}
|
||||
else if ( !strcmpi( key, "maxspeedfactor" ) )
|
||||
{
|
||||
prop.data.game.maxSpeedFactor = atof(value);
|
||||
}
|
||||
else if ( !strcmpi( key, "jumpfactor" ) )
|
||||
{
|
||||
prop.data.game.jumpFactor = atof(value);
|
||||
}
|
||||
else if ( !strcmpi( key, "climbable" ) )
|
||||
{
|
||||
prop.data.game.climbable = atoi(value);
|
||||
}
|
||||
// audio parameters
|
||||
else if ( !strcmpi( key, "audioReflectivity" ) )
|
||||
{
|
||||
prop.data.audio.reflectivity = atof(value);
|
||||
}
|
||||
else if ( !strcmpi( key, "audioHardnessFactor" ) )
|
||||
{
|
||||
prop.data.audio.hardnessFactor = atof(value);
|
||||
}
|
||||
else if ( !strcmpi( key, "audioHardMinVelocity" ) )
|
||||
{
|
||||
prop.data.audio.hardVelocityThreshold = atof(value);
|
||||
}
|
||||
else if ( !strcmpi( key, "audioRoughnessFactor" ) )
|
||||
{
|
||||
prop.data.audio.roughnessFactor = atof(value);
|
||||
}
|
||||
else if ( !strcmpi( key, "scrapeRoughThreshold" ) )
|
||||
{
|
||||
prop.data.audio.roughThreshold = atof(value);
|
||||
}
|
||||
else if ( !strcmpi( key, "impactHardThreshold" ) )
|
||||
{
|
||||
prop.data.audio.hardThreshold = atof(value);
|
||||
}
|
||||
// sound names
|
||||
else if ( !strcmpi( key, "stepleft" ) )
|
||||
{
|
||||
prop.data.sounds.stepleft = m_strings.AddString( value );
|
||||
}
|
||||
else if ( !strcmpi( key, "stepright" ) )
|
||||
{
|
||||
prop.data.sounds.stepright = m_strings.AddString( value );
|
||||
}
|
||||
else if ( !strcmpi( key, "impactsoft" ) )
|
||||
{
|
||||
prop.data.sounds.impactSoft = m_strings.AddString( value );
|
||||
}
|
||||
else if ( !strcmpi( key, "impacthard" ) )
|
||||
{
|
||||
prop.data.sounds.impactHard = m_strings.AddString( value );
|
||||
}
|
||||
else if ( !strcmpi( key, "scrapesmooth" ) )
|
||||
{
|
||||
prop.data.sounds.scrapeSmooth = m_strings.AddString( value );
|
||||
}
|
||||
else if ( !strcmpi( key, "scraperough" ) )
|
||||
{
|
||||
prop.data.sounds.scrapeRough = m_strings.AddString( value );
|
||||
}
|
||||
else if ( !strcmpi( key, "bulletimpact" ) )
|
||||
{
|
||||
prop.data.sounds.bulletImpact = m_strings.AddString( value );
|
||||
}
|
||||
else if ( !strcmpi( key, "break" ) )
|
||||
{
|
||||
prop.data.sounds.breakSound = m_strings.AddString( value );
|
||||
}
|
||||
else if ( !strcmpi( key, "strain" ) )
|
||||
{
|
||||
prop.data.sounds.strainSound = m_strings.AddString( value );
|
||||
}
|
||||
else if ( !strcmpi( key, "rolling" ) )
|
||||
{
|
||||
prop.data.sounds.rolling = m_strings.AddString( value );
|
||||
}
|
||||
else if ( !strcmpi( key, "gamematerial" ) )
|
||||
{
|
||||
if ( strlen(value) == 1 && !V_isdigit( value[0]) )
|
||||
{
|
||||
prop.data.game.material = toupper(value[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
prop.data.game.material = atoi(value);
|
||||
}
|
||||
}
|
||||
else if ( !strcmpi( key, "dampening" ) )
|
||||
{
|
||||
prop.data.physics.dampening = atof(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// force a breakpoint
|
||||
AssertMsg2( 0, "Bad surfaceprop key %s (%s)\n", key, value );
|
||||
}
|
||||
} while (pText);
|
||||
}
|
||||
} while (pText);
|
||||
|
||||
if ( !m_init )
|
||||
{
|
||||
m_init = true;
|
||||
//AddReservedMaterials
|
||||
CSurface prop;
|
||||
|
||||
int baseMaterial = GetSurfaceIndex( "default" );
|
||||
memset( &prop.data, 0, sizeof(prop.data) );
|
||||
prop.m_name = m_strings.AddString( GetReservedMaterialName(MATERIAL_INDEX_SHADOW) );
|
||||
CopyPhysicsProperties( &prop, baseMaterial );
|
||||
prop.data.physics.elasticity = 1e-3f;
|
||||
prop.data.physics.friction = 0.8f;
|
||||
m_shadowFallback = m_props.AddToTail( prop );
|
||||
}
|
||||
return m_props.Size();
|
||||
}
|
||||
|
||||
|
||||
void CPhysicsSurfaceProps::SetWorldMaterialIndexTable( int *pMapArray, int mapSize )
|
||||
{
|
||||
m_ivpManager.SetPropMap( pMapArray, mapSize );
|
||||
}
|
||||
|
||||
CIVPMaterialManager::CIVPMaterialManager( void ) : IVP_Material_Manager( IVP_FALSE )
|
||||
{
|
||||
// by default every index maps to itself (NULL translation)
|
||||
for ( int i = 0; i < ARRAYSIZE(m_propMap); i++ )
|
||||
{
|
||||
m_propMap[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
int CIVPMaterialManager::RemapIVPMaterialIndex( int ivpMaterialIndex ) const
|
||||
{
|
||||
if ( ivpMaterialIndex > 127 )
|
||||
return ivpMaterialIndex;
|
||||
|
||||
return m_propMap[ivpMaterialIndex];
|
||||
}
|
||||
|
||||
// remap the incoming (from IVP) index and get the appropriate material
|
||||
// note that ivp will only supply indices between 1 and 127
|
||||
IVP_Material *CIVPMaterialManager::get_material_by_index(IVP_Real_Object *pObject, const IVP_U_Point *world_position, int index)
|
||||
{
|
||||
IVP_Material *tmp = m_props->GetIVPMaterial( RemapIVPMaterialIndex(index) );
|
||||
Assert(tmp);
|
||||
if ( tmp )
|
||||
{
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_props->GetIVPMaterial( m_props->GetSurfaceIndex( "default" ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Installs a LUT for remapping IVP material indices to physprop indices
|
||||
// A table of the names of the materials in index order is stored with the
|
||||
// compiled bsp file. This is then remapped dynamically without touching the
|
||||
// per-triangle indices on load. If we wanted to support multiple LUTs, it would
|
||||
// be better to preprocess/remap the triangles in the collision models at load time
|
||||
void CIVPMaterialManager::SetPropMap( int *map, int mapSize )
|
||||
{
|
||||
// ??? just ignore any extra bits
|
||||
if ( mapSize > 128 )
|
||||
{
|
||||
mapSize = 128;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < mapSize; i++ )
|
||||
{
|
||||
m_propMap[i] = (unsigned short)map[i];
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PHYSICS_MATERIAL_H
|
||||
#define PHYSICS_MATERIAL_H
|
||||
#pragma once
|
||||
|
||||
#include "vphysics_interface.h"
|
||||
class IVP_Material;
|
||||
class IVP_Material_Manager;
|
||||
|
||||
class IPhysicsSurfacePropsInternal : public IPhysicsSurfaceProps
|
||||
{
|
||||
public:
|
||||
virtual IVP_Material *GetIVPMaterial( int materialIndex ) = 0;
|
||||
|
||||
virtual int GetIVPMaterialIndex( const IVP_Material *pIVP ) const = 0;
|
||||
virtual IVP_Material_Manager *GetIVPManager( void ) = 0;
|
||||
virtual int RemapIVPMaterialIndex( int ivpMaterialIndex ) const = 0;
|
||||
};
|
||||
|
||||
extern IPhysicsSurfacePropsInternal *physprops;
|
||||
|
||||
// Special material indices outside of the normal system
|
||||
enum
|
||||
{
|
||||
MATERIAL_INDEX_SHADOW = 0xF000,
|
||||
};
|
||||
|
||||
#endif // PHYSICS_MATERIAL_H
|
@ -1,334 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning (disable:4127)
|
||||
#pragma warning (disable:4244)
|
||||
#endif
|
||||
|
||||
#include "cbase.h"
|
||||
#include "ivp_controller.hxx"
|
||||
|
||||
#include "physics_motioncontroller.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
struct vphysics_save_motioncontroller_t
|
||||
{
|
||||
CUtlVector<IPhysicsObject *> m_objectList;
|
||||
int m_nPriority;
|
||||
|
||||
DECLARE_SIMPLE_DATADESC();
|
||||
};
|
||||
|
||||
|
||||
BEGIN_SIMPLE_DATADESC( vphysics_save_motioncontroller_t )
|
||||
DEFINE_VPHYSPTR_UTLVECTOR( m_objectList ),
|
||||
DEFINE_FIELD( m_nPriority, FIELD_INTEGER ),
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
|
||||
class CPhysicsMotionController : public IVP_Controller_Independent, public IPhysicsMotionController
|
||||
{
|
||||
public:
|
||||
CPhysicsMotionController( IMotionEvent *pHandler, CPhysicsEnvironment *pVEnv );
|
||||
virtual ~CPhysicsMotionController( void );
|
||||
virtual void do_simulation_controller(IVP_Event_Sim *event,IVP_U_Vector<IVP_Core> *core_list);
|
||||
virtual IVP_CONTROLLER_PRIORITY get_controller_priority();
|
||||
virtual void core_is_going_to_be_deleted_event(IVP_Core *core)
|
||||
{
|
||||
m_coreList.FindAndRemove( core );
|
||||
}
|
||||
virtual const char *get_controller_name() { return "vphysics:motion"; }
|
||||
|
||||
virtual void SetEventHandler( IMotionEvent *handler );
|
||||
virtual void AttachObject( IPhysicsObject *pObject, bool checkIfAlreadyAttached );
|
||||
virtual void DetachObject( IPhysicsObject *pObject );
|
||||
|
||||
void RemoveCore( IVP_Core *pCore );
|
||||
|
||||
// Save/load
|
||||
void WriteToTemplate( vphysics_save_motioncontroller_t &controllerTemplate );
|
||||
void InitFromTemplate( const vphysics_save_motioncontroller_t &controllerTemplate );
|
||||
|
||||
// returns the number of objects currently attached to the controller
|
||||
virtual int CountObjects( void )
|
||||
{
|
||||
return m_coreList.Count();
|
||||
}
|
||||
// NOTE: pObjectList is an array with at least CountObjects() allocated
|
||||
virtual void GetObjects( IPhysicsObject **pObjectList )
|
||||
{
|
||||
for ( int i = 0; i < m_coreList.Count(); i++ )
|
||||
{
|
||||
IVP_Core *pCore = m_coreList[i];
|
||||
|
||||
IVP_Real_Object *pivp = pCore->objects.element_at(0);
|
||||
IPhysicsObject *pPhys = static_cast<IPhysicsObject *>(pivp->client_data);
|
||||
// copy out
|
||||
pObjectList[i] = pPhys;
|
||||
}
|
||||
}
|
||||
|
||||
// detaches all attached objects
|
||||
virtual void ClearObjects( void )
|
||||
{
|
||||
while ( m_coreList.Count() )
|
||||
{
|
||||
int x = m_coreList.Count()-1;
|
||||
IVP_Core *pCore = m_coreList[x];
|
||||
RemoveCore( pCore );
|
||||
}
|
||||
}
|
||||
|
||||
// wakes up all attached objects
|
||||
virtual void WakeObjects( void )
|
||||
{
|
||||
for ( int i = 0; i < m_coreList.Count(); i++ )
|
||||
{
|
||||
IVP_Core *pCore = m_coreList[i];
|
||||
pCore->ensure_core_to_be_in_simulation();
|
||||
}
|
||||
}
|
||||
virtual void SetPriority( priority_t priority );
|
||||
|
||||
private:
|
||||
IMotionEvent *m_handler;
|
||||
CUtlVector<IVP_Core *> m_coreList;
|
||||
CPhysicsEnvironment *m_pVEnv;
|
||||
int m_priority;
|
||||
};
|
||||
|
||||
|
||||
CPhysicsMotionController::CPhysicsMotionController( IMotionEvent *pHandler, CPhysicsEnvironment *pVEnv )
|
||||
{
|
||||
m_handler = pHandler;
|
||||
m_pVEnv = pVEnv;
|
||||
SetPriority( MEDIUM_PRIORITY );
|
||||
}
|
||||
|
||||
CPhysicsMotionController::~CPhysicsMotionController( void )
|
||||
{
|
||||
Assert( !m_pVEnv->IsInSimulation() );
|
||||
for ( int i = 0; i < m_coreList.Count(); i++ )
|
||||
{
|
||||
m_coreList[i]->rem_core_controller( (IVP_Controller *)this );
|
||||
}
|
||||
}
|
||||
|
||||
void CPhysicsMotionController::do_simulation_controller(IVP_Event_Sim *event,IVP_U_Vector<IVP_Core> *core_list)
|
||||
{
|
||||
if ( m_handler )
|
||||
{
|
||||
for ( int i = 0; i < core_list->len(); i++ )
|
||||
{
|
||||
IVP_U_Float_Point ivpSpeed, ivpRot;
|
||||
IVP_Core *pCore = core_list->element_at(i);
|
||||
|
||||
IVP_Real_Object *pivp = pCore->objects.element_at(0);
|
||||
IPhysicsObject *pPhys = static_cast<IPhysicsObject *>(pivp->client_data);
|
||||
if ( !pPhys->IsMoveable() )
|
||||
continue;
|
||||
|
||||
Vector speed;
|
||||
AngularImpulse rot;
|
||||
speed.Init();
|
||||
rot.Init();
|
||||
|
||||
IMotionEvent::simresult_e ret = m_handler->Simulate( this, pPhys, event->delta_time, speed, rot );
|
||||
|
||||
switch( ret )
|
||||
{
|
||||
case IMotionEvent::SIM_NOTHING:
|
||||
break;
|
||||
case IMotionEvent::SIM_LOCAL_ACCELERATION:
|
||||
{
|
||||
ConvertForceImpulseToIVP( speed, ivpSpeed );
|
||||
ConvertAngularImpulseToIVP( rot, ivpRot );
|
||||
const IVP_U_Matrix *m_world_f_core = pCore->get_m_world_f_core_PSI();
|
||||
// transform to world space
|
||||
m_world_f_core->inline_vmult3( &ivpSpeed, &ivpSpeed );
|
||||
// UNDONE: Put these values into speed change / rot_speed_change instead?
|
||||
pCore->speed.add_multiple( &ivpSpeed, event->delta_time );
|
||||
pCore->rot_speed.add_multiple( &ivpRot, event->delta_time );
|
||||
}
|
||||
break;
|
||||
case IMotionEvent::SIM_LOCAL_FORCE:
|
||||
{
|
||||
ConvertForceImpulseToIVP( speed, ivpSpeed );
|
||||
ConvertAngularImpulseToIVP( rot, ivpRot );
|
||||
const IVP_U_Matrix *m_world_f_core = pCore->get_m_world_f_core_PSI();
|
||||
// transform to world space
|
||||
m_world_f_core->inline_vmult3( &ivpSpeed, &ivpSpeed );
|
||||
pCore->center_push_core_multiple_ws( &ivpSpeed, event->delta_time );
|
||||
pCore->rot_push_core_multiple_cs( &ivpRot, event->delta_time );
|
||||
}
|
||||
break;
|
||||
case IMotionEvent::SIM_GLOBAL_ACCELERATION:
|
||||
{
|
||||
ConvertAngularImpulseToIVP( rot, ivpRot );
|
||||
ConvertForceImpulseToIVP( speed, ivpSpeed );
|
||||
pCore->speed.add_multiple( &ivpSpeed, event->delta_time );
|
||||
pCore->rot_speed.add_multiple( &ivpRot, event->delta_time );
|
||||
}
|
||||
break;
|
||||
case IMotionEvent::SIM_GLOBAL_FORCE:
|
||||
{
|
||||
ConvertAngularImpulseToIVP( rot, ivpRot );
|
||||
ConvertForceImpulseToIVP( speed, ivpSpeed );
|
||||
pCore->center_push_core_multiple_ws( &ivpSpeed, event->delta_time );
|
||||
pCore->rot_push_core_multiple_cs( &ivpRot, event->delta_time );
|
||||
}
|
||||
break;
|
||||
}
|
||||
// TODO(mastercoms): apply sv_maxvelocity?
|
||||
//pCore->apply_velocity_limit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IVP_CONTROLLER_PRIORITY CPhysicsMotionController::get_controller_priority()
|
||||
{
|
||||
return (IVP_CONTROLLER_PRIORITY) m_priority;
|
||||
}
|
||||
|
||||
void CPhysicsMotionController::SetPriority( priority_t priority )
|
||||
{
|
||||
switch ( priority )
|
||||
{
|
||||
case LOW_PRIORITY:
|
||||
m_priority = IVP_CP_CONSTRAINTS_MIN;
|
||||
break;
|
||||
default:
|
||||
case MEDIUM_PRIORITY:
|
||||
m_priority = IVP_CP_MOTION;
|
||||
break;
|
||||
case HIGH_PRIORITY:
|
||||
m_priority = IVP_CP_FORCEFIELDS+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CPhysicsMotionController::SetEventHandler( IMotionEvent *handler )
|
||||
{
|
||||
m_handler = handler;
|
||||
}
|
||||
|
||||
void CPhysicsMotionController::AttachObject( IPhysicsObject *pObject, bool checkIfAlreadyAttached )
|
||||
{
|
||||
// BUGBUG: Sometimes restore comes back with a NULL, REVISIT
|
||||
if ( !pObject || pObject->IsStatic() )
|
||||
return;
|
||||
|
||||
CPhysicsObject *pPhys = static_cast<CPhysicsObject *>(pObject);
|
||||
IVP_Real_Object *pIVP = pPhys->GetObject();
|
||||
IVP_Core *pCore = pIVP->get_core();
|
||||
|
||||
// UNDONE: On save/load, trigger-based motion controllers re-attach their objects.
|
||||
// UNDONE: Do something cheaper about this?
|
||||
// OPTIMIZE: Linear search here?
|
||||
if ( checkIfAlreadyAttached )
|
||||
{
|
||||
int index = m_coreList.Find(pCore);
|
||||
if ( m_coreList.IsValidIndex(index) )
|
||||
{
|
||||
DevMsg(1,"Attached core twice!!!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_coreList.AddToTail( pCore );
|
||||
|
||||
MEM_ALLOC_CREDIT();
|
||||
pCore->add_core_controller( (IVP_Controller *)this );
|
||||
}
|
||||
|
||||
|
||||
void CPhysicsMotionController::RemoveCore( IVP_Core *pCore )
|
||||
{
|
||||
int index = m_coreList.Find(pCore);
|
||||
if ( !m_coreList.IsValidIndex(index) )
|
||||
{
|
||||
#if DEBUG
|
||||
Msg("removed invalid core !!!\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
//Assert( !m_pVEnv->IsInSimulation() );
|
||||
m_coreList.Remove( index );
|
||||
pCore->rem_core_controller( static_cast<IVP_Controller_Independent *>(this) );
|
||||
}
|
||||
|
||||
|
||||
void CPhysicsMotionController::DetachObject( IPhysicsObject *pObject )
|
||||
{
|
||||
CPhysicsObject *pPhys = static_cast<CPhysicsObject *>(pObject);
|
||||
IVP_Real_Object *pIVP = pPhys->GetObject();
|
||||
IVP_Core *core = pIVP->get_core();
|
||||
|
||||
RemoveCore(core);
|
||||
}
|
||||
|
||||
// Save/load
|
||||
void CPhysicsMotionController::WriteToTemplate( vphysics_save_motioncontroller_t &controllerTemplate )
|
||||
{
|
||||
controllerTemplate.m_nPriority = m_priority;
|
||||
|
||||
int nObjectCount = CountObjects();
|
||||
controllerTemplate.m_objectList.AddMultipleToTail( nObjectCount );
|
||||
GetObjects( controllerTemplate.m_objectList.Base() );
|
||||
}
|
||||
|
||||
void CPhysicsMotionController::InitFromTemplate( const vphysics_save_motioncontroller_t &controllerTemplate )
|
||||
{
|
||||
m_priority = controllerTemplate.m_nPriority;
|
||||
|
||||
int nObjectCount = controllerTemplate.m_objectList.Count();
|
||||
for ( int i = 0; i < nObjectCount; ++i )
|
||||
{
|
||||
AttachObject( controllerTemplate.m_objectList[i], true );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IPhysicsMotionController *CreateMotionController( CPhysicsEnvironment *pPhysEnv, IMotionEvent *pHandler )
|
||||
{
|
||||
if ( !pHandler )
|
||||
return NULL;
|
||||
|
||||
return new CPhysicsMotionController( pHandler, pPhysEnv );
|
||||
}
|
||||
|
||||
bool SavePhysicsMotionController( const physsaveparams_t ¶ms, IPhysicsMotionController *pMotionController )
|
||||
{
|
||||
vphysics_save_motioncontroller_t controllerTemplate;
|
||||
memset( &controllerTemplate, 0, sizeof(controllerTemplate) );
|
||||
|
||||
CPhysicsMotionController *pControllerImp = static_cast<CPhysicsMotionController*>(pMotionController);
|
||||
pControllerImp->WriteToTemplate( controllerTemplate );
|
||||
params.pSave->WriteAll( &controllerTemplate );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RestorePhysicsMotionController( const physrestoreparams_t ¶ms, IPhysicsMotionController **ppMotionController )
|
||||
{
|
||||
CPhysicsMotionController *pControllerImp = new CPhysicsMotionController( NULL, static_cast<CPhysicsEnvironment *>(params.pEnvironment) );
|
||||
|
||||
vphysics_save_motioncontroller_t controllerTemplate;
|
||||
memset( &controllerTemplate, 0, sizeof(controllerTemplate) );
|
||||
params.pRestore->ReadAll( &controllerTemplate );
|
||||
|
||||
pControllerImp->InitFromTemplate( controllerTemplate );
|
||||
*ppMotionController = pControllerImp;
|
||||
|
||||
return true;
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PHYSICS_MOTIONCONTROLLER_H
|
||||
#define PHYSICS_MOTIONCONTROLLER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class IPhysicsMotionController;
|
||||
class CPhysicsEnvironment;
|
||||
class IMotionEvent;
|
||||
|
||||
IPhysicsMotionController *CreateMotionController( CPhysicsEnvironment *pEnv, IMotionEvent *pHandler );
|
||||
|
||||
#endif // PHYSICS_MOTIONCONTROLLER_H
|
File diff suppressed because it is too large
Load Diff
@ -1,288 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PHYSICS_OBJECT_H
|
||||
#define PHYSICS_OBJECT_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "vphysics_interface.h"
|
||||
|
||||
class IVP_Real_Object;
|
||||
class IVP_Environment;
|
||||
class IVP_U_Float_Point;
|
||||
class IVP_SurfaceManager;
|
||||
class IVP_Controller;
|
||||
class CPhysicsEnvironment;
|
||||
struct vphysics_save_cphysicsobject_t
|
||||
{
|
||||
const CPhysCollide *pCollide;
|
||||
const char *pName;
|
||||
float sphereRadius;
|
||||
|
||||
bool isStatic;
|
||||
bool collisionEnabled;
|
||||
bool gravityEnabled;
|
||||
bool dragEnabled;
|
||||
bool motionEnabled;
|
||||
bool isAsleep;
|
||||
bool isTrigger;
|
||||
bool asleepSinceCreation; // has this been asleep since creation?
|
||||
bool hasTouchedDynamic;
|
||||
bool hasShadowController;
|
||||
short collideType;
|
||||
unsigned short gameIndex;
|
||||
int hingeAxis;
|
||||
int materialIndex;
|
||||
float mass;
|
||||
Vector rotInertia;
|
||||
float speedDamping;
|
||||
float rotSpeedDamping;
|
||||
Vector massCenterOverride;
|
||||
|
||||
unsigned int callbacks;
|
||||
unsigned int gameFlags;
|
||||
|
||||
unsigned int contentsMask;
|
||||
|
||||
float volume;
|
||||
float dragCoefficient;
|
||||
float angDragCoefficient;
|
||||
IPhysicsShadowController *pShadow;
|
||||
//bool m_shadowTempGravityDisable;
|
||||
|
||||
Vector origin;
|
||||
QAngle angles;
|
||||
Vector velocity;
|
||||
AngularImpulse angVelocity;
|
||||
|
||||
DECLARE_SIMPLE_DATADESC();
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
OBJ_AWAKE = 0, // awake, simulating
|
||||
OBJ_STARTSLEEP = 1, // going to sleep, but not queried yet
|
||||
OBJ_SLEEP = 2, // sleeping, no state changes since last query
|
||||
};
|
||||
|
||||
|
||||
class CPhysicsObject : public IPhysicsObject
|
||||
{
|
||||
public:
|
||||
CPhysicsObject( void );
|
||||
virtual ~CPhysicsObject( void );
|
||||
|
||||
void Init( const CPhysCollide *pCollisionModel, IVP_Real_Object *pObject, int materialIndex, float volume, float drag, float angDrag );
|
||||
|
||||
// IPhysicsObject functions
|
||||
bool IsStatic() const;
|
||||
bool IsAsleep() const;
|
||||
bool IsTrigger() const;
|
||||
bool IsFluid() const;
|
||||
bool IsHinged() const { return (m_hingedAxis != 0) ? true : false; }
|
||||
bool IsCollisionEnabled() const;
|
||||
bool IsGravityEnabled() const;
|
||||
bool IsDragEnabled() const;
|
||||
bool IsMotionEnabled() const;
|
||||
bool IsMoveable() const;
|
||||
bool IsAttachedToConstraint( bool bExternalOnly ) const;
|
||||
|
||||
|
||||
void EnableCollisions( bool enable );
|
||||
// Enable / disable gravity for this object
|
||||
void EnableGravity( bool enable );
|
||||
// Enable / disable air friction / drag for this object
|
||||
void EnableDrag( bool enable );
|
||||
void EnableMotion( bool enable );
|
||||
|
||||
void SetGameData( void *pAppData );
|
||||
void *GetGameData( void ) const;
|
||||
void SetCallbackFlags( unsigned short callbackflags );
|
||||
unsigned short GetCallbackFlags( void ) const;
|
||||
void SetGameFlags( unsigned short userFlags );
|
||||
unsigned short GetGameFlags( void ) const;
|
||||
void SetGameIndex( unsigned short gameIndex );
|
||||
unsigned short GetGameIndex( void ) const;
|
||||
|
||||
void Wake();
|
||||
void WakeNow();
|
||||
void Sleep();
|
||||
void RecheckCollisionFilter();
|
||||
void RecheckContactPoints();
|
||||
|
||||
void SetMass( float mass );
|
||||
float GetMass( void ) const;
|
||||
float GetInvMass( void ) const;
|
||||
void SetInertia( const Vector &inertia );
|
||||
Vector GetInertia( void ) const;
|
||||
Vector GetInvInertia( void ) const;
|
||||
|
||||
void GetDamping( float *speed, float *rot ) const;
|
||||
void SetDamping( const float *speed, const float *rot );
|
||||
void SetDragCoefficient( float *pDrag, float *pAngularDrag );
|
||||
void SetBuoyancyRatio( float ratio );
|
||||
int GetMaterialIndex() const { return GetMaterialIndexInternal(); }
|
||||
void SetMaterialIndex( int materialIndex );
|
||||
inline int GetMaterialIndexInternal( void ) const { return m_materialIndex; }
|
||||
|
||||
unsigned int GetContents() const { return m_contentsMask; }
|
||||
void SetContents( unsigned int contents );
|
||||
|
||||
float GetSphereRadius() const;
|
||||
Vector GetMassCenterLocalSpace() const;
|
||||
float GetEnergy() const;
|
||||
|
||||
void SetPosition( const Vector &worldPosition, const QAngle &angles, bool isTeleport = false );
|
||||
void SetPositionMatrix( const matrix3x4_t& matrix, bool isTeleport = false );
|
||||
void GetPosition( Vector *worldPosition, QAngle *angles ) const;
|
||||
void GetPositionMatrix( matrix3x4_t *positionMatrix ) const;
|
||||
|
||||
void SetVelocity( const Vector *velocity, const AngularImpulse *angularVelocity );
|
||||
void SetVelocityInstantaneous( const Vector *velocity, const AngularImpulse *angularVelocity );
|
||||
void AddVelocity( const Vector *velocity, const AngularImpulse *angularVelocity );
|
||||
void GetVelocity( Vector *velocity, AngularImpulse *angularVelocity ) const;
|
||||
void GetImplicitVelocity( Vector *velocity, AngularImpulse *angularVelocity ) const;
|
||||
void GetVelocityAtPoint( const Vector &worldPosition, Vector *pVelocity ) const;
|
||||
|
||||
void LocalToWorld( Vector *worldPosition, const Vector &localPosition ) const;
|
||||
void WorldToLocal( Vector *localPosition, const Vector &worldPosition ) const;
|
||||
void LocalToWorldVector( Vector *worldVector, const Vector &localVector ) const;
|
||||
void WorldToLocalVector( Vector *localVector, const Vector &worldVector ) const;
|
||||
|
||||
void ApplyForceCenter( const Vector &forceVector );
|
||||
void ApplyForceOffset( const Vector &forceVector, const Vector &worldPosition );
|
||||
void ApplyTorqueCenter( const AngularImpulse & );
|
||||
void CalculateForceOffset( const Vector &forceVector, const Vector &worldPosition, Vector *centerForce, AngularImpulse *centerTorque ) const;
|
||||
void CalculateVelocityOffset( const Vector &forceVector, const Vector &worldPosition, Vector *centerVelocity, AngularImpulse *centerAngularVelocity ) const;
|
||||
float CalculateLinearDrag( const Vector &unitDirection ) const;
|
||||
float CalculateAngularDrag( const Vector &objectSpaceRotationAxis ) const;
|
||||
|
||||
bool GetContactPoint( Vector *contactPoint, IPhysicsObject **contactObject ) const;
|
||||
void SetShadow( float maxSpeed, float maxAngularSpeed, bool allowPhysicsMovement, bool allowPhysicsRotation );
|
||||
void UpdateShadow( const Vector &targetPosition, const QAngle &targetAngles, bool tempDisableGravity, float timeOffset );
|
||||
void RemoveShadowController();
|
||||
int GetShadowPosition( Vector *position, QAngle *angles ) const;
|
||||
IPhysicsShadowController *GetShadowController( void ) const;
|
||||
float ComputeShadowControl( const hlshadowcontrol_params_t ¶ms, float secondsToArrival, float dt );
|
||||
|
||||
const CPhysCollide *GetCollide( void ) const;
|
||||
char const *GetName() const;
|
||||
|
||||
float GetDragInDirection( const IVP_U_Float_Point &dir ) const;
|
||||
float GetAngularDragInDirection( const IVP_U_Float_Point &angVelocity ) const;
|
||||
void BecomeTrigger();
|
||||
void RemoveTrigger();
|
||||
void BecomeHinged( int localAxis );
|
||||
void RemoveHinged();
|
||||
|
||||
IPhysicsFrictionSnapshot *CreateFrictionSnapshot();
|
||||
void DestroyFrictionSnapshot( IPhysicsFrictionSnapshot *pSnapshot );
|
||||
|
||||
void OutputDebugInfo() const;
|
||||
|
||||
// local functions
|
||||
inline IVP_Real_Object *GetObject( void ) const { return m_pObject; }
|
||||
inline int CallbackFlags( void ) const { return m_callbacks; }
|
||||
inline void AddCallbackFlags( unsigned short flags ) { m_callbacks |= flags; }
|
||||
inline void RemoveCallbackFlags( unsigned short flags ) { m_callbacks &= ~flags; }
|
||||
inline bool HasTouchedDynamic();
|
||||
inline void SetTouchedDynamic();
|
||||
void NotifySleep( void );
|
||||
void NotifyWake( void );
|
||||
int GetSleepState( void ) const { return m_sleepState; }
|
||||
inline void ForceSilentDelete() { m_forceSilentDelete = true; }
|
||||
|
||||
inline int GetActiveIndex( void ) const { return m_activeIndex; }
|
||||
inline void SetActiveIndex( int index ) { m_activeIndex = index; }
|
||||
inline float GetBuoyancyRatio( void ) const { return m_buoyancyRatio; }
|
||||
// returns true if the mass center is set to the default for the collision model
|
||||
bool IsMassCenterAtDefault() const;
|
||||
|
||||
// is this object simulated, or controlled by game logic?
|
||||
bool IsControlledByGame() const;
|
||||
|
||||
IVP_SurfaceManager *GetSurfaceManager( void ) const;
|
||||
|
||||
void WriteToTemplate( vphysics_save_cphysicsobject_t &objectTemplate );
|
||||
void InitFromTemplate( CPhysicsEnvironment *pEnvironment, void *pGameData, const vphysics_save_cphysicsobject_t &objectTemplate );
|
||||
|
||||
CPhysicsEnvironment *GetVPhysicsEnvironment();
|
||||
const CPhysicsEnvironment *GetVPhysicsEnvironment() const;
|
||||
|
||||
private:
|
||||
// NOTE: Local to vphysics, used to save/restore shadow controller
|
||||
void RestoreShadowController( IPhysicsShadowController *pShadowController );
|
||||
friend bool RestorePhysicsObject( const physrestoreparams_t ¶ms, CPhysicsObject **ppObject );
|
||||
|
||||
bool IsControlling( const IVP_Controller *pController ) const;
|
||||
float GetVolume() const;
|
||||
void SetVolume( float volume );
|
||||
|
||||
// the mass has changed, recompute the drag information
|
||||
void RecomputeDragBases();
|
||||
|
||||
void ClampVelocity();
|
||||
|
||||
// NOTE: If m_pGameData is not the first member, the constructor debug code must be modified
|
||||
void *m_pGameData;
|
||||
IVP_Real_Object *m_pObject;
|
||||
const CPhysCollide *m_pCollide;
|
||||
IPhysicsShadowController *m_pShadow;
|
||||
|
||||
Vector m_dragBasis;
|
||||
Vector m_angDragBasis;
|
||||
|
||||
// these 5 should pack into a short
|
||||
// pack new bools here
|
||||
bool m_shadowTempGravityDisable : 5;
|
||||
bool m_hasTouchedDynamic : 1;
|
||||
bool m_asleepSinceCreation : 1;
|
||||
bool m_forceSilentDelete : 1;
|
||||
unsigned char m_sleepState : 2;
|
||||
unsigned char m_hingedAxis : 3;
|
||||
unsigned char m_collideType : 3;
|
||||
unsigned short m_gameIndex;
|
||||
|
||||
private:
|
||||
unsigned short m_materialIndex;
|
||||
unsigned short m_activeIndex;
|
||||
|
||||
unsigned short m_callbacks;
|
||||
unsigned short m_gameFlags;
|
||||
unsigned int m_contentsMask;
|
||||
|
||||
float m_volume;
|
||||
float m_buoyancyRatio;
|
||||
float m_dragCoefficient;
|
||||
float m_angDragCoefficient;
|
||||
|
||||
friend CPhysicsObject *CreatePhysicsObject( CPhysicsEnvironment *pEnvironment, const CPhysCollide *pCollisionModel, int materialIndex, const Vector &position, const QAngle& angles, objectparams_t *pParams, bool isStatic );
|
||||
friend bool CPhysicsEnvironment::TransferObject( IPhysicsObject *pObject, IPhysicsEnvironment *pDestinationEnvironment ); //need direct access to m_pShadow for Portal mod's physics object transfer system
|
||||
};
|
||||
|
||||
// If you haven't ever touched a dynamic object, there's no need to search for contacting objects to
|
||||
// wakeup when you are deleted. So cache a bit here when contacts are generated
|
||||
inline bool CPhysicsObject::HasTouchedDynamic()
|
||||
{
|
||||
return m_hasTouchedDynamic;
|
||||
}
|
||||
|
||||
inline void CPhysicsObject::SetTouchedDynamic()
|
||||
{
|
||||
m_hasTouchedDynamic = true;
|
||||
}
|
||||
|
||||
extern CPhysicsObject *CreatePhysicsObject( CPhysicsEnvironment *pEnvironment, const CPhysCollide *pCollisionModel, int materialIndex, const Vector &position, const QAngle &angles, objectparams_t *pParams, bool isStatic );
|
||||
extern CPhysicsObject *CreatePhysicsSphere( CPhysicsEnvironment *pEnvironment, float radius, int materialIndex, const Vector &position, const QAngle &angles, objectparams_t *pParams, bool isStatic );
|
||||
extern void PostRestorePhysicsObject();
|
||||
extern IPhysicsObject *CreateObjectFromBuffer( CPhysicsEnvironment *pEnvironment, void *pGameData, unsigned char *pBuffer, unsigned int bufferSize, bool enableCollisions );
|
||||
extern IPhysicsObject *CreateObjectFromBuffer_UseExistingMemory( CPhysicsEnvironment *pEnvironment, void *pGameData, unsigned char *pBuffer, unsigned int bufferSize, CPhysicsObject *pExistingMemory );
|
||||
|
||||
#endif // PHYSICS_OBJECT_H
|
File diff suppressed because it is too large
Load Diff
@ -1,49 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PHYSICS_SHADOW_H
|
||||
#define PHYSICS_SHADOW_H
|
||||
#pragma once
|
||||
|
||||
class CPhysicsObject;
|
||||
class IPhysicsShadowController;
|
||||
class IPhysicsPlayerController;
|
||||
|
||||
extern IPhysicsShadowController *CreateShadowController( CPhysicsObject *pObject, bool allowTranslation, bool allowRotation );
|
||||
extern IPhysicsPlayerController *CreatePlayerController( CPhysicsObject *pObject );
|
||||
extern void DestroyPlayerController( IPhysicsPlayerController *pController );
|
||||
|
||||
|
||||
extern void ComputeController( IVP_U_Float_Point ¤tSpeed, const IVP_U_Float_Point &delta, const IVP_U_Float_Point &maxSpeed, float scaleDelta, float damping );
|
||||
|
||||
#include "ivp_physics.hxx"
|
||||
|
||||
struct shadowcontrol_params_t
|
||||
{
|
||||
shadowcontrol_params_t()
|
||||
{
|
||||
lastPosition.set_to_zero();
|
||||
lastImpulse.set_to_zero();
|
||||
}
|
||||
|
||||
IVP_U_Point targetPosition;
|
||||
IVP_U_Quat targetRotation;
|
||||
IVP_U_Point lastPosition; // estimate for where the object should be, used to compute error for teleport
|
||||
IVP_U_Float_Point lastImpulse; // Impulse applied last frame
|
||||
float maxAngular;
|
||||
float maxDampAngular;
|
||||
float maxSpeed;
|
||||
float maxDampSpeed;
|
||||
float dampFactor;
|
||||
float teleportDistance;
|
||||
};
|
||||
|
||||
|
||||
float ComputeShadowControllerHL( CPhysicsObject *pObject, const hlshadowcontrol_params_t ¶ms, float secondsToArrival, float dt );
|
||||
float ComputeShadowControllerIVP( IVP_Real_Object *pivp, shadowcontrol_params_t ¶ms, float secondsToArrival, float dt );
|
||||
|
||||
#endif // PHYSICS_SHADOW_H
|
@ -1,286 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
|
||||
#include "ivp_actuator.hxx"
|
||||
#include "ivp_actuator_spring.hxx"
|
||||
#include "ivp_listener_object.hxx"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
struct vphysics_save_cphysicsspring_t : public springparams_t
|
||||
{
|
||||
CPhysicsObject *pObjStart;
|
||||
CPhysicsObject *pObjEnd;
|
||||
DECLARE_SIMPLE_DATADESC();
|
||||
};
|
||||
|
||||
BEGIN_SIMPLE_DATADESC( vphysics_save_cphysicsspring_t )
|
||||
DEFINE_FIELD( constant, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( naturalLength, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( damping, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( relativeDamping, FIELD_FLOAT ),
|
||||
|
||||
// NOTE: These are stored as *relative* vectors, so we don't use FIELD_POSITION_VECTOR
|
||||
DEFINE_FIELD( startPosition, FIELD_VECTOR ),
|
||||
DEFINE_FIELD( endPosition, FIELD_VECTOR ),
|
||||
DEFINE_FIELD( useLocalPositions, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( onlyStretch, FIELD_BOOLEAN ),
|
||||
|
||||
DEFINE_VPHYSPTR( pObjStart ),
|
||||
DEFINE_VPHYSPTR( pObjEnd ),
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
// BUGBUG: No way to delete a spring because springs get auto-deleted without notification
|
||||
// when an object they are attached to is deleted.
|
||||
// So there is no way to tell if the pointer is valid.
|
||||
class CPhysicsSpring : public IPhysicsSpring, public IVP_Listener_Object
|
||||
{
|
||||
public:
|
||||
CPhysicsSpring( CPhysicsObject *pObjectStart, CPhysicsObject *pObjectEnd, IVP_Actuator_Spring *pSpring );
|
||||
~CPhysicsSpring();
|
||||
|
||||
// IPhysicsSpring
|
||||
void GetEndpoints( Vector* worldPositionStart, Vector* worldPositionEnd );
|
||||
void SetSpringConstant( float flSpringContant);
|
||||
void SetSpringDamping( float flSpringDamping);
|
||||
void SetSpringLength( float flSpringLength);
|
||||
IPhysicsObject *GetStartObject( void ) { return m_pObjStart; }
|
||||
IPhysicsObject *GetEndObject( void ) { return m_pObjEnd; }
|
||||
|
||||
void AttachListener();
|
||||
void DetachListener();
|
||||
|
||||
// Object listener
|
||||
virtual void event_object_deleted( IVP_Event_Object *);
|
||||
virtual void event_object_created( IVP_Event_Object *) {}
|
||||
virtual void event_object_revived( IVP_Event_Object *) {}
|
||||
virtual void event_object_frozen ( IVP_Event_Object *) {}
|
||||
void WriteToTemplate( vphysics_save_cphysicsspring_t ¶ms );
|
||||
|
||||
private:
|
||||
|
||||
CPhysicsSpring( void );
|
||||
IVP_Actuator_Spring *m_pSpring;
|
||||
CPhysicsObject *m_pObjStart;
|
||||
CPhysicsObject *m_pObjEnd;
|
||||
};
|
||||
|
||||
CPhysicsSpring::CPhysicsSpring( CPhysicsObject *pObjectStart, CPhysicsObject *pObjectEnd, IVP_Actuator_Spring *pSpring ) : m_pSpring(pSpring)
|
||||
{
|
||||
m_pObjStart = pObjectStart;
|
||||
m_pObjEnd = pObjectEnd;
|
||||
AttachListener();
|
||||
}
|
||||
|
||||
void CPhysicsSpring::AttachListener()
|
||||
{
|
||||
if ( !(m_pObjStart->CallbackFlags() & CALLBACK_NEVER_DELETED) )
|
||||
{
|
||||
m_pObjStart->GetObject()->add_listener_object( this );
|
||||
}
|
||||
|
||||
if ( !(m_pObjEnd->CallbackFlags() & CALLBACK_NEVER_DELETED) )
|
||||
{
|
||||
m_pObjEnd->GetObject()->add_listener_object( this );
|
||||
}
|
||||
}
|
||||
|
||||
CPhysicsSpring::~CPhysicsSpring()
|
||||
{
|
||||
if ( m_pSpring )
|
||||
{
|
||||
delete m_pSpring;
|
||||
DetachListener();
|
||||
}
|
||||
}
|
||||
|
||||
void CPhysicsSpring::DetachListener()
|
||||
{
|
||||
if ( !(m_pObjStart->CallbackFlags() & CALLBACK_NEVER_DELETED) )
|
||||
{
|
||||
m_pObjStart->GetObject()->remove_listener_object( this );
|
||||
}
|
||||
|
||||
if ( !(m_pObjEnd->CallbackFlags() & CALLBACK_NEVER_DELETED) )
|
||||
{
|
||||
m_pObjEnd->GetObject()->remove_listener_object( this );
|
||||
}
|
||||
|
||||
m_pObjStart = NULL;
|
||||
m_pObjEnd = NULL;
|
||||
m_pSpring = NULL;
|
||||
}
|
||||
|
||||
void CPhysicsSpring::event_object_deleted( IVP_Event_Object * )
|
||||
{
|
||||
// the spring is going to delete itself now, so NULL it.
|
||||
DetachListener();
|
||||
}
|
||||
|
||||
void CPhysicsSpring::GetEndpoints( Vector* worldPositionStart, Vector* worldPositionEnd )
|
||||
{
|
||||
Vector localHL;
|
||||
|
||||
if ( !m_pSpring )
|
||||
return;
|
||||
|
||||
if ( worldPositionStart )
|
||||
{
|
||||
const IVP_Anchor *anchor = m_pSpring->get_actuator_anchor(0);
|
||||
ConvertPositionToHL( anchor->object_pos, localHL );
|
||||
m_pObjStart->LocalToWorld( worldPositionStart, localHL );
|
||||
}
|
||||
|
||||
if ( worldPositionEnd )
|
||||
{
|
||||
const IVP_Anchor *anchor = m_pSpring->get_actuator_anchor(1);
|
||||
ConvertPositionToHL( anchor->object_pos, localHL );
|
||||
m_pObjEnd->LocalToWorld( worldPositionEnd, localHL );
|
||||
}
|
||||
}
|
||||
|
||||
void CPhysicsSpring::SetSpringConstant( float flSpringConstant )
|
||||
{
|
||||
if ( m_pSpring )
|
||||
{
|
||||
float currentConstant = m_pSpring->get_constant();
|
||||
if ( currentConstant != flSpringConstant )
|
||||
{
|
||||
m_pSpring->set_constant(flSpringConstant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPhysicsSpring::SetSpringDamping( float flSpringDamping )
|
||||
{
|
||||
if ( m_pSpring )
|
||||
{
|
||||
m_pSpring->set_damp(flSpringDamping);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CPhysicsSpring::SetSpringLength( float flSpringLength )
|
||||
{
|
||||
if ( m_pSpring )
|
||||
{
|
||||
float currentLengthIVP = m_pSpring->get_spring_length_zero_force();
|
||||
float desiredLengthIVP = ConvertDistanceToIVP(flSpringLength);
|
||||
|
||||
// must change enough, or skip to keep objects sleeping
|
||||
const float SPRING_LENGTH_EPSILON = 1e-3f;
|
||||
if ( fabs(desiredLengthIVP-currentLengthIVP) < ConvertDistanceToIVP(SPRING_LENGTH_EPSILON) )
|
||||
return;
|
||||
|
||||
m_pSpring->set_len( desiredLengthIVP );
|
||||
}
|
||||
}
|
||||
|
||||
void CPhysicsSpring::WriteToTemplate( vphysics_save_cphysicsspring_t ¶ms )
|
||||
{
|
||||
if ( !m_pSpring )
|
||||
{
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
return;
|
||||
}
|
||||
params.constant = m_pSpring->get_constant();
|
||||
params.naturalLength = ConvertDistanceToHL( m_pSpring->get_spring_length_zero_force() );
|
||||
params.damping = m_pSpring->get_damp_factor();
|
||||
params.relativeDamping = m_pSpring->get_rel_pos_damp();
|
||||
|
||||
const IVP_Anchor *anchor0 = m_pSpring->get_actuator_anchor(0);
|
||||
ConvertPositionToHL( anchor0->object_pos, params.startPosition );
|
||||
const IVP_Anchor *anchor1 = m_pSpring->get_actuator_anchor(1);
|
||||
ConvertPositionToHL( anchor1->object_pos, params.endPosition );
|
||||
params.useLocalPositions = true;
|
||||
|
||||
params.onlyStretch = m_pSpring->get_only_stretch() ? true : false;
|
||||
params.pObjStart = m_pObjStart;
|
||||
params.pObjEnd = m_pObjEnd;
|
||||
}
|
||||
|
||||
|
||||
IPhysicsSpring *CreateSpring( IVP_Environment *pEnvironment, CPhysicsObject *pObjectStart, CPhysicsObject *pObjectEnd, springparams_t *pParams )
|
||||
{
|
||||
// fill in template
|
||||
IVP_Template_Spring spring_template;
|
||||
|
||||
spring_template.spring_values_are_relative=IVP_FALSE;
|
||||
spring_template.spring_constant = pParams->constant;
|
||||
spring_template.spring_len = ConvertDistanceToIVP( pParams->naturalLength );
|
||||
spring_template.spring_damp = pParams->damping;
|
||||
spring_template.rel_pos_damp = pParams->relativeDamping;
|
||||
|
||||
spring_template.spring_force_only_on_stretch = pParams->onlyStretch ? IVP_TRUE : IVP_FALSE;
|
||||
|
||||
// Create anchors for the objects
|
||||
IVP_Template_Anchor anchorTemplateObjectStart, anchorTemplateObjectEnd;
|
||||
// create spring
|
||||
|
||||
IVP_U_Float_Point ivpPosStart;
|
||||
IVP_U_Float_Point ivpPosEnd;
|
||||
|
||||
if ( !pParams->useLocalPositions )
|
||||
{
|
||||
Vector local;
|
||||
pObjectStart->WorldToLocal( &local, pParams->startPosition );
|
||||
ConvertPositionToIVP( local, ivpPosStart );
|
||||
|
||||
pObjectEnd->WorldToLocal( &local, pParams->endPosition );
|
||||
ConvertPositionToIVP( local, ivpPosEnd );
|
||||
}
|
||||
else
|
||||
{
|
||||
ConvertPositionToIVP( pParams->startPosition, ivpPosStart );
|
||||
ConvertPositionToIVP( pParams->endPosition, ivpPosEnd );
|
||||
}
|
||||
|
||||
anchorTemplateObjectStart.set_anchor_position_os( pObjectStart->GetObject(), &ivpPosStart );
|
||||
anchorTemplateObjectEnd.set_anchor_position_os( pObjectEnd->GetObject(), &ivpPosEnd );
|
||||
|
||||
spring_template.anchors[0] = &anchorTemplateObjectStart;
|
||||
spring_template.anchors[1] = &anchorTemplateObjectEnd;
|
||||
IVP_Actuator_Spring *pSpring = pEnvironment->create_spring( &spring_template );
|
||||
|
||||
return new CPhysicsSpring( pObjectStart, pObjectEnd, pSpring );
|
||||
}
|
||||
|
||||
|
||||
bool SavePhysicsSpring( const physsaveparams_t ¶ms, CPhysicsSpring *pSpring )
|
||||
{
|
||||
vphysics_save_cphysicsspring_t springTemplate;
|
||||
memset( &springTemplate, 0, sizeof(springTemplate) );
|
||||
|
||||
pSpring->WriteToTemplate( springTemplate );
|
||||
params.pSave->WriteAll( &springTemplate );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RestorePhysicsSpring( const physrestoreparams_t ¶ms, CPhysicsSpring **ppSpring )
|
||||
{
|
||||
vphysics_save_cphysicsspring_t springTemplate;
|
||||
memset( &springTemplate, 0, sizeof(springTemplate) );
|
||||
params.pRestore->ReadAll( &springTemplate );
|
||||
CPhysicsEnvironment *pEnvironment = (CPhysicsEnvironment *)params.pEnvironment;
|
||||
if ( springTemplate.pObjStart && springTemplate.pObjEnd )
|
||||
{
|
||||
*ppSpring = (CPhysicsSpring *)pEnvironment->CreateSpring( springTemplate.pObjStart, springTemplate.pObjEnd, &springTemplate );
|
||||
}
|
||||
else
|
||||
{
|
||||
DevMsg( "Failed to restore spring enpoints\n");
|
||||
*ppSpring = NULL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,22 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PHYSICS_SPRING_H
|
||||
#define PHYSICS_SPRING_H
|
||||
#pragma once
|
||||
|
||||
|
||||
class IPhysicsSpring;
|
||||
class IVP_Environment;
|
||||
class IVP_Real_Object;
|
||||
|
||||
struct springparams_t;
|
||||
|
||||
IPhysicsSpring *CreateSpring( IVP_Environment *pEnvironment, CPhysicsObject *pObjectStart, CPhysicsObject *pObjectEnd, springparams_t *pParams );
|
||||
|
||||
|
||||
#endif // PHYSICS_SPRING_H
|
@ -1,247 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PHYSICS_TRACE_H
|
||||
#define PHYSICS_TRACE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "physics_globals.h"
|
||||
|
||||
class Vector;
|
||||
class QAngle;
|
||||
class CGameTrace;
|
||||
class CTraceRay;
|
||||
class IVP_Compact_Surface;
|
||||
typedef CGameTrace trace_t;
|
||||
struct Ray_t;
|
||||
class IVP_Compact_Surface;
|
||||
class IVP_Compact_Mopp;
|
||||
class IConvexInfo;
|
||||
enum
|
||||
{
|
||||
COLLIDE_POLY = 0,
|
||||
COLLIDE_MOPP = 1,
|
||||
COLLIDE_BALL = 2,
|
||||
COLLIDE_VIRTUAL = 3,
|
||||
};
|
||||
|
||||
class IPhysCollide
|
||||
{
|
||||
public:
|
||||
virtual ~IPhysCollide() {}
|
||||
//virtual void AddReference() = 0;
|
||||
//virtual void ReleaseReference() = 0;
|
||||
|
||||
// get a surface manager
|
||||
virtual IVP_SurfaceManager *CreateSurfaceManager( short & ) const = 0;
|
||||
virtual void GetAllLedges( IVP_U_BigVector<IVP_Compact_Ledge> &ledges ) const = 0;
|
||||
virtual unsigned int GetSerializationSize() const = 0;
|
||||
virtual unsigned int SerializeToBuffer( char *pDest, bool bSwap = false ) const = 0;
|
||||
virtual int GetVCollideIndex() const = 0;
|
||||
virtual Vector GetMassCenter() const = 0;
|
||||
virtual void SetMassCenter( const Vector &massCenter ) = 0;
|
||||
virtual Vector GetOrthographicAreas() const = 0;
|
||||
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
|
||||
#define LEAFMAP_HAS_SINGLE_VERTEX_SPAN 0x0002
|
||||
#define LEAFMAP_HAS_MULTIPLE_VERTEX_SPANS 0x0004
|
||||
struct leafmap_t
|
||||
{
|
||||
void *pLeaf;
|
||||
unsigned short vertCount;
|
||||
byte flags;
|
||||
byte spanCount;
|
||||
unsigned short startVert[8];
|
||||
|
||||
void SetHasCubemap()
|
||||
{
|
||||
flags = LEAFMAP_HAS_CUBEMAP;
|
||||
}
|
||||
|
||||
void SetSingleVertexSpan( int startVertIndex, int vertCountIn )
|
||||
{
|
||||
flags = 0;
|
||||
flags |= LEAFMAP_HAS_SINGLE_VERTEX_SPAN;
|
||||
startVert[0] = startVertIndex;
|
||||
vertCount = vertCountIn;
|
||||
}
|
||||
|
||||
int MaxSpans()
|
||||
{
|
||||
return sizeof(startVert) - sizeof(startVert[0]);
|
||||
}
|
||||
const byte *GetSpans() const
|
||||
{
|
||||
return reinterpret_cast<const byte *>(&startVert[1]);
|
||||
}
|
||||
byte *GetSpans()
|
||||
{
|
||||
return reinterpret_cast<byte *>(&startVert[1]);
|
||||
}
|
||||
|
||||
void SetRLESpans( int startVertIndex, int spanCountIn, byte *pSpans )
|
||||
{
|
||||
flags = 0;
|
||||
if ( spanCountIn > MaxSpans() )
|
||||
return;
|
||||
if ( spanCountIn == 1 )
|
||||
{
|
||||
SetSingleVertexSpan( startVertIndex, pSpans[0] );
|
||||
return;
|
||||
}
|
||||
// write out a run length encoded list of verts to include in this model
|
||||
flags |= LEAFMAP_HAS_MULTIPLE_VERTEX_SPANS;
|
||||
startVert[0] = startVertIndex;
|
||||
vertCount = 0;
|
||||
spanCount = spanCountIn;
|
||||
byte *pSpanOut = GetSpans();
|
||||
for ( int i = 0; i < spanCountIn; i++ )
|
||||
{
|
||||
pSpanOut[i] = pSpans[i];
|
||||
if ( !(i & 1) )
|
||||
{
|
||||
vertCount += pSpans[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline bool HasSpans() const { return (flags & (LEAFMAP_HAS_SINGLE_VERTEX_SPAN|LEAFMAP_HAS_MULTIPLE_VERTEX_SPANS)) ? true : false; }
|
||||
inline bool HasCubemap() const { return (flags & LEAFMAP_HAS_CUBEMAP) ? true : false; }
|
||||
inline bool HasSingleVertexSpan() const { return (flags & LEAFMAP_HAS_SINGLE_VERTEX_SPAN) ? true : false; }
|
||||
inline bool HasRLESpans() const { return (flags & LEAFMAP_HAS_MULTIPLE_VERTEX_SPANS) ? true : false; }
|
||||
};
|
||||
|
||||
struct collidemap_t
|
||||
{
|
||||
int leafCount;
|
||||
leafmap_t leafmap[1];
|
||||
};
|
||||
|
||||
extern void InitLeafmap( IVP_Compact_Ledge *pLeaf, leafmap_t *pLeafmapOut );
|
||||
|
||||
class CPhysCollide : public IPhysCollide
|
||||
{
|
||||
public:
|
||||
static CPhysCollide *UnserializeFromBuffer( const char *pBuffer, unsigned int size, int index, bool swap = false );
|
||||
virtual const IVP_Compact_Surface *GetCompactSurface() const { return NULL; }
|
||||
virtual Vector GetOrthographicAreas() const { return Vector(1,1,1); }
|
||||
virtual float GetSphereRadius() const { return 0; }
|
||||
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
|
||||
{
|
||||
public:
|
||||
virtual int SupportMap( const Vector &dir, Vector *pOut ) const = 0;
|
||||
virtual Vector GetVertByIndex( int index ) const = 0;
|
||||
virtual float Radius( void ) const = 0;
|
||||
};
|
||||
|
||||
// This is the size of the vertex hash
|
||||
#define CONVEX_HASH_SIZE 512
|
||||
// The little hashing trick below allows 64K verts per hash entry
|
||||
#define MAX_CONVEX_VERTS ((CONVEX_HASH_SIZE * (1<<16))-1)
|
||||
|
||||
class CPhysicsTrace
|
||||
{
|
||||
public:
|
||||
CPhysicsTrace();
|
||||
~CPhysicsTrace();
|
||||
// Calculate the intersection of a swept box (mins/maxs) against an IVP object. All coords are in HL space.
|
||||
void SweepBoxIVP( const Vector &start, const Vector &end, const Vector &mins, const Vector &maxs, const CPhysCollide *pSurface, const Vector &surfaceOrigin, const QAngle &surfaceAngles, trace_t *ptr );
|
||||
void SweepBoxIVP( const Ray_t &raySrc, unsigned int contentsMask, IConvexInfo *pConvexInfo, const CPhysCollide *pSurface, const Vector &surfaceOrigin, const QAngle &surfaceAngles, trace_t *ptr );
|
||||
|
||||
// Calculate the intersection of a swept compact surface against another compact surface. All coords are in HL space.
|
||||
// NOTE: BUGBUG: swept surface must be single convex!!!
|
||||
void SweepIVP( const Vector &start, const Vector &end, const CPhysCollide *pSweptSurface, const QAngle &sweptAngles, const CPhysCollide *pSurface, const Vector &surfaceOrigin, const QAngle &surfaceAngles, trace_t *ptr );
|
||||
|
||||
// get an AABB for an oriented collide
|
||||
void GetAABB( Vector *pMins, Vector *pMaxs, const CPhysCollide *pCollide, const Vector &collideOrigin, const QAngle &collideAngles );
|
||||
|
||||
// get the support map/extent for a collide along the axis given by "direction"
|
||||
Vector GetExtent( const CPhysCollide *pCollide, const Vector &collideOrigin, const QAngle &collideAngles, const Vector &direction );
|
||||
|
||||
bool IsBoxIntersectingCone( const Vector &boxAbsMins, const Vector &boxAbsMaxs, const truncatedcone_t &cone );
|
||||
};
|
||||
|
||||
|
||||
class CVisitHash
|
||||
{
|
||||
public:
|
||||
CVisitHash();
|
||||
inline unsigned short VertIndexToID( int vertIndex );
|
||||
inline void VisitVert( int vertIndex );
|
||||
inline bool WasVisited( int vertIndex );
|
||||
inline void NewVisit( void );
|
||||
|
||||
private:
|
||||
|
||||
// Store the current increment and the vertex ID (rotating hash) to guarantee no collisions
|
||||
struct vertmarker_t
|
||||
{
|
||||
unsigned short visitID;
|
||||
unsigned short vertID;
|
||||
};
|
||||
|
||||
vertmarker_t m_vertVisit[CONVEX_HASH_SIZE];
|
||||
unsigned short m_vertVisitID;
|
||||
unsigned short m_isInUse;
|
||||
};
|
||||
|
||||
// Calculate the intersection of a swept box (mins/maxs) against an IVP object. All coords are in HL space.
|
||||
inline unsigned short CVisitHash::VertIndexToID( int vertIndex )
|
||||
{
|
||||
// A little hashing trick here:
|
||||
// rotate the hash key each time you wrap around at 64K
|
||||
// That way, the index will not collide until you've hit 64K # hash entries times
|
||||
int high = vertIndex >> 16;
|
||||
return (unsigned short) ((vertIndex + high) & 0xFFFF);
|
||||
}
|
||||
|
||||
inline void CVisitHash::VisitVert( int vertIndex )
|
||||
{
|
||||
int index = vertIndex & (CONVEX_HASH_SIZE-1);
|
||||
m_vertVisit[index].visitID = m_vertVisitID;
|
||||
m_vertVisit[index].vertID = VertIndexToID(vertIndex);
|
||||
}
|
||||
|
||||
inline bool CVisitHash::WasVisited( int vertIndex )
|
||||
{
|
||||
unsigned short hashIndex = vertIndex & (CONVEX_HASH_SIZE-1);
|
||||
unsigned short id = VertIndexToID(vertIndex);
|
||||
if ( m_vertVisit[hashIndex].visitID == m_vertVisitID && m_vertVisit[hashIndex].vertID == id )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void CVisitHash::NewVisit( void )
|
||||
{
|
||||
m_vertVisitID++;
|
||||
if ( m_vertVisitID == 0 )
|
||||
{
|
||||
memset( m_vertVisit, 0, sizeof(m_vertVisit) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern IVP_SurfaceManager *CreateSurfaceManager( const CPhysCollide *pCollisionModel, short &collideType );
|
||||
extern void OutputCollideDebugInfo( const CPhysCollide *pCollisionModel );
|
||||
|
||||
#endif // PHYSICS_TRACE_H
|
File diff suppressed because it is too large
Load Diff
@ -1,25 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PHYSICS_VEHICLE_H
|
||||
#define PHYSICS_VEHICLE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
struct vehicleparams_t;
|
||||
class IPhysicsVehicleController;
|
||||
class CPhysicsObject;
|
||||
class CPhysicsEnvironment;
|
||||
class IVP_Real_Object;
|
||||
|
||||
bool ShouldOverrideWheelContactFriction( float *pFrictionOut, IVP_Real_Object *pivp0, IVP_Real_Object *pivp1, IVP_U_Float_Point *pNormal );
|
||||
|
||||
IPhysicsVehicleController *CreateVehicleController( CPhysicsEnvironment *pEnv, CPhysicsObject *pBodyObject, const vehicleparams_t ¶ms, unsigned int nVehicleType, IPhysicsGameTrace *pGameTrace );
|
||||
|
||||
#endif // PHYSICS_VEHICLE_H
|
@ -1,641 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Virtual mesh implementation. Cached terrain collision model
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#include "cbase.h"
|
||||
#include "convert.h"
|
||||
#include "ivp_surface_manager.hxx"
|
||||
#include "ivp_surman_polygon.hxx"
|
||||
#include "ivp_template_surbuild.hxx"
|
||||
#include "ivp_compact_surface.hxx"
|
||||
#include <ivp_compact_ledge.hxx>
|
||||
#include <ivp_ray_solver.hxx>
|
||||
#include <ivp_compact_ledge_solver.hxx>
|
||||
#include "ivp_surbuild_pointsoup.hxx"
|
||||
#include "ivp_surbuild_ledge_soup.hxx"
|
||||
#include "physics_trace.h"
|
||||
#include "collisionutils.h"
|
||||
#include "datamanager.h"
|
||||
#include "utlbuffer.h"
|
||||
#include "ledgewriter.h"
|
||||
#include "tier1/mempool.h"
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class CPhysCollideVirtualMesh;
|
||||
|
||||
CTSPool< CUtlVector<CPhysCollideVirtualMesh *> > g_MeshFrameLocksPool;
|
||||
CTHREADLOCALPTR(CUtlVector<CPhysCollideVirtualMesh *>) g_pMeshFrameLocks;
|
||||
|
||||
// This is the surfacemanager class for IVP that implements the required functions by layering CPhysCollideVirtualMesh
|
||||
class IVP_SurfaceManager_VirtualMesh : public IVP_SurfaceManager
|
||||
{
|
||||
public:
|
||||
void add_reference_to_ledge(const IVP_Compact_Ledge *ledge);
|
||||
void remove_reference_to_ledge(const IVP_Compact_Ledge *ledge);
|
||||
void insert_all_ledges_hitting_ray(IVP_Ray_Solver *ray_solver, IVP_Real_Object *object);
|
||||
void get_radius_and_radius_dev_to_given_center(const IVP_U_Float_Point *center, IVP_FLOAT *radius, IVP_FLOAT *radius_deviation) const;
|
||||
virtual IVP_SURMAN_TYPE get_type() { return IVP_SURMAN_POLYGON; }
|
||||
|
||||
// assume mesh is never a single triangle
|
||||
virtual const IVP_Compact_Ledge *get_single_convex() const;
|
||||
void get_mass_center(IVP_U_Float_Point *mass_center_out) const;
|
||||
void get_rotation_inertia( IVP_U_Float_Point *rotation_inertia_out ) const;
|
||||
void get_all_ledges_within_radius(const IVP_U_Point *observer_os, IVP_DOUBLE radius,
|
||||
const IVP_Compact_Ledge *root_ledge, IVP_Real_Object *other_object, const IVP_Compact_Ledge *other_reference_ledge,
|
||||
IVP_U_BigVector<IVP_Compact_Ledge> *resulting_ledges);
|
||||
|
||||
void get_all_terminal_ledges(IVP_U_BigVector<IVP_Compact_Ledge> *resulting_ledges);
|
||||
IVP_SurfaceManager_VirtualMesh( CPhysCollideVirtualMesh *pMesh );
|
||||
virtual ~IVP_SurfaceManager_VirtualMesh();
|
||||
|
||||
private:
|
||||
CPhysCollideVirtualMesh *m_pMesh;
|
||||
};
|
||||
|
||||
// These are the managed objects for the LRU of terrain collisions
|
||||
// These get created/destroyed dynamically by a resourcemanager
|
||||
// These contain the uncompressed collision models for each displacement patch
|
||||
// The idea is to have only the necessary instances of these in memory at any given time - never all of them
|
||||
class CMeshInstance
|
||||
{
|
||||
public:
|
||||
// resourcemanager
|
||||
static unsigned int EstimatedSize( const virtualmeshlist_t &list );
|
||||
static CMeshInstance *CreateResource( const virtualmeshlist_t &list );
|
||||
static unsigned int ComputeRootLedgeSize( const byte *pHull );
|
||||
void DestroyResource() { delete this; }
|
||||
unsigned int Size() { return m_memSize; }
|
||||
CMeshInstance *GetData() { return this; }
|
||||
const triangleledge_t *GetLedges() { return (triangleledge_t *)m_pMemory; }
|
||||
inline int HullCount() { return m_hullCount; }
|
||||
const IVP_Compact_Ledge *GetOuterHull() { return (m_hullCount==1) ? (const IVP_Compact_Ledge *)(m_pMemory + m_hullOffset) : NULL; }
|
||||
int GetRootLedges( IVP_Compact_Ledge **pLedges, int outCount )
|
||||
{
|
||||
int hullOffset = m_hullOffset;
|
||||
int count = min(outCount, (int)m_hullCount);
|
||||
for ( int i = 0; i < count; i++ )
|
||||
{
|
||||
pLedges[i] = (IVP_Compact_Ledge *)(m_pMemory + hullOffset);
|
||||
hullOffset += sizeof(IVP_Compact_Ledge) + (sizeof(IVP_Compact_Triangle) * pLedges[i]->get_n_triangles());
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// locals
|
||||
CMeshInstance() { m_pMemory = 0; }
|
||||
~CMeshInstance();
|
||||
|
||||
private:
|
||||
void Init( const virtualmeshlist_t &list );
|
||||
|
||||
int m_memSize;
|
||||
char *m_pMemory;
|
||||
unsigned short m_hullOffset;
|
||||
byte m_hullCount;
|
||||
byte m_pad;
|
||||
};
|
||||
|
||||
CMeshInstance::~CMeshInstance()
|
||||
{
|
||||
if ( m_pMemory )
|
||||
{
|
||||
ivp_free_aligned( m_pMemory );
|
||||
m_pMemory = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int CMeshInstance::EstimatedSize( const virtualmeshlist_t &list )
|
||||
{
|
||||
int ledgeSize = sizeof(triangleledge_t) * list.triangleCount;
|
||||
int pointSize = sizeof(IVP_Compact_Poly_Point) * list.vertexCount;
|
||||
|
||||
int hullSize = ComputeRootLedgeSize(list.pHull);
|
||||
return ledgeSize + pointSize + hullSize;
|
||||
}
|
||||
|
||||
// computes the unpacked size of the array of root ledges
|
||||
unsigned int CMeshInstance::ComputeRootLedgeSize( const byte *pData )
|
||||
{
|
||||
if ( !pData )
|
||||
return 0;
|
||||
virtualmeshhull_t *pHeader = (virtualmeshhull_t *)pData;
|
||||
packedhull_t *pHull = (packedhull_t *)(pHeader+1);
|
||||
unsigned int size = pHeader->hullCount * sizeof(IVP_Compact_Ledge);
|
||||
for ( int i = 0; i < pHeader->hullCount; i++ )
|
||||
{
|
||||
size += sizeof(IVP_Compact_Triangle) * pHull[i].triangleCount;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
CMeshInstance *CMeshInstance::CreateResource( const virtualmeshlist_t &list )
|
||||
{
|
||||
CMeshInstance *pMesh = new CMeshInstance;
|
||||
pMesh->Init( list );
|
||||
return pMesh;
|
||||
}
|
||||
|
||||
|
||||
// flat memory footprint has triangleledges (ledge + 2 triangles for terrain), then has verts, then optional convex hull
|
||||
void CMeshInstance::Init( const virtualmeshlist_t &list )
|
||||
{
|
||||
int ledgeSize = sizeof(triangleledge_t) * list.triangleCount;
|
||||
int pointSize = sizeof(IVP_Compact_Poly_Point) * list.vertexCount;
|
||||
int memSize = ledgeSize + pointSize + ComputeRootLedgeSize(list.pHull);
|
||||
m_memSize = memSize;
|
||||
m_hullCount = 0;
|
||||
m_pMemory = (char *)ivp_malloc_aligned( memSize, 16 );
|
||||
Assert( (intp(m_pMemory) & 15) == 0 ); // make sure it is aligned
|
||||
IVP_Compact_Poly_Point *pPoints = (IVP_Compact_Poly_Point *)&m_pMemory[ledgeSize];
|
||||
triangleledge_t *pLedges = (triangleledge_t *) m_pMemory;
|
||||
memset( m_pMemory, 0, memSize );
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < list.vertexCount; i++ )
|
||||
{
|
||||
ConvertPositionToIVP( list.pVerts[i], pPoints[i] );
|
||||
}
|
||||
|
||||
for ( i = 0; i < list.triangleCount; i++ )
|
||||
{
|
||||
Vector v0 = list.pVerts[list.indices[i*3+0]];
|
||||
Vector v1 = list.pVerts[list.indices[i*3+1]];
|
||||
Vector v2 = list.pVerts[list.indices[i*3+2]];
|
||||
Assert( v0 != v1 && v1 != v2 && v0 != v2 );
|
||||
CVPhysicsVirtualMeshWriter::InitTwoSidedTriangleLege( &pLedges[i], pPoints, list.indices[i*3+0], list.indices[i*3+1], list.indices[i*3+2], 0 );
|
||||
}
|
||||
Assert( list.triangleCount > 0 && list.triangleCount <= MAX_VIRTUAL_TRIANGLES );
|
||||
// if there's a hull, build it out too
|
||||
if ( list.pHull )
|
||||
{
|
||||
virtualmeshhull_t *pHeader = (virtualmeshhull_t *)list.pHull;
|
||||
m_hullCount = pHeader->hullCount;
|
||||
Assert( (ledgeSize + pointSize) < 65536 );
|
||||
m_hullOffset = ledgeSize + pointSize;
|
||||
byte *pMem = (byte *)m_pMemory + m_hullOffset;
|
||||
#if _DEBUG
|
||||
int hullSize = CVPhysicsVirtualMeshWriter::UnpackLedgeListFromHull( pMem, pHeader, pPoints );
|
||||
Assert((m_hullOffset+hullSize)==memSize);
|
||||
#else
|
||||
CVPhysicsVirtualMeshWriter::UnpackLedgeListFromHull( pMem, pHeader, pPoints );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
const int g_MeshSize = (2048 * 1024 * 4); // nillerusr: 2 MiB should be enough, old value causes problems in ep2
|
||||
static CDataManager<CMeshInstance, virtualmeshlist_t, CMeshInstance *, CThreadFastMutex> g_MeshManager( g_MeshSize );
|
||||
static int numIndices = 0, numTriangles = 0, numBaseTriangles = 0, numSplits = 0;
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This allows for just-in-time procedural triangle soup data to be
|
||||
// instanced & cached as IVP collision data (compact ledges)
|
||||
//-----------------------------------------------------------------------------
|
||||
// NOTE: This is the permanent in-memory representation. It holds the compressed data
|
||||
// and the parameters necessary to request the proxy geometry as needed
|
||||
class CPhysCollideVirtualMesh : public CPhysCollide
|
||||
{
|
||||
public:
|
||||
// UNDONE: Unlike other CPhysCollide objects, operations the virtual mesh are
|
||||
// non-const because they may instantiate the cache. This causes problems with the interface.
|
||||
// Maybe the cache stuff should be mutable, but it amounts to the same kind of
|
||||
// hackery to cast away const.
|
||||
|
||||
// get a surface manager
|
||||
virtual IVP_SurfaceManager *CreateSurfaceManager( short &collideType ) const
|
||||
{
|
||||
collideType = COLLIDE_VIRTUAL;
|
||||
// UNDONE: Figure out how to avoid this const_cast
|
||||
return new IVP_SurfaceManager_VirtualMesh(const_cast<CPhysCollideVirtualMesh *>(this));
|
||||
}
|
||||
virtual void GetAllLedges( IVP_U_BigVector<IVP_Compact_Ledge> &ledges ) const
|
||||
{
|
||||
const triangleledge_t *pLedges = const_cast<CPhysCollideVirtualMesh *>(this)->AddRef()->GetLedges();
|
||||
for ( int i = 0; i < m_ledgeCount; i++ )
|
||||
{
|
||||
ledges.add( const_cast<IVP_Compact_Ledge *>(&pLedges[i].ledge) );
|
||||
}
|
||||
const_cast<CPhysCollideVirtualMesh *>(this)->Release();
|
||||
}
|
||||
virtual unsigned int GetSerializationSize() const
|
||||
{
|
||||
if ( !m_pHull )
|
||||
return 0;
|
||||
return m_pHull->TotalSize();
|
||||
}
|
||||
|
||||
virtual unsigned int SerializeToBuffer( char *pDest, bool bSwap = false ) const
|
||||
{
|
||||
unsigned int size = GetSerializationSize();
|
||||
if ( size )
|
||||
{
|
||||
memcpy( pDest, m_pHull, size );
|
||||
}
|
||||
return size;
|
||||
}
|
||||
virtual int GetVCollideIndex() const { return 0; }
|
||||
virtual void SetMassCenter( const Vector &massCenter ) {Assert(0); }
|
||||
virtual Vector GetOrthographicAreas() const { return Vector(1,1,1);}
|
||||
|
||||
Vector GetMassCenter() const;
|
||||
virtual float GetSphereRadius() const;
|
||||
float GetSphereRadiusIVP() const;
|
||||
void Init( const char *pBuffer, unsigned int size )
|
||||
{
|
||||
}
|
||||
void GetAllLedgesWithinRadius( const IVP_U_Point *observer_os, IVP_DOUBLE radius, IVP_U_BigVector<IVP_Compact_Ledge> *resulting_ledges, const IVP_Compact_Ledge *pRootLedge = NULL )
|
||||
{
|
||||
virtualmeshtrianglelist_t list;
|
||||
list.triangleCount = 0;
|
||||
Vector centerHL;
|
||||
ConvertPositionToHL( *observer_os, centerHL );
|
||||
float radiusHL = ConvertDistanceToHL(radius);
|
||||
m_params.pMeshEventHandler->GetTrianglesInSphere( m_params.userData, centerHL, radiusHL, &list );
|
||||
if ( list.triangleCount )
|
||||
{
|
||||
CMeshInstance *pMesh = AddRef();
|
||||
const triangleledge_t *pLedges = pMesh->GetLedges();
|
||||
FrameRelease();
|
||||
|
||||
// If we have two root ledges, then each one contains half the triangles
|
||||
// only return triangles indexed under the root ledge being queried
|
||||
int minTriangle = 0;
|
||||
int maxTriangle = m_ledgeCount;
|
||||
if ( pMesh->HullCount() > 1 )
|
||||
{
|
||||
Assert(pMesh->HullCount()==2);
|
||||
IVP_Compact_Ledge *pRootNodes[2];
|
||||
pMesh->GetRootLedges( pRootNodes, 2 );
|
||||
int midTriangle = m_ledgeCount/2;
|
||||
if ( pRootLedge == pRootNodes[0] )
|
||||
{
|
||||
maxTriangle = midTriangle;
|
||||
}
|
||||
else
|
||||
{
|
||||
minTriangle = midTriangle;
|
||||
}
|
||||
}
|
||||
IVP_DOUBLE radiusSq = radius * radius;
|
||||
for ( int i = 0; i < list.triangleCount; i++ )
|
||||
{
|
||||
Assert( list.triangleIndices[i] < m_ledgeCount );
|
||||
if ( list.triangleIndices[i] < minTriangle || list.triangleIndices[i] >= maxTriangle )
|
||||
continue;
|
||||
|
||||
const IVP_Compact_Ledge *ledge = &pLedges[list.triangleIndices[i]].ledge;
|
||||
Assert(ledge->get_n_triangles() == 2);
|
||||
const IVP_Compact_Triangle *triangle = ledge->get_first_triangle();
|
||||
IVP_DOUBLE qdist = IVP_CLS.calc_qlen_PF_F_space(ledge, triangle, observer_os);
|
||||
if ( qdist > radiusSq )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
resulting_ledges->add( const_cast<IVP_Compact_Ledge *>(ledge) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OutputDebugInfo() const
|
||||
{
|
||||
Msg("Virtual mesh!\n");
|
||||
}
|
||||
|
||||
CPhysCollideVirtualMesh(const virtualmeshparams_t ¶ms) : m_params(params), m_hMemory( INVALID_MEMHANDLE ), m_ledgeCount( 0 )
|
||||
{
|
||||
m_pHull = NULL;
|
||||
if ( params.buildOuterHull )
|
||||
{
|
||||
BuildBoundingLedge();
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~CPhysCollideVirtualMesh();
|
||||
|
||||
// adds a lock on the collsion memory :: MUST CALL Release() or FrameRelease corresponding to this call!!!
|
||||
CMeshInstance *AddRef();
|
||||
|
||||
void BuildBoundingLedge();
|
||||
static virtualmeshhull_t *CreateMeshBoundingHull( const virtualmeshlist_t &list );
|
||||
static void DestroyMeshBoundingHull(virtualmeshhull_t *pHull) { CVPhysicsVirtualMeshWriter::DestroyPackedHull(pHull); }
|
||||
static IVP_Compact_Surface *CreateBoundingSurfaceFromRange( const virtualmeshlist_t &list, int firstIndex, int indexCount );
|
||||
|
||||
int GetRootLedges( IVP_Compact_Ledge **pLedges, int outCount )
|
||||
{
|
||||
int count = AddRef()->GetRootLedges(pLedges, outCount);
|
||||
FrameRelease();
|
||||
return count;
|
||||
}
|
||||
|
||||
IVP_Compact_Ledge *GetBoundingLedge()
|
||||
{
|
||||
IVP_Compact_Ledge *pLedge = const_cast<IVP_Compact_Ledge *>(AddRef()->GetOuterHull());
|
||||
FrameRelease();
|
||||
return pLedge;
|
||||
}
|
||||
|
||||
// releases a lock on the collision memory
|
||||
void Release();
|
||||
// Analagous to Release, but happens at the end of the frame
|
||||
void FrameRelease()
|
||||
{
|
||||
CUtlVector<CPhysCollideVirtualMesh *> *pLocks = g_pMeshFrameLocks;
|
||||
if ( !pLocks )
|
||||
{
|
||||
g_pMeshFrameLocks = pLocks = g_MeshFrameLocksPool.GetObject();
|
||||
Assert( pLocks );
|
||||
}
|
||||
pLocks->AddToTail(this);
|
||||
}
|
||||
inline void GetBounds( Vector &mins, Vector &maxs ) const
|
||||
{
|
||||
m_params.pMeshEventHandler->GetWorldspaceBounds( m_params.userData, &mins, &maxs );
|
||||
}
|
||||
|
||||
private:
|
||||
CMeshInstance *BuildLedges();
|
||||
|
||||
virtualmeshparams_t m_params;
|
||||
virtualmeshhull_t *m_pHull;
|
||||
memhandle_t m_hMemory;
|
||||
short m_ledgeCount;
|
||||
};
|
||||
|
||||
static void FlushFrameLocks()
|
||||
{
|
||||
CUtlVector<CPhysCollideVirtualMesh *> *pLocks = g_pMeshFrameLocks;
|
||||
if ( pLocks )
|
||||
{
|
||||
for ( int i = 0; i < pLocks->Count(); i++ )
|
||||
{
|
||||
Assert( (*pLocks)[i] );
|
||||
(*pLocks)[i]->Release();
|
||||
}
|
||||
pLocks->RemoveAll();
|
||||
g_MeshFrameLocksPool.PutObject( g_pMeshFrameLocks );
|
||||
g_pMeshFrameLocks = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualMeshPSI()
|
||||
{
|
||||
FlushFrameLocks();
|
||||
}
|
||||
|
||||
|
||||
Vector CPhysCollideVirtualMesh::GetMassCenter() const
|
||||
{
|
||||
Vector mins, maxs;
|
||||
GetBounds( mins, maxs );
|
||||
return 0.5 * (mins + maxs);
|
||||
}
|
||||
|
||||
float CPhysCollideVirtualMesh::GetSphereRadius() const
|
||||
{
|
||||
Vector mins, maxs;
|
||||
GetBounds( mins, maxs );
|
||||
Vector point = 0.5 * (mins+maxs);
|
||||
return (maxs - point).Length();
|
||||
}
|
||||
|
||||
float CPhysCollideVirtualMesh::GetSphereRadiusIVP() const
|
||||
{
|
||||
return ConvertDistanceToIVP( GetSphereRadius() );
|
||||
}
|
||||
|
||||
static CThreadFastMutex s_BuildVirtualMeshMutex;
|
||||
CMeshInstance *CPhysCollideVirtualMesh::AddRef()
|
||||
{
|
||||
CMeshInstance *pMesh = g_MeshManager.LockResource( m_hMemory );
|
||||
if ( !pMesh )
|
||||
{
|
||||
s_BuildVirtualMeshMutex.Lock();
|
||||
pMesh = g_MeshManager.LockResource( m_hMemory );
|
||||
if ( !pMesh )
|
||||
{
|
||||
pMesh = BuildLedges();
|
||||
}
|
||||
s_BuildVirtualMeshMutex.Unlock();
|
||||
}
|
||||
Assert( pMesh );
|
||||
return pMesh;
|
||||
}
|
||||
|
||||
void CPhysCollideVirtualMesh::Release()
|
||||
{
|
||||
g_MeshManager.UnlockResource( m_hMemory );
|
||||
}
|
||||
|
||||
CPhysCollideVirtualMesh::~CPhysCollideVirtualMesh()
|
||||
{
|
||||
CVPhysicsVirtualMeshWriter::DestroyPackedHull(m_pHull);
|
||||
g_MeshManager.DestroyResource( m_hMemory );
|
||||
}
|
||||
|
||||
CMeshInstance *CPhysCollideVirtualMesh::BuildLedges()
|
||||
{
|
||||
virtualmeshlist_t list;
|
||||
m_params.pMeshEventHandler->GetVirtualMesh( m_params.userData, &list );
|
||||
if ( !list.pHull )
|
||||
{
|
||||
list.pHull = (byte *)m_pHull;
|
||||
}
|
||||
|
||||
if ( list.triangleCount )
|
||||
{
|
||||
m_hMemory = g_MeshManager.CreateResource( list );
|
||||
m_ledgeCount = list.triangleCount;
|
||||
CMeshInstance *pMesh = g_MeshManager.LockResource( m_hMemory );
|
||||
|
||||
Assert( g_MeshManager.AvailableSize() != 0 );
|
||||
|
||||
return pMesh;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// build the outer ledge, split into two if necessary
|
||||
void CPhysCollideVirtualMesh::BuildBoundingLedge()
|
||||
{
|
||||
virtualmeshlist_t list;
|
||||
m_params.pMeshEventHandler->GetVirtualMesh( m_params.userData, &list );
|
||||
m_pHull = CreateMeshBoundingHull(list);
|
||||
}
|
||||
|
||||
virtualmeshhull_t *CPhysCollideVirtualMesh::CreateMeshBoundingHull( const virtualmeshlist_t &list )
|
||||
{
|
||||
virtualmeshhull_t *pHull = NULL;
|
||||
if ( list.triangleCount )
|
||||
{
|
||||
IVP_Compact_Surface *pSurface = CreateBoundingSurfaceFromRange( list, 0, list.indexCount );
|
||||
if ( pSurface )
|
||||
{
|
||||
const IVP_Compact_Ledge *pLedge = pSurface->get_compact_ledge_tree_root()->get_compact_hull();
|
||||
if ( CVPhysicsVirtualMeshWriter::LedgeCanBePacked(pLedge, list) )
|
||||
{
|
||||
pHull = CVPhysicsVirtualMeshWriter::CreatePackedHullFromLedges( list, &pLedge, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// too big to pack to 8-bits, split in two
|
||||
IVP_Compact_Surface *pSurface0 = CreateBoundingSurfaceFromRange( list, 0, list.indexCount/2 );
|
||||
IVP_Compact_Surface *pSurface1 = CreateBoundingSurfaceFromRange( list, list.indexCount/2, list.indexCount/2 );
|
||||
|
||||
const IVP_Compact_Ledge *pLedges[2] = {pSurface0->get_compact_ledge_tree_root()->get_compact_hull(), pSurface1->get_compact_ledge_tree_root()->get_compact_hull()};
|
||||
pHull = CVPhysicsVirtualMeshWriter::CreatePackedHullFromLedges( list, pLedges, 2 );
|
||||
ivp_free_aligned(pSurface0);
|
||||
ivp_free_aligned(pSurface1);
|
||||
}
|
||||
ivp_free_aligned(pSurface);
|
||||
}
|
||||
}
|
||||
return pHull;
|
||||
}
|
||||
|
||||
IVP_Compact_Surface *CPhysCollideVirtualMesh::CreateBoundingSurfaceFromRange( const virtualmeshlist_t &list, int firstIndex, int indexCount )
|
||||
{
|
||||
Assert( list.triangleCount );
|
||||
IVP_U_Point triVerts[3];
|
||||
IVP_U_Vector<IVP_U_Point> triList;
|
||||
IVP_SurfaceBuilder_Ledge_Soup builder;
|
||||
triList.add( &triVerts[0] );
|
||||
triList.add( &triVerts[1] );
|
||||
triList.add( &triVerts[2] );
|
||||
int lastIndex = firstIndex + indexCount;
|
||||
int firstTriangle = firstIndex/3;
|
||||
int lastTriangle = lastIndex/3;
|
||||
for ( int i = firstTriangle; i < lastTriangle; i++ )
|
||||
{
|
||||
ConvertPositionToIVP( list.pVerts[list.indices[i*3+0]], triVerts[0] );
|
||||
ConvertPositionToIVP( list.pVerts[list.indices[i*3+1]], triVerts[1] );
|
||||
ConvertPositionToIVP( list.pVerts[list.indices[i*3+2]], triVerts[2] );
|
||||
IVP_Compact_Ledge *pLedge = IVP_SurfaceBuilder_Pointsoup::convert_pointsoup_to_compact_ledge( &triList );
|
||||
builder.insert_ledge( pLedge );
|
||||
}
|
||||
// build a convex hull of those verts
|
||||
IVP_Template_Surbuild_LedgeSoup params;
|
||||
params.build_root_convex_hull = IVP_TRUE;
|
||||
IVP_Compact_Surface *pSurface = builder.compile( ¶ms );
|
||||
|
||||
#if _DEBUG
|
||||
const IVP_Compact_Ledgetree_Node *node = pSurface->get_compact_ledge_tree_root();
|
||||
IVP_Compact_Ledge *pLedge = const_cast<IVP_Compact_Ledge *>(node->get_compact_hull()); // we're going to write into client data on each vert before we throw this away
|
||||
Assert(pLedge && !pLedge->is_terminal());
|
||||
#endif
|
||||
return pSurface;
|
||||
}
|
||||
|
||||
CPhysCollide *CreateVirtualMesh( const virtualmeshparams_t ¶ms )
|
||||
{
|
||||
return new CPhysCollideVirtualMesh(params);
|
||||
}
|
||||
|
||||
void DestroyVirtualMesh( CPhysCollide *pMesh )
|
||||
{
|
||||
delete pMesh;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// IVP_SurfaceManager_VirtualMesh
|
||||
// This hooks the underlying collision model to IVP's surfacemanager interface
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
IVP_SurfaceManager_VirtualMesh::IVP_SurfaceManager_VirtualMesh( CPhysCollideVirtualMesh *pMesh ) : m_pMesh(pMesh)
|
||||
{
|
||||
}
|
||||
|
||||
IVP_SurfaceManager_VirtualMesh::~IVP_SurfaceManager_VirtualMesh()
|
||||
{
|
||||
FlushFrameLocks();
|
||||
}
|
||||
|
||||
void IVP_SurfaceManager_VirtualMesh::add_reference_to_ledge(const IVP_Compact_Ledge *ledge)
|
||||
{
|
||||
m_pMesh->AddRef();
|
||||
}
|
||||
void IVP_SurfaceManager_VirtualMesh::remove_reference_to_ledge(const IVP_Compact_Ledge *ledge)
|
||||
{
|
||||
m_pMesh->Release();
|
||||
}
|
||||
|
||||
// Implement the IVP raycast. This is done by testing each triangle (front & back) - so it's slow
|
||||
void IVP_SurfaceManager_VirtualMesh::insert_all_ledges_hitting_ray(IVP_Ray_Solver *ray_solver, IVP_Real_Object *object)
|
||||
{
|
||||
IVP_Vector_of_Ledges_256 ledges;
|
||||
IVP_Ray_Solver_Os ray_solver_os( ray_solver, object);
|
||||
|
||||
IVP_U_Point center(&ray_solver_os.ray_center_point);
|
||||
m_pMesh->GetAllLedgesWithinRadius( ¢er, ray_solver_os.ray_length * 0.5f, &ledges );
|
||||
|
||||
for (int i=ledges.len()-1;i>=0;i--)
|
||||
{
|
||||
const IVP_Compact_Ledge *l = ledges.element_at(i);
|
||||
ray_solver_os.check_ray_against_compact_ledge_os(l);
|
||||
}
|
||||
}
|
||||
|
||||
// Used to predict collision detection needs
|
||||
void IVP_SurfaceManager_VirtualMesh::get_radius_and_radius_dev_to_given_center(const IVP_U_Float_Point *center, IVP_FLOAT *radius, IVP_FLOAT *radius_deviation) const
|
||||
{
|
||||
// UNDONE: Check radius_deviation to see if there is a useful optimization to be made here
|
||||
*radius = m_pMesh->GetSphereRadiusIVP();
|
||||
*radius_deviation = *radius;
|
||||
}
|
||||
|
||||
// get a single convex if appropriate
|
||||
const IVP_Compact_Ledge *IVP_SurfaceManager_VirtualMesh::get_single_convex() const
|
||||
{
|
||||
return m_pMesh->GetBoundingLedge();
|
||||
}
|
||||
|
||||
// get a mass center for objects using this collision rep
|
||||
void IVP_SurfaceManager_VirtualMesh::get_mass_center(IVP_U_Float_Point *mass_center_out) const
|
||||
{
|
||||
Vector center = m_pMesh->GetMassCenter();
|
||||
ConvertPositionToIVP( center, *mass_center_out );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Compute a diagonalized inertia tensor.
|
||||
//-----------------------------------------------------------------------------
|
||||
void IVP_SurfaceManager_VirtualMesh::get_rotation_inertia( IVP_U_Float_Point *rotation_inertia_out ) const
|
||||
{
|
||||
// HACKHACK: No need for this because we only support static objects for now
|
||||
rotation_inertia_out->set(1,1,1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Query ledges (triangles in this case) in sphere
|
||||
//-----------------------------------------------------------------------------
|
||||
void IVP_SurfaceManager_VirtualMesh::get_all_ledges_within_radius(const IVP_U_Point *observer_os, IVP_DOUBLE radius,
|
||||
const IVP_Compact_Ledge *root_ledge, IVP_Real_Object *other_object, const IVP_Compact_Ledge *other_reference_ledge,
|
||||
IVP_U_BigVector<IVP_Compact_Ledge> *resulting_ledges)
|
||||
{
|
||||
if ( !root_ledge )
|
||||
{
|
||||
IVP_Compact_Ledge *pLedges[2];
|
||||
int count = m_pMesh->GetRootLedges( pLedges, ARRAYSIZE(pLedges) );
|
||||
if ( count )
|
||||
{
|
||||
for ( int i = 0; i < count; i++ )
|
||||
{
|
||||
resulting_ledges->add( pLedges[i] ); // return the recursive/virtual outer hull
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_pMesh->GetAllLedgesWithinRadius( observer_os, radius, resulting_ledges, root_ledge );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Query all of the ledges (triangles)
|
||||
//-----------------------------------------------------------------------------
|
||||
void IVP_SurfaceManager_VirtualMesh::get_all_terminal_ledges(IVP_U_BigVector<IVP_Compact_Ledge> *resulting_ledges)
|
||||
{
|
||||
m_pMesh->GetAllLedges( *resulting_ledges );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,19 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef PHYSICS_VIRTUALMESH_H
|
||||
#define PHYSICS_VIRTUALMESH_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
CPhysCollide *CreateVirtualMesh( const virtualmeshparams_t ¶ms );
|
||||
void DestroyVirtualMesh( CPhysCollide *pSurf );
|
||||
void DumpVirtualMeshStats();
|
||||
void VirtualMeshPSI();
|
||||
|
||||
#endif // PHYSICS_VIRTUALMESH_H
|
@ -1,9 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: precompiled header for vphysics
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,9 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// traceperf.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
@ -1,15 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "phyfile.h"
|
||||
#include "vphysics_interface.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "tier0/vprof.h"
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
@ -1,406 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// traceperf.cpp : Defines the entry point for the console application.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "gametrace.h"
|
||||
#include "fmtstr.h"
|
||||
#include "appframework/appframework.h"
|
||||
#include "filesystem.h"
|
||||
#include "filesystem_init.h"
|
||||
#include "tier1/tier1.h"
|
||||
#include "tier2/tier2.h"
|
||||
#include "tier3/tier3.h"
|
||||
|
||||
IPhysicsCollision *physcollision = NULL;
|
||||
|
||||
#define NUM_COLLISION_TESTS 2500
|
||||
|
||||
void ReadPHYFile(const char *name, vcollide_t &collide )
|
||||
{
|
||||
FileHandle_t fp = g_pFullFileSystem->Open(name, "rb");
|
||||
if (!fp)
|
||||
Error ("Couldn't open %s", name);
|
||||
|
||||
phyheader_t header;
|
||||
|
||||
g_pFullFileSystem->Read( &header, sizeof(header), fp );
|
||||
if ( header.size != sizeof(header) || header.solidCount <= 0 )
|
||||
return;
|
||||
|
||||
int fileSize = g_pFullFileSystem->Size(fp);
|
||||
|
||||
char *buf = (char *)_alloca( fileSize );
|
||||
g_pFullFileSystem->Read( buf, fileSize, fp );
|
||||
g_pFullFileSystem->Close( fp );
|
||||
|
||||
physcollision->VCollideLoad( &collide, header.solidCount, (const char *)buf, fileSize );
|
||||
}
|
||||
|
||||
|
||||
struct testlist_t
|
||||
{
|
||||
Vector start;
|
||||
Vector end;
|
||||
Vector normal;
|
||||
bool hit;
|
||||
};
|
||||
|
||||
struct benchresults_t
|
||||
{
|
||||
int collisionTests;
|
||||
int collisionHits;
|
||||
float totalTime;
|
||||
float rayTime;
|
||||
float boxTime;
|
||||
};
|
||||
|
||||
testlist_t g_Traces[NUM_COLLISION_TESTS];
|
||||
void Benchmark_PHY( const CPhysCollide *pCollide, benchresults_t *pOut )
|
||||
{
|
||||
int i;
|
||||
Vector start = vec3_origin;
|
||||
static Vector *targets = NULL;
|
||||
static bool first = true;
|
||||
static float test[2] = {1,1};
|
||||
if ( first )
|
||||
{
|
||||
float radius = 0;
|
||||
float theta = 0;
|
||||
float phi = 0;
|
||||
for ( int i = 0; i < NUM_COLLISION_TESTS; i++ )
|
||||
{
|
||||
radius += NUM_COLLISION_TESTS * 123.123f;
|
||||
radius = fabs(fmod(radius, 128));
|
||||
theta += NUM_COLLISION_TESTS * 0.76f;
|
||||
theta = fabs(fmod(theta, DEG2RAD(360)));
|
||||
phi += NUM_COLLISION_TESTS * 0.16666666f;
|
||||
phi = fabs(fmod(phi, DEG2RAD(180)));
|
||||
|
||||
float st, ct, sp, cp;
|
||||
SinCos( theta, &st, &ct );
|
||||
SinCos( phi, &sp, &cp );
|
||||
st = sin(theta);
|
||||
ct = cos(theta);
|
||||
sp = sin(phi);
|
||||
cp = cos(phi);
|
||||
|
||||
g_Traces[i].start.x = radius * ct * sp;
|
||||
g_Traces[i].start.y = radius * st * sp;
|
||||
g_Traces[i].start.z = radius * cp;
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
|
||||
float duration = 0;
|
||||
Vector size[2];
|
||||
size[0].Init(0,0,0);
|
||||
size[1].Init(16,16,16);
|
||||
|
||||
#if VPROF_LEVEL > 0
|
||||
g_VProfCurrentProfile.Reset();
|
||||
g_VProfCurrentProfile.ResetPeaks();
|
||||
g_VProfCurrentProfile.Start();
|
||||
#endif
|
||||
|
||||
#if TEST_BBOX
|
||||
Vector mins, maxs;
|
||||
physcollision->CollideGetAABB( &mins, &maxs, pCollide, Vector(-500, 200, -100), vec3_angle );
|
||||
Vector extents = maxs - mins;
|
||||
Vector center = 0.5f * (maxs+mins);
|
||||
Msg("bbox: %.2f,%.2f, %.2f @ %.2f, %.2f, %.2f\n", extents.x, extents.y, extents.z, center.x, center.y, center.z );
|
||||
#endif
|
||||
unsigned int hitCount = 0;
|
||||
double startTime = Plat_FloatTime();
|
||||
trace_t tr;
|
||||
for ( i = 0; i < NUM_COLLISION_TESTS; i++ )
|
||||
{
|
||||
physcollision->TraceBox( g_Traces[i].start, start, -size[0], size[0], pCollide, vec3_origin, vec3_angle, &tr );
|
||||
if ( tr.DidHit() )
|
||||
{
|
||||
g_Traces[i].end = tr.endpos;
|
||||
g_Traces[i].normal = tr.plane.normal;
|
||||
g_Traces[i].hit = true;
|
||||
hitCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_Traces[i].hit = false;
|
||||
}
|
||||
}
|
||||
for ( i = 0; i < NUM_COLLISION_TESTS; i++ )
|
||||
{
|
||||
physcollision->TraceBox( g_Traces[i].start, start, -size[1], size[1], pCollide, vec3_origin, vec3_angle, &tr );
|
||||
}
|
||||
duration = Plat_FloatTime() - startTime;
|
||||
|
||||
#if VPROF_LEVEL > 0
|
||||
g_VProfCurrentProfile.MarkFrame();
|
||||
g_VProfCurrentProfile.Stop();
|
||||
g_VProfCurrentProfile.Reset();
|
||||
g_VProfCurrentProfile.ResetPeaks();
|
||||
g_VProfCurrentProfile.Start();
|
||||
#endif
|
||||
hitCount = 0;
|
||||
startTime = Plat_FloatTime();
|
||||
for ( i = 0; i < NUM_COLLISION_TESTS; i++ )
|
||||
{
|
||||
physcollision->TraceBox( g_Traces[i].start, start, -size[0], size[0], pCollide, vec3_origin, vec3_angle, &tr );
|
||||
if ( tr.DidHit() )
|
||||
{
|
||||
g_Traces[i].end = tr.endpos;
|
||||
g_Traces[i].normal = tr.plane.normal;
|
||||
g_Traces[i].hit = true;
|
||||
hitCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_Traces[i].hit = false;
|
||||
}
|
||||
#if VPROF_LEVEL > 0
|
||||
g_VProfCurrentProfile.MarkFrame();
|
||||
#endif
|
||||
}
|
||||
double midTime = Plat_FloatTime();
|
||||
for ( i = 0; i < NUM_COLLISION_TESTS; i++ )
|
||||
{
|
||||
physcollision->TraceBox( g_Traces[i].start, start, -size[1], size[1], pCollide, vec3_origin, vec3_angle, &tr );
|
||||
#if VPROF_LEVEL > 0
|
||||
g_VProfCurrentProfile.MarkFrame();
|
||||
#endif
|
||||
}
|
||||
double endTime = Plat_FloatTime();
|
||||
duration = endTime - startTime;
|
||||
pOut->collisionTests = NUM_COLLISION_TESTS;
|
||||
pOut->collisionHits = hitCount;
|
||||
pOut->totalTime = duration * 1000.0f;
|
||||
pOut->rayTime = (midTime - startTime) * 1000.0f;
|
||||
pOut->boxTime = (endTime - midTime)*1000.0f;
|
||||
|
||||
#if VPROF_LEVEL > 0
|
||||
g_VProfCurrentProfile.Stop();
|
||||
g_VProfCurrentProfile.OutputReport( VPRT_FULL & ~VPRT_HIERARCHY, NULL );
|
||||
#endif
|
||||
}
|
||||
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The application object
|
||||
//-----------------------------------------------------------------------------
|
||||
class CBenchmarkApp : public CDefaultAppSystemGroup< CSteamAppSystemGroup >
|
||||
{
|
||||
typedef CDefaultAppSystemGroup< CSteamAppSystemGroup > BaseClass;
|
||||
|
||||
public:
|
||||
// Methods of IApplication
|
||||
virtual bool Create();
|
||||
virtual bool PreInit( );
|
||||
virtual int Main();
|
||||
virtual void PostShutdown();
|
||||
bool SetupSearchPaths();
|
||||
|
||||
private:
|
||||
bool ParseArguments();
|
||||
};
|
||||
|
||||
DEFINE_CONSOLE_STEAM_APPLICATION_OBJECT( CBenchmarkApp );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The application object
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBenchmarkApp::Create()
|
||||
{
|
||||
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f, false, false, false, false );
|
||||
|
||||
// Add in the cvar factory
|
||||
//AppModule_t cvarModule = LoadModule( VStdLib_GetICVarFactory() );
|
||||
//AddSystem( cvarModule, VENGINE_CVAR_INTERFACE_VERSION );
|
||||
|
||||
AppSystemInfo_t appSystems[] =
|
||||
{
|
||||
{ "vphysics.dll", VPHYSICS_INTERFACE_VERSION },
|
||||
{ "", "" } // Required to terminate the list
|
||||
};
|
||||
|
||||
bool bRet = AddSystems( appSystems );
|
||||
if ( bRet )
|
||||
{
|
||||
physcollision = (IPhysicsCollision*)FindSystem( VPHYSICS_COLLISION_INTERFACE_VERSION );
|
||||
if ( !physcollision )
|
||||
return false;
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
|
||||
bool CBenchmarkApp::SetupSearchPaths()
|
||||
{
|
||||
CFSSteamSetupInfo steamInfo;
|
||||
steamInfo.m_pDirectoryName = NULL;
|
||||
steamInfo.m_bOnlyUseDirectoryName = false;
|
||||
steamInfo.m_bToolsMode = true;
|
||||
steamInfo.m_bSetSteamDLLPath = true;
|
||||
steamInfo.m_bSteam = g_pFullFileSystem->IsSteam();
|
||||
|
||||
if ( FileSystem_SetupSteamEnvironment( steamInfo ) != FS_OK )
|
||||
return false;
|
||||
|
||||
CFSMountContentInfo fsInfo;
|
||||
fsInfo.m_pFileSystem = g_pFullFileSystem;
|
||||
fsInfo.m_bToolsMode = true;
|
||||
fsInfo.m_pDirectoryName = steamInfo.m_GameInfoPath;
|
||||
|
||||
if ( FileSystem_MountContent( fsInfo ) != FS_OK )
|
||||
return false;
|
||||
|
||||
// Finally, load the search paths for the "GAME" path.
|
||||
CFSSearchPathsInit searchPathsInit;
|
||||
searchPathsInit.m_pDirectoryName = steamInfo.m_GameInfoPath;
|
||||
searchPathsInit.m_pFileSystem = g_pFullFileSystem;
|
||||
if ( FileSystem_LoadSearchPaths( searchPathsInit ) != FS_OK )
|
||||
return false;
|
||||
|
||||
g_pFullFileSystem->AddSearchPath( steamInfo.m_GameInfoPath, "SKIN", PATH_ADD_TO_HEAD );
|
||||
|
||||
FileSystem_AddSearchPath_Platform( g_pFullFileSystem, steamInfo.m_GameInfoPath );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBenchmarkApp::PreInit( )
|
||||
{
|
||||
CreateInterfaceFn factory = GetFactory();
|
||||
ConnectTier1Libraries( &factory, 1 );
|
||||
ConnectTier2Libraries( &factory, 1 );
|
||||
ConnectTier3Libraries( &factory, 1 );
|
||||
|
||||
if ( !g_pFullFileSystem || !physcollision )
|
||||
{
|
||||
Warning( "benchmark is missing a required interface!\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
return SetupSearchPaths();//( NULL, false, true );
|
||||
}
|
||||
|
||||
|
||||
void CBenchmarkApp::PostShutdown()
|
||||
{
|
||||
DisconnectTier3Libraries();
|
||||
DisconnectTier2Libraries();
|
||||
DisconnectTier1Libraries();
|
||||
}
|
||||
|
||||
struct baseline_t
|
||||
{
|
||||
float total;
|
||||
float ray;
|
||||
float box;
|
||||
};
|
||||
|
||||
// current baseline measured on Core2DuoE6600
|
||||
baseline_t g_Baselines[] =
|
||||
{
|
||||
{ 40.56f, 10.64f, 29.92f}, // bench01a.phy
|
||||
{ 38.13f, 10.76f, 27.37f }, // bicycle01a.phy
|
||||
{ 25.46f, 8.34f, 17.13f }, // furnituretable001a.phy
|
||||
{ 12.65f, 6.02f, 6.62f }, // gravestone003a.phy
|
||||
{ 40.58f, 16.49f, 24.10f }, // combineinnerwall001a.phy
|
||||
};
|
||||
|
||||
const float g_TotalBaseline = 157.38f;
|
||||
|
||||
/*
|
||||
Benchmark models\props_c17\bench01a.phy!
|
||||
|
||||
33.90 ms [1.20 X] 2500/2500 hits
|
||||
8.95 ms rays [1.19 X] 24.95 ms boxes [1.20 X]
|
||||
Benchmark models\props_junk\bicycle01a.phy!
|
||||
|
||||
30.55 ms [1.25 X] 803/2500 hits
|
||||
8.96 ms rays [1.20 X] 21.59 ms boxes [1.27 X]
|
||||
Benchmark models\props_c17\furnituretable001a.phy!
|
||||
|
||||
20.61 ms [1.24 X] 755/2500 hits
|
||||
6.88 ms rays [1.21 X] 13.73 ms boxes [1.25 X]
|
||||
Benchmark models\props_c17\gravestone003a.phy!
|
||||
|
||||
9.13 ms [1.39 X] 2500/2500 hits
|
||||
4.34 ms rays [1.39 X] 4.79 ms boxes [1.38 X]
|
||||
Benchmark models\props_combine\combineinnerwall001a.phy!
|
||||
|
||||
33.04 ms [1.23 X] 985/2500 hits
|
||||
13.37 ms rays [1.23 X] 19.67 ms boxes [1.23 X]
|
||||
|
||||
127.22s total [1.24 X]!
|
||||
*/
|
||||
|
||||
#define IMPROVEMENT_FACTOR(x,baseline) (baseline/(x))
|
||||
#define IMPROVEMENT_PERCENT(x,baseline) (((baseline-(x)) / baseline) * 100.0f)
|
||||
#include <windows.h>
|
||||
//-----------------------------------------------------------------------------
|
||||
// The application object
|
||||
//-----------------------------------------------------------------------------
|
||||
int CBenchmarkApp::Main()
|
||||
{
|
||||
const char *pFileNames[] =
|
||||
{
|
||||
"models\\props_c17\\bench01a.phy",
|
||||
"models\\props_junk\\bicycle01a.phy",
|
||||
"models\\props_c17\\furnituretable001a.phy",
|
||||
"models\\props_c17\\gravestone003a.phy",
|
||||
"models\\props_combine\\combineinnerwall001a.phy",
|
||||
};
|
||||
vcollide_t testModels[ARRAYSIZE(pFileNames)];
|
||||
for ( int i = 0; i < ARRAYSIZE(pFileNames); i++ )
|
||||
{
|
||||
ReadPHYFile( pFileNames[i], testModels[i] );
|
||||
}
|
||||
SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS );
|
||||
SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_HIGHEST );
|
||||
float totalTime = 0.0f;
|
||||
int loopCount = ARRAYSIZE(pFileNames);
|
||||
#if VPROF_LEVEL > 0
|
||||
// loopCount = 3;
|
||||
#endif
|
||||
for ( int i = 0; i < loopCount; i++ )
|
||||
{
|
||||
if ( testModels[i].solidCount < 1 )
|
||||
{
|
||||
Msg("Failed to load %s, skipping test!\n", pFileNames[i] );
|
||||
continue;
|
||||
}
|
||||
Msg("Benchmark %s!\n\n", pFileNames[i] );
|
||||
|
||||
benchresults_t results;
|
||||
memset( &results, 0, sizeof(results));
|
||||
int numRepeats = 3;
|
||||
#if VPROF_LEVEL > 0
|
||||
numRepeats = 1;
|
||||
#endif
|
||||
for ( int j = 0; j < numRepeats; j++ )
|
||||
{
|
||||
Benchmark_PHY( testModels[i].solids[0], &results );
|
||||
}
|
||||
Msg("%.2f ms [%.2f X] %d/%d hits\n", results.totalTime, IMPROVEMENT_FACTOR(results.totalTime, g_Baselines[i].total), results.collisionHits, results.collisionTests);
|
||||
Msg("%.2f ms rays \t[%.2f X] \t%.2f ms boxes [%.2f X]\n",
|
||||
results.rayTime, IMPROVEMENT_FACTOR(results.rayTime, g_Baselines[i].ray),
|
||||
results.boxTime, IMPROVEMENT_FACTOR(results.boxTime, g_Baselines[i].box));
|
||||
totalTime += results.totalTime;
|
||||
}
|
||||
SetPriorityClass( GetCurrentProcess(), NORMAL_PRIORITY_CLASS );
|
||||
|
||||
Msg("\n%.2fs total \t[%.2f X]!\n", totalTime, IMPROVEMENT_FACTOR(totalTime, g_TotalBaseline) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,43 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// VBSP.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE,..\common,..\vmpi"
|
||||
$PreprocessorDefinitions "$BASE;MACRO_MATHLIB;PROTECTED_THINGS_DISABLE"
|
||||
$FloatingPointModel "Precise (/fp:precise)"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "traceperf"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "stdafx.cpp"
|
||||
$File "traceperf.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "stdafx.h"
|
||||
$File "$SRCDIR\public\vphysics_interface.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib appframework
|
||||
$Lib mathlib
|
||||
$Lib tier2
|
||||
$Lib tier3
|
||||
}
|
||||
}
|
@ -1,940 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
|
||||
#include "vcollide_parse_private.h"
|
||||
|
||||
#include "tier1/strtools.h"
|
||||
#include "vphysics/constraints.h"
|
||||
#include "vphysics/vehicles.h"
|
||||
#include "filesystem_helpers.h"
|
||||
#include "bspfile.h"
|
||||
#include "utlbuffer.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
static void ReadVector( const char *pString, Vector& out )
|
||||
{
|
||||
float x, y, z;
|
||||
sscanf( pString, "%f %f %f", &x, &y, &z );
|
||||
out[0] = x;
|
||||
out[1] = y;
|
||||
out[2] = z;
|
||||
}
|
||||
|
||||
static void ReadAngles( const char *pString, QAngle& out )
|
||||
{
|
||||
float x, y, z;
|
||||
sscanf( pString, "%f %f %f", &x, &y, &z );
|
||||
out[0] = x;
|
||||
out[1] = y;
|
||||
out[2] = z;
|
||||
}
|
||||
|
||||
static void ReadVector4D( const char *pString, Vector4D& out )
|
||||
{
|
||||
float x, y, z, w;
|
||||
sscanf( pString, "%f %f %f %f", &x, &y, &z, &w );
|
||||
out[0] = x;
|
||||
out[1] = y;
|
||||
out[2] = z;
|
||||
out[3] = w;
|
||||
}
|
||||
|
||||
class CVPhysicsParse : public IVPhysicsKeyParser
|
||||
{
|
||||
public:
|
||||
~CVPhysicsParse() {}
|
||||
|
||||
CVPhysicsParse( const char *pKeyData );
|
||||
void NextBlock( void );
|
||||
|
||||
const char *GetCurrentBlockName( void );
|
||||
bool Finished( void );
|
||||
void ParseSolid( solid_t *pSolid, IVPhysicsKeyHandler *unknownKeyHandler );
|
||||
void ParseFluid( fluid_t *pFluid, IVPhysicsKeyHandler *unknownKeyHandler );
|
||||
void ParseRagdollConstraint( constraint_ragdollparams_t *pConstraint, IVPhysicsKeyHandler *unknownKeyHandler );
|
||||
void ParseSurfaceTable( int *table, IVPhysicsKeyHandler *unknownKeyHandler );
|
||||
void ParseSurfaceTablePacked( CUtlVector<char> &out );
|
||||
void ParseVehicle( vehicleparams_t *pVehicle, IVPhysicsKeyHandler *unknownKeyHandler );
|
||||
void ParseCustom( void *pCustom, IVPhysicsKeyHandler *unknownKeyHandler );
|
||||
void SkipBlock( void ) { ParseCustom(NULL, NULL); }
|
||||
|
||||
private:
|
||||
void ParseVehicleAxle( vehicle_axleparams_t &axle );
|
||||
void ParseVehicleWheel( vehicle_wheelparams_t &wheel );
|
||||
void ParseVehicleSuspension( vehicle_suspensionparams_t &suspension );
|
||||
void ParseVehicleBody( vehicle_bodyparams_t &body );
|
||||
void ParseVehicleEngine( vehicle_engineparams_t &engine );
|
||||
void ParseVehicleEngineBoost( vehicle_engineparams_t &engine );
|
||||
void ParseVehicleSteering( vehicle_steeringparams_t &steering );
|
||||
|
||||
const char *m_pText;
|
||||
char m_blockName[MAX_KEYVALUE];
|
||||
};
|
||||
|
||||
|
||||
CVPhysicsParse::CVPhysicsParse( const char *pKeyData )
|
||||
{
|
||||
m_pText = pKeyData;
|
||||
NextBlock();
|
||||
}
|
||||
|
||||
void CVPhysicsParse::NextBlock( void )
|
||||
{
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
while ( m_pText )
|
||||
{
|
||||
m_pText = ParseKeyvalue( m_pText, key, value );
|
||||
if ( !Q_strcmp(value, "{") )
|
||||
{
|
||||
V_strcpy_safe( m_blockName, key );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure m_blockName is initialized -- should this be done?
|
||||
m_blockName[ 0 ] = 0;
|
||||
}
|
||||
|
||||
|
||||
const char *CVPhysicsParse::GetCurrentBlockName( void )
|
||||
{
|
||||
if ( m_pText )
|
||||
return m_blockName;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool CVPhysicsParse::Finished( void )
|
||||
{
|
||||
if ( m_pText )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CVPhysicsParse::ParseSolid( solid_t *pSolid, IVPhysicsKeyHandler *unknownKeyHandler )
|
||||
{
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
key[0] = 0;
|
||||
|
||||
if ( unknownKeyHandler )
|
||||
{
|
||||
unknownKeyHandler->SetDefaults( pSolid );
|
||||
}
|
||||
else
|
||||
{
|
||||
memset( pSolid, 0, sizeof(*pSolid) );
|
||||
}
|
||||
|
||||
// disable these until the ragdoll is created
|
||||
pSolid->params.enableCollisions = false;
|
||||
|
||||
while ( m_pText )
|
||||
{
|
||||
m_pText = ParseKeyvalue( m_pText, key, value );
|
||||
if ( key[0] == '}' )
|
||||
{
|
||||
NextBlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( key, "index" ) )
|
||||
{
|
||||
pSolid->index = atoi(value);
|
||||
}
|
||||
else if ( !Q_stricmp( key, "name" ) )
|
||||
{
|
||||
Q_strncpy( pSolid->name, value, sizeof(pSolid->name) );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "parent" ) )
|
||||
{
|
||||
Q_strncpy( pSolid->parent, value, sizeof(pSolid->parent) );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "surfaceprop" ) )
|
||||
{
|
||||
Q_strncpy( pSolid->surfaceprop, value, sizeof(pSolid->surfaceprop) );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "mass" ) )
|
||||
{
|
||||
pSolid->params.mass = atof(value);
|
||||
}
|
||||
else if ( !Q_stricmp( key, "massCenterOverride" ) )
|
||||
{
|
||||
ReadVector( value, pSolid->massCenterOverride );
|
||||
pSolid->params.massCenterOverride = &pSolid->massCenterOverride;
|
||||
}
|
||||
else if ( !Q_stricmp( key, "inertia" ) )
|
||||
{
|
||||
pSolid->params.inertia = atof(value);
|
||||
}
|
||||
else if ( !Q_stricmp( key, "damping" ) )
|
||||
{
|
||||
pSolid->params.damping = atof(value);
|
||||
}
|
||||
else if ( !Q_stricmp( key, "rotdamping" ) )
|
||||
{
|
||||
pSolid->params.rotdamping = atof(value);
|
||||
}
|
||||
else if ( !Q_stricmp( key, "volume" ) )
|
||||
{
|
||||
pSolid->params.volume = atof(value);
|
||||
}
|
||||
else if ( !Q_stricmp( key, "drag" ) )
|
||||
{
|
||||
pSolid->params.dragCoefficient = atof(value);
|
||||
}
|
||||
else if ( !Q_stricmp( key, "rollingdrag" ) )
|
||||
{
|
||||
//pSolid->params.rollingDrag = atof(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( unknownKeyHandler )
|
||||
{
|
||||
unknownKeyHandler->ParseKeyValue( pSolid, key, value );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVPhysicsParse::ParseRagdollConstraint( constraint_ragdollparams_t *pConstraint, IVPhysicsKeyHandler *unknownKeyHandler )
|
||||
{
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
|
||||
key[0] = 0;
|
||||
if ( unknownKeyHandler )
|
||||
{
|
||||
unknownKeyHandler->SetDefaults( pConstraint );
|
||||
}
|
||||
else
|
||||
{
|
||||
memset( pConstraint, 0, sizeof(*pConstraint) );
|
||||
pConstraint->childIndex = -1;
|
||||
pConstraint->parentIndex = -1;
|
||||
}
|
||||
|
||||
// BUGBUG: xmin/xmax, ymin/ymax, zmin/zmax specify clockwise rotations.
|
||||
// BUGBUG: HL rotations are counter-clockwise, so reverse these limits at some point!!!
|
||||
pConstraint->useClockwiseRotations = true;
|
||||
|
||||
while ( m_pText )
|
||||
{
|
||||
m_pText = ParseKeyvalue( m_pText, key, value );
|
||||
if ( key[0] == '}' )
|
||||
{
|
||||
NextBlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( key, "parent" ) )
|
||||
{
|
||||
pConstraint->parentIndex = atoi( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "child" ) )
|
||||
{
|
||||
pConstraint->childIndex = atoi( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "xmin" ) )
|
||||
{
|
||||
pConstraint->axes[0].minRotation = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "xmax" ) )
|
||||
{
|
||||
pConstraint->axes[0].maxRotation = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "xfriction" ) )
|
||||
{
|
||||
pConstraint->axes[0].angularVelocity = 0;
|
||||
pConstraint->axes[0].torque = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "ymin" ) )
|
||||
{
|
||||
pConstraint->axes[1].minRotation = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "ymax" ) )
|
||||
{
|
||||
pConstraint->axes[1].maxRotation = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "yfriction" ) )
|
||||
{
|
||||
pConstraint->axes[1].angularVelocity = 0;
|
||||
pConstraint->axes[1].torque = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "zmin" ) )
|
||||
{
|
||||
pConstraint->axes[2].minRotation = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "zmax" ) )
|
||||
{
|
||||
pConstraint->axes[2].maxRotation = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "zfriction" ) )
|
||||
{
|
||||
pConstraint->axes[2].angularVelocity = 0;
|
||||
pConstraint->axes[2].torque = atof( value );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( unknownKeyHandler )
|
||||
{
|
||||
unknownKeyHandler->ParseKeyValue( pConstraint, key, value );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CVPhysicsParse::ParseFluid( fluid_t *pFluid, IVPhysicsKeyHandler *unknownKeyHandler )
|
||||
{
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
|
||||
key[0] = 0;
|
||||
pFluid->index = -1;
|
||||
if ( unknownKeyHandler )
|
||||
{
|
||||
unknownKeyHandler->SetDefaults( pFluid );
|
||||
}
|
||||
else
|
||||
{
|
||||
memset( pFluid, 0, sizeof(*pFluid) );
|
||||
// HACKHACK: This is a reasonable default even though it is hardcoded
|
||||
V_strcpy_safe( pFluid->surfaceprop, "water" );
|
||||
}
|
||||
|
||||
while ( m_pText )
|
||||
{
|
||||
m_pText = ParseKeyvalue( m_pText, key, value );
|
||||
if ( key[0] == '}' )
|
||||
{
|
||||
NextBlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( key, "index" ) )
|
||||
{
|
||||
pFluid->index = atoi( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "damping" ) )
|
||||
{
|
||||
pFluid->params.damping = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "surfaceplane" ) )
|
||||
{
|
||||
ReadVector4D( value, pFluid->params.surfacePlane );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "currentvelocity" ) )
|
||||
{
|
||||
ReadVector( value, pFluid->params.currentVelocity );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "contents" ) )
|
||||
{
|
||||
pFluid->params.contents = atoi( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "surfaceprop" ) )
|
||||
{
|
||||
Q_strncpy( pFluid->surfaceprop, value, sizeof(pFluid->surfaceprop) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( unknownKeyHandler )
|
||||
{
|
||||
unknownKeyHandler->ParseKeyValue( pFluid, key, value );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVPhysicsParse::ParseSurfaceTable( int *table, IVPhysicsKeyHandler *unknownKeyHandler )
|
||||
{
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
|
||||
key[0] = 0;
|
||||
while ( m_pText )
|
||||
{
|
||||
m_pText = ParseKeyvalue( m_pText, key, value );
|
||||
if ( key[0] == '}' )
|
||||
{
|
||||
NextBlock();
|
||||
return;
|
||||
}
|
||||
|
||||
int propIndex = physprops->GetSurfaceIndex( key );
|
||||
int tableIndex = atoi(value);
|
||||
if ( tableIndex >= 0 && tableIndex < 128 )
|
||||
{
|
||||
table[tableIndex] = propIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVPhysicsParse::ParseSurfaceTablePacked( CUtlVector<char> &out )
|
||||
{
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
|
||||
key[0] = 0;
|
||||
int lastIndex = 0;
|
||||
while ( m_pText )
|
||||
{
|
||||
m_pText = ParseKeyvalue( m_pText, key, value );
|
||||
if ( key[0] == '}' )
|
||||
{
|
||||
NextBlock();
|
||||
return;
|
||||
}
|
||||
|
||||
int len = Q_strlen( key );
|
||||
int outIndex = out.AddMultipleToTail( len + 1 );
|
||||
memcpy( &out[outIndex], key, len+1 );
|
||||
int tableIndex = atoi(value);
|
||||
Assert( tableIndex == lastIndex + 1);
|
||||
lastIndex = tableIndex;
|
||||
}
|
||||
}
|
||||
|
||||
void CVPhysicsParse::ParseVehicleAxle( vehicle_axleparams_t &axle )
|
||||
{
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
|
||||
memset( &axle, 0, sizeof(axle) );
|
||||
key[0] = 0;
|
||||
while ( m_pText )
|
||||
{
|
||||
m_pText = ParseKeyvalue( m_pText, key, value );
|
||||
if ( key[0] == '}' )
|
||||
return;
|
||||
|
||||
// parse subchunks
|
||||
if ( value[0] == '{' )
|
||||
{
|
||||
if ( !Q_stricmp( key, "wheel" ) )
|
||||
{
|
||||
ParseVehicleWheel( axle.wheels );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "suspension" ) )
|
||||
{
|
||||
ParseVehicleSuspension( axle.suspension );
|
||||
}
|
||||
else
|
||||
{
|
||||
SkipBlock();
|
||||
}
|
||||
}
|
||||
else if ( !Q_stricmp( key, "offset" ) )
|
||||
{
|
||||
ReadVector( value, axle.offset );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "wheeloffset" ) )
|
||||
{
|
||||
ReadVector( value, axle.wheelOffset );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "torquefactor" ) )
|
||||
{
|
||||
axle.torqueFactor = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "brakefactor" ) )
|
||||
{
|
||||
axle.brakeFactor = atof( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVPhysicsParse::ParseVehicleWheel( vehicle_wheelparams_t &wheel )
|
||||
{
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
|
||||
key[0] = 0;
|
||||
while ( m_pText )
|
||||
{
|
||||
m_pText = ParseKeyvalue( m_pText, key, value );
|
||||
if ( key[0] == '}' )
|
||||
return;
|
||||
|
||||
if ( !Q_stricmp( key, "radius" ) )
|
||||
{
|
||||
wheel.radius = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "mass" ) )
|
||||
{
|
||||
wheel.mass = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "inertia" ) )
|
||||
{
|
||||
wheel.inertia = atof(value);
|
||||
}
|
||||
else if ( !Q_stricmp( key, "damping" ) )
|
||||
{
|
||||
wheel.damping = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "rotdamping" ) )
|
||||
{
|
||||
wheel.rotdamping = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "frictionscale" ) )
|
||||
{
|
||||
wheel.frictionScale = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "material" ) )
|
||||
{
|
||||
wheel.materialIndex = physprops->GetSurfaceIndex( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "skidmaterial" ) )
|
||||
{
|
||||
wheel.skidMaterialIndex = physprops->GetSurfaceIndex( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "brakematerial" ) )
|
||||
{
|
||||
wheel.brakeMaterialIndex = physprops->GetSurfaceIndex( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CVPhysicsParse::ParseVehicleSuspension( vehicle_suspensionparams_t &suspension )
|
||||
{
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
|
||||
key[0] = 0;
|
||||
while ( m_pText )
|
||||
{
|
||||
m_pText = ParseKeyvalue( m_pText, key, value );
|
||||
if ( key[0] == '}' )
|
||||
return;
|
||||
|
||||
if ( !Q_stricmp( key, "springconstant" ) )
|
||||
{
|
||||
suspension.springConstant = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "springdamping" ) )
|
||||
{
|
||||
suspension.springDamping = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "stabilizerconstant" ) )
|
||||
{
|
||||
suspension.stabilizerConstant = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "springdampingcompression" ) )
|
||||
{
|
||||
suspension.springDampingCompression = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "maxbodyforce" ) )
|
||||
{
|
||||
suspension.maxBodyForce = atof( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CVPhysicsParse::ParseVehicleBody( vehicle_bodyparams_t &body )
|
||||
{
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
|
||||
key[0] = 0;
|
||||
while ( m_pText )
|
||||
{
|
||||
m_pText = ParseKeyvalue( m_pText, key, value );
|
||||
if ( key[0] == '}' )
|
||||
return;
|
||||
|
||||
if ( !Q_stricmp( key, "massCenterOverride" ) )
|
||||
{
|
||||
ReadVector( value, body.massCenterOverride );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "addgravity" ) )
|
||||
{
|
||||
body.addGravity = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "maxAngularVelocity" ) )
|
||||
{
|
||||
body.maxAngularVelocity = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "massOverride" ) )
|
||||
{
|
||||
body.massOverride = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "tiltforce" ) )
|
||||
{
|
||||
body.tiltForce = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "tiltforceheight" ) )
|
||||
{
|
||||
body.tiltForceHeight = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "countertorquefactor" ) )
|
||||
{
|
||||
body.counterTorqueFactor = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "keepuprighttorque" ) )
|
||||
{
|
||||
body.keepUprightTorque = atof( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CVPhysicsParse::ParseVehicleEngineBoost( vehicle_engineparams_t &engine )
|
||||
{
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
|
||||
key[0] = 0;
|
||||
while ( m_pText )
|
||||
{
|
||||
m_pText = ParseKeyvalue( m_pText, key, value );
|
||||
if ( key[0] == '}' )
|
||||
return;
|
||||
// parse subchunks
|
||||
if ( !Q_stricmp( key, "force" ) )
|
||||
{
|
||||
engine.boostForce = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "duration" ) )
|
||||
{
|
||||
engine.boostDuration = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "delay" ) )
|
||||
{
|
||||
engine.boostDelay = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "maxspeed" ) )
|
||||
{
|
||||
engine.boostMaxSpeed = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "torqueboost" ) )
|
||||
{
|
||||
engine.torqueBoost = atoi( value ) != 0 ? true : false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void CVPhysicsParse::ParseVehicleEngine( vehicle_engineparams_t &engine )
|
||||
{
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
|
||||
key[0] = 0;
|
||||
while ( m_pText )
|
||||
{
|
||||
m_pText = ParseKeyvalue( m_pText, key, value );
|
||||
if ( key[0] == '}' )
|
||||
return;
|
||||
// parse subchunks
|
||||
if ( value[0] == '{' )
|
||||
{
|
||||
if ( !Q_stricmp( key, "boost" ) )
|
||||
{
|
||||
ParseVehicleEngineBoost( engine );
|
||||
}
|
||||
else
|
||||
{
|
||||
SkipBlock();
|
||||
}
|
||||
}
|
||||
else if ( !Q_stricmp( key, "gear" ) )
|
||||
{
|
||||
// Protect against exploits/overruns
|
||||
if ( engine.gearCount < ARRAYSIZE(engine.gearRatio) )
|
||||
{
|
||||
engine.gearRatio[engine.gearCount] = atof( value );
|
||||
engine.gearCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( 0 );
|
||||
}
|
||||
}
|
||||
else if ( !Q_stricmp( key, "horsepower" ) )
|
||||
{
|
||||
engine.horsepower = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "maxSpeed" ) )
|
||||
{
|
||||
engine.maxSpeed = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "maxReverseSpeed" ) )
|
||||
{
|
||||
engine.maxRevSpeed = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "axleratio" ) )
|
||||
{
|
||||
engine.axleRatio = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "maxRPM" ) )
|
||||
{
|
||||
engine.maxRPM = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "throttleTime" ) )
|
||||
{
|
||||
engine.throttleTime = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "AutoTransmission" ) )
|
||||
{
|
||||
engine.isAutoTransmission = atoi( value ) != 0 ? true : false;
|
||||
}
|
||||
else if ( !Q_stricmp( key, "shiftUpRPM" ) )
|
||||
{
|
||||
engine.shiftUpRPM = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "shiftDownRPM" ) )
|
||||
{
|
||||
engine.shiftDownRPM = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "autobrakeSpeedGain" ) )
|
||||
{
|
||||
engine.autobrakeSpeedGain = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "autobrakeSpeedFactor" ) )
|
||||
{
|
||||
engine.autobrakeSpeedFactor = atof( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CVPhysicsParse::ParseVehicleSteering( vehicle_steeringparams_t &steering )
|
||||
{
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
|
||||
key[0] = 0;
|
||||
while ( m_pText )
|
||||
{
|
||||
m_pText = ParseKeyvalue( m_pText, key, value );
|
||||
if ( key[0] == '}' )
|
||||
return;
|
||||
// parse subchunks
|
||||
if ( !Q_stricmp( key, "degreesSlow" ) )
|
||||
{
|
||||
steering.degreesSlow = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "degreesFast" ) )
|
||||
{
|
||||
steering.degreesFast = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "degreesBoost" ) )
|
||||
{
|
||||
steering.degreesBoost = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "fastcarspeed" ) )
|
||||
{
|
||||
steering.speedFast = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "slowcarspeed" ) )
|
||||
{
|
||||
steering.speedSlow = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "slowsteeringrate" ) )
|
||||
{
|
||||
steering.steeringRateSlow = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "faststeeringrate" ) )
|
||||
{
|
||||
steering.steeringRateFast = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "steeringRestRateSlow" ) )
|
||||
{
|
||||
steering.steeringRestRateSlow = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "steeringRestRateFast" ) )
|
||||
{
|
||||
steering.steeringRestRateFast = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "throttleSteeringRestRateFactor" ) )
|
||||
{
|
||||
steering.throttleSteeringRestRateFactor = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "boostSteeringRestRateFactor" ) )
|
||||
{
|
||||
steering.boostSteeringRestRateFactor = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "boostSteeringRateFactor" ) )
|
||||
{
|
||||
steering.boostSteeringRateFactor = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "steeringExponent" ) )
|
||||
{
|
||||
steering.steeringExponent = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "turnThrottleReduceSlow" ) )
|
||||
{
|
||||
steering.turnThrottleReduceSlow = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "turnThrottleReduceFast" ) )
|
||||
{
|
||||
steering.turnThrottleReduceFast = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "brakeSteeringRateFactor" ) )
|
||||
{
|
||||
steering.brakeSteeringRateFactor = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "powerSlideAccel" ) )
|
||||
{
|
||||
steering.powerSlideAccel = atof( value );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "skidallowed" ) )
|
||||
{
|
||||
steering.isSkidAllowed = atoi( value ) != 0 ? true : false;
|
||||
}
|
||||
else if ( !Q_stricmp( key, "dustcloud" ) )
|
||||
{
|
||||
steering.dustCloud = atoi( value ) != 0 ? true : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVPhysicsParse::ParseVehicle( vehicleparams_t *pVehicle, IVPhysicsKeyHandler *unknownKeyHandler )
|
||||
{
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
|
||||
key[0] = 0;
|
||||
if ( unknownKeyHandler )
|
||||
{
|
||||
unknownKeyHandler->SetDefaults( pVehicle );
|
||||
}
|
||||
else
|
||||
{
|
||||
memset( pVehicle, 0, sizeof(*pVehicle) );
|
||||
}
|
||||
|
||||
while ( m_pText )
|
||||
{
|
||||
m_pText = ParseKeyvalue( m_pText, key, value );
|
||||
if ( key[0] == '}' )
|
||||
{
|
||||
NextBlock();
|
||||
return;
|
||||
}
|
||||
|
||||
// parse subchunks
|
||||
if ( value[0] == '{' )
|
||||
{
|
||||
if ( !Q_stricmp( key, "axle" ) )
|
||||
{
|
||||
// Protect against exploits/overruns
|
||||
if ( pVehicle->axleCount < ARRAYSIZE(pVehicle->axles) )
|
||||
{
|
||||
ParseVehicleAxle( pVehicle->axles[pVehicle->axleCount] );
|
||||
pVehicle->axleCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( 0 );
|
||||
}
|
||||
}
|
||||
else if ( !Q_stricmp( key, "body" ) )
|
||||
{
|
||||
ParseVehicleBody( pVehicle->body );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "engine" ) )
|
||||
{
|
||||
ParseVehicleEngine( pVehicle->engine );
|
||||
}
|
||||
else if ( !Q_stricmp( key, "steering" ) )
|
||||
{
|
||||
ParseVehicleSteering( pVehicle->steering );
|
||||
}
|
||||
else
|
||||
{
|
||||
SkipBlock();
|
||||
}
|
||||
}
|
||||
else if ( !Q_stricmp( key, "wheelsperaxle" ) )
|
||||
{
|
||||
pVehicle->wheelsPerAxle = atoi( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVPhysicsParse::ParseCustom( void *pCustom, IVPhysicsKeyHandler *unknownKeyHandler )
|
||||
{
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
|
||||
key[0] = 0;
|
||||
int indent = 0;
|
||||
if ( unknownKeyHandler )
|
||||
{
|
||||
unknownKeyHandler->SetDefaults( pCustom );
|
||||
}
|
||||
|
||||
while ( m_pText )
|
||||
{
|
||||
m_pText = ParseKeyvalue( m_pText, key, value );
|
||||
|
||||
if ( m_pText )
|
||||
{
|
||||
if ( key[0] == '{' )
|
||||
{
|
||||
indent++;
|
||||
}
|
||||
else if ( value[0] == '{' )
|
||||
{
|
||||
// They've got a named block here
|
||||
// Increase our indent, and let them parse the key
|
||||
indent++;
|
||||
if ( unknownKeyHandler )
|
||||
{
|
||||
unknownKeyHandler->ParseKeyValue( pCustom, key, value );
|
||||
}
|
||||
}
|
||||
else if ( key[0] == '}' )
|
||||
{
|
||||
indent--;
|
||||
if ( indent < 0 )
|
||||
{
|
||||
NextBlock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( unknownKeyHandler )
|
||||
{
|
||||
unknownKeyHandler->ParseKeyValue( pCustom, key, value );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IVPhysicsKeyParser *CreateVPhysicsKeyParser( const char *pKeyData )
|
||||
{
|
||||
return new CVPhysicsParse( pKeyData );
|
||||
}
|
||||
|
||||
void DestroyVPhysicsKeyParser( IVPhysicsKeyParser *pParser )
|
||||
{
|
||||
delete pParser;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper functions for parsing script file
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const char *ParseKeyvalue( const char *pBuffer, char (&key)[MAX_KEYVALUE], char (&value)[MAX_KEYVALUE] )
|
||||
{
|
||||
// Make sure value is always null-terminated.
|
||||
value[0] = 0;
|
||||
|
||||
pBuffer = ParseFile( pBuffer, key, NULL );
|
||||
|
||||
// no value on a close brace
|
||||
if ( key[0] == '}' && key[1] == 0 )
|
||||
{
|
||||
value[0] = 0;
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
Q_strlower( key );
|
||||
|
||||
pBuffer = ParseFile( pBuffer, value, NULL );
|
||||
|
||||
Q_strlower( value );
|
||||
|
||||
return pBuffer;
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef VCOLLIDE_PARSE_PRIVATE_H
|
||||
#define VCOLLIDE_PARSE_PRIVATE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "vcollide_parse.h"
|
||||
|
||||
#define MAX_KEYVALUE 1024
|
||||
|
||||
class IVPhysicsKeyParser;
|
||||
class CPackedPhysicsDescription;
|
||||
|
||||
const char *ParseKeyvalue( const char *pBuffer, OUT_Z_ARRAY char (&key)[MAX_KEYVALUE], OUT_Z_ARRAY char (&value)[MAX_KEYVALUE] );
|
||||
IVPhysicsKeyParser *CreateVPhysicsKeyParser( const char *pKeyData );
|
||||
void DestroyVPhysicsKeyParser( IVPhysicsKeyParser * );
|
||||
const char *PackVCollideText( IPhysicsCollision *physcollision, const char *pTextIn, int *pSizeOut, bool storeSolidNames, bool storeSurfacepropsAsNames );
|
||||
CPackedPhysicsDescription *CreatePackedDescription( const char *pPackedBuffer, int packedSize );
|
||||
void DestroyPackedDescription( CPackedPhysicsDescription *pPhysics );
|
||||
|
||||
#endif // VCOLLIDE_PARSE_PRIVATE_H
|
@ -1,136 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// VPHYSICS.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$macro SRCDIR ".."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE;.;$SRCDIR\ivp\ivp_intern;$SRCDIR\ivp\ivp_collision;$SRCDIR\ivp\ivp_physics;$SRCDIR\ivp\ivp_surface_manager;$SRCDIR\ivp\ivp_utility;$SRCDIR\ivp\ivp_controller;$SRCDIR\ivp\ivp_compact_builder;$SRCDIR\ivp\havana\havok;$SRCDIR\ivp\havana"
|
||||
$PreprocessorDefinitions "$BASE;VPHYSICS_EXPORTS;HAVANA_CONSTRAINTS;HAVOK_MOPP"
|
||||
$Create/UsePrecompiledHeader "Use Precompiled Header (/Yu)"
|
||||
$Create/UsePCHThroughFile "cbase.h"
|
||||
$PrecompiledHeaderFile "$(IntDir)\vphysics.pch"
|
||||
// Language
|
||||
$EnableRunTimeTypeInfo "No (/GR-)"
|
||||
}
|
||||
$Compiler [$WIN32]
|
||||
{
|
||||
$EnableEnhancedInstructionSet "Streaming SIMD Extensions (/arch:SSE)"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$AdditionalDependencies "$BASE odbc32.lib odbccp32.lib" [$WIN32]
|
||||
$SystemLibraries "iconv" [$OSXALL]
|
||||
}
|
||||
}
|
||||
|
||||
$Project "vphysics"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "stdafx.cpp"
|
||||
{
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$Create/UsePrecompiledHeader "Create Precompiled Header (/Yc)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$File "convert.cpp" \
|
||||
"$SRCDIR\public\filesystem_helpers.cpp"
|
||||
{
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$Create/UsePrecompiledHeader "Not Using Precompiled Headers"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$File "ledgewriter.cpp"
|
||||
$File "main.cpp"
|
||||
$File "physics_airboat.cpp"
|
||||
$File "physics_collide.cpp"
|
||||
$File "physics_constraint.cpp"
|
||||
$File "physics_controller_raycast_vehicle.cpp"
|
||||
$File "physics_environment.cpp"
|
||||
$File "physics_fluid.cpp"
|
||||
$File "physics_friction.cpp"
|
||||
$File "physics_material.cpp"
|
||||
$File "physics_motioncontroller.cpp"
|
||||
$File "physics_object.cpp"
|
||||
$File "physics_shadow.cpp"
|
||||
$File "physics_spring.cpp"
|
||||
$File "physics_vehicle.cpp"
|
||||
$File "physics_virtualmesh.cpp"
|
||||
$File "trace.cpp"
|
||||
$File "vcollide_parse.cpp"
|
||||
$File "vphysics_saverestore.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "cbase.h"
|
||||
$File "convert.h"
|
||||
$File "linear_solver.h"
|
||||
$File "physics_airboat.h"
|
||||
$File "physics_constraint.h"
|
||||
$File "physics_controller_raycast_vehicle.h"
|
||||
$File "physics_environment.h"
|
||||
$File "physics_fluid.h"
|
||||
$File "physics_friction.h"
|
||||
$File "physics_material.h"
|
||||
$File "physics_motioncontroller.h"
|
||||
$File "physics_object.h"
|
||||
$File "physics_shadow.h"
|
||||
$File "physics_spring.h"
|
||||
$File "physics_trace.h"
|
||||
$File "physics_vehicle.h"
|
||||
$File "vcollide_parse_private.h"
|
||||
$File "vphysics_internal.h"
|
||||
$File "vphysics_saverestore.h"
|
||||
}
|
||||
|
||||
$Folder "Public Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\vphysics\collision_set.h"
|
||||
$File "$SRCDIR\public\vphysics\constraints.h"
|
||||
$File "$SRCDIR\public\datamap.h"
|
||||
$File "$SRCDIR\public\filesystem_helpers.h"
|
||||
$File "$SRCDIR\public\vphysics\friction.h"
|
||||
$File "$SRCDIR\public\vphysics\object_hash.h"
|
||||
$File "$SRCDIR\public\vphysics\performance.h"
|
||||
$File "$SRCDIR\public\vphysics\player_controller.h"
|
||||
$File "$SRCDIR\public\vphysics\stats.h"
|
||||
$File "$SRCDIR\public\vcollide.h"
|
||||
$File "$SRCDIR\public\vcollide_parse.h"
|
||||
$File "$SRCDIR\public\vphysics\vehicles.h"
|
||||
$File "$SRCDIR\public\vphysics_interface.h"
|
||||
$File "$SRCDIR\public\vphysics_interfaceV30.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib "$LIBCOMMON/havana_constraints"
|
||||
$Lib "$LIBCOMMON/hk_base"
|
||||
$Lib "$LIBCOMMON/hk_math"
|
||||
$Lib "$LIBCOMMON/ivp_compactbuilder"
|
||||
$Lib "$LIBCOMMON/ivp_physics"
|
||||
$Lib mathlib
|
||||
$Lib tier2
|
||||
}
|
||||
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef VPHYSICS_INTERNAL_H
|
||||
#define VPHYSICS_INTERNAL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier0/memalloc.h"
|
||||
|
||||
extern class IPhysics *g_PhysicsInternal;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Memory debugging
|
||||
//-----------------------------------------------------------------------------
|
||||
#if defined(_DEBUG) || defined(USE_MEM_DEBUG)
|
||||
#define BEGIN_IVP_ALLOCATION() MemAlloc_PushAllocDbgInfo("IVP: " __FILE__ , __LINE__ )
|
||||
#define END_IVP_ALLOCATION() MemAlloc_PopAllocDbgInfo()
|
||||
#else
|
||||
#define BEGIN_IVP_ALLOCATION() 0
|
||||
#define END_IVP_ALLOCATION() 0
|
||||
#endif
|
||||
|
||||
|
||||
#endif // VPHYSICS_INTERNAL_H
|
@ -1,224 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Phys pointer association
|
||||
//-----------------------------------------------------------------------------
|
||||
static CUtlMap<void *, void *> s_VPhysPtrMap( 0, 0, DefLessFunc(void *) );
|
||||
|
||||
|
||||
CVPhysPtrSaveRestoreOps g_VPhysPtrSaveRestoreOps;
|
||||
CVPhysPtrUtlVectorSaveRestoreOps g_VPhysPtrUtlVectorSaveRestoreOps;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Phys pointer association
|
||||
//-----------------------------------------------------------------------------
|
||||
static void AddPtrAssociation( void *pOldValue, void *pNewValue )
|
||||
{
|
||||
s_VPhysPtrMap.Insert( pOldValue, pNewValue );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Save/load part of CPhysicsEnvironment
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool NoPhysSaveFunc( const physsaveparams_t ¶ms, void * )
|
||||
{
|
||||
AssertMsg( 0, "Physics cannot save the specified type" );
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CPhysicsEnvironment::Save( const physsaveparams_t ¶ms )
|
||||
{
|
||||
const PhysInterfaceId_t type = params.type;
|
||||
Assert( type >= 0 && type < PIID_NUM_TYPES );
|
||||
|
||||
static PhysSaveFunc_t saveFuncs[PIID_NUM_TYPES] =
|
||||
{
|
||||
NoPhysSaveFunc,
|
||||
(PhysSaveFunc_t)SavePhysicsObject,
|
||||
(PhysSaveFunc_t)SavePhysicsFluidController,
|
||||
(PhysSaveFunc_t)SavePhysicsSpring,
|
||||
(PhysSaveFunc_t)SavePhysicsConstraintGroup,
|
||||
(PhysSaveFunc_t)SavePhysicsConstraint,
|
||||
(PhysSaveFunc_t)SavePhysicsShadowController,
|
||||
(PhysSaveFunc_t)SavePhysicsPlayerController,
|
||||
(PhysSaveFunc_t)SavePhysicsMotionController,
|
||||
(PhysSaveFunc_t)SavePhysicsVehicleController,
|
||||
};
|
||||
|
||||
if ( type >= 0 && type < PIID_NUM_TYPES )
|
||||
{
|
||||
params.pSave->WriteData( (char *)¶ms.pObject, sizeof(void*) );
|
||||
return (*saveFuncs[type])( params, params.pObject );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool NoPhysRestoreFunc( const physrestoreparams_t ¶ms, void ** )
|
||||
{
|
||||
AssertMsg( 0, "Physics cannot save the specified type" );
|
||||
return false;
|
||||
}
|
||||
|
||||
CVPhysPtrSaveRestoreOps::CVPhysPtrSaveRestoreOps()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CPhysicsEnvironment::PreRestore( const physprerestoreparams_t ¶ms )
|
||||
{
|
||||
g_VPhysPtrSaveRestoreOps.PreRestore();
|
||||
for ( int i = 0; i < params.recreatedObjectCount; i++ )
|
||||
{
|
||||
AddPtrAssociation( params.recreatedObjectList[i].pOldObject, params.recreatedObjectList[i].pNewObject );
|
||||
}
|
||||
}
|
||||
|
||||
bool CPhysicsEnvironment::Restore( const physrestoreparams_t ¶ms )
|
||||
{
|
||||
const PhysInterfaceId_t type = params.type;
|
||||
Assert( type >= 0 && type < PIID_NUM_TYPES );
|
||||
|
||||
static PhysRestoreFunc_t restoreFuncs[PIID_NUM_TYPES] =
|
||||
{
|
||||
NoPhysRestoreFunc,
|
||||
(PhysRestoreFunc_t)RestorePhysicsObject,
|
||||
(PhysRestoreFunc_t)RestorePhysicsFluidController,
|
||||
(PhysRestoreFunc_t)RestorePhysicsSpring,
|
||||
(PhysRestoreFunc_t)RestorePhysicsConstraintGroup,
|
||||
(PhysRestoreFunc_t)RestorePhysicsConstraint,
|
||||
(PhysRestoreFunc_t)RestorePhysicsShadowController,
|
||||
(PhysRestoreFunc_t)RestorePhysicsPlayerController,
|
||||
(PhysRestoreFunc_t)RestorePhysicsMotionController,
|
||||
(PhysRestoreFunc_t)RestorePhysicsVehicleController,
|
||||
};
|
||||
|
||||
if ( type >= 0 && type < PIID_NUM_TYPES )
|
||||
{
|
||||
void *pOldObject;
|
||||
params.pRestore->ReadData( (char *)&pOldObject, sizeof(void*), 0 );
|
||||
if ( (*restoreFuncs[type])( params, params.ppObject ) )
|
||||
{
|
||||
AddPtrAssociation( pOldObject, *params.ppObject );
|
||||
if ( type == PIID_IPHYSICSOBJECT )
|
||||
{
|
||||
m_objects.AddToTail( (IPhysicsObject *)(*params.ppObject) );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CPhysicsEnvironment::PostRestore()
|
||||
{
|
||||
g_VPhysPtrSaveRestoreOps.PostRestore();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Fixes up pointers beteween vphysics objects
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void CVPhysPtrSaveRestoreOps::Save( const SaveRestoreFieldInfo_t &fieldInfo, ISave *pSave )
|
||||
{
|
||||
char *pField = (char *)fieldInfo.pField;
|
||||
int nObjects = fieldInfo.pTypeDesc->fieldSize;
|
||||
for ( int i = 0; i < nObjects; i++ )
|
||||
{
|
||||
pSave->WriteData( (char*)pField, sizeof(void*) );
|
||||
pField += sizeof(void*);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void CVPhysPtrSaveRestoreOps::PreRestore()
|
||||
{
|
||||
Assert( s_VPhysPtrMap.Count() == 0 );
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void CVPhysPtrSaveRestoreOps::Restore( const SaveRestoreFieldInfo_t &fieldInfo, IRestore *pRestore )
|
||||
{
|
||||
void **ppField = (void **)fieldInfo.pField;
|
||||
int nObjects = fieldInfo.pTypeDesc->fieldSize;
|
||||
|
||||
for ( int i = 0; i < nObjects; i++ )
|
||||
{
|
||||
pRestore->ReadData( (char *)ppField, sizeof(void*), 0 );
|
||||
|
||||
int iNewVal = s_VPhysPtrMap.Find( *ppField );
|
||||
if ( iNewVal != s_VPhysPtrMap.InvalidIndex() )
|
||||
{
|
||||
*ppField = s_VPhysPtrMap[iNewVal];
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppField = NULL;
|
||||
}
|
||||
|
||||
++ppField;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void CVPhysPtrSaveRestoreOps::PostRestore()
|
||||
{
|
||||
s_VPhysPtrMap.RemoveAll();
|
||||
PostRestorePhysicsObject();
|
||||
PostRestorePhysicsConstraintGroup();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void CVPhysPtrUtlVectorSaveRestoreOps::Save( const SaveRestoreFieldInfo_t &fieldInfo, ISave *pSave )
|
||||
{
|
||||
Assert( fieldInfo.pTypeDesc->fieldSize == 1 );
|
||||
|
||||
VPhysPtrVector *pUtlVector = (VPhysPtrVector*)fieldInfo.pField;
|
||||
int nObjects = pUtlVector->Count();
|
||||
|
||||
pSave->WriteInt( &nObjects );
|
||||
for ( int i = 0; i < nObjects; i++ )
|
||||
{
|
||||
pSave->WriteData( (char*)&pUtlVector->Element(i), sizeof(void*) );
|
||||
}
|
||||
}
|
||||
|
||||
void CVPhysPtrUtlVectorSaveRestoreOps::Restore( const SaveRestoreFieldInfo_t &fieldInfo, IRestore *pRestore )
|
||||
{
|
||||
Assert( fieldInfo.pTypeDesc->fieldSize == 1 );
|
||||
|
||||
VPhysPtrVector *pUtlVector = (VPhysPtrVector*)fieldInfo.pField;
|
||||
|
||||
int nObjects;
|
||||
pRestore->ReadInt( &nObjects );
|
||||
pUtlVector->AddMultipleToTail( nObjects );
|
||||
for ( int i = 0; i < nObjects; i++ )
|
||||
{
|
||||
void **ppElem = (void**)(&pUtlVector->Element(i));
|
||||
pRestore->ReadData( (char *)ppElem, sizeof(void*), 0 );
|
||||
|
||||
int iNewVal = s_VPhysPtrMap.Find( *ppElem );
|
||||
if ( iNewVal != s_VPhysPtrMap.InvalidIndex() )
|
||||
{
|
||||
*ppElem = s_VPhysPtrMap[iNewVal];
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppElem = NULL;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef VPHYSICS_SAVERESTORE_H
|
||||
#define VPHYSICS_SAVERESTORE_H
|
||||
|
||||
#if defined( _WIN32 )
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "datamap.h"
|
||||
#include "utlmap.h"
|
||||
#include "isaverestore.h"
|
||||
#include "utlvector.h"
|
||||
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
class ISave;
|
||||
class IRestore;
|
||||
|
||||
class CPhysicsObject;
|
||||
class CPhysicsFluidController;
|
||||
class CPhysicsSpring;
|
||||
class CPhysicsConstraint;
|
||||
class CPhysicsConstraintGroup;
|
||||
class CShadowController;
|
||||
class CPlayerController;
|
||||
class CPhysicsMotionController;
|
||||
class CVehicleController;
|
||||
struct physsaveparams_t;
|
||||
struct physrestoreparams_t;
|
||||
class ISaveRestoreOps;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Fixes up pointers beteween vphysics objects
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CVPhysPtrSaveRestoreOps : public CDefSaveRestoreOps
|
||||
{
|
||||
public:
|
||||
CVPhysPtrSaveRestoreOps();
|
||||
void Save( const SaveRestoreFieldInfo_t &fieldInfo, ISave *pSave );
|
||||
void PreRestore();
|
||||
void PostRestore();
|
||||
void Restore( const SaveRestoreFieldInfo_t &fieldInfo, IRestore *pRestore );
|
||||
};
|
||||
|
||||
extern CVPhysPtrSaveRestoreOps g_VPhysPtrSaveRestoreOps;
|
||||
|
||||
#define DEFINE_VPHYSPTR(name) \
|
||||
{ FIELD_CUSTOM, #name, { offsetof(classNameTypedef,name), 0 }, 1, FTYPEDESC_SAVE, NULL, &g_VPhysPtrSaveRestoreOps, NULL }
|
||||
|
||||
#define DEFINE_VPHYSPTR_ARRAY(name,count) \
|
||||
{ FIELD_CUSTOM, #name, { offsetof(classNameTypedef,name), 0 }, count, FTYPEDESC_SAVE, NULL, &g_VPhysPtrSaveRestoreOps, NULL }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CVPhysPtrUtlVectorSaveRestoreOps : public CVPhysPtrSaveRestoreOps
|
||||
{
|
||||
public:
|
||||
void Save( const SaveRestoreFieldInfo_t &fieldInfo, ISave *pSave );
|
||||
void Restore( const SaveRestoreFieldInfo_t &fieldInfo, IRestore *pRestore );
|
||||
|
||||
private:
|
||||
typedef CUtlVector<intp> VPhysPtrVector;
|
||||
};
|
||||
|
||||
extern CVPhysPtrUtlVectorSaveRestoreOps g_VPhysPtrUtlVectorSaveRestoreOps;
|
||||
|
||||
#define DEFINE_VPHYSPTR_UTLVECTOR(name) \
|
||||
{ FIELD_CUSTOM, #name, { offsetof(classNameTypedef,name), 0 }, 1, FTYPEDESC_SAVE, NULL, &g_VPhysPtrUtlVectorSaveRestoreOps, NULL }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
typedef bool (*PhysSaveFunc_t)( const physsaveparams_t ¶ms, void *pCastedObject ); // second parameter for convenience
|
||||
typedef bool (*PhysRestoreFunc_t)( const physrestoreparams_t ¶ms, void **ppCastedObject );
|
||||
|
||||
bool SavePhysicsObject( const physsaveparams_t ¶ms, CPhysicsObject *pObject );
|
||||
bool RestorePhysicsObject( const physrestoreparams_t ¶ms, CPhysicsObject **ppObject );
|
||||
|
||||
bool SavePhysicsFluidController( const physsaveparams_t ¶ms, CPhysicsFluidController *pFluidObject );
|
||||
bool RestorePhysicsFluidController( const physrestoreparams_t ¶ms, CPhysicsFluidController **ppFluidObject );
|
||||
|
||||
bool SavePhysicsSpring( const physsaveparams_t ¶ms, CPhysicsSpring *pSpring );
|
||||
bool RestorePhysicsSpring( const physrestoreparams_t ¶ms, CPhysicsSpring **ppSpring );
|
||||
|
||||
bool SavePhysicsConstraint( const physsaveparams_t ¶ms, CPhysicsConstraint *pConstraint );
|
||||
bool RestorePhysicsConstraint( const physrestoreparams_t ¶ms, CPhysicsConstraint **ppConstraint );
|
||||
|
||||
bool SavePhysicsConstraintGroup( const physsaveparams_t ¶ms, CPhysicsConstraintGroup *pConstraintGroup );
|
||||
bool RestorePhysicsConstraintGroup( const physrestoreparams_t ¶ms, CPhysicsConstraintGroup **ppConstraintGroup );
|
||||
void PostRestorePhysicsConstraintGroup();
|
||||
|
||||
bool SavePhysicsShadowController( const physsaveparams_t ¶ms, IPhysicsShadowController *pShadowController );
|
||||
bool RestorePhysicsShadowController( const physrestoreparams_t ¶ms, IPhysicsShadowController **ppShadowController );
|
||||
bool RestorePhysicsShadowControllerInternal( const physrestoreparams_t ¶ms, IPhysicsShadowController **ppShadowController, CPhysicsObject *pObject );
|
||||
|
||||
bool SavePhysicsPlayerController( const physsaveparams_t ¶ms, CPlayerController *pPlayerController );
|
||||
bool RestorePhysicsPlayerController( const physrestoreparams_t ¶ms, CPlayerController **ppPlayerController );
|
||||
|
||||
bool SavePhysicsMotionController( const physsaveparams_t ¶ms, IPhysicsMotionController *pMotionController );
|
||||
bool RestorePhysicsMotionController( const physrestoreparams_t ¶ms, IPhysicsMotionController **ppMotionController );
|
||||
|
||||
bool SavePhysicsVehicleController( const physsaveparams_t ¶ms, CVehicleController *pVehicleController );
|
||||
bool RestorePhysicsVehicleController( const physrestoreparams_t ¶ms, CVehicleController **ppVehicleController );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ISaveRestoreOps* MaterialIndexDataOps();
|
||||
|
||||
#endif // VPHYSICS_SAVERESTORE_H
|
@ -1,95 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
from waflib import Utils
|
||||
import os
|
||||
|
||||
top = '.'
|
||||
PROJECT_NAME = 'vphysics'
|
||||
|
||||
def options(opt):
|
||||
# stub
|
||||
return
|
||||
|
||||
def configure(conf):
|
||||
conf.env.append_unique('DEFINES',[
|
||||
'VPHYSICS_EXPORTS',
|
||||
'HAVANA_CONSTRAINTS',
|
||||
'HAVOK_MOPP'
|
||||
])
|
||||
|
||||
conf.env.append_unique('LINKFLAGS', [
|
||||
# "-L/home/nillerusr/projects/PhysX/physx/install/linux/PhysX/bin/linux.clang/release/"
|
||||
"-L/home/nillerusr/projects/PhysX/physx/install/linux/PhysX/bin/linux.clang/debug/"
|
||||
])
|
||||
|
||||
conf.check(lib='PhysX_static_64', uselib_store='PHYSX')
|
||||
conf.check(lib='PhysXFoundation_static_64', uselib_store='PHYSX_FOUNDATION')
|
||||
conf.check(lib='PhysXCommon_static_64', uselib_store='PHYSX_COMMON')
|
||||
conf.check(lib='PhysXPvdSDK_static_64', uselib_store='PHYSX_PVD')
|
||||
conf.check(lib='PhysXExtensions_static_64', uselib_store='PHYSX_EXT')
|
||||
conf.check(lib='PhysXCooking_static_64', uselib_store='PHYSX_COOKING')
|
||||
|
||||
def build(bld):
|
||||
source = [
|
||||
'convert.cpp',
|
||||
'../public/filesystem_helpers.cpp',
|
||||
'ledgewriter.cpp',
|
||||
'main.cpp',
|
||||
'physics_airboat.cpp',
|
||||
'physics_collide.cpp',
|
||||
'physics_constraint.cpp',
|
||||
'physics_controller_raycast_vehicle.cpp',
|
||||
'physics_environment.cpp',
|
||||
'physics_fluid.cpp',
|
||||
'physics_friction.cpp',
|
||||
'physics_material.cpp',
|
||||
'physics_motioncontroller.cpp',
|
||||
'physics_object.cpp',
|
||||
'physics_shadow.cpp',
|
||||
'physics_spring.cpp',
|
||||
'physics_vehicle.cpp',
|
||||
'physics_virtualmesh.cpp',
|
||||
'trace.cpp',
|
||||
'vcollide_parse.cpp',
|
||||
'vphysics_saverestore.cpp',
|
||||
'../public/tier0/memoverride.cpp'
|
||||
]
|
||||
|
||||
includes = [
|
||||
'.',
|
||||
'../public',
|
||||
'../public/tier0',
|
||||
'../public/tier1',
|
||||
'../ivp/ivp_intern',
|
||||
'../ivp/ivp_collision',
|
||||
'../ivp/ivp_physics',
|
||||
'../ivp/ivp_surface_manager',
|
||||
'../ivp/ivp_utility',
|
||||
'../ivp/ivp_controller',
|
||||
'../ivp/ivp_compact_builder',
|
||||
'../ivp/havana/havok',
|
||||
'../ivp/havana',
|
||||
'/home/nillerusr/projects/PhysX/physx/install/linux/PhysX/include',
|
||||
'/home/nillerusr/projects/PhysX/physx/install/linux/PxShared/include'
|
||||
]
|
||||
|
||||
defines = []
|
||||
|
||||
libs = ['tier0','havana_constraints','hk_math','hk_base','ivp_compactbuilder','ivp_physics','tier1','tier2','vstdlib','mathlib', 'PHYSX', 'PHYSX_PVD', 'PHYSX_EXT', 'PHYSX_COOKING', 'PHYSX_FOUNDATION', 'PHYSX_COMMON']
|
||||
|
||||
install_path = bld.env.LIBDIR
|
||||
|
||||
bld.shlib(
|
||||
source = source,
|
||||
target = PROJECT_NAME,
|
||||
name = PROJECT_NAME,
|
||||
features = 'c cxx',
|
||||
includes = includes,
|
||||
defines = defines,
|
||||
use = libs,
|
||||
install_path = install_path,
|
||||
subsystem = bld.env.MSVC_SUBSYSTEM,
|
||||
idx = bld.get_taskgen_count()
|
||||
)
|
||||
|
@ -1,3 +0,0 @@
|
||||
LIBRARY vphysics_360.dll
|
||||
EXPORTS
|
||||
CreateInterface @1
|
66
wscript
66
wscript
@ -26,6 +26,21 @@ FC_CHECK='''extern "C" {
|
||||
int main() { return (int)FcInit(); }
|
||||
'''
|
||||
|
||||
CPP_64BIT_CHECK='''
|
||||
#define TEST(a) (sizeof(void*) == a ? 1 : -1)
|
||||
int g_Test[TEST(8)];
|
||||
|
||||
int main () { return 0; }
|
||||
'''
|
||||
|
||||
CPP_32BIT_CHECK='''
|
||||
#define TEST(a) (sizeof(void*) == a ? 1 : -1)
|
||||
int g_Test[TEST(4)];
|
||||
|
||||
int main () { return 0; }
|
||||
'''
|
||||
|
||||
|
||||
Context.Context.line_just = 55 # should fit for everything on 80x26
|
||||
|
||||
projects={
|
||||
@ -72,7 +87,7 @@ projects={
|
||||
'vgui2/vgui_surfacelib',
|
||||
'vguimatsurface',
|
||||
'video',
|
||||
'vphysics-physx',
|
||||
'vphysics',
|
||||
'vpklib',
|
||||
'vstdlib',
|
||||
'vtf',
|
||||
@ -125,6 +140,7 @@ projects={
|
||||
'tier1',
|
||||
'tier2',
|
||||
'tier3',
|
||||
'vgui2/vgui_controls',
|
||||
'vphysics',
|
||||
'vpklib',
|
||||
'vstdlib',
|
||||
@ -155,6 +171,11 @@ def get_taskgen_count(self):
|
||||
except: idx = 0 # don't set tg_idx_count to not increase counter
|
||||
return idx
|
||||
|
||||
@Configure.conf
|
||||
def run_test(self, fragment, msg):
|
||||
result = self.check_cxx(fragment=fragment, msg=msg, mandatory = False)
|
||||
return False if result == None else True
|
||||
|
||||
def define_platform(conf):
|
||||
conf.env.DEDICATED = conf.options.DEDICATED
|
||||
conf.env.TESTS = conf.options.TESTS
|
||||
@ -162,6 +183,12 @@ def define_platform(conf):
|
||||
conf.env.GL = conf.options.GL and not conf.options.TESTS and not conf.options.DEDICATED
|
||||
conf.env.OPUS = conf.options.OPUS
|
||||
|
||||
arch32 = conf.run_test(CPP_32BIT_CHECK, 'Testing 32bit support')
|
||||
arch64 = conf.run_test(CPP_64BIT_CHECK, 'Testing 64bit support')
|
||||
|
||||
if not (arch32 ^ arch64):
|
||||
conf.fatal('Your compiler sucks')
|
||||
|
||||
if conf.options.DEDICATED:
|
||||
conf.options.SDL = False
|
||||
conf.define('DEDICATED', 1)
|
||||
@ -186,7 +213,7 @@ def define_platform(conf):
|
||||
conf.env.SDL = 1
|
||||
conf.define('USE_SDL', 1)
|
||||
|
||||
if conf.options.ALLOW64:
|
||||
if arch64:
|
||||
conf.define('PLATFORM_64BITS', 1)
|
||||
|
||||
if conf.env.DEST_OS == 'linux':
|
||||
@ -252,11 +279,14 @@ def define_platform(conf):
|
||||
'NDEBUG'
|
||||
])
|
||||
|
||||
conf.define('GIT_COMMIT_HASH', conf.env.GIT_VERSION)
|
||||
|
||||
|
||||
def options(opt):
|
||||
grp = opt.add_option_group('Common options')
|
||||
|
||||
grp.add_option('-8', '--64bits', action = 'store_true', dest = 'ALLOW64', default = False,
|
||||
help = 'allow targetting 64-bit engine(Linux/Windows/OSX x86 only) [default: %default]')
|
||||
grp.add_option('-4', '--32bits', action = 'store_true', dest = 'TARGET32', default = False,
|
||||
help = 'allow targetting 32-bit engine(Linux/Windows/OSX x86 only) [default: %default]')
|
||||
|
||||
grp.add_option('-d', '--dedicated', action = 'store_true', dest = 'DEDICATED', default = False,
|
||||
help = 'build dedicated server [default: %default]')
|
||||
@ -302,7 +332,7 @@ def options(opt):
|
||||
def check_deps(conf):
|
||||
if conf.env.DEST_OS != 'win32':
|
||||
conf.check_cc(lib='dl', mandatory=False)
|
||||
conf.check_cc(lib='bz2', mandatory=False)
|
||||
conf.check_cc(lib='bz2', mandatory=True)
|
||||
conf.check_cc(lib='rt', mandatory=False)
|
||||
|
||||
if not conf.env.LIB_M: # HACK: already added in xcompile!
|
||||
@ -410,19 +440,24 @@ def configure(conf):
|
||||
# subsystem=bld.env.MSVC_SUBSYSTEM
|
||||
# TODO: wrapper around bld.stlib, bld.shlib and so on?
|
||||
conf.env.MSVC_SUBSYSTEM = 'WINDOWS,5.01'
|
||||
conf.env.MSVC_TARGETS = ['x86'] # explicitly request x86 target for MSVC
|
||||
if conf.options.ALLOW64:
|
||||
conf.env.MSVC_TARGETS = ['x64']
|
||||
conf.env.MSVC_TARGETS = ['x64'] # explicitly request x86 target for MSVC
|
||||
if conf.options.TARGET32:
|
||||
conf.env.MSVC_TARGETS = ['x86']
|
||||
|
||||
if sys.platform == 'win32':
|
||||
conf.load('msvc_pdb_ext msdev msvs')
|
||||
conf.load('subproject xcompile compiler_c compiler_cxx gitversion clang_compilation_database strip_on_install_v2 waf_unit_test enforce_pic')
|
||||
conf.load('msvc_pdb_ext msdev msvs msvcdeps')
|
||||
conf.load('subproject xcompile compiler_c compiler_cxx gccdeps gitversion clang_compilation_database strip_on_install_v2 waf_unit_test enforce_pic')
|
||||
if conf.env.DEST_OS == 'win32' and conf.env.DEST_CPU == 'amd64':
|
||||
conf.load('masm')
|
||||
elif conf.env.DEST_OS == 'darwin':
|
||||
conf.load('mm_hook')
|
||||
|
||||
conf.env.BIT32_MANDATORY = conf.options.TARGET32
|
||||
if conf.env.BIT32_MANDATORY:
|
||||
Logs.info('WARNING: will build engine for 32-bit target')
|
||||
conf.load('force_32bit')
|
||||
|
||||
define_platform(conf)
|
||||
conf.define('GIT_COMMIT_HASH', conf.env.GIT_VERSION)
|
||||
|
||||
if conf.env.TOGLES:
|
||||
projects['game'] += ['togles']
|
||||
@ -435,11 +470,6 @@ def configure(conf):
|
||||
if conf.options.OPUS or conf.env.DEST_OS == 'android':
|
||||
projects['game'] += ['engine/voice_codecs/opus']
|
||||
|
||||
conf.env.BIT32_MANDATORY = not conf.options.ALLOW64
|
||||
if conf.env.BIT32_MANDATORY:
|
||||
Logs.info('WARNING: will build engine for 32-bit target')
|
||||
conf.load('force_32bit')
|
||||
|
||||
if conf.options.DISABLE_WARNS:
|
||||
compiler_optional_flags = ['-w']
|
||||
else:
|
||||
@ -497,7 +527,7 @@ def configure(conf):
|
||||
flags += ['-fsigned-char']
|
||||
|
||||
if conf.env.DEST_CPU == 'arm':
|
||||
flags += ['-mfpu=neon-vfpv4']
|
||||
flags += ['-march=armv7-a', '-mfpu=neon-vfpv4']
|
||||
|
||||
if conf.env.DEST_OS == 'freebsd':
|
||||
linkflags += ['-lexecinfo']
|
||||
@ -521,11 +551,11 @@ def configure(conf):
|
||||
|
||||
if conf.options.BUILD_TYPE == 'debug':
|
||||
linkflags += [
|
||||
'/FORCE:MULTIPLE',
|
||||
'/INCREMENTAL:NO',
|
||||
'/NODEFAULTLIB:libc',
|
||||
'/NODEFAULTLIB:libcd',
|
||||
'/NODEFAULTLIB:libcmt',
|
||||
'/FORCE',
|
||||
'/LARGEADDRESSAWARE'
|
||||
]
|
||||
else:
|
||||
|
Loading…
Reference in New Issue
Block a user