/*==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 #include "plAvBrain.h" #include "plAvBehaviors.h" #include "plArmatureMod.h" #include "plAvatarMgr.h" #include "plAvatarTasks.h" // global #include "hsGeometry3.h" #include "hsQuat.h" // other #include "../pnSceneObject/plSceneObject.h" #include "../plPipeline/plDebugText.h" // messages #include "../plMessage/plAvatarMsg.h" ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// plArmatureBrain::plArmatureBrain() : fCurTask(nil), fArmature(nil), fAvMod(nil) { } plArmatureBrain::~plArmatureBrain() { while (fTaskQueue.size() > 0) { plAvTask *task = fTaskQueue.front(); delete task; fTaskQueue.pop_front(); } if (fCurTask) delete fCurTask; } hsBool plArmatureBrain::Apply(double timeNow, hsScalar elapsed) { IProcessTasks(timeNow, elapsed); fArmature->ApplyAnimations(timeNow, elapsed); return true; } void plArmatureBrain::Activate(plArmatureModBase *armature) { fArmature = armature; fAvMod = plArmatureMod::ConvertNoRef(armature); } void plArmatureBrain::QueueTask(plAvTask *task) { if (task) fTaskQueue.push_back(task); } hsBool plArmatureBrain::LeaveAge() { if (fCurTask) fCurTask->LeaveAge(plArmatureMod::ConvertNoRef(fArmature)); plAvTaskQueue::iterator i = fTaskQueue.begin(); for (; i != fTaskQueue.end(); i++) { plAvTask *task = *i; task->LeaveAge(plArmatureMod::ConvertNoRef(fArmature)); // Give it a chance to do something before we nuke it. delete task; } fTaskQueue.clear(); return true; } hsBool plArmatureBrain::IsRunningTask() const { if (fCurTask) return true; if(fTaskQueue.size() > 0) return true; return false; } // Nothing for this class to read/write. These methods exist // for backwards compatability with plAvBrain and plAvBrainUser void plArmatureBrain::Write(hsStream *stream, hsResMgr *mgr) { plCreatable::Write(stream, mgr); // plAvBrain stream->WriteSwap32(0); stream->WriteBool(false); // plAvBrainUser stream->WriteSwap32(0); stream->WriteSwapScalar(0.f); stream->WriteSwapDouble(0.f); } void plArmatureBrain::Read(hsStream *stream, hsResMgr *mgr) { plCreatable::Read(stream, mgr); // plAvBrain stream->ReadSwap32(); if (stream->ReadBool()) mgr->ReadKey(stream); // plAvBrainUser stream->ReadSwap32(); stream->ReadSwapScalar(); stream->ReadSwapDouble(); } // MSGRECEIVE hsBool plArmatureBrain::MsgReceive(plMessage * msg) { plAvTaskMsg *taskMsg = plAvTaskMsg::ConvertNoRef(msg); if (taskMsg) { return IHandleTaskMsg(taskMsg); } return false; } void plArmatureBrain::IProcessTasks(double time, hsScalar elapsed) { if (!fCurTask || !fCurTask->Process(plArmatureMod::ConvertNoRef(fArmature), this, time, elapsed)) { if (fCurTask) { fCurTask->Finish(plArmatureMod::ConvertNoRef(fArmature), this, time, elapsed); delete fCurTask; fCurTask = nil; } // need a new task if (fTaskQueue.size() > 0) { plAvTask *newTask = fTaskQueue.front(); if (newTask && newTask->Start(plArmatureMod::ConvertNoRef(fArmature), this, time, elapsed)) { fCurTask = newTask; fTaskQueue.pop_front(); } // if we couldn't start the task, we'll keep trying until we can. } } } hsBool plArmatureBrain::IHandleTaskMsg(plAvTaskMsg *msg) { plAvTask *task = msg->GetTask(); QueueTask(task); return true; }