Jason McKesson avatar Jason McKesson committed f300244

MousePole now used in the lighting tutorials.

Comments (0)

Files changed (8)

Tut 08 Lights on/Ambient Lighting.cpp

 #include "../framework/framework.h"
 #include "../framework/Mesh.h"
 #include "../framework/MatrixStack.h"
+#include "../framework/MousePole.h"
 #include <glm/glm.hpp>
 #include <glm/gtc/type_ptr.hpp>
 
 	g_VertexAmbDiffuseColor = LoadProgram("DirAmbVertexLighting_PCN.vert", "ColorPassthrough.frag");
 }
 
-glm::mat4 CalcLookAtMatrix(const glm::vec3 &cameraPt, const glm::vec3 &lookPt, const glm::vec3 &upPt)
-{
-	glm::vec3 lookDir = glm::normalize(lookPt - cameraPt);
-	glm::vec3 upDir = glm::normalize(upPt);
-
-	glm::vec3 rightDir = glm::normalize(glm::cross(lookDir, upDir));
-	glm::vec3 perpUpDir = glm::cross(rightDir, lookDir);
-
-	glm::mat4 rotMat(1.0f);
-	rotMat[0] = glm::vec4(rightDir, 0.0f);
-	rotMat[1] = glm::vec4(perpUpDir, 0.0f);
-	rotMat[2] = glm::vec4(-lookDir, 0.0f);
-
-	rotMat = glm::transpose(rotMat);
-
-	glm::mat4 transMat(1.0f);
-	transMat[3] = glm::vec4(-cameraPt, 1.0f);
-
-	return rotMat * transMat;
-}
-
 Framework::Mesh *g_pCylinderMesh = NULL;
 Framework::Mesh *g_pPlaneMesh = NULL;
 
+Framework::RadiusDef radiusDef = {5.0f, 3.0f, 20.0f, 1.5f, 0.5f};
+Framework::MousePole g_mousePole(glm::vec3(0.0f, 0.5f, 0.0f), radiusDef);
+
+namespace
+{
+	void MouseMotion(int x, int y)
+	{
+		g_mousePole.GLUTMouseMove(glm::ivec2(x, y));
+		glutPostRedisplay();
+	}
+
+	void MouseButton(int button, int state, int x, int y)
+	{
+		g_mousePole.GLUTMouseButton(button, state, glm::ivec2(x, y));
+		glutPostRedisplay();
+	}
+
+	void MouseWheel(int wheel, int direction, int x, int y)
+	{
+		g_mousePole.GLUTMouseWheel(direction, glm::ivec2(x, y));
+		glutPostRedisplay();
+	}
+}
+
 //Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
 void init()
 {
 		printf(except.what());
 	}
 
+ 	glutMouseFunc(MouseButton);
+ 	glutMotionFunc(MouseMotion);
+	glutMouseWheelFunc(MouseWheel);
+
 	glEnable(GL_CULL_FACE);
 	glCullFace(GL_BACK);
 	glFrontFace(GL_CW);
 	glEnable(GL_DEPTH_CLAMP);
 }
 
-static glm::vec3 g_camTarget(0.0f, 0.5f, 0.0f);
-
-//In spherical coordinates.
-static glm::vec3 g_sphereCamRelPos(67.5f, -46.0f, 5.0f);
-
-glm::vec3 ResolveCamPosition()
-{
-	float rho = Framework::DegToRad(g_sphereCamRelPos.x);
-	float theta = Framework::DegToRad(g_sphereCamRelPos.y + 90.0f);
-
-	float fSinTheta = sinf(theta);
-	float fCosTheta = cosf(theta);
-	float fCosRho = cosf(rho);
-	float fSinRho = sinf(rho);
-
-	glm::vec3 dirToCamera(fSinTheta * fCosRho, fCosTheta, fSinTheta * fSinRho);
-	return (dirToCamera * g_sphereCamRelPos.z) + g_camTarget;
-}
-
 glm::vec4 g_lightDirection(0.866f, 0.5f, 0.0f, 0.0f);
 
 static float g_CylYaw = 0.0f;
 //Called to update the display.
 //You should call glutSwapBuffers after all of your rendering to display what you rendered.
 //If you need continuous updates of the screen, call glutPostRedisplay() at the end of the function.
+
 void display()
 {
 	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 
 	if(g_pPlaneMesh && g_pCylinderMesh)
 	{
-		const glm::vec3 &camPos = ResolveCamPosition();
-
 		Framework::MatrixStack modelMatrix;
-		modelMatrix.SetMatrix(CalcLookAtMatrix(camPos, g_camTarget, glm::vec3(0.0f, 1.0f, 0.0f)));
+		modelMatrix.SetMatrix(g_mousePole.CalcMatrix());
 
 		glm::vec4 lightDirCameraSpace = modelMatrix.Top() * g_lightDirection;
 
 	case 'A': g_CylRoll += 4.0f; break;
 	case 'E': g_CylYaw -= 4.0f; break;
 	case 'Q': g_CylYaw += 4.0f; break;
-	case 'i': g_sphereCamRelPos.y -= 11.25f; break;
-	case 'k': g_sphereCamRelPos.y += 11.25f; break;
-	case 'j': g_sphereCamRelPos.x += 11.25f; break;
-	case 'l': g_sphereCamRelPos.x -= 11.25f; break;
-	case 'o': g_sphereCamRelPos.z -= 1.5f; break;
-	case 'u': g_sphereCamRelPos.z += 1.5f; break;
-	case 'I': g_sphereCamRelPos.y -= 1.125f; break;
-	case 'K': g_sphereCamRelPos.y += 1.125f; break;
-	case 'J': g_sphereCamRelPos.x += 1.125f; break;
-	case 'L': g_sphereCamRelPos.x -= 1.125f; break;
-	case 'O': g_sphereCamRelPos.z -= 0.25f; break;
-	case 'U': g_sphereCamRelPos.z += 0.25f; break;
 		
 	case 32:
 		g_bDrawColoredCyl = !g_bDrawColoredCyl;
-		printf("Position: %f, %f, %f\n", g_sphereCamRelPos.x, g_sphereCamRelPos.y, g_sphereCamRelPos.z);
 		printf("Yaw: %f, Pitch: %f, Roll: %f\n", g_CylYaw, g_CylPitch, g_CylRoll);
 		break;
 
 		break;
 	}
 
-	g_sphereCamRelPos.y = glm::clamp(g_sphereCamRelPos.y, -78.75f, 78.75f);
-	g_camTarget.y = g_camTarget.y > 0.0f ? g_camTarget.y : 0.0f;
-	g_sphereCamRelPos.z = g_sphereCamRelPos.z > 2.0f ? g_sphereCamRelPos.z : 2.0f;
-
 	glutPostRedisplay();
 }
 

Tut 08 Lights on/Basic Lighting.cpp

 #include "../framework/framework.h"
 #include "../framework/Mesh.h"
 #include "../framework/MatrixStack.h"
+#include "../framework/MousePole.h"
 #include <glm/glm.hpp>
 #include <glm/gtc/type_ptr.hpp>
 
 	g_VertexDiffuseColor = LoadProgram("DirVertexLighting_PCN.vert", "ColorPassthrough.frag");
 }
 
-glm::mat4 CalcLookAtMatrix(const glm::vec3 &cameraPt, const glm::vec3 &lookPt, const glm::vec3 &upPt)
-{
-	glm::vec3 lookDir = glm::normalize(lookPt - cameraPt);
-	glm::vec3 upDir = glm::normalize(upPt);
-
-	glm::vec3 rightDir = glm::normalize(glm::cross(lookDir, upDir));
-	glm::vec3 perpUpDir = glm::cross(rightDir, lookDir);
-
-	glm::mat4 rotMat(1.0f);
-	rotMat[0] = glm::vec4(rightDir, 0.0f);
-	rotMat[1] = glm::vec4(perpUpDir, 0.0f);
-	rotMat[2] = glm::vec4(-lookDir, 0.0f);
-
-	rotMat = glm::transpose(rotMat);
-
-	glm::mat4 transMat(1.0f);
-	transMat[3] = glm::vec4(-cameraPt, 1.0f);
-
-	return rotMat * transMat;
-}
-
 Framework::Mesh *g_pCylinderMesh = NULL;
 Framework::Mesh *g_pPlaneMesh = NULL;
+Framework::RadiusDef radiusDef = {5.0f, 3.0f, 20.0f, 1.5f, 0.5f};
+Framework::MousePole g_mousePole(glm::vec3(0.0f, 0.5f, 0.0f), radiusDef);
+
+namespace
+{
+	void MouseMotion(int x, int y)
+	{
+		g_mousePole.GLUTMouseMove(glm::ivec2(x, y));
+		glutPostRedisplay();
+	}
+
+	void MouseButton(int button, int state, int x, int y)
+	{
+		g_mousePole.GLUTMouseButton(button, state, glm::ivec2(x, y));
+		glutPostRedisplay();
+	}
+
+	void MouseWheel(int wheel, int direction, int x, int y)
+	{
+		g_mousePole.GLUTMouseWheel(direction, glm::ivec2(x, y));
+		glutPostRedisplay();
+	}
+}
 
 //Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
 void init()
 		printf(except.what());
 	}
 
+	glutMouseFunc(MouseButton);
+	glutMotionFunc(MouseMotion);
+	glutMouseWheelFunc(MouseWheel);
+
 	glEnable(GL_CULL_FACE);
 	glCullFace(GL_BACK);
 	glFrontFace(GL_CW);
 	glEnable(GL_DEPTH_CLAMP);
 }
 
-static glm::vec3 g_camTarget(0.0f, 0.5f, 0.0f);
-
-//In spherical coordinates.
-static glm::vec3 g_sphereCamRelPos(67.5f, -46.0f, 5.0f);
-
-glm::vec3 ResolveCamPosition()
-{
-	float rho = Framework::DegToRad(g_sphereCamRelPos.x);
-	float theta = Framework::DegToRad(g_sphereCamRelPos.y + 90.0f);
-
-	float fSinTheta = sinf(theta);
-	float fCosTheta = cosf(theta);
-	float fCosRho = cosf(rho);
-	float fSinRho = sinf(rho);
-
-	glm::vec3 dirToCamera(fSinTheta * fCosRho, fCosTheta, fSinTheta * fSinRho);
-	return (dirToCamera * g_sphereCamRelPos.z) + g_camTarget;
-}
-
 glm::vec4 g_lightDirection(0.866f, 0.5f, 0.0f, 0.0f);
 
 static float g_CylYaw = 0.0f;
 
 	if(g_pPlaneMesh && g_pCylinderMesh)
 	{
-		const glm::vec3 &camPos = ResolveCamPosition();
-
 		Framework::MatrixStack modelMatrix;
-		modelMatrix.SetMatrix(CalcLookAtMatrix(camPos, g_camTarget, glm::vec3(0.0f, 1.0f, 0.0f)));
+		modelMatrix.SetMatrix(g_mousePole.CalcMatrix());
 
 		glm::vec4 lightDirCameraSpace = modelMatrix.Top() * g_lightDirection;
 
 	case 'A': g_CylRoll += 4.0f; break;
 	case 'E': g_CylYaw -= 4.0f; break;
 	case 'Q': g_CylYaw += 4.0f; break;
-	case 'i': g_sphereCamRelPos.y -= 11.25f; break;
-	case 'k': g_sphereCamRelPos.y += 11.25f; break;
-	case 'j': g_sphereCamRelPos.x += 11.25f; break;
-	case 'l': g_sphereCamRelPos.x -= 11.25f; break;
-	case 'o': g_sphereCamRelPos.z -= 1.5f; break;
-	case 'u': g_sphereCamRelPos.z += 1.5f; break;
-	case 'I': g_sphereCamRelPos.y -= 1.125f; break;
-	case 'K': g_sphereCamRelPos.y += 1.125f; break;
-	case 'J': g_sphereCamRelPos.x += 1.125f; break;
-	case 'L': g_sphereCamRelPos.x -= 1.125f; break;
-	case 'O': g_sphereCamRelPos.z -= 0.25f; break;
-	case 'U': g_sphereCamRelPos.z += 0.25f; break;
 		
 	case 32:
 		g_bDrawColoredCyl = !g_bDrawColoredCyl;
-		printf("Position: %f, %f, %f\n", g_sphereCamRelPos.x, g_sphereCamRelPos.y, g_sphereCamRelPos.z);
 		printf("Yaw: %f, Pitch: %f, Roll: %f\n", g_CylYaw, g_CylPitch, g_CylRoll);
 		break;
 	}
 
-	g_sphereCamRelPos.y = glm::clamp(g_sphereCamRelPos.y, -78.75f, 78.75f);
-	g_camTarget.y = g_camTarget.y > 0.0f ? g_camTarget.y : 0.0f;
-	g_sphereCamRelPos.z = g_sphereCamRelPos.z > 2.0f ? g_sphereCamRelPos.z : 2.0f;
-
 	glutPostRedisplay();
 }
 

Tut 08 Lights on/Scale and Lighting.cpp

 #include "../framework/framework.h"
 #include "../framework/Mesh.h"
 #include "../framework/MatrixStack.h"
+#include "../framework/MousePole.h"
 #include <glm/glm.hpp>
 #include <glm/gtc/type_ptr.hpp>
 
 	g_VertexDiffuseColor = LoadProgram("DirVertexLighting_PCN.vert", "ColorPassthrough.frag");
 }
 
-glm::mat4 CalcLookAtMatrix(const glm::vec3 &cameraPt, const glm::vec3 &lookPt, const glm::vec3 &upPt)
+Framework::Mesh *g_pCylinderMesh = NULL;
+Framework::Mesh *g_pPlaneMesh = NULL;
+Framework::RadiusDef radiusDef = {5.0f, 3.0f, 20.0f, 1.5f, 0.5f};
+Framework::MousePole g_mousePole(glm::vec3(0.0f, 0.5f, 0.0f), radiusDef);
+
+namespace
 {
-	glm::vec3 lookDir = glm::normalize(lookPt - cameraPt);
-	glm::vec3 upDir = glm::normalize(upPt);
+	void MouseMotion(int x, int y)
+	{
+		g_mousePole.GLUTMouseMove(glm::ivec2(x, y));
+		glutPostRedisplay();
+	}
 
-	glm::vec3 rightDir = glm::normalize(glm::cross(lookDir, upDir));
-	glm::vec3 perpUpDir = glm::cross(rightDir, lookDir);
+	void MouseButton(int button, int state, int x, int y)
+	{
+		g_mousePole.GLUTMouseButton(button, state, glm::ivec2(x, y));
+		glutPostRedisplay();
+	}
 
-	glm::mat4 rotMat(1.0f);
-	rotMat[0] = glm::vec4(rightDir, 0.0f);
-	rotMat[1] = glm::vec4(perpUpDir, 0.0f);
-	rotMat[2] = glm::vec4(-lookDir, 0.0f);
-
-	rotMat = glm::transpose(rotMat);
-
-	glm::mat4 transMat(1.0f);
-	transMat[3] = glm::vec4(-cameraPt, 1.0f);
-
-	return rotMat * transMat;
+	void MouseWheel(int wheel, int direction, int x, int y)
+	{
+		g_mousePole.GLUTMouseWheel(direction, glm::ivec2(x, y));
+		glutPostRedisplay();
+	}
 }
 
-Framework::Mesh *g_pCylinderMesh = NULL;
-Framework::Mesh *g_pPlaneMesh = NULL;
 
 //Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
 void init()
 		printf(except.what());
 	}
 
+	glutMouseFunc(MouseButton);
+	glutMotionFunc(MouseMotion);
+	glutMouseWheelFunc(MouseWheel);
+
 	glEnable(GL_CULL_FACE);
 	glCullFace(GL_BACK);
 	glFrontFace(GL_CW);
 	glEnable(GL_DEPTH_CLAMP);
 }
 
-static glm::vec3 g_camTarget(0.0f, 0.5f, 0.0f);
-
-//In spherical coordinates.
-static glm::vec3 g_sphereCamRelPos(67.5f, -46.0f, 5.0f);
-
-glm::vec3 ResolveCamPosition()
-{
-	float rho = Framework::DegToRad(g_sphereCamRelPos.x);
-	float theta = Framework::DegToRad(g_sphereCamRelPos.y + 90.0f);
-
-	float fSinTheta = sinf(theta);
-	float fCosTheta = cosf(theta);
-	float fCosRho = cosf(rho);
-	float fSinRho = sinf(rho);
-
-	glm::vec3 dirToCamera(fSinTheta * fCosRho, fCosTheta, fSinTheta * fSinRho);
-	return (dirToCamera * g_sphereCamRelPos.z) + g_camTarget;
-}
-
 glm::vec4 g_lightDirection(0.866f, 0.5f, 0.0f, 0.0f);
 
 static float g_CylYaw = 0.0f;
 
 	if(g_pPlaneMesh && g_pCylinderMesh)
 	{
-		const glm::vec3 &camPos = ResolveCamPosition();
-
 		Framework::MatrixStack modelMatrix;
-		modelMatrix.SetMatrix(CalcLookAtMatrix(camPos, g_camTarget, glm::vec3(0.0f, 1.0f, 0.0f)));
+		modelMatrix.SetMatrix(g_mousePole.CalcMatrix());
 
 		glm::vec4 lightDirCameraSpace = modelMatrix.Top() * g_lightDirection;
 
 	case 'A': g_CylRoll += 4.0f; break;
 	case 'E': g_CylYaw -= 4.0f; break;
 	case 'Q': g_CylYaw += 4.0f; break;
-	case 'i': g_sphereCamRelPos.y -= 11.25f; break;
-	case 'k': g_sphereCamRelPos.y += 11.25f; break;
-	case 'j': g_sphereCamRelPos.x += 11.25f; break;
-	case 'l': g_sphereCamRelPos.x -= 11.25f; break;
-	case 'o': g_sphereCamRelPos.z -= 1.5f; break;
-	case 'u': g_sphereCamRelPos.z += 1.5f; break;
-	case 'I': g_sphereCamRelPos.y -= 1.125f; break;
-	case 'K': g_sphereCamRelPos.y += 1.125f; break;
-	case 'J': g_sphereCamRelPos.x += 1.125f; break;
-	case 'L': g_sphereCamRelPos.x -= 1.125f; break;
-	case 'O': g_sphereCamRelPos.z -= 0.25f; break;
-	case 'U': g_sphereCamRelPos.z += 0.25f; break;
-		
+
 	case 32:
 		g_bScaleCyl = !g_bScaleCyl;
-		printf("Position: %f, %f, %f\n", g_sphereCamRelPos.x, g_sphereCamRelPos.y, g_sphereCamRelPos.z);
 		printf("Yaw: %f, Pitch: %f, Roll: %f\n", g_CylYaw, g_CylPitch, g_CylRoll);
 		break;
 
 		break;
 	}
 
-	g_sphereCamRelPos.y = glm::clamp(g_sphereCamRelPos.y, -78.75f, 78.75f);
-	g_camTarget.y = g_camTarget.y > 0.0f ? g_camTarget.y : 0.0f;
-	g_sphereCamRelPos.z = g_sphereCamRelPos.z > 2.0f ? g_sphereCamRelPos.z : 2.0f;
-
 	glutPostRedisplay();
 }
 

framework/MatrixStack.cpp

 	void MatrixStack::Rotate( glm::vec3 &axisOfRotation, float fAngDeg )
 	{
 		float fAngRad = DegToRad(fAngDeg);
+
+		RotateRadians(axisOfRotation, fAngRad);
+	}
+
+	void MatrixStack::RotateRadians( glm::vec3 &axisOfRotation, float fAngRad )
+	{
 		float fCos = cosf(fAngRad);
 		float fInvCos = 1.0f - fCos;
 		float fSin = sinf(fAngRad);

framework/MatrixStack.h

 		}
 
 		void Rotate(glm::vec3 &axisOfRotation, float fAngDeg);
+		void RotateRadians(glm::vec3 &axisOfRotation, float fAngRad);
 		void RotateX(float fAngDeg);
 		void RotateY(float fAngDeg);
 		void RotateZ(float fAngDeg);

framework/MousePole.cpp

+// MousePole.cpp: implementation of the MousePole class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include <GL/freeglut.h>
+#include "framework.h"
+#include "MousePole.h"
+#include "MatrixStack.h"
+
+#include <math.h>
+
+#ifndef M_PI
+#define M_PI 3.14159265f
+#endif
+
+#define PI_2 1.570796325f
+
+glm::vec3 g_UnitZ(0.0f, 0.0f, 1.0f);
+
+namespace Framework
+{
+	MousePole::MousePole(glm::vec3 target, const RadiusDef &radiusDef)
+		: m_lookAt(target)
+		, m_radCurrXZAngle(0.0)
+		, m_radCurrYAngle(-PI_2 / 2.0f)
+		, m_radCurrSpin(0.0f)
+		, m_fRadius(20.0f)
+		, m_radius(radiusDef)
+		, m_bIsDragging(false)
+	{}
+
+	MousePole::~MousePole()
+	{
+	}
+
+	namespace
+	{
+		glm::mat4 CalcLookAtMatrix(const glm::vec3 &cameraPt,
+			const glm::vec3 &lookPt, const glm::vec3 &upPt)
+		{
+			glm::vec3 lookDir = glm::normalize(lookPt - cameraPt);
+			glm::vec3 upDir = glm::normalize(upPt);
+
+			glm::vec3 rightDir = glm::normalize(glm::cross(lookDir, upDir));
+			glm::vec3 perpUpDir = glm::cross(rightDir, lookDir);
+
+			glm::mat4 rotMat(1.0f);
+			rotMat[0] = glm::vec4(rightDir, 0.0f);
+			rotMat[1] = glm::vec4(perpUpDir, 0.0f);
+			rotMat[2] = glm::vec4(-lookDir, 0.0f);
+
+			rotMat = glm::transpose(rotMat);
+
+			glm::mat4 transMat(1.0f);
+			transMat[3] = glm::vec4(-cameraPt, 1.0f);
+
+			return rotMat * transMat;
+		}
+	}
+
+	glm::mat4 MousePole::CalcMatrix() const
+	{
+		//Compute the position vector along the xz plane.
+		float cosa = cosf(m_radCurrXZAngle);
+		float sina = sinf(m_radCurrXZAngle);
+
+		glm::vec3 currPos(-sina, 0.0f, cosa);
+
+		//Compute the "up" rotation axis.
+		//This axis is a 90 degree rotation around the y axis. Just a component-swap and negate.
+		glm::vec3 UpRotAxis;
+
+		UpRotAxis.x = currPos.z;
+		UpRotAxis.y = currPos.y;
+		UpRotAxis.z = -currPos.x;
+
+		//Now, rotate around this axis by the angle.
+		Framework::MatrixStack theStack;
+
+		theStack.SetIdentity();
+		theStack.RotateRadians(UpRotAxis, m_radCurrYAngle);
+		currPos = glm::vec3(theStack.Top() * glm::vec4(currPos, 0.0));
+
+		//Set the position of the camera.
+		glm::vec3 tempVec = currPos * m_radius.fCurrRadius;
+		glm::vec3 cameraPosition = tempVec + m_lookAt;
+
+		//Now, compute the up-vector.
+		//The direction of the up-vector is the cross-product of currPos and UpRotAxis.
+		//Rotate this vector around the currPos axis given m_currSpin.
+
+		glm::vec3 upVec = glm::cross(currPos, UpRotAxis);
+
+		theStack.SetIdentity();
+		theStack.RotateRadians(currPos, m_radCurrSpin);
+		upVec = glm::vec3(theStack.Top() * glm::vec4(upVec, 0.0));
+
+		return CalcLookAtMatrix(cameraPosition, m_lookAt, upVec);
+	}
+
+
+	void MousePole::BeginDragRotate(const glm::ivec2 &ptStart, RotateMode rotMode)
+	{
+		m_RotateMode = rotMode;
+
+		m_initialPt = ptStart;
+
+		m_radInitXZAngle = m_radCurrXZAngle;
+		m_radInitYAngle = m_radCurrYAngle;
+		m_radInitSpin = m_radCurrSpin;
+
+		m_bIsDragging = true;
+	}
+
+	void MousePole::OnDragRotate(const glm::ivec2 &ptCurr)
+	{
+		glm::ivec2 iDiff = ptCurr - m_initialPt;
+
+		switch(m_RotateMode)
+		{
+		case RM_DUAL_AXIS_ROTATE:
+			ProcessXChange(iDiff.x);
+			ProcessYChange(iDiff.y);
+			break;
+		case RM_XZ_AXIS_ROTATE:
+			ProcessXChange(iDiff.x);
+			break;
+		case RM_Y_AXIS_ROTATE:
+			ProcessYChange(iDiff.y);
+			break;
+		case RM_SPIN_VIEW_AXIS:
+			ProcessSpinAxis(iDiff.x, iDiff.y);
+		default:
+			break;
+		}
+	}
+#define SCALE_FACTOR 250
+
+	const float X_CONVERSION_FACTOR = PI_2 / SCALE_FACTOR;
+	const float Y_CONVERSION_FACTOR = PI_2 / SCALE_FACTOR;
+	const float SPIN_CONV_FACTOR = PI_2 / SCALE_FACTOR;
+
+	void MousePole::ProcessXChange(int iXDiff)
+	{
+		m_radCurrXZAngle = (iXDiff * X_CONVERSION_FACTOR) + m_radInitXZAngle;
+	}
+
+	void MousePole::ProcessYChange(int iYDiff)
+	{
+		m_radCurrYAngle = (-iYDiff * Y_CONVERSION_FACTOR) + m_radInitYAngle;
+	}
+
+	void MousePole::ProcessSpinAxis(int iXDiff, int iYDiff)
+	{
+		m_radCurrSpin = (iXDiff * SPIN_CONV_FACTOR) + m_radInitSpin;
+	}
+
+
+	void MousePole::EndDragRotate(const glm::ivec2 &ptEnd, bool bKeepResults)
+	{
+		if(bKeepResults)
+		{
+			OnDragRotate(ptEnd);
+		}
+		else
+		{
+			m_radCurrXZAngle = m_radInitXZAngle;
+			m_radCurrYAngle = m_radInitYAngle;
+		}
+
+		m_bIsDragging = false;
+	}
+
+	void MousePole::MoveCloser( bool bLargeStep /*= true*/ )
+	{
+		if(bLargeStep)
+			m_radius.fCurrRadius -= m_radius.fLargeDelta;
+		else
+			m_radius.fCurrRadius -= m_radius.fSmallDelta;
+
+		if(m_radius.fCurrRadius < m_radius.fMinRadius)
+			m_radius.fCurrRadius = m_radius.fMinRadius;
+	}
+
+	void MousePole::MoveAway( bool bLargeStep /*= true*/ )
+	{
+		if(bLargeStep)
+			m_radius.fCurrRadius += m_radius.fLargeDelta;
+		else
+			m_radius.fCurrRadius += m_radius.fSmallDelta;
+
+		if(m_radius.fCurrRadius > m_radius.fMaxRadius)
+			m_radius.fCurrRadius = m_radius.fMaxRadius;
+	}
+
+	void MousePole::GLUTMouseMove( const glm::ivec2 &position )
+	{
+		if(m_bIsDragging)
+			OnDragRotate(position);
+	}
+
+	void MousePole::GLUTMouseButton( int button, int btnState, const glm::ivec2 &position )
+	{
+		if(btnState == GLUT_DOWN)
+		{
+			//Ignore all other button presses when dragging.
+			if(!m_bIsDragging)
+			{
+				switch(button)
+				{
+				case GLUT_LEFT_BUTTON:
+					if(glutGetModifiers() & GLUT_ACTIVE_CTRL)
+						this->BeginDragRotate(position, MousePole::RM_XZ_AXIS_ROTATE);
+					else
+						this->BeginDragRotate(position, MousePole::RM_DUAL_AXIS_ROTATE);
+					break;
+				case GLUT_MIDDLE_BUTTON:
+					this->BeginDragRotate(position, MousePole::RM_SPIN_VIEW_AXIS);
+					break;
+				case GLUT_RIGHT_BUTTON:
+					this->BeginDragRotate(position, MousePole::RM_Y_AXIS_ROTATE);
+					break;
+				default:
+					break;
+				}
+			}
+		}
+		else
+		{
+			//Ignore all other button releases when not dragging
+			if(m_bIsDragging)
+			{
+				switch(button)
+				{
+				case GLUT_LEFT_BUTTON:
+					if(m_RotateMode == MousePole::RM_XZ_AXIS_ROTATE ||
+						m_RotateMode == MousePole::RM_DUAL_AXIS_ROTATE)
+						this->EndDragRotate(position);
+					break;
+				case GLUT_MIDDLE_BUTTON:
+					if(m_RotateMode == MousePole::RM_SPIN_VIEW_AXIS)
+						this->EndDragRotate(position);
+					break;
+				case GLUT_RIGHT_BUTTON:
+					if(m_RotateMode == MousePole::RM_Y_AXIS_ROTATE)
+						this->EndDragRotate(position);
+					break;
+				default:
+					break;
+				}
+			}
+		}
+	}
+
+	void MousePole::GLUTMouseWheel( int direction, const glm::ivec2 &position )
+	{
+		if(direction > 0)
+			this->MoveCloser(!(glutGetModifiers() & GLUT_ACTIVE_SHIFT));
+		else
+			this->MoveAway(!(glutGetModifiers() & GLUT_ACTIVE_SHIFT));
+	}
+}
+

framework/MousePole.h

+#ifndef FRAMEWORK_MOUSE_POLE_H
+#define FRAMEWORK_MOUSE_POLE_H
+
+#include <glm/glm.hpp>
+
+namespace Framework
+{
+	struct RadiusDef
+	{
+		float fCurrRadius;
+		float fMinRadius;
+		float fMaxRadius;
+		float fLargeDelta;
+		float fSmallDelta;
+	};
+
+	class MousePole  
+	{
+	public:
+		MousePole(glm::vec3 target, const RadiusDef &radiusDef);
+		virtual ~MousePole();
+
+		void GetCurrVectors(glm::vec3 &pos, glm::vec3 &lookAt, glm::vec3 &upVec);
+		glm::mat4 CalcMatrix() const;
+
+		enum RotateMode
+		{
+			RM_DUAL_AXIS_ROTATE,
+			RM_XZ_AXIS_ROTATE,
+			RM_Y_AXIS_ROTATE,
+			RM_SPIN_VIEW_AXIS,
+		};
+
+		void GLUTMouseMove(const glm::ivec2 &position);
+		void GLUTMouseButton(int button, int btnState, const glm::ivec2 &position);
+		void GLUTMouseWheel(int direction, const glm::ivec2 &position);
+
+	protected:
+		glm::vec3 m_lookAt;
+
+		float m_radCurrXZAngle;	//Angle around the y-axis. In radians
+		float m_radCurrYAngle;		//Angle above the xz plane. In radians
+		float m_radCurrSpin;		//Angle spin around the look-at direction. Changes up-vector.
+		float m_fRadius;		//Camera distance
+		RadiusDef m_radius;
+
+
+		//Used when rotating.
+		RotateMode m_RotateMode;
+		bool m_bIsDragging;
+
+		glm::ivec2 m_initialPt;
+
+		float m_radInitXZAngle;
+		float m_radInitYAngle;
+		float m_radInitSpin;
+
+		void ProcessXChange(int iXDiff);
+		void ProcessYChange(int iYDiff);
+		void ProcessSpinAxis(int iXDiff, int iYDiff);
+
+		void BeginDragRotate(const glm::ivec2 &ptStart, RotateMode rotMode = RM_DUAL_AXIS_ROTATE);
+		void OnDragRotate(const glm::ivec2 &ptCurr);
+		void EndDragRotate(const glm::ivec2 &ptEnd, bool bKeepResults = true);
+		bool IsDragging() {return m_bIsDragging;}
+
+		void MoveCloser(bool bLargeStep = true);
+		void MoveAway(bool bLargeStep = true);
+	};
+}
+
+#endif //FRAMEWORK_MOUSE_POLE_H

framework/framework.cpp

 void reshape(int w, int h);
 void keyboard(unsigned char key, int x, int y);
 
+
 int main(int argc, char** argv)
 {
 	glutInit(&argc, argv);
 	gleLoadFunctions();
 	init();
 
+// 	glutMouseFunc(MouseButton);
+// 	glutMotionFunc(MouseMotion);
 	glutDisplayFunc(display); 
 	glutReshapeFunc(reshape);
 	glutKeyboardFunc(keyboard);
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.