mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 12:44:46 +00:00
218 lines
7.5 KiB
C++
218 lines
7.5 KiB
C++
//-----------------------------------------------------------------------------
|
|
// Copyright (c) 2012 GarageGames, LLC
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to
|
|
// deal in the Software without restriction, including without limitation the
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
// IN THE SOFTWARE.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "platform/platform.h"
|
|
#include "T3D/physics/physicsPlugin.h"
|
|
|
|
#include "console/console.h"
|
|
#include "console/engineAPI.h"
|
|
#include "console/consoleTypes.h"
|
|
#include "console/simSet.h"
|
|
#include "core/strings/stringFunctions.h"
|
|
#include "scene/sceneObject.h"
|
|
#include "scene/sceneManager.h"
|
|
#include "scene/sceneRenderState.h"
|
|
#include "T3D/physics/physicsObject.h"
|
|
#include "T3D/physics/physicsWorld.h"
|
|
#include "core/util/tNamedFactory.h"
|
|
|
|
PhysicsPlugin* PhysicsPlugin::smSingleton = NULL;
|
|
PhysicsResetSignal PhysicsPlugin::smPhysicsResetSignal;
|
|
bool PhysicsPlugin::smSinglePlayer = false;
|
|
U32 PhysicsPlugin::smThreadCount = 2;
|
|
bool PhysicsPlugin::smGpuAccelerationAllowed = false;
|
|
|
|
String PhysicsPlugin::smServerWorldName( "server" );
|
|
String PhysicsPlugin::smClientWorldName( "client" );
|
|
|
|
AFTER_MODULE_INIT( Sim )
|
|
{
|
|
Con::addVariable( "$Physics::isSinglePlayer", TypeBool, &PhysicsPlugin::smSinglePlayer,
|
|
"@brief Informs the physics simulation if only a single player exists.\n\n"
|
|
"If true, optimizations will be implemented to better cater to a single player environmnent.\n\n"
|
|
"@ingroup Physics\n");
|
|
Con::addVariable("$Physics::gpuAccelerationAllowed", TypeBool, &PhysicsPlugin::smGpuAccelerationAllowed,
|
|
"@brief Informs the physics plugin if it is allowed to use gpu acceleration.\n\n"
|
|
"Not all physics implemenations or gpus can support gpu acceleration, this simply informs the plugin if it is allowed to try and use it or not.\n\n"
|
|
"@ingroup Physics\n");
|
|
Con::addVariable( "$pref::Physics::threadCount", TypeS32, &PhysicsPlugin::smThreadCount,
|
|
"@brief Number of threads to use in a single pass of the physics engine.\n\n"
|
|
"Defaults to 2 if not set.\n\n"
|
|
"@ingroup Physics\n");
|
|
}
|
|
|
|
bool PhysicsPlugin::activate( const char *library )
|
|
{
|
|
// Cleanup any previous plugin.
|
|
if ( smSingleton )
|
|
{
|
|
smSingleton->destroyPlugin();
|
|
AssertFatal( smSingleton == NULL,
|
|
"PhysicsPlugin::activate - destroyPlugin didn't delete the plugin!" );
|
|
}
|
|
|
|
// Create it thru the factory.
|
|
PhysicsPlugin *plugin = NamedFactory<PhysicsPlugin>::create( library );
|
|
if ( !plugin )
|
|
{
|
|
// One last try... try the first available one.
|
|
plugin = NamedFactory<PhysicsPlugin>::create();
|
|
if ( !plugin )
|
|
return false;
|
|
}
|
|
|
|
smSingleton = plugin;
|
|
return true;
|
|
}
|
|
|
|
PhysicsPlugin::PhysicsPlugin()
|
|
{
|
|
mPhysicsCleanup = new SimSet();
|
|
mPhysicsCleanup->assignName( "PhysicsCleanupSet" );
|
|
mPhysicsCleanup->registerObject();
|
|
Sim::getRootGroup()->addObject( mPhysicsCleanup );
|
|
}
|
|
|
|
PhysicsPlugin::~PhysicsPlugin()
|
|
{
|
|
AssertFatal( smSingleton == this, "PhysicsPlugin::~PhysicsPlugin() - Wrong active plugin!" );
|
|
|
|
if ( mPhysicsCleanup )
|
|
mPhysicsCleanup->deleteObject();
|
|
|
|
smSingleton = NULL;
|
|
}
|
|
|
|
void PhysicsPlugin::enableDebugDraw( bool enabled )
|
|
{
|
|
if ( enabled )
|
|
SceneManager::getPostRenderSignal().notify( &PhysicsPlugin::_debugDraw );
|
|
else
|
|
SceneManager::getPostRenderSignal().remove( &PhysicsPlugin::_debugDraw );
|
|
|
|
_onDebugDrawEnabled( enabled );
|
|
}
|
|
|
|
void PhysicsPlugin::_debugDraw( SceneManager *graph, const SceneRenderState *state )
|
|
{
|
|
// We only debug draw in the diffuse pass if we have a physics object.
|
|
if ( !PHYSICSMGR || !state->isDiffusePass() )
|
|
return;
|
|
|
|
// Render the server by default... else the client.
|
|
PhysicsWorld *world = PHYSICSMGR->getWorld( smServerWorldName );
|
|
if ( !world )
|
|
world = PHYSICSMGR->getWorld( smClientWorldName );
|
|
|
|
if ( world )
|
|
world->onDebugDraw( state );
|
|
}
|
|
|
|
DefineEngineFunction( physicsPluginPresent, bool, (), , "physicsPluginPresent()"
|
|
"@brief Returns true if a physics plugin exists and is initialized.\n\n"
|
|
"@ingroup Physics" )
|
|
{
|
|
return PHYSICSMGR != NULL;
|
|
}
|
|
|
|
DefineEngineFunction( physicsInit, bool, (const char * library), ("default"), "physicsInit( [string library] )")
|
|
{
|
|
return PhysicsPlugin::activate( library );
|
|
}
|
|
|
|
DefineEngineFunction( physicsDestroy, void, (), , "physicsDestroy()")
|
|
{
|
|
if ( PHYSICSMGR )
|
|
PHYSICSMGR->destroyPlugin();
|
|
}
|
|
|
|
DefineEngineFunction( physicsInitWorld, bool, (const char * worldName), , "physicsInitWorld( String worldName )")
|
|
{
|
|
bool res = PHYSICSMGR && PHYSICSMGR->createWorld( String( worldName ) );
|
|
return res;
|
|
}
|
|
|
|
DefineEngineFunction( physicsDestroyWorld, void, (const char * worldName), , "physicsDestroyWorld( String worldName )")
|
|
{
|
|
if ( PHYSICSMGR )
|
|
PHYSICSMGR->destroyWorld( worldName );
|
|
}
|
|
|
|
|
|
// Control/query of the stop/started state
|
|
// of the currently running simulation.
|
|
DefineEngineFunction( physicsStartSimulation, void, (const char * worldName), , "physicsStartSimulation( String worldName )")
|
|
{
|
|
if ( PHYSICSMGR )
|
|
PHYSICSMGR->enableSimulation( String( worldName ), true );
|
|
}
|
|
|
|
DefineEngineFunction( physicsStopSimulation, void, (const char * worldName), , "physicsStopSimulation( String worldName )")
|
|
{
|
|
if ( PHYSICSMGR )
|
|
PHYSICSMGR->enableSimulation( String( worldName ), false );
|
|
}
|
|
|
|
DefineEngineFunction( physicsSimulationEnabled, bool, (), , "physicsStopSimulation( String worldName )")
|
|
{
|
|
return PHYSICSMGR && PHYSICSMGR->isSimulationEnabled();
|
|
}
|
|
|
|
// Used for slowing down time on the
|
|
// physics simulation, and for pausing/restarting
|
|
// the simulation.
|
|
DefineEngineFunction( physicsSetTimeScale, void, (F32 scale), , "physicsSetTimeScale( F32 scale )")
|
|
{
|
|
if ( PHYSICSMGR )
|
|
PHYSICSMGR->setTimeScale( scale );
|
|
}
|
|
|
|
// Get the currently set time scale.
|
|
DefineEngineFunction( physicsGetTimeScale, F32, (), , "physicsGetTimeScale()")
|
|
{
|
|
return PHYSICSMGR && PHYSICSMGR->getTimeScale();
|
|
}
|
|
|
|
// Used to send a signal to objects in the
|
|
// physics simulation that they should store
|
|
// their current state for later restoration,
|
|
// such as when the editor is closed.
|
|
DefineEngineFunction( physicsStoreState, void, (), , "physicsStoreState()")
|
|
{
|
|
PhysicsPlugin::getPhysicsResetSignal().trigger( PhysicsResetEvent_Store );
|
|
}
|
|
|
|
// Used to send a signal to objects in the
|
|
// physics simulation that they should restore
|
|
// their saved state, such as when the editor is opened.
|
|
DefineEngineFunction( physicsRestoreState, void, (), , "physicsRestoreState()")
|
|
{
|
|
if ( PHYSICSMGR )
|
|
PHYSICSMGR->reset();
|
|
}
|
|
|
|
DefineEngineFunction( physicsDebugDraw, void, (bool enable), , "physicsDebugDraw( bool enable )")
|
|
{
|
|
if ( PHYSICSMGR )
|
|
PHYSICSMGR->enableDebugDraw( enable );
|
|
}
|