You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
610 lines
18 KiB
610 lines
18 KiB
/*==LICENSE==* |
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools |
|
Copyright (C) 2011 Cyan Worlds, Inc. |
|
|
|
This program is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
or by snail mail at: |
|
Cyan Worlds, Inc. |
|
14617 N Newport Hwy |
|
Mead, WA 99021 |
|
|
|
*==LICENSE==*/ |
|
//#pragma warning(disable: 4503 4786) |
|
//#define HK_HARDCORE |
|
// |
|
//#include <hkmath/vector3.h> // for havok Vector3 |
|
////#include <.//gpi/math/quaternion.h> // for havok Vector3 |
|
//#include <hkgeometry/geomdef.h> // for havok Vertex |
|
// |
|
// |
|
//#include "hsTypes.h" |
|
//#include "../plInterp/plController.h" |
|
//#include "plPlayerModifier.h" |
|
//#include "hsTimer.h" |
|
//#include "../pnSceneObject/plSceneObject.h" |
|
//#include "../pnSceneObject/plSimulationInterface.h" |
|
//#include "../pnInputCore/plControlEventCodes.h" |
|
//#include "../pnMessage/plTimeMsg.h" |
|
//#include "../pnMessage/plWarpMsg.h" |
|
//#include "../pnMessage/plCameraMsg.h" |
|
//#include "../pnSceneObject/plCoordinateInterface.h" |
|
//#include "plgDispatch.h" |
|
//#include "../pfCamera/plCameraModifier.h" |
|
//#include "hsResMgr.h" |
|
//#include "../pnKeyedObject/plKey.h" |
|
//#include "../plNetClient/plNetClientMgr.h" |
|
//#include "../plModifier/plSpawnModifier.h" |
|
//#include "../plMessage/plMatrixUpdateMsg.h" |
|
// |
|
//#include "../pnTimer/plTimerCallbackManager.h" |
|
//#include "../plAudio/plAudioSystem.h" |
|
//#include "../plMessage/plInputEventMsg.h" |
|
//#include "../plMessage/plSpawnRequestMsg.h" |
|
//#include "../plMessage/plSpawnModMsg.h" |
|
//#include "../plMessage/plPlayerMsg.h" |
|
//#include "../pnMessage/plAudioSysMsg.h" |
|
//#include "../pfCamera/plCameraBrain.h" |
|
// |
|
//#include "../plHavok1/plHKPhysical.h" |
|
// |
|
//hsScalar plPlayerModifier::fTurnRate = 1.0f; |
|
//hsScalar plPlayerModifier::fAcceleration = 80.0f; |
|
//hsScalar plPlayerModifier::fDeceleration = 80.0f; |
|
//hsScalar plPlayerModifier::fMaxVelocity = 200.0f; |
|
// |
|
//plPlayerModifier::plPlayerModifier() : |
|
//bUseDesiredFacing(false), |
|
//bUseDesiredMatrix(false) |
|
//{ |
|
// fCurSpeed = 0.0f; |
|
// fLastTime = 0.0; |
|
// bMoving = false; |
|
// fRotationScalar = 1.0f; |
|
// bIgnoreDesiredMatrix = false; |
|
// SetFlag( kWantsToSpawn ); |
|
//} |
|
// |
|
//plPlayerModifier::~plPlayerModifier() |
|
//{ |
|
// for (int i = 0; i < fSpawnPoints.Count(); i++) |
|
// delete fSpawnPoints[i]; |
|
// fSpawnPoints.SetCount(0); |
|
//} |
|
// |
|
//// Adding RemoveTarget override of plSingleModifier to tell everyone we |
|
//// told in AddTarget about our subject that he's gone now. |
|
//void plPlayerModifier::RemoveTarget(plSceneObject* so) |
|
//{ |
|
// if( fTarget && fTarget->IsLocallyOwned()==plSynchedObject::kYes ) |
|
// { |
|
// plCameraMsg* pMsg = TRACKED_NEW plCameraMsg; |
|
// pMsg->SetCmd(plCameraMsg::kSetSubject); |
|
// pMsg->SetSubject(nil); |
|
// pMsg->SetBCastFlag( plMessage::kBCastByExactType ); |
|
// plgDispatch::MsgSend(pMsg); |
|
// |
|
// plAudioSysMsg* pAudMsg1 = TRACKED_NEW plAudioSysMsg(plAudioSysMsg::kSetListenerCoordinateRefCamera); |
|
// plAudioSysMsg* pAudMsg2 = TRACKED_NEW plAudioSysMsg(plAudioSysMsg::kSetListenerVelocityRefCamera); |
|
// plAudioSysMsg* pAudMsg3 = TRACKED_NEW plAudioSysMsg(plAudioSysMsg::kSetListenerFacingRefCamera); |
|
// plgDispatch::MsgSend(pAudMsg1); |
|
// plgDispatch::MsgSend(pAudMsg2); |
|
// plgDispatch::MsgSend(pAudMsg3); |
|
// } |
|
// plSingleModifier::RemoveTarget(so); |
|
//} |
|
// |
|
//void plPlayerModifier::AddTarget(plSceneObject* so) |
|
//{ |
|
// fTarget = so; |
|
// plSimulationInterface * pSI = IGetTargetSimulationInterface(0); // so->GetSimulationInterface(); // |
|
// |
|
// plgDispatch::Dispatch()->RegisterForExactType(plEvalMsg::Index(), GetKey()); |
|
// |
|
// // set the desired rotation vector... |
|
//// hsAssert(fTarget->GetCoordinateInterface(), "Player modifier target has no coordinate interface"); |
|
// |
|
// // These are now set in the component |
|
//// if(pSI) |
|
//// { |
|
//// pSI->SetProperty(plSimulationInterface::kAffectLOS, false); |
|
//// pSI->SetProperty(kUpright, true); |
|
//// } |
|
// |
|
// // |
|
// // setup for local player if necessary |
|
// // |
|
// int locallyOwned=so->IsLocallyOwned(); |
|
// if (locallyOwned==plSynchedObject::kMaybe) // don't know since we're still loading, defer |
|
// SetFlag(kNeedsLocalSetup); |
|
// else if (locallyOwned==plSynchedObject::kYes) |
|
// IDoLocalSetup(so); |
|
//} |
|
// |
|
//void plPlayerModifier::IDoLocalSetup(plSceneObject* so) |
|
//{ |
|
// plCameraMsg* pMsg = TRACKED_NEW plCameraMsg; |
|
// pMsg->SetCmd(plCameraMsg::kSetSubject); |
|
// pMsg->SetSubject(so); |
|
// pMsg->SetBCastFlag( plMessage::kBCastByExactType ); |
|
// plgDispatch::MsgSend(pMsg); |
|
// |
|
// // this is to solve the problem of physical vs nonphysical players... |
|
//// plCameraMsg* pMsg2 = TRACKED_NEW plCameraMsg; |
|
//// pMsg2->SetBCastFlag(plMessage::kBCastByExactType); |
|
//// pMsg2->SetCmd(plCameraMsg::kSetOffset); |
|
//// pMsg2->SetCmd(plCameraMsg::kEntering); |
|
//// pMsg2->SetTriggerer(so->GetKey()); |
|
//// pMsg2->SetOffsetY(50); |
|
//// pMsg2->SetOffsetZ(10); |
|
//// plgDispatch::MsgSend(pMsg2); |
|
//} |
|
// |
|
//void plPlayerModifier::IMakeUsListener( plSceneObject *so ) |
|
//{ |
|
// // set the listener to use us... |
|
// plAudioSysMsg* pAudMsg1 = TRACKED_NEW plAudioSysMsg(plAudioSysMsg::kSetListenerFacingRef); |
|
// pAudMsg1->SetSceneObject(so->GetKey()); |
|
// plAudioSysMsg* pAudMsg2 = TRACKED_NEW plAudioSysMsg(plAudioSysMsg::kSetListenerCoordinateRef); |
|
// pAudMsg2->SetSceneObject(so->GetKey()); |
|
// plAudioSysMsg* pAudMsg3 = TRACKED_NEW plAudioSysMsg(plAudioSysMsg::kSetListenerVelocityRef); |
|
// pAudMsg3->SetSceneObject(so->GetKey()); |
|
// plgDispatch::MsgSend(pAudMsg1); |
|
// plgDispatch::MsgSend(pAudMsg2); |
|
// plgDispatch::MsgSend(pAudMsg3); |
|
// |
|
// // Now that we have a valid listener, unmute the audio system |
|
// plgAudioSys::SetMuted( false ); |
|
//} |
|
// |
|
//hsBool plPlayerModifier::MsgReceive(plMessage* msg) |
|
//{ |
|
// plControlEventMsg* pCommandMsg = plControlEventMsg::ConvertNoRef(msg); |
|
// if (pCommandMsg) |
|
// return(HandleControlInput(pCommandMsg)); |
|
// |
|
// plMatrixUpdateMsg* pMMsg = plMatrixUpdateMsg::ConvertNoRef( msg ); |
|
// if (pMMsg && HasFlag(kHasSpawned)) |
|
// { |
|
// hsAssert(GetTarget()->IsLocallyOwned()==plSynchedObject::kNo, "master objects should not get correction msgs"); |
|
// fDesiredMatrix = pMMsg->fMatrix; |
|
// if (bIgnoreDesiredMatrix) |
|
// bIgnoreDesiredMatrix = false; |
|
// else |
|
// { |
|
// bUseDesiredMatrix = true; |
|
// } |
|
// return true; |
|
// } |
|
// |
|
// plSpawnModMsg* pSpawn = plSpawnModMsg::ConvertNoRef(msg); |
|
// if (pSpawn && HasFlag(kWantsToSpawn)) |
|
// { |
|
// spawnPt* pt = TRACKED_NEW spawnPt; |
|
// pt->pt = pSpawn->fPos; |
|
// |
|
// hsVector3 temp(fTarget->GetCoordinateInterface()->GetLocalToWorld().GetTranslate() - pt->pt); |
|
// pt->dist = temp.MagnitudeSquared(); |
|
// fSpawnPoints.Append(pt); |
|
// } |
|
// plPlayerMsg* pPMsg = plPlayerMsg::ConvertNoRef(msg); |
|
// if (pPMsg) |
|
// { |
|
// if (pPMsg->Cmd(plPlayerMsg::kWarpToSpawnPoint)) |
|
// { |
|
// WarpToSpawnPoint(); |
|
// return true; |
|
// } |
|
// } |
|
// return plSingleModifier::MsgReceive(msg); |
|
//} |
|
// |
|
//hsBool plPlayerModifier::HandleControlInput(plControlEventMsg* pMsg) |
|
//{ |
|
// hsBool ret=false; |
|
// |
|
// if (pMsg->ControlActivated() && (pMsg->GetControlCode() == B_CONTROL_ROTATE_RIGHT || pMsg->GetControlCode() == B_CONTROL_ROTATE_LEFT || pMsg->GetControlCode() == A_CONTROL_TURN)) |
|
// { |
|
// fRotationScalar = pMsg->GetPct(); |
|
// if ( HasMovementFlag( pMsg->GetControlCode() ) ) |
|
// bIgnoreDesiredMatrix = true; |
|
// } |
|
// if (pMsg->ControlActivated() && !HasMovementFlag( pMsg->GetControlCode() ) ) |
|
// { |
|
// SetMovementFlag( pMsg->GetControlCode() ); |
|
// if ( pMsg->GetControlCode() == B_CONTROL_TURN_TO ) |
|
// { |
|
// //fFacingTarget = pMsg->GetTurnToPt(); |
|
// } |
|
// } |
|
// else |
|
// if ( !pMsg->ControlActivated() && HasMovementFlag( pMsg->GetControlCode() ) ) |
|
// { |
|
// ClearMovementFlag( pMsg->GetControlCode() ); |
|
// } |
|
// |
|
// ret = true; |
|
// return ret; |
|
//} |
|
// |
|
//void plPlayerModifier::SetMoving(hsBool b) |
|
//{ |
|
// if (b != bMoving) |
|
// { |
|
// plPlayerMsg* pMsg = TRACKED_NEW plPlayerMsg; |
|
// |
|
// if (b) |
|
// pMsg->SetCmd( plPlayerMsg::kMovementStarted ); |
|
// else |
|
// pMsg->SetCmd( plPlayerMsg::kMovementStopped ); |
|
// |
|
// plgDispatch::MsgSend( pMsg ); |
|
// bMoving = b; |
|
// } |
|
//} |
|
// |
|
// |
|
//hsPoint3 forceForward(0,-200,0); |
|
//hsPoint3 forceRight(-200,0,0); |
|
//hsPoint3 forceUp(0,0,15); |
|
// |
|
//hsBool plPlayerModifier::IEval(double secs, hsScalar del, UInt32 dirty) |
|
//{ |
|
// // setup for local player if necessary |
|
// if (HasFlag(kNeedsLocalSetup)) |
|
// { |
|
// int locallyOwned=fTarget->IsLocallyOwned(); |
|
// if (locallyOwned==plSynchedObject::kYes) |
|
// IDoLocalSetup(fTarget); |
|
// else |
|
// if (locallyOwned==plSynchedObject::kNo) |
|
// ClearFlag(kNeedsLocalSetup); |
|
// } |
|
// |
|
// if (HasFlag(kWantsToSpawn)) |
|
// { |
|
// if (fTarget->IsLocallyOwned()==plSynchedObject::kNo) |
|
// { |
|
// // if our target is a proxy player, don't warp him to a spawn point; |
|
// // we will receive his location as a state update. |
|
// ClearFlag(kWantsToSpawn); |
|
// } |
|
// else |
|
// if (fSpawnPoints.Count() |
|
// // if MP game, make sure we're connected before spawning |
|
// && (!plNetClientMgr::GetInstance()->IsEnabled() || |
|
// plNetClientMgr::GetInstance()->HasJoined()) |
|
// ) |
|
// { |
|
// int i; |
|
//#if 0 |
|
// for (i = 0; i < fSpawnPoints.Count(); i++) |
|
// { |
|
// for (int j = i + 1; j < fSpawnPoints.Count(); j++) |
|
// { |
|
// if (fSpawnPoints[j]->dist < fSpawnPoints[i]->dist) |
|
// { |
|
// spawnPt* pt; |
|
// pt = fSpawnPoints[j]; |
|
// fSpawnPoints[j] = fSpawnPoints[i]; |
|
// fSpawnPoints[i] = pt; |
|
// } |
|
// } |
|
// } |
|
// hsPoint3 warpPoint = fSpawnPoints[0]->pt; |
|
//#else |
|
// // choose spawnPoint based on netID, not distance |
|
// int netID = plNetClientMgr::GetInstance()->GetClientNum(); |
|
// if (netID==-1) |
|
// netID=0; |
|
// hsPoint3 warpPoint = netID>=fSpawnPoints.Count() ? |
|
// fSpawnPoints[fSpawnPoints.Count()-1]->pt : fSpawnPoints[netID]->pt; |
|
//#endif |
|
// // Send msg for net synchronization |
|
// plWarpMsg* warpMsg = TRACKED_NEW plWarpMsg; |
|
// warpMsg->fPos = warpPoint; |
|
// warpMsg->AddReceiver( fTarget->GetKey() ); |
|
// warpMsg->SetWarpFlags(warpMsg->GetWarpFlags() | plWarpMsg::kFlushTransform | plWarpMsg::kZeroVelocity ); |
|
// plgDispatch::MsgSend( warpMsg ); |
|
//#ifdef HS_DEBUGGING |
|
// char str[256]; |
|
// sprintf(str, "%s has %d spawnPoints. Using pt %f %f %f\n", |
|
// GetKeyName(), fSpawnPoints.GetCount(), |
|
// fSpawnPoints[0]->pt.fX,fSpawnPoints[0]->pt.fY,fSpawnPoints[0]->pt.fZ); |
|
// hsStatusMessage(str); |
|
//#endif |
|
// for (i = 0; i < fSpawnPoints.Count(); i++) |
|
// delete fSpawnPoints[i]; |
|
// |
|
// fSpawnPoints.SetCount(0); |
|
// ClearFlag(kWantsToSpawn); |
|
// } |
|
// else |
|
// { |
|
// plSpawnRequestMsg* pMsg = TRACKED_NEW plSpawnRequestMsg; |
|
// pMsg->SetSender(GetKey()); |
|
// plgDispatch::MsgSend( pMsg ); |
|
// } |
|
// bIgnoreDesiredMatrix = true; |
|
// return true; |
|
// } |
|
// else |
|
// { |
|
// if( !HasFlag( kHasSpawned ) ) |
|
// { |
|
// // Don't make us listener until we have actually spawned |
|
// IMakeUsListener( fTarget ); |
|
// SetFlag(kHasSpawned); |
|
// } |
|
// } |
|
// |
|
// if (!fTarget->GetCoordinateInterface()) |
|
// return true; |
|
// |
|
// // update our desired position: |
|
//// hsScalar eTime = secs - fLastTime; |
|
// hsScalar eTime = hsTimer::GetDelSysSeconds(); |
|
// |
|
// hsPoint3 newLinearForce(0,0,0); |
|
// |
|
// hsMatrix44 targetMatrix; |
|
// if (bUseDesiredMatrix) |
|
// targetMatrix = fDesiredMatrix; |
|
// else |
|
// targetMatrix = fTarget->GetCoordinateInterface()->GetLocalToWorld(); |
|
// hsPoint3 playerPos = targetMatrix.GetTranslate(); |
|
// hsVector3 view, up, right; |
|
// targetMatrix.GetAxis(&view, &up, &right); |
|
// |
|
// hsScalar speed = fMaxVelocity; |
|
// hsScalar turn = fTurnRate; |
|
// |
|
// if (HasMovementFlag(B_CONTROL_MODIFIER_FAST)) |
|
// { |
|
// turn *= 0.25; |
|
// speed *= 3.5; |
|
// } |
|
// if (HasMovementFlag(B_CONTROL_MOVE_FORWARD)) |
|
// { |
|
// playerPos += view * speed * eTime; |
|
// newLinearForce = newLinearForce + forceForward * speed * eTime; // calc force for physics |
|
// } |
|
// if (HasMovementFlag(B_CONTROL_MOVE_BACKWARD)) |
|
// { |
|
// playerPos += view * speed * eTime * -1; |
|
// newLinearForce = newLinearForce + forceForward * speed * eTime * -1; // calc force for physics |
|
// } |
|
// if (HasMovementFlag(B_CONTROL_STRAFE_LEFT)) |
|
// { |
|
// playerPos += right * speed * eTime * -1; |
|
// |
|
// newLinearForce = newLinearForce + forceRight * speed * eTime * -1; |
|
// } |
|
// if (HasMovementFlag(B_CONTROL_STRAFE_RIGHT)) |
|
// { |
|
// playerPos += right * speed * eTime; |
|
// |
|
// newLinearForce = newLinearForce + forceRight * speed * eTime; |
|
// } |
|
// if (HasMovementFlag(B_CONTROL_MOVE_DOWN)) |
|
// { |
|
// playerPos += up * speed * eTime * -1; |
|
// |
|
// newLinearForce = newLinearForce + forceUp * speed * eTime * -1; |
|
// } |
|
// if (HasMovementFlag(B_CONTROL_MOVE_UP)) |
|
// { |
|
// playerPos += up * speed * eTime; |
|
// |
|
// newLinearForce = newLinearForce + forceUp * speed * eTime; |
|
// } |
|
// |
|
// |
|
// fDesiredPosition = playerPos; |
|
// |
|
// // move toward our desired position... |
|
// |
|
// hsPoint3 curPos = targetMatrix.GetTranslate(); |
|
// hsPoint3 newPos; |
|
// |
|
// hsVector3 dir(fDesiredPosition - curPos); |
|
// hsScalar distToGoal=dir.Magnitude(); |
|
// |
|
// if (dir.MagnitudeSquared() > 0.0f) |
|
// dir.Normalize(); |
|
// |
|
// hsVector3 vel( view * fCurSpeed ); |
|
// |
|
// IAdjustVelocity(fAcceleration, fDeceleration, &dir, &vel, fMaxVelocity, distToGoal, eTime); |
|
// fCurSpeed = vel.Magnitude(); |
|
// |
|
// hsScalar distMoved = IClampVelocity(&vel, fMaxVelocity, eTime); |
|
// |
|
// // compute final pos |
|
// if (distMoved > distToGoal) |
|
// newPos = fDesiredPosition; |
|
// else |
|
// newPos = curPos + vel; |
|
// |
|
// // calculate rotation matrix |
|
// |
|
// hsVector3 rotUp(0,0,1); |
|
// hsVector3 rotRight(1,0,0); |
|
// hsMatrix44 rot; |
|
// |
|
// if ( HasMovementFlag( B_CONTROL_TURN_TO ) ) |
|
// { |
|
// // compute view goal |
|
// |
|
// hsVector3 fPlayerViewGoal(&fFacingTarget,&curPos); |
|
// fPlayerViewGoal.fZ = 0; |
|
// fPlayerViewGoal.Normalize(); |
|
// |
|
// // compute degrees needed to turn left/right |
|
// hsVector3 cross = fPlayerViewGoal % view; |
|
// hsScalar dot = fPlayerViewGoal * view; |
|
// hsScalar rad = hsACosine(dot); |
|
// fRotationScalar = 1.0f; |
|
// |
|
// if (cross.fZ<0) |
|
// { |
|
// SetMovementFlag( B_CONTROL_ROTATE_LEFT ); |
|
// } |
|
// else |
|
// { |
|
// SetMovementFlag( B_CONTROL_ROTATE_RIGHT ); |
|
// } |
|
// if (dot >= 0.999f) |
|
// { |
|
// ClearMovementFlag( B_CONTROL_TURN_TO ); |
|
// ClearMovementFlag( B_CONTROL_ROTATE_RIGHT ); |
|
// ClearMovementFlag( B_CONTROL_ROTATE_LEFT ); |
|
// } |
|
// } |
|
// |
|
// hsScalar angle = 0; |
|
// |
|
// if ( HasMovementFlag( B_CONTROL_ROTATE_RIGHT ) ) |
|
// { |
|
// angle = fTurnRate * eTime * -1 * fRotationScalar; |
|
// } |
|
// |
|
// if ( HasMovementFlag( B_CONTROL_ROTATE_LEFT ) || HasMovementFlag( A_CONTROL_TURN ) ) |
|
// { |
|
// angle = fTurnRate * eTime * fRotationScalar; |
|
// } |
|
// |
|
// hsMatrix44 justRot(targetMatrix); |
|
// hsPoint3 zero(0,0,0); |
|
// justRot.SetTranslate(&zero); |
|
// |
|
// if(angle) { |
|
// hsQuat q(angle, &rotUp); |
|
// q.NormalizeIfNeeded(); |
|
// q.MakeMatrix(&rot); |
|
// |
|
// justRot = rot * justRot; |
|
// |
|
// targetMatrix = rot * targetMatrix; |
|
// } |
|
// |
|
// // use the desired rotation matrix to set position and rotation: |
|
// |
|
// |
|
// plSimulationInterface * SI = IGetTargetSimulationInterface(0); |
|
// |
|
// if(SI) |
|
// { |
|
// Havok::Vector3 hkLocalForce(newLinearForce.fX, newLinearForce.fY, newLinearForce.fZ); |
|
// if (bUseDesiredMatrix) |
|
// { |
|
// hsMatrix44 inv; |
|
// |
|
// fDesiredMatrix.GetInverse(&inv); |
|
// |
|
// // we're just going to set the position on the simulation interface directly |
|
// // because it will then be further modified by the simulation and its final position |
|
// // will *then* be sent to the coordinate interface |
|
// SI->SetTransform(fDesiredMatrix, inv); |
|
// } |
|
// |
|
// SI->SetRotation(justRot);//rot); |
|
// SI->ApplyForce(plSimulationInterface::kForce, hkLocalForce); |
|
// } else { |
|
// hsMatrix44 inv; |
|
// targetMatrix.SetTranslate(&newPos); |
|
// targetMatrix.GetInverse(&inv); |
|
// |
|
// plCoordinateInterface* pCI = pCI = IGetTargetCoordinateInterface(0); |
|
// pCI->SetTransform(targetMatrix, inv); |
|
// |
|
// |
|
// } |
|
// |
|
// fLastTime = secs; |
|
// SetMoving(fCurSpeed); |
|
// |
|
// if (bUseDesiredMatrix) |
|
// bUseDesiredMatrix = false; |
|
// return true; |
|
//} |
|
// |
|
//// |
|
//// vector version. dir vector should be normalized |
|
//// |
|
//void plPlayerModifier::IAdjustVelocity(hsScalar adjAccelRate, hsScalar adjDecelRate, |
|
// hsVector3* dir, hsVector3* vel, hsScalar maxSpeed, |
|
// hsScalar distToGoal, double elapsedTime) |
|
//{ |
|
// hsScalar speed = vel->Magnitude(); // save current speed |
|
// *vel = *dir * speed; // change vel to correct dir |
|
// |
|
// // compute accel/decel |
|
// hsScalar finalAccelRate; |
|
// if (IShouldDecelerate(adjDecelRate, speed, distToGoal)) |
|
// { |
|
// finalAccelRate = -adjDecelRate; |
|
// } |
|
// else |
|
// { |
|
// finalAccelRate = adjAccelRate; |
|
// } |
|
// |
|
// if (finalAccelRate != 0) |
|
// { |
|
// // compute accel vector in the direction of the goal |
|
// hsVector3 accelVec = *dir * finalAccelRate; |
|
// accelVec = accelVec * elapsedTime; |
|
// |
|
// // add acceleration to velocity |
|
// *vel = *vel + accelVec; |
|
// } |
|
// else |
|
// { |
|
// *vel = *dir * maxSpeed; |
|
// } |
|
//} |
|
// |
|
//hsScalar plPlayerModifier::IClampVelocity(hsVector3* vel, hsScalar maxSpeed, double elapsedTime) |
|
//{ |
|
// *vel = *vel * elapsedTime; |
|
// maxSpeed *= elapsedTime; |
|
// |
|
// // clamp speed (clamp if going negative?) |
|
// hsScalar distMoved = vel->Magnitude(); |
|
// if (distMoved > maxSpeed) |
|
// { |
|
// vel->Normalize(); |
|
// *vel = *vel * maxSpeed; |
|
// return maxSpeed; |
|
// } |
|
// return distMoved; |
|
//} |
|
// |
|
//hsBool32 plPlayerModifier::IShouldDecelerate(hsScalar decelSpeed, hsScalar curSpeed, hsScalar distToGoal) |
|
//{ |
|
// if (decelSpeed == 0) |
|
// // no deceleration |
|
// return false; |
|
// |
|
// // compute distance required to stop, given decel speed (in units/sec sq) |
|
// hsScalar stopTime = curSpeed / decelSpeed; |
|
// hsScalar avgSpeed = curSpeed * .5f; |
|
// hsScalar stopDist = avgSpeed * stopTime; |
|
// |
|
// return (hsABS(distToGoal) <= hsABS(stopDist)); // stopDist+avgSpeed? |
|
//} |
|
//
|
|
|