Tutorial 13 - Movimiento-3D (Vehículo)
Fecha Miércoles, 05 septiembre a las 23:08:36
Tema DirectX/Opengl


Empecemos a movernos por el mundo 3D. En este caso el movimiento será como el de un vehículo, como un coche. Relamente el movimiento no reproduce fielmente el comportamiento de un coche ya que habría que añadir física, pero nos servirá para empezar.



Se ha modificado la clase Object, añadiendo métodos para realizar giros y traslaciones del objeto modificando la matriz de transformación.

En el método CheckMovement(), en función de la tecla pulsada (flechas del cursor) giraremos a izquierda o a derecha. Avanzaremos siempre en función de la velocidad a la que nos movamos. Con ''+'' se acelera y con ''-'' se frena.


    ///////////////////////////////////////////////////////////////////////////////
    ///     CheckMovement: Comprueba si hay pulsada una tecla.
    ///
    ///     @param  long msElapsed: misilegundos transcurridos entre cada frame.
    ///
    ///     @return  nada
    ///////////////////////////////////////////////////////////////////////////////
    void GraphicApplication::CheckMovement( long msElapsed )
    {
    // ********************************* NEW **************************************

        float speed= m_Player.GetSpeed();

        if ( m_KeysPressed[KEY_PLUS] || m_KeysPressed[KEY_NUMERIC_PLUS] )
        {
            m_Player.SetSpeed( speed + OBJECT_ACCELERATION );   // Aceleramos
        }

        if ( m_KeysPressed[KEY_MINUS] || m_KeysPressed[KEY_NUMERIC_MINUS] )
        {
            m_Player.SetSpeed( speed - OBJECT_ACCELERATION );   // Frenamos
        }

        m_Player.Forward( speed * msElapsed );                  // Avanzamos

        if ( m_KeysPressed[KEY_LEFT] )
        {
            m_Player.Yaw( OBJECT_TURN * msElapsed );
        }

        if ( m_KeysPressed[KEY_RIGHT] )
        {
            m_Player.Yaw( -OBJECT_TURN * msElapsed );
        }

    // ****************************************************************************
    }

Vemos como a la hora de actualizar el estado de los objetos, recorremos la lista (en este caso el map) de principio a fin. Para acceder a cada elemento del map, lo hacemos a través del iterador. STL dispone de lo que se denominan iteradores (iterator) para recorrer las estructuras de datos. Con itObj->first se accede al valor clave y con itObj->second se accede al elemento que se almacena.


    ///////////////////////////////////////////////////////////////////////////////
    ///     UpdateObjects: Actualizamos el estado de los objetos.
    ///
    ///     @param  long msElapsed: Tiempo transcurrido entre cada frame.
    ///
    ///     @return  nada
    ///////////////////////////////////////////////////////////////////////////////
    void GraphicApplication::UpdateObjects(long msElapsed)
    {
    // ********************************* NEW **************************************
        Object *pObject;
        OBJECT_MAP::iterator itObj;

        for ( itObj=m_ObjectList.begin(); itObj!=m_ObjectList.end(); ++itObj )
        {
            pObject= itObj->second;
            if ( pObject )
                pObject->Update( msElapsed );
        }
    // ****************************************************************************
    }

No basta sólo con variar la posición y orientación de nuestro vehículo. Puesto que debe parecer que nos movemos, lo que hacemos es llevar la transformación realizada sobre el objeto, al punto de vista del observador.


    ///////////////////////////////////////////////////////////////////////////////
    ///     OnRender: Esta función es invocada cuando el sistema está listo para renderizar.
    ///
    ///     @param  nada
    ///
    ///     @return  nada
    ///////////////////////////////////////////////////////////////////////////////
    void GraphicApplication::OnRender()
    {
        Matrix mIdentity;
        fColorRGBA clearColor= { 0.0f, 0.0f, 0.8f, 1.0f };  // Color de fondo.

        if ( m_pVideoDriver )
        {
            // Limpiamos la pantalla.
            m_pVideoDriver->ClearColor( clearColor );
            m_pVideoDriver->ClearZBuffer();
            m_pVideoDriver->EnableDepthBuffer( true );

            // Proyección en perspectiva
            m_pVideoDriver->SetPerspective( FOV, m_WindowProps.width, m_WindowProps.height );

    // ********************************* NEW **************************************
            Vector3 vPosition = m_Player.GetPosition();                 // Posición de la cámara.
            Vector3 vLookAt   = m_Player.GetLookAtVector();             // A dónde mira.
            Vector3 vUp       = m_Player.GetLocalMatrix().GetUpVector();// Dónde se encuentra el "techo", eje Y.  
            m_pVideoDriver->LookAt( vPosition, vLookAt, vUp );
    // ****************************************************************************

            m_pVideoDriver->BeginRender();

            m_pVideoDriver->SetTransform( mIdentity );          // Reseteamos las transformaciones previas.
            m_pVideoDriver->EnableLighting( false );            // Desactivamos la iluminación.
            RenderFloor ( 20, 20 );                             // Renderizamos el suelo.

            if ( m_bWireframe )
            {
                m_pVideoDriver->SetRenderMode ( eWireFrame );   // Renderizado wireframe
                m_pVideoDriver->SetCullFaces  ( eCullNone  );   // Desactivamos la selección de caras a renderizar.
            }
            else
            {
                m_pVideoDriver->SetRenderMode ( eSolid     );   // Renderizado sólido.
                m_pVideoDriver->SetCullFaces  ( eCullBack  );   // No se renderizarán las caras traseras.
            }

            m_pVideoDriver->EnableLighting( true );             // Activamos la iluminación.
            RenderSceneObjects();                               // Renderizamos las geometrías.

            m_pVideoDriver->EndRender();
        }
    }

Podéis descargaros el ejemplo: tutorial-13.zip



Compartir en Facebook



Este artículo proviene de Programacion Grafica: Desarrollo 2D/3D con C++ y DirectX/OpenGL/GLUT/SDL - Windows/Linux
http://www.programaciongrafica.com

La dirección de esta noticia es:
http://www.programaciongrafica.com/modules.php?name=News&file=article&sid=14