Openglローミングモデルの例

10724 ワード

Openglローミングモデルの例:
#include <stdio.h>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
#include <GLFW/glfw3.h>
#include "TrackballController.h"

#define CIGAMA 0.1

TrackballController* TrackballController::m_inst(0);

TrackballController* TrackballController::Inst()
{
    if(!m_inst)
    {
        m_inst = new TrackballController();
    }

    return m_inst;
}

TrackballController::TrackballController(void)
{
    mOldMouseX=0;
    mOldMouseY=0;
    m_vPtTrans = glm::vec2(0.0f, 0.0f);//      

    mRotationAangle=0;//    
    mDistanceToModelCenter = -2.0;

    mRotationAaxis_Local=glm::vec3(1.0f, 0.0f, 0.0f);
    //     、  、  、    
    mViewMatrix = mTranslationMatrix = mRotationMatrix = mScaleMatrix = glm::mat4(1.0);

    mScrollSpeed = 0.0f;
    m_fScale = 1.0f;//    

    mMouseButton = -1;//        
    spin_y_old = 0.0f;//         
}


TrackballController::~TrackballController(void)
{
}

void TrackballController::OnMouseMove(int x, int y)
{
    //
    /*if ( abs(x - mOldMouseX) < CIGAMA && abs(y - mOldMouseY) < CIGAMA ) { return; }*/

    if ( GLFW_MOUSE_BUTTON_LEFT == mMouseButton )
    {
        GLint viewport[4];
        glGetIntegerv(GL_VIEWPORT,viewport);//      
         //       opengl  
        glm::vec2 newMouse = scaleMouse( glm::vec2(x, y), glm::vec2(viewport[2],viewport[3]));
        glm::vec2 oldMouse = scaleMouse( glm::vec2(mOldMouseX, mOldMouseY), glm::vec2(viewport[2],viewport[3]));
        //      
        glm::vec2 d = (newMouse - oldMouse);
        //y           x        ,  
        if (abs(mOldMouseX - x) < abs(mOldMouseY - y))
        {
            m_vPtTrans = d;
        }
        else//  ,  
        {
            float RotationAangle = 360*(x-mOldMouseX)/m_fWinWidth;
            mRotationMatrix=glm::rotate(mRotationMatrix, RotationAangle,glm::vec3(0.0f,1.0f,0.0f) );

            //spin_y_old = mRotationAangle;
            //SetRotateParameter(newMouse,oldMouse);
        }

        mOldMouseX = x;
        mOldMouseY = y;
        //      
        UpdateMatrix();
    }       
}

void TrackballController::OnMouseScroll( int value )
{
    if ( value > 0 )
    {
        //     
        //mDistanceToModelCenter += mScrollSpeed;

        m_fScale *= (1.0f+mScrollSpeed);
    }
    else if ( value < 0 && m_fScale >= mScrollSpeed)
    {
        //     
        //mDistanceToModelCenter -= mScrollSpeed;

        m_fScale *= (1.0f-mScrollSpeed);
    }

    //printf("value=%d, mDistanceToModelCenter=%f
",value, mDistanceToModelCenter);
UpdateMatrix(); } void TrackballController::onMouseButton( int action, int button ,int x,int y) { if (action != GLFW_PRESS) { mMouseButton = -1; return; } mMouseButton = button; mOldMouseX = x; mOldMouseY = y; } void TrackballController::UpdateMatrix() { //mTranslationMatrix = glm::translate(glm::mat4(1.0f),glm::vec3(0.0f, 0.0f, mDistanceToModelCenter)); mScaleMatrix = glm::scale(glm::mat4(1.0f),glm::vec3(m_fScale, m_fScale, m_fScale)); mTranslationMatrix = glm::translate(mTranslationMatrix,glm::vec3(0.0f, m_vPtTrans.y, mDistanceToModelCenter)); mViewMatrix = mTranslationMatrix * mRotationMatrix * mScaleMatrix; m_vPtTrans = glm::vec2(0.0f,0.0f); mDistanceToModelCenter = 0.0f; } glm::vec2 TrackballController::scaleMouse(glm::vec2 coords, glm::vec2 viewport) { /*return glm::vec2( static_cast<float>(coords.x*2.0f) / static_cast<float>(viewport.x) - 1.0f, 1.0f - static_cast<float>(coords.y*2.0f) / static_cast<float>(viewport.y) );*/ return glm::vec2( static_cast<float>(coords.x) / static_cast<float>(viewport.x), 1.0f - static_cast<float>(coords.y) / static_cast<float>(viewport.y) ); } glm::vec3 TrackballController::projectToSphere(glm::vec2 xy) { static const float sqrt2 = sqrtf(2.f); glm::vec3 result; float d = glm::length(xy); float size_=2; if (d < size_ * sqrt2 / 2.f) { result.z = sqrtf(size_ * size_ - d*d); } else { float t = size_ / sqrt2; result.z = t*t / d; } result.x = xy.x; result.y = xy.y; return glm::normalize(result); } void TrackballController::SetRotateParameter(glm::vec2 newMouse,glm::vec2 oldMouse) { if (newMouse == oldMouse) { return; } glm::vec3 p1 = projectToSphere(oldMouse); glm::vec3 p2 = projectToSphere(newMouse); glm::vec3 r_axis_world = glm::cross(p1, p2); glm::vec3 d = 0.5f*(p1 - p2); mRotationAangle= 180*glm::length(d); glm::vec3 r_axis_local_end=glm::vec3(glm::inverse(mViewMatrix)*glm::vec4(r_axis_world,1)); glm::vec3 r_axis_local_start=glm::vec3(glm::inverse(mViewMatrix)*glm::vec4(0.0,0.0,0.0,1)); mRotationAaxis_Local=r_axis_local_end-r_axis_local_start; mRotationMatrix=glm::rotate(mRotationMatrix, mRotationAangle,mRotationAaxis_Local );//glm::vec3(0,1,0) } // void TrackballController::SetInitialState( glm::vec3 CameraPos, glm::vec3 modelCenter, glm::vec3 modelSize ) { m_fScale = 1.0f; mTranslationMatrix = mRotationMatrix = mScaleMatrix = glm::mat4(1.0); spin_y_old = 0; mDistanceToModelCenter = -1.0 * glm::length( CameraPos - modelCenter ); mViewMatrix = glm::lookAt(CameraPos, modelCenter, glm::vec3(0.0f,1.0f,0.0f)); // , float length = glm::length( modelSize ); mScrollSpeed = length * 0.1f; UpdateMatrix(); } // void TrackballController::AutoRotateAngle( GLfloat fAngle ) { mRotationMatrix=glm::rotate(mRotationMatrix, fAngle-spin_y_old,glm::vec3(0.0f,1.0f,0.0f) ); spin_y_old = fAngle; UpdateMatrix(); } // void TrackballController::ReSize( GLfloat fWidth,GLfloat fHeight ) { m_fWinWidth = fWidth; m_fWinHeight = fHeight; }