Browse Source

Merge remote-tracking branch 'origin/master' into plString

Michael Hansen 13 years ago
parent
commit
77cd055a27
  1. 31
      Sources/Plasma/Apps/plClient/plClient.cpp
  2. 4
      Sources/Plasma/FeatureLib/pfPython/pyGlueHelpers.h
  3. 24
      Sources/Plasma/FeatureLib/pfPython/pyStatusLogGlue.cpp
  4. 7
      Sources/Plasma/PubUtilLib/plPhysX/plPXPhysical.cpp
  5. 56
      Sources/Plasma/PubUtilLib/plPhysX/plSimulationMgr.cpp
  6. 17
      Sources/Plasma/PubUtilLib/plPhysX/plSimulationMgr.h

31
Sources/Plasma/Apps/plClient/plClient.cpp

@ -1292,7 +1292,20 @@ void plClient::IProgressMgrCallbackProc(plOperationProgress * progress)
return; return;
fInstance->fMessagePumpProc(); fInstance->fMessagePumpProc();
fInstance->IDraw();
// HACK HACK HACK HACK!
// Yes, this is the ORIGINAL, EVIL famerate limit from plClient::IDraw (except I bumped it to 60fps)
// As it so happens, this callback is happening in the main resource loading thread
// Without this NASTY ASS HACK, we draw after loading every KO, which starves the loader.
// At some point, a better solution should be found... Like running the loader in a separate thread.
static float lastDrawTime;
static const float kMaxFrameRate = 1.f/60.f;
float currTime = (float) hsTimer::GetSeconds();
if ((currTime - lastDrawTime) > kMaxFrameRate)
{
fInstance->IDraw();
lastDrawTime = currTime;
}
} }
//============================================================================ //============================================================================
@ -1838,22 +1851,6 @@ hsBool plClient::IDrawProgress() {
hsBool plClient::IDraw() hsBool plClient::IDraw()
{ {
// Limit framerate
static float lastDrawTime;
static const float kMaxFrameRate = 1.f/30.f;
float currTime = (float) hsTimer::GetSeconds();
if (!fPipeline->IsDebugFlagSet(plPipeDbg::kFlagNVPerfHUD))
{
// If we're using NVPerfHUD to step through draw calls,
// We're going to have a frame delta of zero. In that
// case we need to draw no matter what, and we don't
// care as much about starving other threads because
// we're presumably just debugging a graphics glitch.
if ((currTime - lastDrawTime) < kMaxFrameRate)
return true;
}
lastDrawTime = currTime;
// If we're shutting down, don't attempt to draw. Doing so // If we're shutting down, don't attempt to draw. Doing so
// tends to cause a device reload each frame. // tends to cause a device reload each frame.
if (fDone) if (fDone)

4
Sources/Plasma/FeatureLib/pfPython/pyGlueHelpers.h

@ -45,8 +45,8 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include <Python.h> #include <Python.h>
// Useful string functions // Useful string functions
char* PyString_AsStringEx(PyObject*); char* PyString_AsStringEx(PyObject* obj);
inline bool PyString_CheckEx(PyObject*); bool PyString_CheckEx(PyObject* obj);
// A set of macros to take at least some of the tediousness out of creating straight python glue code // A set of macros to take at least some of the tediousness out of creating straight python glue code

24
Sources/Plasma/FeatureLib/pfPython/pyStatusLogGlue.cpp

@ -58,21 +58,31 @@ PYTHON_INIT_DEFINITION(ptStatusLog, args, keywords)
PYTHON_METHOD_DEFINITION(ptStatusLog, open, args) PYTHON_METHOD_DEFINITION(ptStatusLog, open, args)
{ {
char* logName; PyObject* logName;
unsigned long numLines, flags; unsigned long numLines, flags;
if (!PyArg_ParseTuple(args, "sll", &logName, &numLines, &flags)) if (!PyArg_ParseTuple(args, "Oll", &logName, &numLines, &flags))
{ {
PyErr_SetString(PyExc_TypeError, "open expects a string and two unsigned longs"); PyErr_SetString(PyExc_TypeError, "open expects a string and two unsigned longs");
PYTHON_RETURN_ERROR; PYTHON_RETURN_ERROR;
} }
PYTHON_RETURN_BOOL(self->fThis->Open(logName, numLines, flags)); if (!PyString_CheckEx(logName))
{
PyErr_SetString(PyExc_TypeError, "open expects a string and two unsigned longs");
PYTHON_RETURN_ERROR;
}
PYTHON_RETURN_BOOL(self->fThis->Open(PyString_AsStringEx(logName), numLines, flags));
} }
PYTHON_METHOD_DEFINITION(ptStatusLog, write, args) PYTHON_METHOD_DEFINITION(ptStatusLog, write, args)
{ {
char* text; PyObject* text;
PyObject* colorObj = NULL; PyObject* colorObj = NULL;
if (!PyArg_ParseTuple(args, "s|O", &text, &colorObj)) if (!PyArg_ParseTuple(args, "O|O", &text, &colorObj))
{
PyErr_SetString(PyExc_TypeError, "write expects a string and an optional ptColor");
PYTHON_RETURN_ERROR;
}
if (!PyString_CheckEx(text))
{ {
PyErr_SetString(PyExc_TypeError, "write expects a string and an optional ptColor"); PyErr_SetString(PyExc_TypeError, "write expects a string and an optional ptColor");
PYTHON_RETURN_ERROR; PYTHON_RETURN_ERROR;
@ -85,9 +95,9 @@ PYTHON_METHOD_DEFINITION(ptStatusLog, write, args)
PYTHON_RETURN_ERROR; PYTHON_RETURN_ERROR;
} }
pyColor* color = pyColor::ConvertFrom(colorObj); pyColor* color = pyColor::ConvertFrom(colorObj);
PYTHON_RETURN_BOOL(self->fThis->WriteColor(text, *color)); PYTHON_RETURN_BOOL(self->fThis->WriteColor(PyString_AsStringEx(text), *color));
} }
PYTHON_RETURN_BOOL(self->fThis->Write(text)); PYTHON_RETURN_BOOL(self->fThis->Write(PyString_AsStringEx(text)));
} }
PYTHON_BASIC_METHOD_DEFINITION(ptStatusLog, close, Close); PYTHON_BASIC_METHOD_DEFINITION(ptStatusLog, close, Close);

7
Sources/Plasma/PubUtilLib/plPhysX/plPXPhysical.cpp

@ -827,7 +827,12 @@ void plPXPhysical::ApplyHitForce()
void plPXPhysical::ISetTransformGlobal(const hsMatrix44& l2w) void plPXPhysical::ISetTransformGlobal(const hsMatrix44& l2w)
{ {
hsAssert(fActor->isDynamic(), "Shouldn't move a static actor"); hsAssert(fActor->isDynamic(), "Shouldn't move a static actor");
fActor->wakeUp();
// If we wake up normal dynamic actors, they might explode.
// However, kinematics won't update if they are asleep. Thankfully, kinematics don't
// explode, move, or cause spontaneous nuclear warfare.
if (fActor->readBodyFlag(NX_BF_KINEMATIC))
fActor->wakeUp();
NxMat34 mat; NxMat34 mat;

56
Sources/Plasma/PubUtilLib/plPhysX/plSimulationMgr.cpp

@ -56,6 +56,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "pnSceneObject/plCoordinateInterface.h" #include "pnSceneObject/plCoordinateInterface.h"
#include "pnNetCommon/plSDLTypes.h" #include "pnNetCommon/plSDLTypes.h"
#include "plMessage/plCollideMsg.h" #include "plMessage/plCollideMsg.h"
#include "plMessage/plAgeLoadedMsg.h"
#include "plModifier/plDetectorLog.h" #include "plModifier/plDetectorLog.h"
@ -357,7 +358,7 @@ void plSimulationMgr::Init()
if (gTheInstance->InitSimulation()) if (gTheInstance->InitSimulation())
{ {
gTheInstance->RegisterAs(kSimulationMgr_KEY); gTheInstance->RegisterAs(kSimulationMgr_KEY);
gTheInstance->GetKey()->RefObject(); plgDispatch::Dispatch()->RegisterForExactType(plAgeLoadedMsg::Index(), gTheInstance->GetKey());
} }
else else
{ {
@ -374,10 +375,8 @@ void plSimulationMgr::Shutdown()
hsAssert(gTheInstance, "Simulation manager missing during shutdown."); hsAssert(gTheInstance, "Simulation manager missing during shutdown.");
if (gTheInstance) if (gTheInstance)
{ {
// UnRef to match our Ref in Init(). Unless something strange is plgDispatch::Dispatch()->UnRegisterForExactType(plAgeLoadedMsg::Index(), gTheInstance->GetKey());
// going on, this should destroy the instance and set gTheInstance to nil. gTheInstance->UnRegisterAs(kSimulationMgr_KEY); // this will destroy the instance
// gTheInstance->GetKey()->UnRefObject();
gTheInstance->UnRegister(); // this will destroy the instance
gTheInstance = nil; gTheInstance = nil;
} }
} }
@ -391,8 +390,6 @@ plSimulationMgr* plSimulationMgr::GetInstance()
plSimulationMgr::plSimulationMgr() plSimulationMgr::plSimulationMgr()
: fSuspended(true) : fSuspended(true)
, fMaxDelta(kDefaultMaxDelta)
, fStepSize(kDefaultStepSize)
, fLOSDispatch(new plLOSDispatch()) , fLOSDispatch(new plLOSDispatch())
, fSoundMgr(new plPhysicsSoundMgr) , fSoundMgr(new plPhysicsSoundMgr)
, fLog(nil) , fLog(nil)
@ -451,16 +448,20 @@ NxScene* plSimulationMgr::GetScene(plKey world)
if (!scene) if (!scene)
{ {
uint32_t maxSteps = (uint32_t)ceil(fMaxDelta / fStepSize);
NxSceneDesc sceneDesc; NxSceneDesc sceneDesc;
sceneDesc.gravity.set(0, 0, -32.174049f); sceneDesc.gravity.set(0, 0, -32.174049f);
sceneDesc.userTriggerReport = &gSensorReport; sceneDesc.userTriggerReport = &gSensorReport;
sceneDesc.userContactReport = &gContactReport; sceneDesc.userContactReport = &gContactReport;
sceneDesc.maxTimestep = fStepSize;
sceneDesc.maxIter = maxSteps;
scene = fSDK->createScene(sceneDesc); scene = fSDK->createScene(sceneDesc);
// See "Advancing The Simulation State" in the PhysX SDK Documentation
// This will cause PhysX to only update for our step size. If we call simulate
// faster than that, PhysX will return immediately. If we call it slower than that,
// PhysX will do some extra steps for us (isn't that nice?).
// Anyway, this should be a good way to make us independent of the framerate.
// If not, I blame the usual suspects (Tye, eap, etc...)
scene->setTiming(kDefaultStepSize);
// Most physicals use the default friction and restitution values, so we // Most physicals use the default friction and restitution values, so we
// make them the default. // make them the default.
NxMaterial* mat = scene->getMaterialFromIndex(0); NxMaterial* mat = scene->getMaterialFromIndex(0);
@ -603,12 +604,6 @@ void plSimulationMgr::Advance(float delSecs)
if (fSuspended) if (fSuspended)
return; return;
if (delSecs > fMaxDelta)
{
if (fExtraProfile)
Log("Step clamped from %f to limit of %f", delSecs, fMaxDelta);
delSecs = fMaxDelta;
}
plProfile_IncCount(StepLen, (int)(delSecs*1000)); plProfile_IncCount(StepLen, (int)(delSecs*1000));
#ifndef PLASMA_EXTERNAL_RELASE #ifndef PLASMA_EXTERNAL_RELASE
@ -756,6 +751,13 @@ void plSimulationMgr::ISendUpdates()
hsBool plSimulationMgr::MsgReceive(plMessage *msg) hsBool plSimulationMgr::MsgReceive(plMessage *msg)
{ {
// Suspend/resume the simulation based on whether or not we're in an age...
if (plAgeLoadedMsg* aMsg = plAgeLoadedMsg::ConvertNoRef(msg))
{
fSuspended = !aMsg->fLoaded;
return true;
}
return hsKeyedObject::MsgReceive(msg); return hsKeyedObject::MsgReceive(msg);
} }
@ -765,26 +767,6 @@ hsBool plSimulationMgr::MsgReceive(plMessage *msg)
// //
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
void plSimulationMgr::SetMaxDelta(float maxDelta)
{
fMaxDelta = maxDelta;
}
float plSimulationMgr::GetMaxDelta() const
{
return fMaxDelta;
}
void plSimulationMgr::SetStepsPerSecond(int stepsPerSecond)
{
fStepSize = 1.0f / (float)stepsPerSecond;
}
int plSimulationMgr::GetStepsPerSecond()
{
return (int)((1.0 / fStepSize) + 0.5f); // round to nearest int
}
int plSimulationMgr::GetMaterialIdx(NxScene* scene, float friction, float restitution) int plSimulationMgr::GetMaterialIdx(NxScene* scene, float friction, float restitution)
{ {
if (friction == 0.5f && restitution == 0.5f) if (friction == 0.5f && restitution == 0.5f)

17
Sources/Plasma/PubUtilLib/plPhysX/plSimulationMgr.h

@ -115,20 +115,6 @@ protected:
plSimulationMgr(); plSimulationMgr();
virtual ~plSimulationMgr(); virtual ~plSimulationMgr();
// Set the maximum amount of time (in seconds) that the physics will advance
// between frames. If a frame-to-frame delta is bigger than this, we'll
// clamp it to this value.
// WARNING: animation doesn't do this, so if we clamp the time animated
// physicals and the avatar may move at a faster rate than usual.
void SetMaxDelta(float maxDelta);
float GetMaxDelta() const;
// Set the number of steps per second that physics will advance.
// The more steps per second, the less fallthough and more accurate
// simulation response.
void SetStepsPerSecond(int stepsPerSecond);
int GetStepsPerSecond();
// Walk through the synchronization requests and send them as appropriate. // Walk through the synchronization requests and send them as appropriate.
void IProcessSynchs(); void IProcessSynchs();
@ -151,9 +137,6 @@ protected:
// but nothing will move. // but nothing will move.
bool fSuspended; bool fSuspended;
float fMaxDelta;
float fStepSize;
// A utility class to keep track of a request for a physical synchronization. // A utility class to keep track of a request for a physical synchronization.
// These requests must pass a certain criteria (see the code for the latest) // These requests must pass a certain criteria (see the code for the latest)
// before they are actually either sent over the network or rejected. // before they are actually either sent over the network or rejected.

Loading…
Cancel
Save