topical media & game development

talk show tell print

lib-game-delta3d-sdk-examples-testAAR-testaarmessageprocessor.cpp / cpp



  /* -*-c++-*-
   * testAAR - testaarmessageprocessor (.h & .cpp) - Using 'The MIT License'
   * Copyright (C) 2006-2008, Alion Science and Technology Corporation
   *
   * Permission is hereby granted, free of charge, to any person obtaining a copy
   * of this software and associated documentation files (the "Software"), to deal
   * in the Software without restriction, including without limitation the rights
   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   * copies of the Software, and to permit persons to whom the Software is
   * furnished to do so, subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included in
   * all copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   * THE SOFTWARE.
   *
   * This software was developed by Alion Science and Technology Corporation under
   * circumstances in which the U. S. Government may have rights in the software.
   *
   * William E. Johnson II
   */
  
  include <testaarmessageprocessor.h>
  include <testaarhud.h>
  include <testaarmessagetypes.h>
  include <testaarexceptionenum.h>
  include <testaarinput.h>
  include <testaargameevent.h>
  
  include <dtABC/application.h>
  include <dtCore/globals.h>
  include <dtCore/keyboard.h>
  include <dtCore/system.h>
  include <dtCore/object.h>
  include <dtCore/scene.h>
  include <dtCore/transform.h>
  include <dtGame/logcontroller.h>
  include <dtGame/actorupdatemessage.h>
  include <dtGame/logkeyframe.h>
  include <dtGame/logstatus.h>
  include <dtGame/logtag.h>
  include <dtGame/serverloggercomponent.h>
  include <dtGame/basemessages.h>
  include <dtDAL/gameeventmanager.h>
  include <dtDAL/gameevent.h>
  include <dtDAL/actortype.h>
  include <dtDAL/enginepropertytypes.h>
  include <dtActors/taskactor.h>
  include <dtActors/taskactorgameevent.h>
  include <dtActors/taskactorordered.h>
  include <dtActors/taskactorrollup.h>
  include <dtLMS/lmscomponent.h>
  include <dtUtil/mathdefines.h>
  include <dtUtil/exception.h>
  
  include <iostream>
  
  TestAARMessageProcessor::TestAARMessageProcessor(dtLMS::LmsComponent& lmsComp,
                                                   dtGame::LogController& logCtrl,
                                                   dtGame::ServerLoggerComponent& srvrCtrl)
     : mLogController(&logCtrl)
     , mLmsComponent(&lmsComp)
     , mLastAutoRequestStatus(0.0)
     , mServerLogger(&srvrCtrl)
     , mPlayer(NULL)
  {
  }
  
  TestAARMessageProcessor::~TestAARMessageProcessor()
  {
  }
  
  void TestAARMessageProcessor::ProcessMessage(const dtGame::Message& msg)
  {
     const dtGame::MessageType& type = msg.GetMessageType();
  
     if (type == dtGame::MessageType::TICK_LOCAL)
     {
        const dtGame::TickMessage& tick = static_cast<const dtGame::TickMessage&>(msg);
        PreFrame(tick.GetDeltaSimTime());
     }
     else if (type == dtGame::MessageType::INFO_ACTOR_DELETED)
     {
        if (mPlayer != NULL && msg.GetAboutActorId() == mPlayer->GetId())
        {
           mPlayer = NULL;
        }
     }
     else if (type == TestAARMessageType::PLACE_ACTOR)
     {
        PlaceActor();
     }
     else if (type == TestAARMessageType::PLACE_IGNORED_ACTOR)
     {
        PlaceActor(true);
     }
     else if (type == TestAARMessageType::RESET)
     {
        GetGameManager()->ChangeMap("testAAR");
     }
     else if (type == TestAARMessageType::REQUEST_ALL_CONTROLLER_UPDATES)
     {
        RequestAllControllerUpdates();
     }
     else if (type == TestAARMessageType::PRINT_TASKS)
     {
        PrintTasks();
     }
     else if (type == TestAARMessageType::UPDATE_TASK_CAMERA)
     {
        UpdateTaskCamera();
     }
     else if (type == dtGame::MessageType::INFO_ACTOR_UPDATED)
     {
        if (mPlayer != NULL && msg.GetAboutActorId() == mPlayer->GetId())
        {
           UpdatePlayerActor(static_cast<const dtGame::ActorUpdateMessage&>(msg));
        }
     }
     else if (type == dtGame::MessageType::INFO_MAP_CHANGED)
     {
        Reset();
     }
  
     dtGame::DefaultMessageProcessor::ProcessMessage(msg);
  }
  
  
////////////////////////////////////////////////////////////////////

void TestAARMessageProcessor::OnAddedToGM() { mLogController->SignalReceivedStatus().connect_slot(this, &TestAARMessageProcessor::OnReceivedStatus); mLogController->SignalReceivedRejection().connect_slot(this, &TestAARMessageProcessor::OnReceivedRejection); mLogController->SignalReceivedTags().connect_slot(this, &TestAARMessageProcessor::OnReceivedTags); mLogController->SignalReceivedKeyframes().connect_slot(this, &TestAARMessageProcessor::OnReceivedKeyframes); }
////////////////////////////////////////////////////////////////////

dtCore::RefPtr<dtGame::GameActorProxy> TestAARMessageProcessor::CreateNewMovingActor(const std::string& meshName, float velocity, float turnRate, bool bSetLocation, bool ignoreRecording) { if (mLogController->GetLastKnownStatus().GetStateEnum() == dtGame::LogStateEnumeration::LOGGER_STATE_PLAYBACK) { return NULL; } float xScale = 0.0f, yScale = 0.0f, zScale = 0.0f; float xRot = 0.0f, yRot = 0.0f, zRot = 0.0f; dtCore::RefPtr<dtGame::GameActorProxy> object; dtCore::Transform position; dtCore::RefPtr<const dtDAL::ActorType> playerType = GetGameManager()->FindActorType("ExampleActors", "TestPlayer"); object = dynamic_cast<dtGame::GameActorProxy *>(GetGameManager()->CreateActor(*playerType).get()); if (bSetLocation) { object->SetTranslation(mPlayer->GetTranslation()); // rescale our object to make it neat. zScale = dtUtil::RandFloat(0.70f, 1.3f); xScale = dtUtil::RandFloat(0.70f, 1.3f) * zScale; yScale = dtUtil::RandFloat(0.70f, 1.3f) * zScale; //object->SetScale(osg::Vec3(xScale, yScale, zScale)); // set initial random rotation (X = pitch, Y = roll, Z = yaw) for non rotating objects // don't change rotating objects cause the movement will follow the rotation, which may // look weird. if (turnRate == 0.0f) { xRot = dtUtil::RandFloat(-5.0f, 5.0f); yRot = dtUtil::RandFloat(-5.0f, 5.0f); zRot = dtUtil::RandFloat(0.0f, 360.0f); object->SetRotation(osg::Vec3(xRot, yRot, zRot)); } } if (ignoreRecording) { mLogController->RequestAddIgnoredActor(object->GetId()); } GetGameManager()->AddActor(*object,false,false); // set mesh, velocity, and turn rate dtDAL::StringActorProperty* prop = static_cast<dtDAL::StringActorProperty *>(object->GetProperty("mesh")); prop->SetValue(meshName); dtDAL::FloatActorProperty* velocityProp = static_cast<dtDAL::FloatActorProperty *>(object->GetProperty("velocity")); velocityProp->SetValue(velocity); dtDAL::FloatActorProperty* turnRateProp = static_cast<dtDAL::FloatActorProperty *>(object->GetProperty("turnrate")); turnRateProp->SetValue(turnRate); return object; }
////////////////////////////////////////////////////////////////////

void TestAARMessageProcessor::PlaceActor(bool ignored) { float turn, velocity; float chance, chance2; dtCore::RefPtr<dtGame::GameActorProxy> obj; turn = dtUtil::RandFloat(-0.60f, 0.60f); if (turn < 0.1f && turn > -0.1f) { turn = 0.1f; } velocity = dtUtil::RandFloat(-12.0f, 12.0f); if (velocity < 0.5f && velocity > -0.5f) { velocity = 0.0f; } chance = dtUtil::RandFloat(0.0, 1.0f); // make only some of them move cause it causes problems computing // the intersection with the ground. (Performance bug..) chance2 = dtUtil::RandFloat(0.0f, 1.0f); if (chance2 <= 0.75f) { velocity = 0.0f; } std::string path; if (ignored) { path = dtCore::FindFileInPathList("models/ignore_me.ive"); if (!path.empty()) { obj = CreateNewMovingActor(path,velocity,turn,true,ignored); } else { LOG_ERROR("Failed to find the ignore_me model file."); } } else if (chance <= 0.5f) { path = dtCore::FindFileInPathList("models/physics_crate.ive"); if (!path.empty()) { obj = CreateNewMovingActor(path,velocity,turn,true,ignored); } else { LOG_ERROR("Failed to find the physics_crate model file."); } } else { path = dtCore::FindFileInPathList("models/physics_barrel.ive"); if (!path.empty()) { obj = CreateNewMovingActor(path,velocity,turn,true,ignored); } else { LOG_ERROR("Failed to find the physics_barrel model file."); } } // fire a box created event dtCore::RefPtr<dtGame::GameEventMessage> eventMsg = static_cast<dtGame::GameEventMessage*> (GetGameManager()->GetMessageFactory().CreateMessage(dtGame::MessageType::INFO_GAME_EVENT).get()); eventMsg->SetGameEvent(*TestAARGameEvent::EVENT_BOX_PLACED); GetGameManager()->SendMessage(*eventMsg); }
////////////////////////////////////////////////////////////////////

void TestAARMessageProcessor::OnReceivedStatus(const dtGame::LogStatus& newStatus) { static bool isFirstPlayback = true; // so we don't update again if user just requested it mLastAutoRequestStatus = GetGameManager()->GetSimulationTime(); if (newStatus.GetStateEnum() == dtGame::LogStateEnumeration::LOGGER_STATE_IDLE) { isFirstPlayback = true; } //The following is a great big hack due to the fact that we do not yet //support the task hierarchy as actor properties. Since the task hierarchy //is not wrapped within actor properties, it does not get recreated //properly when changing to playback mode. However, the since the task //actors themselves got properly recreated, we just need to manually set //the hierarchy when changing from IDLE state to PLAYBACK state. if (newStatus.GetStateEnum() == dtGame::LogStateEnumeration::LOGGER_STATE_PLAYBACK && isFirstPlayback) { isFirstPlayback = false; dtActors::TaskActorProxy* placeObjects = static_cast<dtActors::TaskActorProxy*>(mLmsComponent->GetTaskByName("Place Objects (Ordered)")); dtActors::TaskActorProxy* movePlayerRollup = static_cast<dtActors::TaskActorProxy*>(mLmsComponent->GetTaskByName("Move the Player (Rollup)")); dtActors::TaskActorProxy* movePlayerLeft = static_cast<dtActors::TaskActorProxy*>(mLmsComponent->GetTaskByName("Turn Player Left")); dtActors::TaskActorProxy* movePlayerRight = static_cast<dtActors::TaskActorProxy*>(mLmsComponent->GetTaskByName("Turn Player Right")); dtActors::TaskActorProxy* movePlayerForward = static_cast<dtActors::TaskActorProxy*>(mLmsComponent->GetTaskByName("Move Player Forward")); dtActors::TaskActorProxy* movePlayerBack = static_cast<dtActors::TaskActorProxy*>(mLmsComponent->GetTaskByName("Move Player Back")); dtActors::TaskActorProxy* drop5Boxes = static_cast<dtActors::TaskActorProxy*>(mLmsComponent->GetTaskByName("Drop 5 boxes")); //Recreate the hierarchy... movePlayerRollup->AddSubTask(*movePlayerLeft); movePlayerRollup->AddSubTask(*movePlayerRight); movePlayerRollup->AddSubTask(*movePlayerForward); movePlayerRollup->AddSubTask(*movePlayerBack); placeObjects->AddSubTask(*movePlayerRollup); placeObjects->AddSubTask(*drop5Boxes); //mTaskComponent->CheckTaskHierarchy(); mLmsComponent->CheckTaskHierarchy(); } }
////////////////////////////////////////////////////////////////////

void TestAARMessageProcessor::OnReceivedRejection(const dtGame::Message& newMessage) { const dtGame::ServerMessageRejected& rejMsg = static_cast<const dtGame::ServerMessageRejected&>(newMessage); std::ostringstream ss; ss << "## REJECTION RECEIVED std::cout << ss.str() << std::endl; const dtGame::Message* causeMsg = rejMsg.GetCausingMessage(); if (causeMsg != NULL) { ss.str(""); std::string paramsString; causeMsg->ToString(paramsString); ss << " CAUSE: Type[" << causeMsg->GetMessageType().GetName() << "], Params[" << paramsString << "]"; std::cout << ss.str() << std::endl; } }
////////////////////////////////////////////////////////////////////

void TestAARMessageProcessor::RequestAllControllerUpdates() { mLogController->RequestServerGetStatus(); mLogController->RequestServerGetKeyframes(); mLogController->RequestServerGetTags(); }
////////////////////////////////////////////////////////////////////

void TestAARMessageProcessor::PreFrame(const double deltaFrameTime) { // roughly every 3 real seconds, we force status update so the HUD updates and doesn't look broken. if (mLastAutoRequestStatus > GetGameManager()->GetSimulationTime()) { mLastAutoRequestStatus = GetGameManager()->GetSimulationTime(); } else if ((mLastAutoRequestStatus + 3.0*GetGameManager()->GetTimeScale()) < GetGameManager()->GetSimulationTime()) { RequestAllControllerUpdates(); mLastAutoRequestStatus = GetGameManager()->GetSimulationTime(); } }
////////////////////////////////////////////////////////////////////

void TestAARMessageProcessor::Reset() { mLmsComponent->ClearTaskList(); //dtCore::System::GetInstance().Step(); TestAARGameEvent::InitEvents(); // setup terrain dtCore::RefPtr<dtCore::Object> terrain = new dtCore::Object(); std::string path = dtCore::FindFileInPathList("models/terrain_simple.ive"); if (path.empty()) { LOG_ERROR("Failed to find the terrain model."); } else { terrain->LoadFile(path); GetGameManager()->GetScene().AddDrawable(terrain.get()); } dtCore::RefPtr<const dtDAL::ActorType> playerType = GetGameManager()->FindActorType("ExampleActors", "TestPlayer"); dtCore::RefPtr<dtDAL::ActorProxy> player = GetGameManager()->CreateActor(*playerType); mPlayer = dynamic_cast<dtGame::GameActorProxy*>(player.get()); GetGameManager()->AddActor(*mPlayer, false, false); dtDAL::StringActorProperty* prop = static_cast<dtDAL::StringActorProperty*>(mPlayer->GetProperty("mesh")); path = dtCore::FindFileInPathList("models/physics_happy_sphere.ive"); if (!path.empty()) { prop->SetValue(path); } else { LOG_ERROR("Failed to find the physics_happy_sphere file."); } dtGame::GMComponent* gmc = GetGameManager()->GetComponentByName("TestInputComponent"); if (gmc != NULL) { static_cast<TestAARInput*>(gmc)->SetPlayerActor(*mPlayer); } //SetupTasks(); std::vector<dtDAL::ActorProxy*> toFill; GetGameManager()->FindActorsByName("Move Camera", toFill); if (toFill.size() == 0) { LOG_ERROR("Unable to find the \"Move Camera\" task. The application will likely fail."); return; } mTaskMoveCameraProxy = dynamic_cast<dtActors::TaskActorProxy*>(toFill[0]); if (mTaskMoveCameraProxy == NULL) { LOG_ERROR("The \"Move Camera\" actor was found but it is not a task. The application will likely fail."); return; } mTaskMoveCamera = &static_cast<dtActors::TaskActor&>(mTaskMoveCameraProxy->GetGameActor()); }
////////////////////////////////////////////////////////////////////

void TestAARMessageProcessor::PrintTasks() { std::ostringstream printer; std::vector< dtCore::RefPtr<dtGame::GameActorProxy> > tasks; printer << "Number of Top Level Tasks: " << mLmsComponent->GetNumTopLevelTasks() << " Total Number of Tasks: " << mLmsComponent->GetNumTasks(); mLmsComponent->GetAllTasks(tasks); printer << std::endl << "Task List:" << std::endl; for (std::vector< dtCore::RefPtr<dtGame::GameActorProxy> >::iterator itor = tasks.begin(); itor != tasks.end(); ++itor) { printer << "\tTask Name: " << (*itor)->GetName() << " Complete: " << (*itor)->GetProperty("Complete")->ToString() << std::endl; } std::cout << printer.str() << std::endl; }
////////////////////////////////////////////////////////////////////

void TestAARMessageProcessor::OnReceivedTags(const std::vector<dtGame::LogTag>& newTagList) { // left this cruft in for debugging //std::ostringstream ss; //ss << "## RECEIVED TAG LIST //std::cout << ss.str() << std::endl; }
////////////////////////////////////////////////////////////////////

void TestAARMessageProcessor::OnReceivedKeyframes(const std::vector<dtGame::LogKeyframe>& newKeyframesList) { // left this cruft in for debugging... //std::ostringstream ss; //ss << "## RECEIVED Keyframes LIST //std::cout << ss.str() << std::endl; }
////////////////////////////////////////////////////////////////////

void TestAARMessageProcessor::UpdateTaskCamera() { if (mLogController->GetLastKnownStatus().GetStateEnum() != dtGame::LogStateEnumeration::LOGGER_STATE_PLAYBACK) { if (!mTaskMoveCamera->IsComplete()) { mTaskMoveCamera->SetScore(1.0); mTaskMoveCamera->SetComplete(true); dtActors::TaskActorProxy& proxy = static_cast<dtActors::TaskActorProxy&>(mTaskMoveCamera->GetGameActorProxy()); proxy.NotifyActorUpdate(); } } }
/////////////////////////////////////////////////////////////////////

void TestAARMessageProcessor::UpdatePlayerActor(const dtGame::ActorUpdateMessage& aum) { dtDAL::ActorProxy* gap = GetGameManager()->FindActorById(aum.GetAboutActorId()); if (gap != mPlayer) { return; } dtDAL::FloatActorProperty* playerVelocity = static_cast<dtDAL::FloatActorProperty*>(mPlayer->GetProperty("velocity")); dtDAL::FloatActorProperty* playerTurnRate = static_cast<dtDAL::FloatActorProperty*>(mPlayer->GetProperty("turnrate")); const dtGame::MessageParameter* mp = aum.GetUpdateParameter("Velocity"); if (mp != NULL) { playerVelocity->SetValue(static_cast<const dtGame::FloatMessageParameter*>(mp)->GetValue()); } mp = aum.GetUpdateParameter("Turn Rate"); if (mp != NULL) { playerTurnRate->SetValue(static_cast<const dtGame::FloatMessageParameter*>(mp)->GetValue()); } }


(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.