//----------------------------------------------------------------------------- // onTrigger //----------------------------------------------------------------------------- //!! void CPhysicScene::onTrigger (NxShape &triggerShape, NxShape &otherShape, NxTriggerFlag status) { if (!m_pCollisionMng) return; TActorInfo *triggerInfo = (TActorInfo*) triggerShape.getActor().userData; TActorInfo *otherInfo = (TActorInfo*) otherShape.getActor().userData; m_pCollisionMng->onTrigger(*triggerInfo, *otherInfo, status); }
void pTriggerReport::onTrigger(NxShape& triggerShape, NxShape& otherShape, NxTriggerFlag status) { NxActor *triggerActor = &triggerShape.getActor(); NxActor *otherActor = &otherShape.getActor(); pRigidBody *triggerBody = NULL; pRigidBody *otherBody = NULL; if (triggerActor) { triggerBody = static_cast<pRigidBody*>(triggerActor->userData); triggerBody->getTriggers().Clear(); } if (otherActor) { otherBody = static_cast<pRigidBody*>(otherActor->userData); otherBody->getTriggers().Clear(); } pTriggerEntry entry; entry.shapeA = &triggerShape; entry.shapeB = &otherShape; entry.triggerEvent = status; if (triggerBody) { triggerBody->getTriggers().PushBack(entry); } /*if(status & NX_TRIGGER_ON_ENTER) { } if(status & NX_TRIGGER_ON_LEAVE) { } if(status & NX_TRIGGER_ON_STAY) { // A body entered the trigger area for the first time }*/ }
CPhysicUserData* CPhysicsManager::RaycastClosestActor( const Vect3f _vPosRay, const Vect3f& _vDirRay, uint32 _uiImpactMask, SCollisionInfo& _Info, float _uiMaxDistance ) { //NxUserRaycastReport::ALL_SHAPES assert(m_pScene != NULL); NxRay ray; ray.dir = NxVec3 ( _vDirRay.x, _vDirRay.y, _vDirRay.z ); ray.orig = NxVec3 ( _vPosRay.x, _vPosRay.y, _vPosRay.z ); NxRaycastHit hit; NxShape* closestShape = NULL; //closestShape = m_pScene->raycastClosestShape ( ray, NX_ALL_SHAPES, hit, _uiImpactMask, NX_MAX_F32, _uiImpactMask ); //closestShape = m_pScene->raycastClosestShape( ray, NX_ALL_SHAPES, hit, 0xffffffff, NX_MAX_F32, 0xffffffff, NULL, NULL ); NxReal l_Distance = (NxReal) _uiMaxDistance; // --- Jordi : Provisional. Cal deixar aquesta linia i modificar la col·lisió de càmera closestShape = m_pScene->raycastClosestShape( ray, NX_ALL_SHAPES, hit, _uiImpactMask, l_Distance ); if (!closestShape) { //No hemos tocado a ningún objeto físico de la escena. return NULL; } NxActor* actor = &closestShape->getActor(); CPhysicUserData* impactObject =(CPhysicUserData*)actor->userData; //Si está petando aquí quiere decir que se ha registrado un objeto físico sin proporcionarle UserData assert(impactObject); _Info.m_fDistance = hit.distance; _Info.m_Normal = Vect3f(hit.worldNormal.x, hit.worldNormal.y, hit.worldNormal.z ); _Info.m_CollisionPoint = Vect3f(hit.worldImpact.x, hit.worldImpact.y, hit.worldImpact.z ); return impactObject; }
CPhysicUserData* CPhysicsManager::RaycastClosestActor (const Vect3f posRay, const Vect3f& dirRay, uint32 impactMask, SCollisionInfo& info ) { //NxUserRaycastReport::ALL_SHAPES assert(m_pScene != NULL); NxRay ray; ray.dir = NxVec3(dirRay.x, dirRay.y, dirRay.z); ray.orig = NxVec3(posRay.x, posRay.y, posRay.z); NxRaycastHit hit; NxShape* closestShape = NULL; closestShape = m_pScene->raycastClosestShape(ray, NX_ALL_SHAPES, hit, impactMask); if (!closestShape) { //No hemos tocado a ningún objeto físico de la escena. return NULL; } NxActor* actor = &closestShape->getActor(); CPhysicUserData* impactObject =(CPhysicUserData*)actor->userData; //Si está petando aquí quiere decir que se ha registrado un objeto físico sin proporcionarle UserData assert(impactObject); info.m_fDistance = hit.distance; info.m_Normal = Vect3f(hit.worldNormal.x, hit.worldNormal.y, hit.worldNormal.z ); info.m_CollisionPoint = Vect3f(hit.worldImpact.x, hit.worldImpact.y, hit.worldImpact.z ); return impactObject; }
void myTrigger::onTrigger(NxShape& triggerShape, NxShape& otherShape, NxTriggerFlag status){ if ( ! triggerShape.getActor().userData && ! otherShape.getActor().userData ) { return; } if (status & NX_TRIGGER_ON_ENTER) { // A body just entered the trigger area NxActor* triggerActor = &triggerShape.getActor(); String name = triggerActor->getName(); int thisTarget = StringConverter::parseInt(name); creditTarget(thisTarget); } }
pWheelContactData* pWheel2::getContact() { NxWheelShape *wShape = getWheelShape(); if (!wShape) { return new pWheelContactData(); } NxWheelContactData wcd; NxShape* contactShape = wShape->getContact(wcd); pWheelContactData result; result.contactEntity = NULL; if (contactShape) { result.contactForce = wcd.contactForce; result.contactNormal = getFrom(wcd.contactNormal); result.contactPoint= getFrom(wcd.contactPoint); result.contactPosition= wcd.contactPosition; result.lateralDirection= getFrom(wcd.lateralDirection); result.lateralImpulse= wcd.lateralImpulse; result.lateralSlip = wcd.lateralSlip; result.longitudalDirection = getFrom(wcd.longitudalDirection); result.longitudalImpulse = wcd.longitudalImpulse; result.longitudalSlip= wcd.longitudalSlip; pSubMeshInfo *sInfo = static_cast<pSubMeshInfo*>(contactShape->userData); if (sInfo->entID) { CKObject *obj = (CKObject*)GetPMan()->m_Context->GetObject(sInfo->entID); if (obj) { result.contactEntity = (CK3dEntity*)obj; }else { result.contactEntity = NULL; } } result.otherShapeMaterialIndex = contactShape->getMaterial(); NxMaterial* otherMaterial = contactShape->getActor().getScene().getMaterialFromIndex(contactShape->getMaterial()); if (otherMaterial) { pFactory::Instance()->copyTo(result.otherMaterial,otherMaterial); } } return &result; }
virtual void onTrigger(NxShape& triggerShape, NxShape& otherShape, NxTriggerFlag status) { plKey otherKey = nil; bool doReport = false; // Get our trigger physical. This should definitely have a plPXPhysical plPXPhysical* triggerPhys = (plPXPhysical*)triggerShape.getActor().userData; // Get the triggerer. If it doesn't have a plPXPhyscial, it's an avatar plPXPhysical* otherPhys = (plPXPhysical*)otherShape.getActor().userData; if (otherPhys) { otherKey = otherPhys->GetObjectKey(); doReport = triggerPhys->DoReportOn((plSimDefs::Group)otherPhys->GetGroup()); } else { plPXPhysicalControllerCore* controller = plPXPhysicalControllerCore::GetController(otherShape.getActor()); if (controller) { otherKey = controller->GetOwner(); doReport = triggerPhys->DoReportOn(plSimDefs::kGroupAvatar); } } if (doReport) { if (status & NX_TRIGGER_ON_ENTER) { if (plSimulationMgr::fExtraProfile) DetectorLogRed("-->Send Collision %s enter",triggerPhys->GetObjectKey()->GetName().c_str()); plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, true); } else if (status & NX_TRIGGER_ON_LEAVE) { if (plSimulationMgr::fExtraProfile) DetectorLogRed("-->Send Collision %s exit",triggerPhys->GetObjectKey()->GetName().c_str()); plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, false); } } }
NxActor*pWheel2::getTouchedActor()const { NxWheelContactData wcd; NxShape * s = mWheelShape->getContact(wcd); if (s) { if (&s->getActor()) { return &s->getActor(); }else { return NULL; } }else { return NULL; } return NULL; //return s ? &s->getActor() : NULL; }
virtual void onTrigger(NxShape& triggerShape, NxShape& otherShape, NxTriggerFlag status) { // other actor is a trigger too? if (*(int *)(&otherShape.getActor().userData) < 0) return; NxActor& triggerActor = triggerShape.getActor(); NxI32 triggerNumber = -(*(int *)(&triggerActor.userData)); NxI32 triggerIndex = triggerNumber - 1; if(status & NX_TRIGGER_ON_ENTER) { // A body entered the trigger area for the first time gNbTouchedBodies[triggerIndex]++; } if(status & NX_TRIGGER_ON_LEAVE) { // A body left the trigger area gNbTouchedBodies[triggerIndex]--; } NX_ASSERT(gNbTouchedBodies[triggerIndex]>=0); //Shouldn't go negative }
//NX_STATIC_SHAPES,NX_DYNAMIC_SHAPES,NX_ALL_SHAPES GameObject* PhysicsManager::castRayGetClosest(Vector3 startPosition, Vector3 direction, bool omitTriggers,bool omitActors, bool omitStatic, bool omitDynamic, bool omitCharacters) { NxRay worldRay; worldRay.orig = NxTools::convert(startPosition); worldRay.dir = NxTools::convert(direction); NxShapesType flags = NX_ALL_SHAPES; // NxShapeType::; NxRaycastHit hit; NxShape* shape = mScene->raycastClosestShape(worldRay, flags, hit); if(shape) { NxActor& actor = shape->getActor(); if(!omitTriggers) { CPhysicsTrigger* trigger = static_cast<CPhysicsTrigger*>(actor.userData); if(trigger) return trigger->getOwnerObject(); } if(!omitActors) { CPhysicsActor* physicsActor = static_cast<CPhysicsActor*>(actor.userData); if(physicsActor) { //if(!omitDynamic) { // if(physicsActor->isDynamic()) { return physicsActor->getOwnerObject(); // } //} else { //} } } if(!omitCharacters) { CCharacterController* character = static_cast<CCharacterController*>(actor.userData); if(character) return character->getOwnerObject(); } } //if(shape) // return hit.distance; //else // return 0; return NULL; }
CPhysicUserData* CPhysicsManager::RaycastClosestActorShoot (const Vect3f posRay, const Vect3f& dirRay, uint32 impactMask, SCollisionInfo& info, float _fPower) { //NxUserRaycastReport::ALL_SHAPES assert(m_pScene != NULL); NxRay ray; ray.dir = NxVec3(dirRay.x, dirRay.y, dirRay.z); ray.orig = NxVec3(posRay.x, posRay.y, posRay.z); NxRaycastHit hit; NxShape* closestShape = NULL; closestShape = m_pScene->raycastClosestShape(ray, NX_ALL_SHAPES, hit, impactMask); if (!closestShape) { //No hemos tokado a ningún objeto físico de la escena. return NULL; } NxActor* actor = &closestShape->getActor(); CPhysicUserData* impactObject =(CPhysicUserData*)actor->userData; //Si está petando aquí quiere decir que se ha registrado un objeto físico sin proporcionarle UserData assert(impactObject); info.m_fDistance = hit.distance; info.m_Normal = Vect3f(hit.worldNormal.x, hit.worldNormal.y, hit.worldNormal.z ); info.m_CollisionPoint = Vect3f(hit.worldImpact.x, hit.worldImpact.y, hit.worldImpact.z ); Vect3f l_vDirection(dirRay.x-posRay.x,dirRay.y-posRay.y,dirRay.z-posRay.z); l_vDirection.Normalize(); NxVec3 l_vDirectionVec(dirRay.x,dirRay.y,dirRay.z); NxF32 coeff = actor->getMass() * _fPower; actor->addForceAtLocalPos(l_vDirectionVec*coeff, NxVec3(0,0,0), NX_IMPULSE,true); return impactObject; }
void Pick(int x, int y) { LetGo(); NxRay ray; ViewUnProject(x, y, 0.0f, ray.orig); ViewUnProject(x, y, 1.0f, ray.dir); ray.dir -= ray.orig; ray.dir.normalize(); NxRaycastHit hit; NxShape* closestShape = gScene->raycastClosestShape(ray, NX_ALL_SHAPES, hit); NxVec3 origin = ray.orig; NxVec3 impact = hit.worldImpact; NxReal distRB = NX_MAX_REAL; if (closestShape && closestShape->getActor().isDynamic()) { distRB = (impact.x - origin.x) * (impact.x - origin.x) + (impact.y - origin.y) * (impact.y - origin.y) + (impact.z - origin.z) * (impact.z - origin.z); } NxVec3 hitcloth, hitRecord; NxU32 vertexId; NxReal distCloth, closest= NX_MAX_REAL; NxU32 indexCloth, indexClothVertex; NxCloth **cloths = gScene->getCloths(); for (NxU32 i = 0; i < gScene->getNbCloths(); i++) { if (cloths[i]->raycast(ray, hitcloth, vertexId)) { distCloth = (hitcloth.x - origin.x) * (hitcloth.x - origin.x) + (hitcloth.y - origin.y) * (hitcloth.y - origin.y) + (hitcloth.z - origin.z) * (hitcloth.z - origin.z); if(distCloth < closest) { closest = distCloth; indexCloth = i; indexClothVertex = vertexId; hitRecord = hitcloth; } } } if (distRB > closest) // Pick cloth { gHitCloth = cloths[indexCloth]; gHitClothVertex = indexClothVertex; int hitx, hity; ViewProject(hitRecord, hitx, hity, gMouseDepth); } else if (distRB < closest) // Pick actor { gHitActor = &closestShape->getActor(); gHitActor->wakeUp(); int hitx, hity; gMouseSphere = CreateSphere(hit.worldImpact, 0.1, 1); gMouseSphere->raiseBodyFlag(NX_BF_KINEMATIC); gMouseSphere->raiseActorFlag(NX_AF_DISABLE_COLLISION); ViewProject(hit.worldImpact, hitx, hity, gMouseDepth); NxDistanceJointDesc desc; desc.actor[0] = gMouseSphere; desc.actor[1] = gHitActor; gMouseSphere->getGlobalPose().multiplyByInverseRT(hit.worldImpact, desc.localAnchor[0]); gHitActor->getGlobalPose().multiplyByInverseRT(hit.worldImpact, desc.localAnchor[1]); desc.spring.damper = 1; desc.spring.spring = 200; desc.flags |= NX_DJF_MAX_DISTANCE_ENABLED | NX_DJF_SPRING_ENABLED; NxJoint* joint = gScene->createJoint(desc); gMouseJoint = (NxDistanceJoint*)joint->is(NX_JOINT_DISTANCE); } }
virtual void onTrigger(NxShape& triggerShape, NxShape& otherShape, NxTriggerFlag status) { // Get our trigger physical. This should definitely have a plPXPhysical plPXPhysical* triggerPhys = (plPXPhysical*)triggerShape.getActor().userData; bool doReport = false; // Get the triggerer. This may be an avatar, which doesn't have a // plPXPhysical, so we have to extract the necessary info. plKey otherKey = nil; hsPoint3 otherPos = plPXConvert::Point(otherShape.getGlobalPosition()); if (plSimulationMgr::fExtraProfile) DetectorLogRed("-->%s %s (status=%x) other@(%f,%f,%f)",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit",status,otherPos.fX,otherPos.fY,otherPos.fZ); plPXPhysical* otherPhys = (plPXPhysical*)otherShape.getActor().userData; if (otherPhys) { otherKey = otherPhys->GetObjectKey(); doReport = triggerPhys->DoReportOn((plSimDefs::Group)otherPhys->GetGroup()); if (!doReport) { if (plSimulationMgr::fExtraProfile) DetectorLogRed("<--Kill collision %s :failed group. US=%x OTHER=(%s)%x",triggerPhys->GetObjectKey()->GetName().c_str(),triggerPhys->GetGroup(),otherPhys->GetObjectKey()->GetName().c_str(),otherPhys->GetGroup()); } } else { bool isController; plPXPhysicalControllerCore* controller = plPXPhysicalControllerCore::GetController(otherShape.getActor(),&isController); if (controller) { if (isController) { #ifdef PHYSX_ONLY_TRIGGER_FROM_KINEMATIC if (plSimulationMgr::fExtraProfile) DetectorLogRed("<--Kill collision %s : ignoring controller events.",triggerPhys->GetObjectKey()->GetName().c_str()); return; #else // else if trigger on both controller and kinematic // only suppress controller collision 'enters' when disabled but let 'exits' continue // ...this is because there are detector regions that are on the edge on ladders that the exit gets missed. if ( ( !controller->IsEnabled() /*&& (status & NX_TRIGGER_ON_ENTER)*/ ) || controller->IsKinematic() ) { if (plSimulationMgr::fExtraProfile) DetectorLogRed("<--Kill collision %s : controller is not enabled.",triggerPhys->GetObjectKey()->GetName().c_str()); return; } #endif // PHYSX_ONLY_TRIGGER_FROM_KINEMATIC } #ifndef PHYSX_ONLY_TRIGGER_FROM_KINEMATIC // if triggering only kinematics, then all should trigger else { // only suppress kinematic collision 'enters' when disabled but let 'exits' continue // ...this is because there are detector regions that are on the edge on ladders that the exit gets missed. if ( !controller->IsKinematic() /*&& (status & NX_TRIGGER_ON_ENTER) */ ) { if (plSimulationMgr::fExtraProfile) DetectorLogRed("<--Kill collision %s : kinematic is not enabled.",triggerPhys->GetObjectKey()->GetName().c_str()); return; } } #endif // PHYSX_ONLY_TRIGGER_FROM_KINEMATIC otherKey = controller->GetOwner(); doReport = triggerPhys->DoReportOn(plSimDefs::kGroupAvatar); if (plSimulationMgr::fExtraProfile ) { if (!doReport) { DetectorLogRed("<--Kill collision %s :failed group. US=%x OTHER=(NotAvatar)",triggerPhys->GetObjectKey()->GetName().c_str(),triggerPhys->GetGroup()); } else { hsPoint3 avpos; controller->GetPositionSim(avpos); DetectorLogRed("-->Avatar at (%f,%f,%f)",avpos.fX,avpos.fY,avpos.fZ); } } } } if (doReport) { #ifdef USE_PHYSX_CONVEXHULL_WORKAROUND if ( triggerPhys->DoDetectorHullWorkaround() ) { if (status & NX_TRIGGER_ON_ENTER && triggerPhys->Should_I_Trigger(status & NX_TRIGGER_ON_ENTER, otherPos) ) { if (plSimulationMgr::fExtraProfile) DetectorLogRed("-->Send Collision (CH) %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit"); plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, true); } else if (status & NX_TRIGGER_ON_ENTER) { if (plSimulationMgr::fExtraProfile) DetectorLogRed("<--Kill collision %s :failed Should I trigger",triggerPhys->GetObjectKey()->GetName().c_str()); } if (status & NX_TRIGGER_ON_LEAVE && triggerPhys->Should_I_Trigger(status & NX_TRIGGER_ON_ENTER, otherPos) ) { if (plSimulationMgr::fExtraProfile) DetectorLogRed("-->Send Collision (CH) %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit"); plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, false); } else if (status & NX_TRIGGER_ON_LEAVE) { if (plSimulationMgr::fExtraProfile) DetectorLogRed("<--Kill collision %s :failed Should I trigger",triggerPhys->GetObjectKey()->GetName().c_str()); } if (!(status & NX_TRIGGER_ON_ENTER) && !(status & NX_TRIGGER_ON_LEAVE) ) { if (plSimulationMgr::fExtraProfile) DetectorLogRed("<--Kill collision %s :failed event(CH)",triggerPhys->GetObjectKey()->GetName().c_str()); } } else { #endif // USE_PHYSX_CONVEXHULL_WORKAROUND if (status & NX_TRIGGER_ON_ENTER) { if (plSimulationMgr::fExtraProfile) DetectorLogRed("-->Send Collision %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit"); plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, true); } if (status & NX_TRIGGER_ON_LEAVE) { if (plSimulationMgr::fExtraProfile) DetectorLogRed("-->Send Collision %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit"); plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, false); } if (!(status & NX_TRIGGER_ON_ENTER) && !(status & NX_TRIGGER_ON_LEAVE) ) { if (plSimulationMgr::fExtraProfile) DetectorLogRed("<--Kill collision %s :failed event",triggerPhys->GetObjectKey()->GetName().c_str()); } #ifdef USE_PHYSX_CONVEXHULL_WORKAROUND } #endif // USE_PHYSX_CONVEXHULL_WORKAROUND } }
void PhysicsManager::onTrigger(NxShape& triggerShape, NxShape& otherShape, NxTriggerFlag status) { NxActor& triggerActor = triggerShape.getActor(); NxActor& otherActor = otherShape.getActor(); CPhysicsTrigger* trigger = (CPhysicsTrigger*)(triggerActor.userData); CPhysicsActor* actor = (CPhysicsActor*)(otherActor.userData); CCharacterController* character = (CCharacterController*)(otherActor.userData); if(trigger) { if(status & NX_TRIGGER_ON_ENTER) { if(actor) { if(actor->componentID() == "CPhysicsActor") { trigger->OnActorEnter(actor); actor->OnTriggerEnter(trigger); return; } } if(character) { if(character->componentID() == "CCharacterController") { trigger->OnControllerEnter(character); character->OnTriggerEnter(trigger); return; } } } if(status & NX_TRIGGER_ON_STAY) { if(actor) { if(actor->componentID() == "CPhysicsActor") { trigger->OnActorStay(actor); actor->OnTriggerStay(trigger); return; } } if(character) { if(character->componentID() == "CCharacterController") { trigger->OnControllerStay(character); character->OnTriggerStay(trigger); return; } } } if(status & NX_TRIGGER_ON_LEAVE) { if(actor) { if(actor->componentID() == "CPhysicsActor") { trigger->OnActorLeave(actor); actor->OnTriggerLeave(trigger); return; } } if(character) { if(character->componentID() == "CCharacterController") { trigger->OnControllerLeave(character); character->OnTriggerLeave(trigger); return; } } } } }
void pWheel2::_tick(float dt) { NxWheelShape *wShape = getWheelShape(); if (!wShape) return; NxVec3 _localVelocity; bool _breaking=false; ////////////////////////////////////////////////////////////////////////// // // // NxWheelContactData wcd; NxShape* contactShape = wShape->getContact(wcd); if (contactShape) { NxVec3 relativeVelocity; if ( !contactShape->getActor().isDynamic()) { relativeVelocity = getActor()->getLinearVelocity(); } else { relativeVelocity = getActor()->getLinearVelocity() - contactShape->getActor().getLinearVelocity(); } NxQuat rotation = getActor()->getGlobalOrientationQuat(); _localVelocity = relativeVelocity; rotation.inverseRotate(_localVelocity); _breaking = false; //NxMath::abs(_localVelocity.z) < ( 0.1 ); // wShape->setAxleSpeed() } float rollAngle = getWheelRollAngle(); rollAngle+=wShape->getAxleSpeed() * (dt* 0.01f); //rollAngle+=wShape->getAxleSpeed() * (1.0f/60.0f /*dt* 0.01f*/); while (rollAngle > NxTwoPi) //normally just 1x rollAngle-= NxTwoPi; while (rollAngle< -NxTwoPi) //normally just 1x rollAngle+= NxTwoPi; setWheelRollAngle(rollAngle); NxMat34& wheelPose = wShape->getGlobalPose(); NxReal stravel = wShape->getSuspensionTravel(); NxReal radius = wShape->getRadius(); //have ground contact? if( contactShape && wcd.contactPosition <= (stravel + radius) ) { wheelPose.t = NxVec3( wheelPose.t.x, wcd.contactPoint.y + getRadius(), wheelPose.t.z ); } else { wheelPose.t = NxVec3( wheelPose.t.x, wheelPose.t.y - getSuspensionTravel(), wheelPose.t.z ); } float rAngle = getWheelRollAngle(); float steer = wShape->getSteerAngle(); NxVec3 p0; NxVec3 dir; /* getWorldSegmentFast(seg); seg.computeDirection(dir); dir.normalize(); */ NxReal r = wShape->getRadius(); NxReal st = wShape->getSuspensionTravel(); NxReal steerAngle = wShape->getSteerAngle(); p0 = wheelPose.t; //cast from shape origin wheelPose.M.getColumn(1, dir); dir = -dir; //cast along -Y. NxReal castLength = r + st; //cast ray this long NxMat33 rot, axisRot, rollRot; rot.rotY( wShape->getSteerAngle() ); axisRot.rotY(0); rollRot.rotX(rAngle); wheelPose.M = rot * wheelPose.M * axisRot * rollRot; setWheelPose(wheelPose); }
/** Creado por Isaac el 13/4/2012 si teneis alguna duda ya sabeis :P */ int CPhysicScene::detectCollisions(Vector3 point, float maxDist, IPhysicObj * *& physicObjects) const { NxSphere worldSphere; worldSphere.center = NxVec3(point.x, point.y, point.z); worldSphere.radius = maxDist; m_pScene->checkOverlapSphere(worldSphere); NxU32 nbShapes = 100; NxShape** result = new NxShape* [nbShapes]; for (NxU32 i = 0; i < nbShapes; ++i) { result[i] = NULL; } unsigned int overlapCount = m_pScene->overlapSphereShapes(worldSphere, NX_ALL_SHAPES, nbShapes, result, NULL ); //variable en la que guardaremos los objetos fisicos que encontremos, abra como mucho, tantos como detecte el overlapSphereShapes IPhysicObj * * resultado = new IPhysicObj*[overlapCount]; for (int i = 0; i < overlapCount; ++i) { resultado[i] = NULL; } //Recorremos lo devuelto por la funcion overlapSphereShapes, y lo transformamos y añadimos a un array de objetos fisicos int numEntidades = 0; for (int i = 0; i < overlapCount; i++) { if( result[i] != NULL ) { //printf("Shape!!!"); //Solo nos interesan las capsulas if (result[i]->isCapsule()) { NxShape* capsula = result[i]; TActorInfo* pActorInfo = (TActorInfo*) capsula->getActor().userData; //printf("Capsul!!!"); IPhysicObj * entidadFisica = pActorInfo->pPhysicObj; resultado[numEntidades] = entidadFisica; ++numEntidades; } } } if (numEntidades) { //Creamos y guardamos el resultado en la variable referenciada que nos pasan, esta la creamos con el tamaño exacto physicObjects = new IPhysicObj*[numEntidades]; for (int i = 0; i < numEntidades; ++i) { physicObjects[i] = resultado[i]; } } else { physicObjects = NULL; } //Destruimos el array de punteros anterior; delete resultado; return numEntidades; }
void NxVehicle::handleContactPair(NxContactPair& pair, NxU32 carIndex) { NxContactStreamIterator i(pair.stream); while(i.goNextPair()) { NxShape * s = i.getShape(carIndex); while(i.goNextPatch()) { const NxVec3& contactNormal = i.getPatchNormal(); while(i.goNextPoint()) { //user can also call getPoint() and getSeparation() here const NxVec3& contactPoint = i.getPoint(); //add forces: //assuming front wheel drive we need to apply a force at the wheels. if (s->is(NX_SHAPE_CAPSULE) && s->userData != NULL) { //assuming only the wheels of the car are capsules, otherwise we need more checks. //this branch can't be pulled out of loops because we have to do a full iteration through the stream NxQuat local2global = s->getActor().getGlobalOrientationQuat(); NxWheel* w = (NxWheel*)s->userData; if (!w->getWheelFlag(NX_WF_USE_WHEELSHAPE)) { NxWheel1 * wheel = static_cast<NxWheel1*>(w); wheel->contactInfo.otherActor = pair.actors[1-carIndex]; wheel->contactInfo.contactPosition = contactPoint; wheel->contactInfo.contactPositionLocal = contactPoint; wheel->contactInfo.contactPositionLocal -= _bodyActor->getGlobalPosition(); local2global.inverseRotate(wheel->contactInfo.contactPositionLocal); wheel->contactInfo.contactNormal = contactNormal; if (wheel->contactInfo.otherActor->isDynamic()) { NxVec3 globalV = s->getActor().getLocalPointVelocity(wheel->getWheelPos()); globalV -= wheel->contactInfo.otherActor->getLinearVelocity(); local2global.inverseRotate(globalV); wheel->contactInfo.relativeVelocity = globalV.x; //printf("%2.3f (%2.3f %2.3f %2.3f)\n", wheel->contactInfo.relativeVelocity, // globalV.x, globalV.y, globalV.z); } else { NxVec3 vel = s->getActor().getLocalPointVelocity(wheel->getWheelPos()); local2global.inverseRotate(vel); wheel->contactInfo.relativeVelocity = vel.x; wheel->contactInfo.relativeVelocitySide = vel.z; } NX_ASSERT(wheel->hasGroundContact()); //printf(" Wheel %x is touching\n", wheel); } } } } } //printf("----\n"); }