topical media & game development
lib-game-delta3d-sdk-examples-testAI-testai.cpp / cpp
// TestAI.cpp : defines the implementation of the application
if defined (WIN32) || defined (_WIN32) || defined (__WIN32__)
#pragma warning(push)
#pragma warning(disable : 4005)
endif
include <testai.h>
include <dtCore/camera.h>
include <dtCore/globals.h>
include <dtCore/transform.h>
include <dtDAL/map.h>
include <dtDAL/project.h>
include <dtDAL/exceptionenum.h>
include <dtUtil/macros.h>
include <dtAI/waypoint.h>
include <dtAI/waypointmanager.h>
include <dtUtil/mathdefines.h>
include <dtUtil/log.h>
include <dtUtil/fileutils.h>
include <osg/MatrixTransform>
if defined (WIN32) || defined (_WIN32) || defined (__WIN32__)
#pragma warning(pop)
endif
using namespace dtCore;
using namespace dtABC;
using namespace dtDAL;
using namespace dtAI;
TestAI::TestAI(const std::string& pMapFilename, const std::string& configFilename)
: Application(configFilename)
, mMapFilename(pMapFilename)
, mCharacter(0)
{
// Generating a default config file if there isn't one already
if (!dtUtil::FileUtils::GetInstance().FileExists(configFilename))
{
GenerateDefaultConfigFile();
}
}
TestAI::~TestAI()
{
}
void TestAI::Config()
{
Application::Config();
// initialize the Waypoint Helper
WaypointManager::GetInstance();
GetScene()->AddDrawable(&WaypointManager::GetInstance());
// set the waypoint manager to not (redundantly) delete waypoints
dtAI::WaypointManager::GetInstance().SetDeleteOnClear(false);
LoadDemoMap(mMapFilename);
// turn on viewing of waypoints
WaypointManager::GetInstance().SetDrawWaypoints(true);
// by default we wont draw the navmesh
mDrawNavMesh = false;
WaypointManager::GetInstance().SetDrawNavMesh(mDrawNavMesh, true);
// set camera offset
dtCore::Transform trans;
trans.SetTranslation(-1.0f, 5.5f, 1.5f);
trans.SetRotation(180.0f, -2.0f, 0.0f);
GetCamera()->SetTransform(trans);
// this is needed so OSG knows which camera can generate events
GetCamera()->GetOSGCamera()->setAllowEventFocus(true);
// create overhead camera and disable it by default
dtCore::View *overheadView = new dtCore::View("overhead view");
overheadView->SetScene( GetScene() );
AddView( *overheadView );
mOverheadCamera = new dtCore::Camera();
mOverheadCamera->SetWindow(GetWindow());
mOverheadCamera->SetEnabled(false);
overheadView->SetCamera( mOverheadCamera.get() );
// this is needed so OSG knows which camera can generate events
mOverheadCamera->GetOSGCamera()->setAllowEventFocus(false);
// set overhead camera offset
trans.SetTranslation(0.0f, -5.0f, 70.0f);
trans.SetRotation(0.0f, -90.f, 0.0f);
trans.Get(mCameraOffset);
mOverheadCamera->GetMatrixNode()->setMatrix(mCameraOffset);
// get the first waypoint to spawn the character at
const WaypointManager::WaypointMap& pContainer = WaypointManager::GetInstance().GetWaypoints();
if (pContainer.empty())
{
LOG_ERROR("Map '" + mMapFilename + "' does not have any valid waypoints");
exit(1);
}
WaypointManager::WaypointMap::const_iterator iter = pContainer.begin();
const Waypoint* pWaypoint = (*iter).second;
// spawn our character
mCharacter = new dtAI::AICharacter(GetScene(), pWaypoint, "demoMap/SkeletalMeshes/marine.xml", 3);
// add the two Cameras as children so they get moved along with the character
mCharacter->GetCharacter()->AddChild( GetCamera() );
mCharacter->GetCharacter()->AddChild( mOverheadCamera.get() );
GoToWaypoint(1);
// seed the random generator
srand(4);
CreateHelpLabel();
}
bool TestAI::KeyPressed(const dtCore::Keyboard* keyboard, int key)
{
switch (key)
{
case ' ':
if (GetCamera()->GetEnabled())
{
GetCamera()->SetEnabled(false);
mOverheadCamera->SetEnabled(true);
if (mLabel->GetActive())
{
GetCamera()->RemoveChild(mLabel.get());
mOverheadCamera->AddChild(mLabel.get());
}
}
else
{
mOverheadCamera->SetEnabled(false);
GetCamera()->SetEnabled(true);
if (mLabel->GetActive())
{
mOverheadCamera->RemoveChild(mLabel.get());
GetCamera()->AddChild(mLabel.get());
}
}
return true;
case 'n':
mDrawNavMesh = !mDrawNavMesh;
WaypointManager::GetInstance().SetDrawNavMesh(mDrawNavMesh, true);
return true;
case 'a':
if (mOverheadCamera->GetEnabled())
{
mCameraOffset(3,2) -= 1.0f;
mCameraOffset(3,1) -= 15.5f / 100.0f;
mOverheadCamera->GetMatrixNode()->setMatrix(mCameraOffset);
}
return true;
case 'z':
if (mOverheadCamera->GetEnabled())
{
mCameraOffset(3,2) += 1.0f;
mCameraOffset(3,1) += 15.5f / 100.0f;
mOverheadCamera->GetMatrixNode()->setMatrix(mCameraOffset);
}
return true;
case osgGA::GUIEventAdapter::KEY_Escape:
Quit();
return true;
case osgGA::GUIEventAdapter::KEY_F1:
mLabel->SetActive(!mLabel->GetActive());
if (mLabel->GetActive())
{
if (GetCamera()->GetEnabled() &&
GetCamera()->GetChildIndex(mLabel.get()) == GetCamera()->GetNumChildren())
{
mOverheadCamera->RemoveChild(mLabel.get());
GetCamera()->AddChild(mLabel.get());
}
else if (mOverheadCamera->GetEnabled() &&
mOverheadCamera->GetChildIndex(mLabel.get()) == mOverheadCamera->GetNumChildren())
{
GetCamera()->RemoveChild(mLabel.get());
mOverheadCamera->AddChild(mLabel.get());
}
}
return true;
default:
break;
}
return false;
}
void TestAI::PreFrame( const double deltaFrameTime )
{
mCharacter->Update(float(deltaFrameTime));
if (mCharacter->GetCurrentWaypoint() == mCurrentWaypoint)
{
// send the character to a random waypoint
WaypointManager::WaypointMap::size_type pNumWaypoints = WaypointManager::GetInstance().GetWaypoints().size() - 1;
unsigned pWaypointNum = dtUtil::RandRange(0U, unsigned(pNumWaypoints));
GoToWaypoint(pWaypointNum);
}
}
void TestAI::LoadDemoMap(const std::string& pStr)
{
try
{
std::string contextName = dtCore::GetDeltaRootPath()+"/examples/data/demoMap";
Project::GetInstance().SetContext(contextName);
std::string pContext = Project::GetInstance().GetContext();
Map &myMap = Project::GetInstance().GetMap(pStr);
// Since we are in an Application we can simply call...
LoadMap(myMap);
}
catch (const dtUtil::Exception&)
{
LOG_ERROR("ERROR: Map Not Found");
}
}
bool TestAI::GoToWaypoint(int pWaypointNum)
{
// loop through the waypoints and send our character to the one
// whose index is pWaypointNum in the WaypointMap contained within WaypointManager
const WaypointManager::WaypointMap& pWaypoints = WaypointManager::GetInstance().GetWaypoints();
WaypointManager::WaypointMap::const_iterator iter = pWaypoints.begin();
WaypointManager::WaypointMap::const_iterator endOfMap = pWaypoints.end();
bool pHasPath = false;
for (int i = 0; iter != endOfMap; ++i, ++iter)
{
if (i == pWaypointNum)
{
pHasPath = mCharacter->FindPathAndGoToWaypoint((*iter).second);
if (pHasPath)
{
mCurrentWaypoint = (*iter).second;
return true;
}
break;
}
}
return false;
}
void TestAI::CreateHelpLabel()
{
mLabel = new dtABC::LabelActor();
osg::Vec2 testSize(32.0f, 5.5f);
mLabel->SetBackSize(testSize);
mLabel->SetFontSize(0.8f);
mLabel->SetTextAlignment(dtABC::LabelActor::AlignmentEnum::LEFT_CENTER);
mLabel->SetText(CreateHelpLabelText());
mLabel->SetEnableDepthTesting(false);
mLabel->SetEnableLighting(false);
GetCamera()->AddChild(mLabel.get());
dtCore::Transform labelOffset(-17.0f, 50.0f, 10.5f, 0.0f, 90.0f, 0.0f);
mLabel->SetTransform(labelOffset, dtCore::Transformable::REL_CS);
AddDrawable(GetCamera());
}
std::string TestAI::CreateHelpLabelText()
{
std::string testString("");
testString += "F1: Toggle Help Screen\n";
testString += "\n";
testString += "Space: Toggle overhead/first person camera\n";
testString += "n: Toggle navmesh\n";
testString += "a: Zoom in overhead camera\n";
testString += "z: Zoom out overhead camera\n";
return testString;
}
(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.