Projekt_Grafika/dependencies/physx-4.1/source/physx/src/NpRigidDynamic.cpp

579 lines
21 KiB
C++

//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#include "NpRigidDynamic.h"
#include "NpRigidActorTemplateInternal.h"
using namespace physx;
NpRigidDynamic::NpRigidDynamic(const PxTransform& bodyPose)
: NpRigidDynamicT(PxConcreteType::eRIGID_DYNAMIC, PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE, PxActorType::eRIGID_DYNAMIC, bodyPose)
{}
NpRigidDynamic::~NpRigidDynamic()
{
}
// PX_SERIALIZATION
void NpRigidDynamic::requiresObjects(PxProcessPxBaseCallback& c)
{
NpRigidDynamicT::requiresObjects(c);
}
void NpRigidDynamic::preExportDataReset()
{
NpRigidDynamicT::preExportDataReset();
if (isKinematic() && NpActor::getAPIScene(*this))
{
//Restore dynamic data in case the actor is configured as a kinematic.
//otherwise we would loose the data for switching the kinematic actor back to dynamic
//after deserialization.
getScbBodyFast().getScBody().restoreDynamicData();
}
}
NpRigidDynamic* NpRigidDynamic::createObject(PxU8*& address, PxDeserializationContext& context)
{
NpRigidDynamic* obj = new (address) NpRigidDynamic(PxBaseFlag::eIS_RELEASABLE);
address += sizeof(NpRigidDynamic);
obj->importExtraData(context);
obj->resolveReferences(context);
return obj;
}
//~PX_SERIALIZATION
void NpRigidDynamic::release()
{
releaseActorT(this, mBody);
}
void NpRigidDynamic::setGlobalPose(const PxTransform& pose, bool autowake)
{
NpScene* scene = NpActor::getAPIScene(*this);
#if PX_CHECKED
if(scene)
scene->checkPositionSanity(*this, pose, "PxRigidDynamic::setGlobalPose");
#endif
PX_CHECK_AND_RETURN(pose.isSane(), "PxRigidDynamic::setGlobalPose: pose is not valid.");
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
const PxTransform newPose = pose.getNormalized(); //AM: added to fix 1461 where users read and write orientations for no reason.
Scb::Body& b = getScbBodyFast();
const PxTransform body2World = newPose * b.getBody2Actor();
b.setBody2World(body2World, false);
if(scene)
updateDynamicSceneQueryShapes(mShapeManager, scene->getSceneQueryManagerFast(), *this);
// invalidate the pruning structure if the actor bounds changed
if(mShapeManager.getPruningStructure())
{
Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "PxRigidDynamic::setGlobalPose: Actor is part of a pruning structure, pruning structure is now invalid!");
mShapeManager.getPruningStructure()->invalidate(this);
}
if(scene && autowake && !(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION))
wakeUpInternal();
}
PX_FORCE_INLINE void NpRigidDynamic::setKinematicTargetInternal(const PxTransform& targetPose)
{
Scb::Body& b = getScbBodyFast();
// The target is actor related. Transform to body related target
const PxTransform bodyTarget = targetPose * b.getBody2Actor();
b.setKinematicTarget(bodyTarget);
NpScene* scene = NpActor::getAPIScene(*this);
if ((b.getFlags() & PxRigidBodyFlag::eUSE_KINEMATIC_TARGET_FOR_SCENE_QUERIES) && scene)
{
updateDynamicSceneQueryShapes(mShapeManager, scene->getSceneQueryManagerFast(), *this);
}
}
void NpRigidDynamic::setKinematicTarget(const PxTransform& destination)
{
PX_CHECK_AND_RETURN(destination.isSane(), "PxRigidDynamic::setKinematicTarget: destination is not valid.");
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
#if PX_CHECKED
NpScene* scene = NpActor::getAPIScene(*this);
if(scene)
scene->checkPositionSanity(*this, destination, "PxRigidDynamic::setKinematicTarget");
Scb::Body& b = getScbBodyFast();
PX_CHECK_AND_RETURN((b.getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::setKinematicTarget: Body must be kinematic!");
PX_CHECK_AND_RETURN(scene, "PxRigidDynamic::setKinematicTarget: Body must be in a scene!");
PX_CHECK_AND_RETURN(!(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::setKinematicTarget: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
#endif
setKinematicTargetInternal(destination.getNormalized());
}
bool NpRigidDynamic::getKinematicTarget(PxTransform& target) const
{
NP_READ_CHECK(NpActor::getOwnerScene(*this));
const Scb::Body& b = getScbBodyFast();
if(b.getFlags() & PxRigidBodyFlag::eKINEMATIC)
{
PxTransform bodyTarget;
if(b.getKinematicTarget(bodyTarget))
{
// The internal target is body related. Transform to actor related target
target = bodyTarget * b.getBody2Actor().getInverse();
return true;
}
}
return false;
}
void NpRigidDynamic::setCMassLocalPose(const PxTransform& pose)
{
PX_CHECK_AND_RETURN(pose.isSane(), "PxRigidDynamic::setCMassLocalPose pose is not valid.");
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
const PxTransform p = pose.getNormalized();
const PxTransform oldBody2Actor = getScbBodyFast().getBody2Actor();
NpRigidDynamicT::setCMassLocalPoseInternal(p);
Scb::Body& b = getScbBodyFast();
if(b.getFlags() & PxRigidBodyFlag::eKINEMATIC)
{
PxTransform bodyTarget;
if(b.getKinematicTarget(bodyTarget))
{
PxTransform actorTarget = bodyTarget * oldBody2Actor.getInverse(); // get old target pose for the actor from the body target
setKinematicTargetInternal(actorTarget);
}
}
}
void NpRigidDynamic::setLinearDamping(PxReal linearDamping)
{
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(PxIsFinite(linearDamping), "PxRigidDynamic::setLinearDamping: invalid float");
PX_CHECK_AND_RETURN(linearDamping >=0, "PxRigidDynamic::setLinearDamping: The linear damping must be nonnegative!");
getScbBodyFast().setLinearDamping(linearDamping);
}
PxReal NpRigidDynamic::getLinearDamping() const
{
NP_READ_CHECK(NpActor::getOwnerScene(*this));
return getScbBodyFast().getLinearDamping();
}
void NpRigidDynamic::setAngularDamping(PxReal angularDamping)
{
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(PxIsFinite(angularDamping), "PxRigidDynamic::setAngularDamping: invalid float");
PX_CHECK_AND_RETURN(angularDamping>=0, "PxRigidDynamic::setAngularDamping: The angular damping must be nonnegative!")
getScbBodyFast().setAngularDamping(angularDamping);
}
PxReal NpRigidDynamic::getAngularDamping() const
{
NP_READ_CHECK(NpActor::getOwnerScene(*this));
return getScbBodyFast().getAngularDamping();
}
void NpRigidDynamic::setLinearVelocity(const PxVec3& velocity, bool autowake)
{
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(velocity.isFinite(), "PxRigidDynamic::setLinearVelocity: velocity is not valid.");
PX_CHECK_AND_RETURN(!(getScbBodyFast().getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::setLinearVelocity: Body must be non-kinematic!");
PX_CHECK_AND_RETURN(!(getScbBodyFast().getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::setLinearVelocity: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
Scb::Body& b = getScbBodyFast();
b.setLinearVelocity(velocity);
NpScene* scene = NpActor::getAPIScene(*this);
if(scene)
wakeUpInternalNoKinematicTest(b, (!velocity.isZero()), autowake);
}
void NpRigidDynamic::setAngularVelocity(const PxVec3& velocity, bool autowake)
{
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(velocity.isFinite(), "PxRigidDynamic::setAngularVelocity: velocity is not valid.");
PX_CHECK_AND_RETURN(!(getScbBodyFast().getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::setAngularVelocity: Body must be non-kinematic!");
PX_CHECK_AND_RETURN(!(getScbBodyFast().getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::setAngularVelocity: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
Scb::Body& b = getScbBodyFast();
b.setAngularVelocity(velocity);
NpScene* scene = NpActor::getAPIScene(*this);
if(scene)
wakeUpInternalNoKinematicTest(b, (!velocity.isZero()), autowake);
}
void NpRigidDynamic::setMaxAngularVelocity(PxReal maxAngularVelocity)
{
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(PxIsFinite(maxAngularVelocity), "PxRigidDynamic::setMaxAngularVelocity: invalid float");
PX_CHECK_AND_RETURN(maxAngularVelocity>=0.0f, "PxRigidDynamic::setMaxAngularVelocity: threshold must be non-negative!");
getScbBodyFast().setMaxAngVelSq(maxAngularVelocity * maxAngularVelocity);
}
PxReal NpRigidDynamic::getMaxAngularVelocity() const
{
NP_READ_CHECK(NpActor::getOwnerScene(*this));
return PxSqrt(getScbBodyFast().getMaxAngVelSq());
}
void NpRigidDynamic::setMaxLinearVelocity(PxReal maxLinearVelocity)
{
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(PxIsFinite(maxLinearVelocity), "PxRigidDynamic::setMaxAngularVelocity: invalid float");
PX_CHECK_AND_RETURN(maxLinearVelocity >= 0.0f, "PxRigidDynamic::setMaxAngularVelocity: threshold must be non-negative!");
getScbBodyFast().setMaxLinVelSq(maxLinearVelocity * maxLinearVelocity);
}
PxReal NpRigidDynamic::getMaxLinearVelocity() const
{
NP_READ_CHECK(NpActor::getOwnerScene(*this));
return PxSqrt(getScbBodyFast().getMaxLinVelSq());
}
void NpRigidDynamic::addForce(const PxVec3& force, PxForceMode::Enum mode, bool autowake)
{
Scb::Body& b = getScbBodyFast();
PX_CHECK_AND_RETURN(force.isFinite(), "PxRigidDynamic::addForce: force is not valid.");
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(NpActor::getAPIScene(*this), "PxRigidDynamic::addForce: Body must be in a scene!");
PX_CHECK_AND_RETURN(!(b.getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::addForce: Body must be non-kinematic!");
PX_CHECK_AND_RETURN(!(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::addForce: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
addSpatialForce(&force, NULL, mode);
wakeUpInternalNoKinematicTest(b, (!force.isZero()), autowake);
}
void NpRigidDynamic::setForceAndTorque(const PxVec3& force, const PxVec3& torque, PxForceMode::Enum mode)
{
Scb::Body& b = getScbBodyFast();
PX_CHECK_AND_RETURN(force.isFinite(), "PxRigidDynamic::setForce: force is not valid.");
PX_CHECK_AND_RETURN(torque.isFinite(), "PxRigidDynamic::setForce: force is not valid.");
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(NpActor::getAPIScene(*this), "PxRigidDynamic::addForce: Body must be in a scene!");
PX_CHECK_AND_RETURN(!(b.getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::addForce: Body must be non-kinematic!");
PX_CHECK_AND_RETURN(!(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::addForce: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
setSpatialForce(&force, &torque, mode);
wakeUpInternalNoKinematicTest(b, (!force.isZero()), true);
}
void NpRigidDynamic::addTorque(const PxVec3& torque, PxForceMode::Enum mode, bool autowake)
{
Scb::Body& b = getScbBodyFast();
PX_CHECK_AND_RETURN(torque.isFinite(), "PxRigidDynamic::addTorque: torque is not valid.");
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(NpActor::getAPIScene(*this), "PxRigidDynamic::addTorque: Body must be in a scene!");
PX_CHECK_AND_RETURN(!(b.getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::addTorque: Body must be non-kinematic!");
PX_CHECK_AND_RETURN(!(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::addTorque: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
addSpatialForce(NULL, &torque, mode);
wakeUpInternalNoKinematicTest(b, (!torque.isZero()), autowake);
}
void NpRigidDynamic::clearForce(PxForceMode::Enum mode)
{
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(NpActor::getAPIScene(*this), "PxRigidDynamic::clearForce: Body must be in a scene!");
PX_CHECK_AND_RETURN(!(getScbBodyFast().getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::clearForce: Body must be non-kinematic!");
PX_CHECK_AND_RETURN(!(getScbBodyFast().getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::clearForce: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
clearSpatialForce(mode, true, false);
}
void NpRigidDynamic::clearTorque(PxForceMode::Enum mode)
{
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(NpActor::getAPIScene(*this), "PxRigidDynamic::clearTorque: Body must be in a scene!");
PX_CHECK_AND_RETURN(!(getScbBodyFast().getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::clearTorque: Body must be non-kinematic!");
PX_CHECK_AND_RETURN(!(getScbBodyFast().getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::clearTorque: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
clearSpatialForce(mode, false, true);
}
bool NpRigidDynamic::isSleeping() const
{
NP_READ_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN_VAL(NpActor::getAPIScene(*this), "PxRigidDynamic::isSleeping: Body must be in a scene.", true);
return getScbBodyFast().isSleeping();
}
void NpRigidDynamic::setSleepThreshold(PxReal threshold)
{
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(PxIsFinite(threshold), "PxRigidDynamic::setSleepThreshold: invalid float.");
PX_CHECK_AND_RETURN(threshold>=0.0f, "PxRigidDynamic::setSleepThreshold: threshold must be non-negative!");
getScbBodyFast().setSleepThreshold(threshold);
}
PxReal NpRigidDynamic::getSleepThreshold() const
{
NP_READ_CHECK(NpActor::getOwnerScene(*this));
return getScbBodyFast().getSleepThreshold();
}
void NpRigidDynamic::setStabilizationThreshold(PxReal threshold)
{
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(PxIsFinite(threshold), "PxRigidDynamic::setSleepThreshold: invalid float.");
PX_CHECK_AND_RETURN(threshold>=0.0f, "PxRigidDynamic::setSleepThreshold: threshold must be non-negative!");
getScbBodyFast().setFreezeThreshold(threshold);
}
PxReal NpRigidDynamic::getStabilizationThreshold() const
{
NP_READ_CHECK(NpActor::getOwnerScene(*this));
return getScbBodyFast().getFreezeThreshold();
}
void NpRigidDynamic::setWakeCounter(PxReal wakeCounterValue)
{
Scb::Body& b = getScbBodyFast();
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(PxIsFinite(wakeCounterValue), "PxRigidDynamic::setWakeCounter: invalid float.");
PX_CHECK_AND_RETURN(wakeCounterValue>=0.0f, "PxRigidDynamic::setWakeCounter: wakeCounterValue must be non-negative!");
PX_CHECK_AND_RETURN(!(b.getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::setWakeCounter: Body must be non-kinematic!");
PX_CHECK_AND_RETURN(!(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::setWakeCounter: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
b.setWakeCounter(wakeCounterValue);
}
PxReal NpRigidDynamic::getWakeCounter() const
{
NP_READ_CHECK(NpActor::getOwnerScene(*this));
return getScbBodyFast().getWakeCounter();
}
void NpRigidDynamic::wakeUp()
{
Scb::Body& b = getScbBodyFast();
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(NpActor::getAPIScene(*this), "PxRigidDynamic::wakeUp: Body must be in a scene.");
PX_CHECK_AND_RETURN(!(b.getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::wakeUp: Body must be non-kinematic!");
PX_CHECK_AND_RETURN(!(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::wakeUp: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
b.wakeUp();
}
void NpRigidDynamic::putToSleep()
{
Scb::Body& b = getScbBodyFast();
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(NpActor::getAPIScene(*this), "PxRigidDynamic::putToSleep: Body must be in a scene.");
PX_CHECK_AND_RETURN(!(b.getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::putToSleep: Body must be non-kinematic!");
PX_CHECK_AND_RETURN(!(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::putToSleep: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
b.putToSleep();
}
void NpRigidDynamic::setSolverIterationCounts(PxU32 positionIters, PxU32 velocityIters)
{
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(positionIters > 0, "PxRigidDynamic::setSolverIterationCount: positionIters must be more than zero!");
PX_CHECK_AND_RETURN(positionIters <= 255, "PxRigidDynamic::setSolverIterationCount: positionIters must be no greater than 255!");
PX_CHECK_AND_RETURN(velocityIters > 0, "PxRigidDynamic::setSolverIterationCount: velocityIters must be more than zero!");
PX_CHECK_AND_RETURN(velocityIters <= 255, "PxRigidDynamic::setSolverIterationCount: velocityIters must be no greater than 255!");
getScbBodyFast().setSolverIterationCounts((velocityIters & 0xff) << 8 | (positionIters & 0xff));
}
void NpRigidDynamic::getSolverIterationCounts(PxU32 & positionIters, PxU32 & velocityIters) const
{
NP_READ_CHECK(NpActor::getOwnerScene(*this));
PxU16 x = getScbBodyFast().getSolverIterationCounts();
velocityIters = PxU32(x >> 8);
positionIters = PxU32(x & 0xff);
}
void NpRigidDynamic::setContactReportThreshold(PxReal threshold)
{
NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
PX_CHECK_AND_RETURN(PxIsFinite(threshold), "PxRigidDynamic::setContactReportThreshold: invalid float.");
PX_CHECK_AND_RETURN(threshold >= 0.0f, "PxRigidDynamic::setContactReportThreshold: Force threshold must be greater than zero!");
getScbBodyFast().setContactReportThreshold(threshold<0 ? 0 : threshold);
}
PxReal NpRigidDynamic::getContactReportThreshold() const
{
NP_READ_CHECK(NpActor::getOwnerScene(*this));
return getScbBodyFast().getContactReportThreshold();
}
PxU32 physx::NpRigidDynamicGetShapes(Scb::Body& body, void* const*& shapes, bool* isCompound)
{
NpRigidDynamic* a = static_cast<NpRigidDynamic*>(body.getScBody().getPxActor());
NpShapeManager& sm = a->getShapeManager();
shapes = reinterpret_cast<void *const *>(sm.getShapes());
if(isCompound)
*isCompound = sm.isSqCompound();
return sm.getNbShapes();
}
void NpRigidDynamic::switchToNoSim()
{
getScbBodyFast().switchBodyToNoSim();
}
void NpRigidDynamic::switchFromNoSim()
{
getScbBodyFast().switchFromNoSim(true);
}
void NpRigidDynamic::wakeUpInternalNoKinematicTest(Scb::Body& body, bool forceWakeUp, bool autowake)
{
NpScene* scene = NpActor::getOwnerScene(*this);
PX_ASSERT(scene);
PxReal wakeCounterResetValue = scene->getWakeCounterResetValueInteral();
PxReal wakeCounter = body.getWakeCounter();
bool needsWakingUp = body.isSleeping() && (autowake || forceWakeUp);
if (autowake && (wakeCounter < wakeCounterResetValue))
{
wakeCounter = wakeCounterResetValue;
needsWakingUp = true;
}
if (needsWakingUp)
body.wakeUpInternal(wakeCounter);
}
PxRigidDynamicLockFlags NpRigidDynamic::getRigidDynamicLockFlags() const
{
return mBody.getLockFlags();
}
void NpRigidDynamic::setRigidDynamicLockFlags(PxRigidDynamicLockFlags flags)
{
mBody.setLockFlags(flags);
}
void NpRigidDynamic::setRigidDynamicLockFlag(PxRigidDynamicLockFlag::Enum flag, bool value)
{
PxRigidDynamicLockFlags flags = mBody.getLockFlags();
if (value)
flags = flags | flag;
else
flags = flags & (~flag);
mBody.setLockFlags(flags);
}
#if PX_ENABLE_DEBUG_VISUALIZATION
void NpRigidDynamic::visualize(Cm::RenderOutput& out, NpScene* npScene)
{
NpRigidDynamicT::visualize(out, npScene);
if (getScbBodyFast().getActorFlags() & PxActorFlag::eVISUALIZATION)
{
PX_ASSERT(npScene);
const PxReal scale = npScene->getVisualizationParameter(PxVisualizationParameter::eSCALE);
const PxReal massAxes = scale * npScene->getVisualizationParameter(PxVisualizationParameter::eBODY_MASS_AXES);
if (massAxes != 0.0f)
{
PxReal sleepTime = getScbBodyFast().getWakeCounter() / npScene->getWakeCounterResetValueInteral();
PxU32 color = PxU32(0xff * (sleepTime>1.0f ? 1.0f : sleepTime));
color = getScbBodyFast().isSleeping() ? 0xff0000 : (color<<16 | color<<8 | color);
PxVec3 dims = invertDiagInertia(getScbBodyFast().getInverseInertia());
dims = getDimsFromBodyInertia(dims, 1.0f / getScbBodyFast().getInverseMass());
out << color << getScbBodyFast().getBody2World() << Cm::DebugBox(dims * 0.5f);
}
}
}
#endif