/*==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 . 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==*/ // local includes #include "plAvBrainDrive.h" #include "plArmatureMod.h" #include "plAvCallbackAction.h" // global includes #include "hsTimer.h" #include "hsGeometry3.h" // other includes #include "hsQuat.h" #include "../plMessage/plSimStateMsg.h" #include "../pnMessage/plCameraMsg.h" // messages #include "../plMessage/plInputEventMsg.h" // CTOR default plAvBrainDrive::plAvBrainDrive() : fMaxVelocity(20), fTurnRate(1) { } // CTOR max velocity, turn rate plAvBrainDrive::plAvBrainDrive(hsScalar maxVelocity, hsScalar turnRate) : fMaxVelocity(maxVelocity), fTurnRate(turnRate) { } // ACTIVATE void plAvBrainDrive::Activate(plArmatureModBase *avMod) { plArmatureBrain::Activate(avMod); IEnablePhysics(false, avMod->GetTarget(0)->GetKey()); plCameraMsg* pMsg = TRACKED_NEW plCameraMsg; pMsg->SetCmd(plCameraMsg::kNonPhysOn); pMsg->SetBCastFlag(plMessage::kBCastByExactType); pMsg->Send(); } // DEACTIVATE void plAvBrainDrive::Deactivate() { if (fAvMod) { IEnablePhysics(true, fAvMod->GetTarget(0)->GetKey()); plCameraMsg* pMsg = TRACKED_NEW plCameraMsg; pMsg->SetCmd(plCameraMsg::kNonPhysOff); pMsg->SetBCastFlag(plMessage::kBCastByExactType); pMsg->Send(); } } void plAvBrainDrive::IEnablePhysics(bool enable, plKey avKey) { fAvMod->EnablePhysics(enable); } // APPLY hsBool plAvBrainDrive::Apply(double timeNow, hsScalar elapsed) { plSceneObject * avSO = fAvMod->GetTarget(0); hsScalar eTime = hsTimer::GetDelSysSeconds(); hsMatrix44 targetMatrix = avSO->GetLocalToWorld(); hsPoint3 playerPos = targetMatrix.GetTranslate(); hsVector3 view, up, right; targetMatrix.GetAxis(&view, &up, &right); hsScalar speed = fMaxVelocity; hsScalar turn = fTurnRate; if (fAvMod->FastKeyDown()) { turn *= 0.25; speed *= 3.5; } if (fAvMod->GetInputFlag(B_CONTROL_MOVE_FORWARD)) { playerPos += view * speed * eTime; } if (fAvMod->GetInputFlag(B_CONTROL_MOVE_BACKWARD)) { playerPos += view * speed * eTime * -1; } if (fAvMod->StrafeLeftKeyDown() || (fAvMod->StrafeKeyDown() && fAvMod->TurnLeftKeyDown())) { playerPos += right * speed * eTime * -1; } if (fAvMod->StrafeRightKeyDown() || (fAvMod->StrafeKeyDown() && fAvMod->TurnRightKeyDown())) { playerPos += right * speed * eTime; } if (fAvMod->GetInputFlag(B_CONTROL_MOVE_DOWN)) { playerPos += up * speed * eTime * -1; } if (fAvMod->GetInputFlag(B_CONTROL_MOVE_UP)) { playerPos += up * speed * eTime; } hsPoint3 desiredPosition = playerPos; // calculate rotation matrix hsVector3 rotUp(0,0,1); hsVector3 rotRight(1,0,0); hsMatrix44 rot; hsScalar angle = 0; if ( fAvMod->GetInputFlag( B_CONTROL_ROTATE_RIGHT ) || fAvMod->GetInputFlag( B_CONTROL_ROTATE_LEFT ) || fAvMod->GetInputFlag( A_CONTROL_TURN ) ) { angle = fTurnRate * eTime * fAvMod->GetTurnStrength(); } 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: hsMatrix44 inv; targetMatrix.SetTranslate( &desiredPosition ); targetMatrix.GetInverse( &inv ); avSO->SetTransform( targetMatrix, inv ); avSO->FlushTransform(); return true; } // IHANDLECONTROLMSG hsBool plAvBrainDrive::MsgReceive(plMessage* msg) { plControlEventMsg *ctrlMsg = plControlEventMsg::ConvertNoRef(msg); if(ctrlMsg) { if( ctrlMsg->ControlActivated() ) { if(ctrlMsg->GetControlCode() == B_CONTROL_TOGGLE_PHYSICAL) { fAvMod->PopBrain(); return true; } } } return false; }