TutorialHelloWorld3
From delta3d
Contents |
Object Motion Model Part II
In the previous two tutorials we learned about motion models as applied to cameras and objects. Those tutorials used a specific motion model called the orbit model. Delta3d currently includes 3 additional default motion models: fly, ufo, and walk. In this tutorial we will expand on our motion model code to explore these additional motion models, as well as learn more about handing user input.
You are currently in tutorial 2/3 of the object motion model series.
Additional Tutorials that will apply:
HelloWorld2
The Header File
In your HelloWorldApp header file simply:
- Change the name of your mTextObject to mBoxObject.
- Add a public virtual bool KeyPressed(const dtCore::Keyboard* kb, int key) function (we will get more into this later)
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> mBoxObject;
dtCore::RefPtr<dtCore::MotionModel> mMotionModel;
};
The Implementation File
We will first need to add some terrain to our scene in order to make our Box model more interactive. Fortunately, Deltat3d supports Procedural Terrain Modeling (were terrain is generated on the fly via algorithms). We will also remove the "Hello World" mTextObject model from the code to simplify the scene and replace it with the Box model. Finally we will override the Application::KeyPressed function to set input that can trigger a switch between the different motion model types, as well as toggle the motion model target between the Box the camera:
- Add terrain to scene
- Replace mTextObject with mBoxObject
- Override Application::KeyPressed
Your new code after completing steps #1 and #2 will look like this:
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.
mBoxObject = new dtCore::Object("Box");
// Load the model file, in this case an OpenFlight model (.flt) from the zip provided
mBoxObject->LoadFile("box2.3DS");
// 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(mBoxObject);
// 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(mBoxObject.get());
}
Now comes step #3 in which we override the Application::KeyPressed function. Paying attention to the comments will help to understand the source:
//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 == mBoxObject)
{
mMotionModel->SetTarget(mBoxObject);
}
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 == mBoxObject)
{
mMotionModel->SetTarget(mBoxObject);
}
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 == mBoxObject)
{
mMotionModel->SetTarget(mBoxObject);
}
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 == mBoxObject)
{
mMotionModel->SetTarget(mBoxObject);
}
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 == mBoxObject)
{
mMotionModel->SetTarget(GetCamera());
}
else
{
mMotionModel->SetTarget(mBoxObject);
}
}
default:
{
ret = false;
break;
}
}
return ret;
}
Everything else in the .h .cpp files remains the same.
Running
Now let's compile and run the app! You should see an screen similar to this:
Pressing F1-F4 will change you between the different motion model types:
- The orbit motion model simulates the standard controls to manipulate a 3D scene for viewing from arbitrary point (i.e. translate, rotation, and zoom).
- The fly motion model simulates the control of an object in flight.
- The UFO motion model allows the camera to easily move along a horizontal plane easily, while additional controls let camera move up/down and turn left/right.
- The walk motion model simulates walking or driving.
Pressing F5 will toggle the target of the motion model between the Box and the camera.
The controls for each model are:
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
That's the end of the Delta3D Object Motion Model Part II tutorial. To better learn the application, play with it a little: search the web for others 3D models and change the motion model used to see how it will behave. Remember that you may need to adjust the camera position depending on the model used to get a good initial view!
Complete files to download: Hello_World_3_Models.zip
