void ControlledActor::tryStandup() { // overlap with upper part if(mType==PxControllerShapeType::eBOX) { } else if(mType==PxControllerShapeType::eCAPSULE) { PxScene* scene = mController->getScene(); PxSceneReadLock scopedLock(*scene); PxCapsuleController* capsuleCtrl = static_cast<PxCapsuleController*>(mController); PxReal r = capsuleCtrl->getRadius(); PxReal dh = mStandingSize - mCrouchingSize-2*r; PxCapsuleGeometry geom(r, dh*.5f); PxExtendedVec3 position = mController->getPosition(); PxVec3 pos((float)position.x,(float)position.y+mStandingSize*.5f+r,(float)position.z); PxQuat orientation(PxHalfPi, PxVec3(0.0f, 0.0f, 1.0f)); PxOverlapBuffer hit; if(scene->overlap(geom, PxTransform(pos,orientation), hit, PxQueryFilterData(PxQueryFlag::eANY_HIT|PxQueryFlag::eSTATIC|PxQueryFlag::eDYNAMIC))) return; } // if no hit, we can stand up resizeStanding(); mDoStandup = false; mIsCrouching = false; }
void ControlledActor::tryStandup() { // overlap with upper part if(mType==PxControllerShapeType::eBOX) { } else if(mType==PxControllerShapeType::eCAPSULE) { PxCapsuleController* capsuleCtrl = static_cast<PxCapsuleController*>(mController); PxReal r = capsuleCtrl->getRadius(); PxReal dh = mStandingSize - mCrouchingSize-2*r; PxCapsuleGeometry geom(r, dh*.5f); PxExtendedVec3 position = mController->getPosition(); PxVec3 pos((float)position.x,(float)position.y+mStandingSize*.5f+r,(float)position.z); PxQuat orientation(PxHalfPi, PxVec3(0.0f, 0.0f, 1.0f)); PxShape* hit; PxScene* scene = mController->getScene(); if(scene->overlapMultiple(geom, PxTransform(pos,orientation),&hit,1) != 0) return; } // if no hit, we can stand up resizeStanding(); mDoStandup = false; mIsCrouching = false; }
void ControlledActor::resizeController(PxReal height) { mIsCrouching = true; if(mType==PxControllerShapeType::eBOX) { PxBoxController* boxCtrl = static_cast<PxBoxController*>(mController); const float oldHeight = boxCtrl->getHalfHeight(); boxCtrl->setHalfHeight(height); const float delta = height - oldHeight; PxExtendedVec3 pos = mController->getPosition(); pos += PxVec3(0.0f, delta, 0.0f); mController->setPosition(pos); } else if(mType==PxControllerShapeType::eCAPSULE) { PxCapsuleController* capsuleCtrl = static_cast<PxCapsuleController*>(mController); const float oldHeight = capsuleCtrl->getHeight(); capsuleCtrl->setHeight(height); const float delta = height - oldHeight; PxExtendedVec3 pos = mController->getPosition(); pos += PxVec3(0.0f, delta*0.5f, 0.0f); mController->setPosition(pos); } }
PxCapsuleController* CServer::createCapsuleController(const Vector3 &position, float radius, float height, const CPhysicController *component) { assert(_scene); // Nota: PhysX coloca el sistema de coordenadas local en el centro de la cápsula, mientras // que la lógica asume que el origen del sistema de coordenadas está en los piés del // jugador. Para unificar necesitamos realizar una traslación en el eje Y. // Desafortunadamente, el descriptor que se usa para crear los controllers no permite // definir esta transformación local (que sí permite al crear un actor), por lo que // tendremos que realizar la traslación nosotros cada vez. // Transformación entre el sistema de coordenadas lógico y el de PhysX float offsetY = height / 2.0f + radius; PxVec3 pos = Vector3ToPxVec3(position + Vector3(0, offsetY, 0)); // Crear descriptor del controller PxCapsuleControllerDesc desc; desc.position = PxExtendedVec3(pos.x, pos.y, pos.z); desc.height = height; desc.radius = radius; desc.material = _defaultMaterial; desc.climbingMode = PxCapsuleClimbingMode::eEASY; //desc.climbingMode = PxCapsuleClimbingMode::eCONSTRAINED; //desc.slopeLimit = 0.707f; desc.reportCallback = _collisionManager; // Establecer gestor de colisiones desc.userData = (void *) component; // Anotar el componente lógico asociado al controller PxCapsuleController *controller = (PxCapsuleController *) _controllerManager->createController(desc); // Anotar el componente lógico asociado al actor dentro del controller (No es automático) controller->getActor()->userData = (void *) component; return controller; }