IntermediateTutorial2Source

From Ogre Wiki

Jump to: navigation, search

This is the source code for Intermediate Tutorial 2.

#include <CEGUI/CEGUISystem.h>
#include <CEGUI/CEGUISchemeManager.h>
#include <CEGUI/RendererModules/Ogre/CEGUIOgreRenderer.h>

#include "ExampleApplication.h"

class MouseQueryListener : public ExampleFrameListener, public OIS::MouseListener
{
public:

    MouseQueryListener(RenderWindow* win, Camera* cam, SceneManager *sceneManager, CEGUI::Renderer *renderer)
        : ExampleFrameListener(win, cam, false, true), mGUIRenderer(renderer)
    {
        // Setup default variables
        mCount = 0;
        mCurrentObject = NULL;
        mLMouseDown = false;
        mRMouseDown = false;
        mSceneMgr = sceneManager;

        // Reduce move speed
        mMoveSpeed = 50;
        mRotateSpeed /= 500;

        // Register this so that we get mouse events.
        mMouse->setEventCallback(this);

        // Create RaySceneQuery
        mRaySceneQuery = mSceneMgr->createRayQuery(Ray());
    } // MouseQueryListener

    ~MouseQueryListener()
    {
        mSceneMgr->destroyQuery(mRaySceneQuery);
    }

    bool frameStarted(const FrameEvent &evt)
    {
        // Process the base frame listener code.  Since we are going to be
        // manipulating the translate vector, we need this to happen first.
        if (!ExampleFrameListener::frameStarted(evt))
            return false;

        // Setup the scene query
        Vector3 camPos = mCamera->getPosition();
        Ray cameraRay(Vector3(camPos.x, 5000.0f, camPos.z), Vector3::NEGATIVE_UNIT_Y);
        mRaySceneQuery->setRay(cameraRay);

        // Perform the scene query
        RaySceneQueryResult &result = mRaySceneQuery->execute();
        RaySceneQueryResult::iterator itr = result.begin();

        // Get the results, set the camera height
        if (itr != result.end() && itr->worldFragment)
        {
            Real terrainHeight = itr->worldFragment->singleIntersection.y;
            if ((terrainHeight + 10.0f) > camPos.y)
                mCamera->setPosition( camPos.x, terrainHeight + 10.0f, camPos.z );
        }

        return true;
    }

    /* MouseListener callbacks. */
    bool mouseMoved(const OIS::MouseEvent &arg)
    {
        // Update CEGUI with the mouse motion
        CEGUI::System::getSingleton().injectMouseMove(arg.state.X.rel, arg.state.Y.rel);

        // If we are dragging the left mouse button.
        if (mLMouseDown)
        {
            CEGUI::Point mousePos = CEGUI::MouseCursor::getSingleton().getPosition();
            Ray mouseRay = mCamera->getCameraToViewportRay(mousePos.d_x/float(arg.state.width),mousePos.d_y/float(arg.state.height));
            mRaySceneQuery->setRay(mouseRay);

            RaySceneQueryResult &result = mRaySceneQuery->execute();
            RaySceneQueryResult::iterator itr = result.begin();

            if (itr != result.end() && itr->worldFragment)
                mCurrentObject->setPosition(itr->worldFragment->singleIntersection);
        } // if

        // If we are dragging the right mouse button.
        else if (mRMouseDown)
        {
            mCamera->yaw(Degree(-arg.state.X.rel * mRotateSpeed));
            mCamera->pitch(Degree(-arg.state.Y.rel * mRotateSpeed));
        } // else if

        return true;
    }

    bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
    {
        // Left mouse button down
        if (id == OIS::MB_Left)
        {
            // Setup the ray scene query, use CEGUI's mouse position
            CEGUI::Point mousePos = CEGUI::MouseCursor::getSingleton().getPosition();
            Ray mouseRay = mCamera->getCameraToViewportRay(mousePos.d_x/float(arg.state.width), mousePos.d_y/float(arg.state.height));
            mRaySceneQuery->setRay(mouseRay);

            // Execute query
            RaySceneQueryResult &result = mRaySceneQuery->execute();
            RaySceneQueryResult::iterator itr = result.begin( );

            // Get results, create a node/entity on the position
            if (itr != result.end() && itr->worldFragment)
            {
                char name[16];
                sprintf(name, "Robot%d", mCount++);

                Entity *ent = mSceneMgr->createEntity(name, "robot.mesh");
                mCurrentObject = mSceneMgr->getRootSceneNode()->createChildSceneNode(String(name) + "Node", itr->worldFragment->singleIntersection);
                mCurrentObject->attachObject(ent);
                mCurrentObject->setScale(0.1f, 0.1f, 0.1f);
            } // if

            mLMouseDown = true;
        } // if

        // Right mouse button down
        else if (id == OIS::MB_Right)
        {
            CEGUI::MouseCursor::getSingleton().hide();
            mRMouseDown = true;
        } // else if

        return true;
    }

    bool mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
    {
        // Left mouse button up
        if (id == OIS::MB_Left)
        {
            mLMouseDown = false;
        } // if

        // Right mouse button up
        else if (id == OIS::MB_Right)
        {
            CEGUI::MouseCursor::getSingleton().show();
            mRMouseDown = false;
        } // else if

        return true;
    }


protected:
    RaySceneQuery *mRaySceneQuery;     // The ray scene query pointer
    bool mLMouseDown, mRMouseDown;     // True if the mouse buttons are down
    int mCount;                        // The number of robots on the screen
    SceneManager *mSceneMgr;           // A pointer to the scene manager
    SceneNode *mCurrentObject;         // The newly created object
    CEGUI::Renderer *mGUIRenderer;     // CEGUI renderer
};

class MouseQueryApplication : public ExampleApplication
{
protected:
    CEGUI::OgreRenderer *mGUIRenderer;
public:
    MouseQueryApplication()
    {
    }

    ~MouseQueryApplication() 
    {
    }
protected:
    void chooseSceneManager(void)
    {
        // Use the terrain scene manager.
        mSceneMgr = mRoot->createSceneManager(ST_EXTERIOR_CLOSE);
    }

    void createScene(void)
    {
        // Set ambient light
        mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
        mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8);

        // World geometry
        mSceneMgr->setWorldGeometry("terrain.cfg");

        // Set camera look point
        mCamera->setPosition(40, 100, 580);
        mCamera->pitch(Degree(-30));
        mCamera->yaw(Degree(-45));

        // CEGUI setup
        mGUIRenderer = &CEGUI::OgreRenderer::bootstrapSystem();

        // Mouse
        CEGUI::SchemeManager::getSingleton().create((CEGUI::utf8*)"TaharezLook.scheme");
        CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseArrow");
    }

    void createFrameListener(void)
    {
        mFrameListener = new MouseQueryListener(mWindow, mCamera, mSceneMgr, mGUIRenderer);
        mFrameListener->showDebugOverlay(true);
        mRoot->addFrameListener(mFrameListener);
    }
};


#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"

INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT)
#else
int main(int argc, char **argv)
#endif
{
    // Create application object
    MouseQueryApplication app;

    try {
        app.go();
    } catch(Exception& e) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        MessageBoxA(NULL, e.getFullDescription().c_str(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
        fprintf(stderr, "An exception has occurred: %s\n",
            e.getFullDescription().c_str());
#endif
    }

    return 0;
}
Ogre Tutorials

Ogre Beginner Tutorials: 1. Basic Introduction - 2. Cameras, Lights and Shadows - 3. Terrain, Sky and Fog - 4. Frame Listeners and Unbuffered Input - 5. Buffered Input - 6. The Ogre Startup Sequence - 7. CEGUI and OGRE - 8. Multiple and Dual SceneManagers

Intermediate Tutorials: 1. Animation, Interpolation and Quaternions - 2. RaySceneQueries and Basic Mouse Usage (1/2) - 3. Mouse Picking and SceneQuery Masks (2/2) - 4. Volume Selection and Manual Objects - 5. Static Geometry - 6. Projective Decals - 7. Render to Texture

Advanced Tutorials: 1. Resources and ResourceManagers

See also: Artist Tutorials - Ogre Articles - Cookbook

Personal tools
administration