// *************************************************************************** void CTransformShape::traverseLoadBalancingPass0() { CLoadBalancingTrav &loadTrav= getOwnerScene()->getLoadBalancingTrav(); CSkeletonModel *skeleton= getSkeletonModel(); // World Model position const CVector *modelPos; // If this isntance is binded or skinned to a skeleton, take the world matrix of this one as // center for LoadBalancing Resolution. if(skeleton) { // Take the root bone of the skeleton as reference (bone 0) // And so get our position. modelPos= &skeleton->Bones[0].getWorldMatrix().getPos(); } else { // get our position from modelPos= &getWorldMatrix().getPos(); } // Then compute distance from camera. float modelDist= ( loadTrav.CamPos - *modelPos).norm(); // Get the number of triangles this model use now. _FaceCount= getNumTriangles(modelDist); _LoadBalancingGroup->addNbFacesPass0(_FaceCount); }
void NpArticulation::release() { NP_WRITE_CHECK(getOwnerScene()); NpPhysics::getInstance().notifyDeletionListenersUserRelease(this, userData); //!!!AL TODO: Order should not matter in this case. Optimize by having a path which does not restrict release to leaf links or // by using a more advanced data structure PxU32 idx = 0; while(mArticulationLinks.size()) { idx = idx % mArticulationLinks.size(); if (mArticulationLinks[idx]->getNbChildren() == 0) { mArticulationLinks[idx]->releaseInternal(); // deletes joint, link and removes link from list } else { idx++; } } NpScene* npScene = getAPIScene(); if(npScene) { npScene->getScene().removeArticulation(getArticulation()); npScene->removeFromArticulationList(*this); } mArticulationLinks.clear(); mArticulation.destroy(); }
void NpArticulation::getSolverIterationCounts(PxU32 & positionIters, PxU32 & velocityIters) const { NP_READ_CHECK(getOwnerScene()); PxU16 x = getArticulation().getSolverIterationCounts(); velocityIters = PxU32(x >> 8); positionIters = PxU32(x & 0xff); }
PxArticulationLink* NpArticulation::createLink(PxArticulationLink* parent, const PxTransform& pose) { PX_CHECK_AND_RETURN_NULL(pose.isSane(), "NpArticulation::createLink pose is not valid."); NP_WRITE_CHECK(getOwnerScene()); if(parent && mArticulationLinks.empty()) { Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "Root articulation link must have NULL parent pointer!"); return NULL; } if(!parent && !mArticulationLinks.empty()) { Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "Non-root articulation link must have valid parent pointer!"); return NULL; } NpArticulationLink* parentLink = static_cast<NpArticulationLink*>(parent); NpArticulationLink* link = static_cast<NpArticulationLink*>(NpFactory::getInstance().createArticulationLink(*this, parentLink, pose.getNormalized())); if(link) { NpScene* scene = getAPIScene(); if(scene) scene->addArticulationLink(*link); } return link; }
PxArticulationDriveCache* NpArticulation::createDriveCache(PxReal compliance, PxU32 driveIterations) const { PX_CHECK_AND_RETURN_NULL(getAPIScene(), "PxArticulation::createDriveCache: object must be in a scene"); NP_READ_CHECK(getOwnerScene()); // doesn't modify the scene, only reads return reinterpret_cast<PxArticulationDriveCache*>(mArticulation.getScArticulation().createDriveCache(compliance, driveIterations)); }
void NpArticulation::releaseDriveCache(PxArticulationDriveCache&cache ) const { PX_CHECK_AND_RETURN(getAPIScene(), "PxArticulation::releaseDriveCache: object must be in a scene"); NP_READ_CHECK(getOwnerScene()); // doesn't modify the scene, only reads mArticulation.getScArticulation().releaseDriveCache(reinterpret_cast<Sc::ArticulationDriveCache&>(cache)); }
// *************************************************************************** bool CTransformShape::clip() { H_AUTO( NL3D_TrShape_Clip ); CClipTrav &clipTrav= getOwnerScene()->getClipTrav(); if(Shape) { // first test DistMax (faster). float maxDist = getDistMax(); // if DistMax test enabled if(maxDist!=-1) { // Calc the distance float sqrDist = (clipTrav.CamPos - getWorldMatrix().getPos()).sqrnorm (); maxDist*=maxDist; // if dist > maxDist, skip if (sqrDist > maxDist) { // Ok, not shown return false; } } // Else finer clip with pyramid, only if needed if(clipTrav.ForceNoFrustumClip) return true; else return Shape->clip(clipTrav.WorldPyramid, getWorldMatrix()); } else return false; }
void NpArticulationJoint::setTangentialDamping(PxReal damping) { PX_CHECK_AND_RETURN(PxIsFinite(damping) && damping >= 0, "PxArticulationJoint::setTangentialDamping: damping must be > 0"); NP_WRITE_CHECK(getOwnerScene()); mJoint.setTangentialDamping(damping); }
void NpArticulationJoint::setExternalCompliance(PxReal r) { PX_CHECK_AND_RETURN(PxIsFinite(r) && r>0, "PxArticulationJoint::setExternalCompliance: compliance must be > 0"); NP_WRITE_CHECK(getOwnerScene()); mJoint.setExternalCompliance(r); }
bool NpArticulation::isSleeping() const { NP_READ_CHECK(getOwnerScene()); PX_CHECK_AND_RETURN_VAL(getAPIScene(), "Articulation::isSleeping: articulation must be in a scene.", true); return getArticulation().isSleeping(); }
void NpArticulationJoint::setStiffness(PxReal s) { PX_CHECK_AND_RETURN(PxIsFinite(s) && s >= 0.0f, "PxArticulationJoint::setStiffness: spring coefficient must be >= 0!"); NP_WRITE_CHECK(getOwnerScene()); mJoint.setStiffness(s); }
// *************************************************************************** void CTransformShape::traverseLoadBalancing() { CLoadBalancingTrav &loadTrav= getOwnerScene()->getLoadBalancingTrav(); if(loadTrav.getLoadPass()==0) traverseLoadBalancingPass0(); else traverseLoadBalancingPass1(); }
void NpArticulationJoint::setTwistLimit(PxReal lower, PxReal upper) { PX_CHECK_AND_RETURN(PxIsFinite(lower) && PxIsFinite(upper) && lower<upper && lower>-PxPi && upper < PxPi, "PxArticulationJoint::setTwistLimit: illegal parameters"); NP_WRITE_CHECK(getOwnerScene()); mJoint.setTwistLimit(lower, upper); }
void NpArticulationJoint::setTangentialStiffness(PxReal stiffness) { PX_CHECK_AND_RETURN(PxIsFinite(stiffness) && stiffness >= 0, "PxArticulationJoint::setTangentialStiffness: stiffness must be > 0"); NP_WRITE_CHECK(getOwnerScene()); mJoint.setTangentialStiffness(stiffness); }
void NpArticulationJoint::setSwingLimit(PxReal yLimit, PxReal zLimit) { PX_CHECK_AND_RETURN(PxIsFinite(yLimit) && PxIsFinite(zLimit) && yLimit > 0 && zLimit > 0 && yLimit < PxPi && zLimit < PxPi, "PxArticulationJoint::setSwingLimit: values must be >0 and < Pi"); NP_WRITE_CHECK(getOwnerScene()); mJoint.setSwingLimit(yLimit, zLimit); }
void NpArticulationJoint::setTwistLimitContactDistance(PxReal d) { PX_CHECK_AND_RETURN(PxIsFinite(d) && d >= 0.0f, "PxArticulationJoint::setTwistLimitContactDistance: padding coefficient must be > 0!"); NP_WRITE_CHECK(getOwnerScene()); mJoint.setTwistLimitContactDistance(d); }
void NpArticulationJoint::setDamping(PxReal d) { PX_CHECK_AND_RETURN(PxIsFinite(d) && d >= 0.0f, "PxArticulationJoint::setDamping: damping coefficient must be >= 0!"); NP_WRITE_CHECK(getOwnerScene()); mJoint.setDamping(d); }
void NpArticulationJoint::setChildPose(const PxTransform& t) { PX_CHECK_AND_RETURN(t.isSane(), "NpArticulationJoint::setChildPose t is not valid."); NP_WRITE_CHECK(getOwnerScene()); mJoint.setChildPose(mChild->getCMassLocalPose().transformInv(t.getNormalized())); }
void NpArticulationJoint::setTargetVelocity(const PxVec3& v) { PX_CHECK_AND_RETURN(v.isFinite(), "NpArticulationJoint::setTargetVelocity v is not valid."); NP_WRITE_CHECK(getOwnerScene()); mJoint.setTargetVelocity(v); }
void NpArticulationJoint::setTargetOrientation(const PxQuat& p) { PX_CHECK_AND_RETURN(mJoint.getDriveType() != PxArticulationJointDriveType::eTARGET || p.isUnit(), "NpArticulationJoint::setTargetOrientation, quat orientation is not valid."); PX_CHECK_AND_RETURN(mJoint.getDriveType() != PxArticulationJointDriveType::eERROR || (p.getImaginaryPart().isFinite() && p.w == 0), "NpArticulationJoint::setTargetOrientation rotation vector orientation is not valid."); NP_WRITE_CHECK(getOwnerScene()); mJoint.setTargetOrientation(p); }
void NpArticulation::setSolverIterationCounts(PxU32 positionIters, PxU32 velocityIters) { NP_WRITE_CHECK(getOwnerScene()); PX_CHECK_AND_RETURN(positionIters > 0, "Articulation::setSolverIterationCount: positionIters must be more than zero!"); PX_CHECK_AND_RETURN(positionIters <= 255, "Articulation::setSolverIterationCount: positionIters must be no greater than 255!"); PX_CHECK_AND_RETURN(velocityIters > 0, "Articulation::setSolverIterationCount: velocityIters must be more than zero!"); PX_CHECK_AND_RETURN(velocityIters <= 255, "Articulation::setSolverIterationCount: velocityIters must be no greater than 255!"); getArticulation().setSolverIterationCounts((velocityIters & 0xff) << 8 | (positionIters & 0xff)); }
void NpArticulationJoint::setParentPose(const PxTransform& t) { PX_CHECK_AND_RETURN(t.isSane(), "NpArticulationJoint::setParentPose t is not valid."); NP_WRITE_CHECK(getOwnerScene()); if(mParent==NULL) return; mJoint.setParentPose(mParent->getCMassLocalPose().transformInv(t.getNormalized())); }
void NpArticulation::updateDriveCache(PxArticulationDriveCache& cache, PxReal compliance, PxU32 driveIterations) const { PX_CHECK_AND_RETURN(getAPIScene(), "PxArticulation::updateDriveCache: object must be in a scene"); Sc::ArticulationDriveCache& c = reinterpret_cast<Sc::ArticulationDriveCache&>(cache); PX_CHECK_AND_RETURN(mArticulation.getScArticulation().getCacheLinkCount(c) == mArticulationLinks.size(), "PxArticulation::updateDriveCache: Articulation size has changed; drive cache is invalid"); NP_READ_CHECK(getOwnerScene()); // doesn't modify the scene, only reads mArticulation.getScArticulation().updateDriveCache(c, compliance, driveIterations); }
// *************************************************************************** void CTransformShape::profileRender() { // profile the shape. if(Shape) { CRenderTrav &rdrTrav= getOwnerScene()->getRenderTrav(); bool currentPassOpaque= rdrTrav.isCurrentPassOpaque(); Shape->profileSceneRender( &rdrTrav, this, currentPassOpaque ); } }
void NpArticulation::setWakeCounter(PxReal wakeCounterValue) { NP_WRITE_CHECK(getOwnerScene()); for(PxU32 i=0; i < mArticulationLinks.size(); i++) { mArticulationLinks[i]->getScbBodyFast().setWakeCounter(wakeCounterValue); } getArticulation().setWakeCounter(wakeCounterValue); }
PxU32 NpArticulation::getLinks(PxArticulationLink** buffer, PxU32 bufferSize) const { NP_READ_CHECK(getOwnerScene()); const PxU32 size = mArticulationLinks.size(); const PxU32 writeCount = PxMin(size, bufferSize); for(PxU32 i=0; i<writeCount; i++) buffer[i] = mArticulationLinks[i]; return writeCount; // return Ps::dumpPointerArray((const void**)mArticulationLinks.begin(), mArticulationLinks.size(), (void**)buffer, bufferSize); }
void NpArticulation::putToSleep() { NP_WRITE_CHECK(getOwnerScene()); PX_CHECK_AND_RETURN(getAPIScene(), "Articulation::putToSleep: articulation must be in a scene."); for(PxU32 i=0; i < mArticulationLinks.size(); i++) { mArticulationLinks[i]->getScbBodyFast().putToSleepInternal(); } getArticulation().putToSleep(); }
void NpArticulation::wakeUp() { NpScene* scene = getAPIScene(); NP_WRITE_CHECK(getOwnerScene()); // don't use the API scene, since it will be NULL on pending removal PX_CHECK_AND_RETURN(scene, "Articulation::wakeUp: articulation must be in a scene."); for(PxU32 i=0; i < mArticulationLinks.size(); i++) { mArticulationLinks[i]->getScbBodyFast().wakeUpInternal(scene->getWakeCounterResetValueInteral()); } getArticulation().wakeUp(); }
PxBounds3 NpArticulation::getWorldBounds(float inflation) const { NP_READ_CHECK(getOwnerScene()); PxBounds3 bounds = PxBounds3::empty(); for(PxU32 i=0; i < mArticulationLinks.size(); i++) { bounds.include(mArticulationLinks[i]->getWorldBounds()); } PX_ASSERT(bounds.isValid()); // PT: unfortunately we can't just scale the min/max vectors, we need to go through center/extents. const PxVec3 center = bounds.getCenter(); const PxVec3 inflatedExtents = bounds.getExtents() * inflation; return PxBounds3::centerExtents(center, inflatedExtents); }
void NpArticulation::computeImpulseResponse(PxArticulationLink* link, PxVec3& linearResponse, PxVec3& angularResponse, const PxArticulationDriveCache& driveCache, const PxVec3& force, const PxVec3& torque) const { PX_CHECK_AND_RETURN(getAPIScene(), "PxArticulation::computeImpulseResponse: object must be in a scene"); PX_CHECK_AND_RETURN(force.isFinite() && torque.isFinite(), "PxArticulation::computeImpulseResponse: invalid force/torque"); NP_READ_CHECK(getOwnerScene()); const Sc::ArticulationDriveCache& c = reinterpret_cast<const Sc::ArticulationDriveCache&>(driveCache); PX_CHECK_AND_RETURN(mArticulation.getScArticulation().getCacheLinkCount(c) == mArticulationLinks.size(), "PxArticulation::computeImpulseResponse: Articulation size has changed; drive cache is invalid"); PX_UNUSED(&c); mArticulation.getScArticulation().computeImpulseResponse(static_cast<NpArticulationLink*>(link)->getScbBodyFast().getScBody(), linearResponse, angularResponse, reinterpret_cast<const Sc::ArticulationDriveCache&>(driveCache), force, torque); }