WASDDemoApplication

ratatouille
Posts: 21
Joined: Fri Oct 24, 2014 10:48 am

WASDDemoApplication

Post by ratatouille »

Hi,

I thought this might be helpful for some. Derive from WASDDemoApplication instead of PlatformDemoApplication and WASD keys/arrow keys will allow you to fly through a scene.

WASDDemoApplication.h:

Code: Select all

#ifndef WASD_DEMO_APPLICATION
#define WASD_DEMO_APPLICATION

#ifdef _WINDOWS
#include "Win32DemoApplication.h"
#define PlatformDemoApplication Win32DemoApplication
#else
#include "GlutDemoApplication.h"
#define PlatformDemoApplication GlutDemoApplication
#endif

ATTRIBUTE_ALIGNED16(class) WASDDemoApplication : public PlatformDemoApplication {

private:
	static const float STEPSIZE = .1;

protected:
	float m_ele;
	float m_azi;
	btVector3 m_cameraFwd;
	btVector3 m_cameraUp;
	void bCreateLookAt(const btVector3& eye, const btVector3& center, const btVector3& up, GLfloat result[16]);

public:
	WASDDemoApplication();

	void keyboardCallback(unsigned char key, int x, int y);
	void specialKeyboard(int key, int x, int y);

	void strafeLeft();
	void strafeRight();
	void stepFront();
	void stepBack();
	void rotateUp();
	void rotateDown();
	void rotateLeft();
	void rotateRight();

	virtual void updateCamera();

};



#endif /* WASD_DEMO_APPLICATION */
WASDDemoApplication.cpp:

Code: Select all

#include "WASDDemoApplication.h"



void WASDDemoApplication::bCreateLookAt(const btVector3& eye, const btVector3& center, const btVector3& up, GLfloat result[16]) {
	btVector3 f = (center - eye).normalized();
	btVector3 u = up.normalized();
	btVector3 s = (f.cross(u)).normalized();
	u = s.cross(f);

	result[0*4+0] = s.x();
	result[1*4+0] = s.y();
	result[2*4+0] = s.z();

	result[0*4+1] = u.x();
	result[1*4+1] = u.y();
	result[2*4+1] = u.z();

	result[0*4+2] =-f.x();
	result[1*4+2] =-f.y();
	result[2*4+2] =-f.z();

	result[0*4+3] = 0.f;
	result[1*4+3] = 0.f;
	result[2*4+3] = 0.f;

	result[3*4+0] = -s.dot(eye);
	result[3*4+1] = -u.dot(eye);
	result[3*4+2] = f.dot(eye);
	result[3*4+3] = 1.f;
}



void WASDDemoApplication::stepBack() {
	btVector3 rayForward = (getCameraTargetPosition() - getCameraPosition());
	rayForward.normalize();

	m_cameraPosition -= m_zoomStepSize * rayForward;
	m_cameraTargetPosition -= m_zoomStepSize * rayForward;
}



void WASDDemoApplication::stepFront() {
	btVector3 rayForward = (getCameraTargetPosition()-getCameraPosition());
	rayForward.normalize();

	m_cameraPosition += m_zoomStepSize * rayForward;
	m_cameraTargetPosition += m_zoomStepSize * rayForward;
}



void WASDDemoApplication::strafeLeft() {
	btVector3 hor = getRayTo(0,0)-getRayTo(1,0);
	btVector3 vert = getRayTo(0,0)-getRayTo(0,1);
	btScalar multiplierX = btScalar(m_zoomStepSize/10.);
	btScalar multiplierY = btScalar(m_zoomStepSize/10.);

	if (m_ortho) {
		multiplierX = 1;
		multiplierY = 1;
	}

	m_cameraTargetPosition += hor * multiplierX;
	m_cameraPosition += hor * multiplierX;
}



void WASDDemoApplication::strafeRight() {
	btVector3 hor = -getRayTo(0,0)+getRayTo(1,0);
	btVector3 vert = getRayTo(0,0)-getRayTo(0,1);
	btScalar multiplierX = btScalar(m_zoomStepSize/10.);
	btScalar multiplierY = btScalar(m_zoomStepSize/10.);

	if (m_ortho) {
		multiplierX = 1;
		multiplierY = 1;
	}

	m_cameraTargetPosition += hor * multiplierX;
	m_cameraPosition += hor * multiplierX;
}



void WASDDemoApplication::rotateLeft() {
	m_ele += STEPSIZE; if (m_ele >= SIMD_PI) m_ele -= 2.*SIMD_PI; updateCamera();
}



void WASDDemoApplication::rotateRight() {
	m_ele -= STEPSIZE; if (m_ele < -SIMD_PI) m_ele += 2.*SIMD_PI; updateCamera();
}



void WASDDemoApplication::rotateUp() {
	m_azi -= STEPSIZE; if (m_azi < -SIMD_PI) m_azi += 2.*SIMD_PI; updateCamera();
}



void WASDDemoApplication::rotateDown() {
	m_azi += STEPSIZE; if (m_azi >= SIMD_PI) m_azi -= 2.*SIMD_PI; updateCamera();
}



void WASDDemoApplication::keyboardCallback(unsigned char key, int x, int y) {
	switch (key) {
		case 'a' : strafeLeft(); break;
		case 'd' : strafeRight(); break;
		case 'w' : stepFront(); break;
		case 's' : stepBack(); break;
		default:
			DemoApplication::keyboardCallback(key, x, y);
			break;
	}
}



void WASDDemoApplication::specialKeyboard(int key, int x, int y) {
	switch (key) {
#ifdef _WINDOWS
		case VK_LEFT : rotateLeft(); break;
		case VK_RIGHT : rotateRight(); break;
		case VK_UP : rotateUp(); break;
		case VK_DOWN : rotateDown(); break;
#else
		case GLUT_KEY_LEFT : rotateLeft(); break;
		case GLUT_KEY_RIGHT : rotateRight(); break;
		case GLUT_KEY_UP : rotateUp(); break;
		case GLUT_KEY_DOWN : rotateDown(); break;
#endif
		default:
			DemoApplication::keyboardCallback(key, x, y);
			break;
	}
}



void WASDDemoApplication::updateCamera() {

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	btQuaternion camQuat(m_ele, m_azi, 0.);
	m_cameraTargetPosition = btMatrix3x3(camQuat) * m_cameraFwd;
	m_cameraTargetPosition += m_cameraPosition;

	if (m_glutScreenWidth == 0 && m_glutScreenHeight == 0)
		return;

	btScalar aspect;
	btVector3 extents;

	aspect = m_glutScreenWidth / (btScalar)m_glutScreenHeight;
	extents.setValue(aspect * 1.0f, 1.0f,0);


	if (m_ortho)
	{
		// reset matrix
		glLoadIdentity();

		extents *= m_cameraDistance;
		btVector3 lower = m_cameraTargetPosition - extents;
		btVector3 upper = m_cameraTargetPosition + extents;
		//gluOrtho2D(lower.x, upper.x, lower.y, upper.y);
		glOrtho(lower.getX(), upper.getX(), lower.getY(), upper.getY(),-1000,1000);

		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		//glTranslatef(100,210,0);
	}
	else {
		//glFrustum (-aspect, aspect, -1.0, 1.0, 1.0, 10000.0);
		glFrustum (-aspect * m_frustumZNear, aspect * m_frustumZNear, -m_frustumZNear, m_frustumZNear, m_frustumZNear, m_frustumZFar);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		GLfloat resultMat[16];
		bCreateLookAt(m_cameraPosition,m_cameraTargetPosition, m_cameraUp, resultMat);
		glMultMatrixf(resultMat);
	}
}




WASDDemoApplication::WASDDemoApplication() :
m_cameraUp(0, 1, 0),    // up vector for the camera without rotation
m_cameraFwd(0, 0, 1)   // direction the camera points to without rotation
{
	this->m_frustumZNear = 1E-2;
	this->m_frustumZFar = 1E5;
}
Feedback welcome.