topical media & game development

talk show tell print

lib-game-delta3d-demos-fireFighter-flysequenceactor.cpp / cpp



  /* -*-c++-*-
   * Delta3D Open Source Game and Simulation Engine
   * Copyright (C) 2006, Alion Science and Technology, BMH Operation
   *
   * This library is free software; you can redistribute it and/or modify it under
   * the terms of the GNU Lesser General Public License as published by the Free
   * Software Foundation; either version 2.1 of the License, or (at your option)
   * any later version.
   *
   * This library 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 Lesser General Public License for more
   * details.
   *
   * You should have received a copy of the GNU Lesser General Public License
   * along with this library; if not, write to the Free Software Foundation, Inc.,
   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
   *
   * William E. Johnson II
   */
  
  include <fireFighter/flysequenceactor.h>
  include <fireFighter/playeractor.h>
  include <fireFighter/messages.h>
  include <fireFighter/messagetype.h>
  include <fireFighter/gamestate.h>
  include <dtGame/invokable.h>
  include <dtGame/messagetype.h>
  include <dtGame/gamemanager.h>
  include <dtGame/basemessages.h>
  include <dtGame/messagefactory.h>
  include <dtABC/application.h>
  include <dtAudio/audiomanager.h>
  include <dtCore/camera.h>
  include <dtCore/globals.h>
  include <dtDAL/actorproxyicon.h>
  include <fstream>
  
  
/////////////////////////////////////////////////////

FlySequenceActorProxy::FlySequenceActorProxy() { } FlySequenceActorProxy::~FlySequenceActorProxy() { } void FlySequenceActorProxy::BuildPropertyMap() { dtGame::GameActorProxy::BuildPropertyMap(); } void FlySequenceActorProxy::BuildInvokables() { dtGame::GameActorProxy::BuildInvokables(); } dtDAL::ActorProxyIcon* FlySequenceActorProxy::GetBillBoardIcon() { if (!mBillBoardIcon.valid()) { mBillBoardIcon = new dtDAL::ActorProxyIcon(dtDAL::ActorProxyIcon::IMAGE_BILLBOARD_GENERIC); } return mBillBoardIcon.get(); } void FlySequenceActorProxy::OnEnteredWorld() { RegisterForMessages(dtGame::MessageType::TICK_LOCAL, dtGame::GameActorProxy::TICK_LOCAL_INVOKABLE); }
/////////////////////////////////////////////////////

FlySequenceActor::FlySequenceActor(dtGame::GameActorProxy& proxy) : dtGame::GameActor(proxy) , lookAt(0.0f, 0.0f, 100.0f) , up(0.0f, 0.0f, 1.0f) , wayptArray(NULL) , speed(0.4) , delta(speed * 0.95) , prevWaypoint(0) , mFlyBy(true) , mPlayer(NULL) { } FlySequenceActor::~FlySequenceActor() { mPlayer = NULL; if (snd != NULL) { snd->UnloadFile(); dtAudio::Sound* sound = snd.release(); dtAudio::AudioManager::GetInstance().FreeSound(sound); snd = NULL; } if (wayptArray != NULL) { delete [] wayptArray; wayptArray = NULL; } } void FlySequenceActor::OnEnteredWorld() { std::string waypointsFile = dtCore::FindFileInPathList("waypoints.txt"); std::ifstream input(waypointsFile.c_str()); if (!input.is_open()) { LOG_ERROR("Could not open waypoints.txt - Creating single waypoint at the origin"); numWaypoints = 1; wayptArray = new Waypoint[numWaypoints]; wayptArray[0].x = 0.0; wayptArray[0].y = 0.0; wayptArray[0].z = 0.0; } else { input >> numWaypoints; wayptArray = new Waypoint[numWaypoints]; int i = 0; while (input >> wayptArray[i].x >> wayptArray[i].y >> wayptArray[i].z) { i++; } input.close(); } snd = dtAudio::AudioManager::GetInstance().NewSound(); snd->LoadFile("Sounds/spokenIntro.wav"); snd->SetLooping(false); } void FlySequenceActor::OnTickLocal(const dtGame::TickMessage& msg) { if (mPlayer == NULL) { return; } if (mFlyBy) { if (CompareCameraToWaypoint(actPos, wayptArray[prevWaypoint + 1], delta)) { // If completed transit of ship, exit if (++prevWaypoint == numWaypoints - 1) { StopFlying(); } // Set actual position at this waypoint actPos[0] = wayptArray[prevWaypoint].x; actPos[1] = wayptArray[prevWaypoint].y; actPos[2] = wayptArray[prevWaypoint].z; ComputeDirTravel(wayptArray[prevWaypoint + 1], wayptArray[prevWaypoint]); } else { // Verify movement not too great to miss way point double vel = speed * static_cast<const dtGame::TickMessage&>(msg).GetDeltaSimTime() * 100.0; vel > delta ? vel = delta : vel = vel; actPos[0] += dirOfTransit[0] * vel; actPos[1] += dirOfTransit[1] * vel; actPos[2] += dirOfTransit[2] * vel; } // Put the actual position into a sgVec3 to set Transform camPos[0] = actPos[0]; camPos[1] = actPos[1]; camPos[2] = actPos[2]; pos.Set(camPos, lookAt, up); mPlayer->SetTransform(pos); } } void FlySequenceActor::StartFlying() { mPlayer->GetTransform(pos); prevWaypoint = 0; camPos[0] = actPos[0] = wayptArray[0].x; camPos[1] = actPos[1] = wayptArray[0].y; camPos[2] = actPos[2] = wayptArray[0].z; // If only one waypoint, don't move if (numWaypoints > 1) { ComputeDirTravel(wayptArray[prevWaypoint + 1], wayptArray[prevWaypoint]); } else { dirOfTransit[0] = 0.0; dirOfTransit[1] = 0.0; dirOfTransit[2] = 0.0; } pos.Set(camPos, lookAt, up); mPlayer->SetTransform(pos); mFlyBy = true; snd->Play(); } void FlySequenceActor::StopFlying() { prevWaypoint = 0; mFlyBy = false; if (snd != NULL && snd->IsPlaying()) { snd->Stop(); } GetGameActorProxy().UnregisterForMessages(dtGame::MessageType::TICK_LOCAL, dtGame::GameActorProxy::TICK_LOCAL_INVOKABLE); dtGame::MessageFactory& mf = GetGameActorProxy().GetGameManager()->GetMessageFactory(); dtCore::RefPtr<dtGame::Message> msg = mf.CreateMessage(MessageType::GAME_STATE_CHANGED); GameStateChangedMessage& gscm = static_cast<GameStateChangedMessage&>(*msg); gscm.SetOldState(GameState::STATE_INTRO); gscm.SetNewState(GameState::STATE_RUNNING); GetGameActorProxy().GetGameManager()->SendMessage(gscm); } void FlySequenceActor::ComputeDirTravel(const Waypoint& next, const Waypoint& prev) { dirOfTransit[0] = next.x - prev.x; dirOfTransit[1] = next.y - prev.y; dirOfTransit[2] = next.z - prev.z; double length = sqrt((dirOfTransit[0] * dirOfTransit[0]) + (dirOfTransit[1] * dirOfTransit[1]) + (dirOfTransit[2] * dirOfTransit[2])); dirOfTransit[0] /= length; dirOfTransit[1] /= length; dirOfTransit[2] /= length; } bool FlySequenceActor::CompareCameraToWaypoint(const double* cam, const Waypoint& wp, float delta) { if ((cam[0] + delta) < wp.x) { return false; } if ((wp.x + delta) < cam[0]) { return false; } if ((cam[1] + delta) < wp.y) { return false; } if ((wp.y + delta) < cam[1]) { return false; } if ((cam[2] + delta) < wp.z) { return false; } if ((wp.z + delta) < cam[2]) { return false; } return true; } void FlySequenceActor::ResetCameraPath() { camPos[0] = actPos[0] = wayptArray[0].x; camPos[1] = actPos[1] = wayptArray[0].y; camPos[2] = actPos[2] = wayptArray[0].z; prevWaypoint = 0; // If only one waypoint, don't move if (numWaypoints > 1) { ComputeDirTravel(wayptArray[prevWaypoint + 1], wayptArray[prevWaypoint]); } else { dirOfTransit[0] = 0.0; dirOfTransit[1] = 0.0; dirOfTransit[2] = 0.0; } lookAt[0] = 0.0f; lookAt[1] = 0.0f; lookAt[2] = 100.0f; up[0] = 0.0f; up[1] = 0.0f; up[2] = 1.0f; pos.Set(camPos, lookAt, up); mPlayer->SetTransform(pos); mFlyBy = true; }


(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.