void plSwimStrategy::Apply(float delSecs) { hsVector3 velocity = fController->GetLinearVelocity(); hsVector3 achievedVelocity = fController->GetAchievedLinearVelocity(); IAdjustBuoyancy(); //trying to dampen the oscillations float retardent = 0.0f; static float finalBobSpeed = 0.5f; if ((achievedVelocity.fZ > finalBobSpeed) || (achievedVelocity.fZ < -finalBobSpeed)) retardent = achievedVelocity.fZ * -0.90f; float zacc = (1.0f - fBuoyancy) * kGravity + retardent; velocity.fZ += (zacc * delSecs); velocity.fZ += achievedVelocity.fZ; // Water Current if (fCurrentRegion != nil) { float angCurrent = 0.0f; hsVector3 linCurrent(0.0f, 0.0f, 0.0f); fCurrentRegion->GetCurrent(fController, linCurrent, angCurrent, delSecs); if (hsABS(angCurrent) > 0.0001f) fController->IncrementAngle(angCurrent * delSecs); velocity += linCurrent; if (velocity.fZ > fCurrentRegion->fMaxUpwardVel) velocity.fZ = fCurrentRegion->fMaxUpwardVel; } if (velocity.fZ < kTerminalVelocity) velocity.fZ = kTerminalVelocity; // Convert to displacement vector hsVector3 displacement = velocity * delSecs; // Reset vars and move controller // fController->SetPushingPhysical(nil); fController->SetFacingPushingPhysical(false); fHadContacts = fOnGround = false; unsigned int collideResults = 0; unsigned int collideFlags = 1<<plSimDefs::kGroupStatic | 1<<plSimDefs::kGroupAvatarBlocker | 1<<plSimDefs::kGroupDynamic; if (!fController->IsSeeking()) collideFlags |= (1<<plSimDefs::kGroupExcludeRegion); fController->Move(displacement, collideFlags, collideResults); if ((collideResults & kBottom) || (collideResults & kSides)) fHadContacts = true; }
void plSwimStrategy::Apply(float delSecs) { hsAssert(fCore,"PlSwimStrategy::Apply No Core shouldn't be Applying"); uint32_t collideFlags = 1<<plSimDefs::kGroupStatic | 1<<plSimDefs::kGroupAvatarBlocker | 1<<plSimDefs::kGroupDynamic; if(!fCore->IsSeeking()) { collideFlags|=(1<<plSimDefs::kGroupExcludeRegion); } hsVector3 LinearVelocity=fCore->GetLinearVelocity(); hsVector3 AchievedLinearVelocity=fCore->GetAchievedLinearVelocity(); if (fCore->IsKinematic()) { plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded()); if (so) { // If we've been moved since the last physics update (somebody warped us), // update the physics before we apply velocity. const hsMatrix44& l2w = so->GetCoordinateInterface()->GetLocalToWorld(); if (!CompareMatrices(l2w, fCore->GetLastGlobalLoc(), .0001f)) { fCore->SetKinematicLoc(l2w); fCore->SetGlobalLoc(l2w); } } return; } if (!fCore->IsEnabled()) return; fCore->SetPushingPhysical(nil); fCore->SetFacingPushingPhysical( false); fHadContacts=false; fOnGround=false; plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded()); if (so) { // If we've been moved since the last physics update (somebody warped us), // update the physics before we apply velocity. const hsMatrix44& l2w = so->GetCoordinateInterface()->GetLocalToWorld(); if (!CompareMatrices(l2w, fCore->GetLastGlobalLoc(), .0001f)) fCore->SetGlobalLoc(l2w); // Convert our avatar relative velocity to subworld relative if (!LinearVelocity.IsEmpty()) { LinearVelocity = l2w * LinearVelocity; const plCoordinateInterface* subworldCI = fCore->GetSubworldCI(); if (subworldCI) LinearVelocity = subworldCI->GetWorldToLocal() * LinearVelocity; } IAdjustBuoyancy(); float zacc; float retardent=0.0f; static float FinalBobSpeed=0.5f; //trying to dampen the oscillations if((AchievedLinearVelocity.fZ>FinalBobSpeed)||(AchievedLinearVelocity.fZ<-FinalBobSpeed)) retardent=AchievedLinearVelocity.fZ *-.90f; zacc=(1-fBuoyancy)*-32.f + retardent; hsVector3 linCurrent(0.0f,0.0f,0.0f); float angCurrent = 0.f; if (fCurrentRegion != nil) { fCurrentRegion->GetCurrent(fCore, linCurrent, angCurrent, delSecs); //fAngularVelocity+= angCurrent; } hsVector3 vel(LinearVelocity.fX , LinearVelocity.fY , AchievedLinearVelocity.fZ+ LinearVelocity.fZ ); vel.fZ= vel.fZ + zacc*delSecs; if(fCurrentRegion!=nil){ if (vel.fZ > fCurrentRegion->fMaxUpwardVel) { vel.fZ = fCurrentRegion->fMaxUpwardVel; } vel+= linCurrent; } static const float kGravity = -32.f; if(vel.fZ<kGravity) {//applying this terminal velocity just to avoid shooting 100 feet below the surface // and losing our surface ray cast vel.fZ =kGravity; } hsVector3 displacement= vel*delSecs; unsigned int colFlags = 0; fContactNormals.SetCount(0); fCore->Move(displacement,collideFlags,colFlags); if((colFlags&kBottom)||(colFlags&kSides))fHadContacts=true; float angvel=fCore->GetAngularVelocity(); fCore->SetAngularVelocity(angvel +angCurrent); } }