#include <dtABC/application.h>
#include <dtCore/refptr.h>
#include <dtCore/object.h>
#include <dtCore/orbitmotionmodel.h>
#include <dtCore/deltawin.h>
#include <dtCore/transform.h>
#include<dtUtil/datapathutils.h>
#include <dtCore/infiniteterrain.h>
#include <dtCore/flymotionmodel.h>
#include <dtCore/ufomotionmodel.h>
#include <dtCore/walkmotionmodel.h>
/*
Orbit Motion Model:
Left Mouse Button - Rotate camera
Right Mouse Button - Translate camera
Middle Mouse Button - Zoom camera
Fly Motion Model:
Up - Look up
Down - Look down
Left - Turn left
Right - Turn right
S - Move forward
W - Move backward
Left Mouse Button - Look up/down, turn left/right
Right Mouse Button - Move forward/backward
UFO Motion Model:
Up - Move forward
Down - Move backward
Left - Strafe left
Right - Strafe right
A - Turn left
D - Turn right
S - Move up
W - Move down
Left Mouse Button - Move forward/backward, strafe left/right
Right Mouse Button - Move up/down, turn left/right
Walk Motion Model:
Up - Move forward
Down - Move backward
Left - Turn left
Right - Turn right
A - Strafe left
D - Strafe right
Left Mouse Button - Move forward/backward, turn left/right
Right Mouse Button - Strafe left/right
*/
class HelloWorldApp : public dtABC::Application
{
public:
HelloWorldApp(const std::string& configFilename);
// Override this function to setup your scene.
virtual void Config();
virtual bool KeyPressed(const dtCore::Keyboard* kb, int key);
protected:
// Destructors for subclasses of dtCore::Base must have a protected
// destructor. Otherwise use of RefPtrs will cause some serious
// problems if the objects are allocated on the stack.
virtual ~HelloWorldApp();
private:
// dtCore::RefPtr is a template for a smart pointer that takes
// care of reference counting for objects allocated on the heap.
// It is good practice to store all objects that derive from
// dtCore::Base inside a RefPtr.
dtCore::RefPtr<dtCore::Object> mObject;
dtCore::RefPtr<dtCore::MotionModel > mMotionModel;
};
HelloWorldApp::HelloWorldApp(const std::string& configFilename)
: dtABC::Application(configFilename)
{
}
HelloWorldApp::~HelloWorldApp()
{
}
void HelloWorldApp::Config()
{
// Call the parent class, in case something important is happening there
Application::Config();
GetWindow()->SetWindowTitle("Orbit Mode");
// Adjust the Camera position by instantiating a transform object to
// store the camera position and attitude.
dtCore::Transform camPosition;
camPosition.Set(-300.f, -300.f, 100.f, //position
0.f, 0.f, 0.f, //lookat
0.f, 0.f, 1.f); //up Vector
//Set transform to the camera
GetCamera()->SetTransform(camPosition);
// Setting a motion model for the camera
mMotionModel = new dtCore::OrbitMotionModel(GetKeyboard(), GetMouse());
// Allocate a dtCore::Object. This class will be your basic container
// for 3D meshes.
mObject = new dtCore::Object("Box");
// Load the model file, in this case an OpenFlight model (.flt) from the zip provided
mObject->LoadFile("models/uh-1n.ive");
dtCore::RefPtr<dtCore::Object> terrain = new dtCore::Object("Terrain");
terrain->LoadFile("models/terrain_simple.ive");
AddDrawable(terrain.get());
// Setting the camera as a target for the motion model. The camera will
// will be static, and the camera will move the object using the right
// clicked mouse.
mMotionModel->SetTarget(mObject);
// Add the Object to the scene. Since the object is a RefPtr, we must
// pull the internal point out to pass it to the Scene.
//AddDrawable(new dtCore::InfiniteTerrain);
AddDrawable(mObject.get());
}
//Override the Application::KeyPressed function
//This function gets called whenever the user enters any input (as implemented by the Application class)
//We want to have the F1-F4 buttons change between the different motion model types
//Finally we want to be able to change the target of the motion model to be either the camera or the box via F5
bool HelloWorldApp::KeyPressed(const dtCore::Keyboard* kb, int key)
{
bool ret = false;
//Retreive the current target of our motion model
//This is important because if we want to retain the previous target in the new motion model
dtCore::Transformable* target = mMotionModel.get()->GetTarget();
//Check which key has been pressed
switch(key)
{
//osgGA::GUIEventAdapter provides the input values
case osgGA::GUIEventAdapter::KEY_F1: //F1
{
//Set the motion model to be of the Orbit type
mMotionModel = new dtCore::OrbitMotionModel(GetKeyboard(), GetMouse());
//Retain the previous target
if(target == mObject)
{
mMotionModel->SetTarget(mObject);
}
else
{
mMotionModel->SetTarget(GetCamera());
}
GetWindow()->SetWindowTitle("Orbit Mode");
ret = true;
break;
}
case osgGA::GUIEventAdapter::KEY_F2: //F2
{
//Set the motion model to be of the Fly type
mMotionModel = new dtCore::FlyMotionModel(GetKeyboard(), GetMouse());
//Retain the previous target
if(target == mObject)
{
mMotionModel->SetTarget(mObject);
}
else
{
mMotionModel->SetTarget(GetCamera());
}
GetWindow()->SetWindowTitle("Fly Mode");
ret = true;
break;
}
case osgGA::GUIEventAdapter::KEY_F3: //F3
{
//Set the motion model to be of the UFO type
mMotionModel = new dtCore::UFOMotionModel(GetKeyboard(), GetMouse());
//Retain the previous target
if(target == mObject)
{
mMotionModel->SetTarget(mObject);
}
else
{
mMotionModel->SetTarget(GetCamera());
}
GetWindow()->SetWindowTitle("UFO Mode");
ret = true;
break;
}
case osgGA::GUIEventAdapter::KEY_F4: //F4
{
//Set the motion model to be of the Walk type
mMotionModel = new dtCore::WalkMotionModel(GetKeyboard(), GetMouse());
//Retain the previous target
if(target == mObject)
{
mMotionModel->SetTarget(mObject);
}
else
{
mMotionModel->SetTarget(GetCamera());
}
GetWindow()->SetWindowTitle("Walk Mode");
ret = true;
break;
}
case osgGA::GUIEventAdapter::KEY_F5:
{
//If the target was the box then change to the camera, or vice versa
if(target == mObject)
{
mMotionModel->SetTarget(GetCamera());
}
else
{
mMotionModel->SetTarget(mObject);
}
}
default:
{
ret = false;
break;
}
}
return ret;
}
int main(int arc, char **argv)
{
// Setup the data file search paths for the config file and the models files.
// This is best done in main prior to configuring app. That way the paths
// are ensured to be correct when loading data.
dtUtil::SetDataFilePathList( "..;" +
dtUtil::GetDeltaDataPathList() + ";" +
dtUtil::GetDeltaRootPath() + "/examples/data/;");
//Instantiate the application and look for the config file
dtCore::RefPtr<HelloWorldApp> app = new HelloWorldApp("config.xml");
app->Config(); //configuring the application
app->Run(); // running the simulation loop
return 0;
}
Delta3d 物体的控制模式
最新推荐文章于 2022-08-24 23:32:59 发布