SE Team 9 3D Flyer Cole Hoosier Ryan Hannebaum Leanne Gray Alex Stampbach Matt Cook
Project Statement GlobalFlyer allows a player to fly a Wright brothers-style airplane in 3D space using the OGRE graphic rendering engine and the FMOD sound system.
Presentation Outline I.Introduction II.Review of web page III.Project Accomplishments IV.Design (UML Diagrams) V.Source Code A.Lighting B.Sky, Fog, and Terrain C.Physics D.Mouse Controller VI.User Manual VII.Testing VIII.Project Demonstration IX.Conclusion
GlobalFlyer Web Site
Project Accomplishments
Time and Lines of Code Minutes LOC* *In final project Cole4, Matt2, Alex2,5500 Ryan1,9209 Leanne2,20545 Total13,175404
Effort Over the Semester Time in minutes =Presentation during this time period
Task Effort vs. Estimated Time
Design
FrameStarted Sequence Diag
Source Code Explained
Lighting & Shadows
Sky, Fog and Terrain
Sky setSkyPlane(bool enable, const Plane& plane, const String& materialName, Real scale, Real tiling, bool drawFirst, Real bow, int xsegments, int ysegments); mSceneMgr->setSkyPlane( true, plane, "Examples/CloudySky", 500, 20, true, 0.5, 150, 150 );
Fog setFog(FogMode mode, const ColourValue& colour, Real expDensity,Real linearStart, Real linearEnd) mSceneMgr->setFog( FOG_LINEAR, fadeColour, 0, 0, 7500 );
Terrain # Heightmap-source specific settings Heightmap.image=../new_media/terrain_s.png # If you use RAW, fill in the below too # RAW-specific setting - size (horizontal/vertical) #Heightmap.raw.size=257 # RAW-specific setting - bytes per pixel (1 = 8bit, 2=16bit) #Heightmap.raw.bpp=2 # How large is a page of tiles (in vertices)? Must be (2^n)+1 PageSize=257 # How large is each tile? Must be (2^n)+1 and be smaller than PageSize TileSize=17 # The maximum error allowed when determining which LOD to use MaxPixelError=3 # The size of a terrain page, in world units PageWorldX=15000 PageWorldZ=15000 # Maximum height of the terrain MaxHeight=250 terrain_s.png
Physics Engine
Physics PhysicsEngine(); 9 Functions: –void translateFromWorld( const Quaternion &quat, Vector3 *vec); –void translateToWorld( const Quaternion &quat, Vector3 *vec); –void applyForce( const Vector3 *dir, float time); –void applyDrag (const Quaternion &quat, const Vector3 *surface_areas, float coeff, float time); –void update(float time); –void getVelocity( Vector3 *result ); –void setVelocity (const Vector3 *vel); –void getPosition (Vector3 *result ); –void setPosition (const Vector3 *pos); 3 Values: Position, Velocity, and DragP
Translations: –void translateFromWorld( const Quaternion &quat, Vector3 *vec); –void translateToWorld( const Quaternion &quat, Vector3 *vec); Multiplying a Vector3 by a Quaternion translates the Vector into the Quaternion’s orientation. This is accomplished at the Vector’s location in space (away from the Origin) using complex math
Apply Forces: void applyForce( const Vector3 *dir, float time); void applyDrag (const Quaternion &quat, const Vector3 *surface_areas, float coeff, float time); For our plane: time = time since last call to update surface area = 5, 20, 1 coeff = 617.0
Get’s and Set’s void getVelocity( Vector3 *result ); void setVelocity (const Vector3 *vel); void getPosition (Vector3 *result ); void setPosition (const Vector3 *pos);
Example: One Force Two Forces Drag
Text: ResourceGroupManager –Holds Location of Font FontManager –Manages the Font –Creates a resource pointer “font” Font –Sets size, resolution, etc of font
Creating the Text Area OverlayManager –Contains OverlayContainer OverlayContainer “panel” –Has a size and a location –Contains a TextAreaOverlayElement TextAreaOverlayElement “textArea” –Has a size, location, font, and color
So…. Panel TextArea (font) OverlayManager
Execution TextArea, and others, are created, and textArea is passed to sampleListener Every 10 frames, sampleListener updates the text area Calls –OgreCharacter::GetPosit(Vector3 *pos) –OgreCharacter::GetVeloc(Vector3 *pos) –OgreCharacter::GetRelVeloc(Vector3 *pos) –OgreCharacter::GetDrag(Vector3 *pos) Displays Values
Physics Implementation in OgreCharacter Handled in the Update function: –OgreCharacter::update (Real elapsedTime, InputReader *input) 4 forces –Propeler, Drag, Lift, Gravity 3 Directions of Turning –Pitch, Roll, Yaw (new)
OgreCharacter keeps track of: –Quaternion: world’s orientation –Vectors Position, Lift, Speed, Drag, Prop –Constants gravV = Vector3(0.0, -9.8, 0.0); surface_areas = Vector3( 5, 20, 1); LIFT_CONSTANT 206.0f DRAG_CONSTANT 617.0f
Applying Forces While not Crashed –Apply Gravity Relative to world –Apply Lift In Plane’s y direction, relative to speed squared –Apply Drag Relative to velocity squared, and position –Apply Propeller In Plane’s z direction 3.5 to 5
Turning Pitch –Turns up/down at 10 degree’s a frame Roll –Rotates Left/Right at 30 degree’s a frame Yaw –Turns Left/Right at 10 degree’s a frame
Constants Developed from Drag, Lift equations: –Lift = Coeff. * ρ *V^2 *1/2 * Area –Drag = -1/2 * ρ * v^2 * A * Coeff. Adjusted for Idle/Top Speeds –Lose lift at ~ 43.5 Fine Tuned Through Testing: –Lift = 206 –Drag = 617 –Surface Area = 5,20,1
Mouse Listener
MouseListener and MouseMotionListener Our sample listener needs to extend these classes in order to receive mouse events. More information on these classes can be found at:
Mouse Control Incorporation of MouseListener and MouseMotionListener Two classes changed: –class SampleListener –class SampleApplication
Class SampleListener SampleListener extends: –public ExampleFrameListener, –public MouseListener // Extension added –public MouseMotionListener // Extension added class SampleListener : public ExampleFrameListener, public MouseListener, public MouseMotionListener
SampleListener protected variables CEGUI::Renderer *mGUIRenderer; // cegui renderer bool mRMouseDown; // returns true if the mouse button is down SceneManager *mSceneMgr; // a pointer to the scene manager
SampleListener constructor Need to pass SampleListener constructor the scene manager and the renderer objects that we created –SampleListener(RenderWindow* win, Camera* cam, SceneManager *sceneManager, CEGUI::Renderer *renderer) Need to add the mouse listeners so we can process the events for the mouse –mEventProcessor->addMouseListener( this ); –mEventProcessor->addMouseMotionListener( this );
SampleListener public methods virtual void mousePressed(MouseEvent* e) –// Right mouse button down – else if (e->getButtonID() & MouseEvent::BUTTON1_MASK) – { – mRMouseDown = true; – } If the right mouse is pushed we need to set the variable to true
SampleListener public methods virtual void mouseReleased(MouseEvent* e) –// Right mouse released – else if (e->getButtonID() & MouseEvent::BUTTON1_MASK) – { – mRMouseDown = false; – } If the right mouse button is released we need to set the variable back to false
SampleListener public methods virtual void mouseDragged (MouseEvent *e) –mouseMoved(e); –// Update CEGUI with the mouse motion –if ( mRMouseDown ) – { – mCamera->yaw( -e->getRelX() * mRotateSpeed ); – mCamera->pitch( -e->getRelY() * mRotateSpeed ); – } If the mouse button is down then rotate the camera relative to the current position getRel() - Finds the distance since last time the method was called
Class SampleApplication Protected –CEGUI::OgreCEGUIRenderer *mGUIRenderer; –CEGUI::System *mGUISystem; ~SampleApplication() –delete mGUISystem; –delete mGUIRenderer;
Class SampleApplication void createScene(void) –mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, mSceneMgr); –mGUISystem = new CEGUI::System(mGUIRenderer); // Declaration of the mGUI Renderer and System
Analysis Estimated time for mouse implementation: 11 hours Actual time spent for mouse implementation: 12 hours
Explanation The task was more complex than initially determined –Ran into unseen linker errors Remedy –Needed to allocate more time to the task –Or needed another person working on the task
User Manual Gameplay Support references Software requirements
Testing of the GlobalFlyer C1 (and C0) coverage
Testing Method Debugging output at the start of every block and other key places “If” blocks without a corresponding “else” block had one added During the course of testing, every decision was covered at least once For the final run, unlikely cases that required code modification were skipped
Covering the Cases Use all movement keys: –q, w, e, a, s, d, Use all camera-selection keys: –F1, F2, F3 Crash the plane and restart with F1 Fly to/through the edge of the world Toggle SHOW_STATS in testing.h
Exceptions to Coverage All FMOD-related code was skipped –Rationale: This was inherited code that never functioned properly this semester. –Plan: Correct the problems next semester and commence testing at that point
Exceptions to Coverage ExtendedCamera::ExtendedCamera –Remove camera argument in constructor at sample_application.cpp:73 if (camera == 0) { debug("ExtendedCamera::ExtendedCamera 2 (if)"); mCamera = mSceneMgr->createCamera (mName); mOwnCamera = true; }
Exceptions to Coverage SampleListener::update –showstats section: 3e Enable SHOW_STATS, and change bool to “false” for setTextArea sample_application.cpp:119 –mchar and mExCamera sections: 2e, 7e, 11e, 12e, 13e, 15e, 16e, 17e, 20e, 21e, 22e Remove calls to setCharacter and/or setExtendedCamera at sample_application.cpp:79-80