How to make a free camera

This tutorial shows how to make a free camera using C++.

A free camera in 3D games/applications is a camera which can rotate and move around the scene with no restrictions and it has no physics at all. It's useful for debugging purposes.

You can actually also add physics to it, in that case you will not use the function setPosition but you will use the function MPhysicsContext::addCentralForce.

To start, you have to already have your MGame-derived class: see the plugin tutorial.

centerCursor function
First of all we need a function to center the mouse cursor. We can take that directly from MScript.cpp (the lua script functions source code): void MyGame::centerCursor(void) {	MEngine * engine = MEngine::getInstance; MSystemContext * system = engine->getSystemContext; MInputContext * input = engine->getInputContext;

unsigned int width = 0; unsigned int height = 0; system->getScreenSize(&width, &height); int x = width/2; int y = height/2;

system->setCursorPosition(x, y); input->setAxis("MOUSE_X", (float)(x / (float)width)); input->setAxis("MOUSE_Y", (float)(y / (float)height)); }

Header
On our header file: MOCamera * camera; float camera_dx = 0.0f; float camera_dy = 0.0f; float mouseX, mouseY, mouseX_prev, mouseY_prev;

onBeginScene
On onBeginScene: system->hideCursor; camera = scene->getCameraByName("Camera");

Update
On update, before anything else, we could store the mouse position in the mouseX and mouseY variable. You could do that at the start of the function so that these variables can be used from other code you may write in the future without the need to retrieve the values again: MEngine * engine = MEngine::getInstance; MInputContext * input = engine->getInputContext; mouseX = input->getAxis("MOUSE_X"); mouseY = input->getAxis("MOUSE_Y");

Still on update, in whichever part of the function you want, we put our actual camera movement code.

MGame::update is the last thing that should be called, which is the "original" code of the update function from the base class MGame. So we'll put our camera movement code before that line of code.

The values -2, 2, -1, 1 on the move the camera part can be changed to allow the vector to have different length which means more or less space, which in turn means more or less speed when moving the camera. Left and right movement is generally made slower, that's why you have half the speed/vector length there. /*	free camera	*/ //rotate horizontal (X mouse) camera->addAxisAngleRotation(camera->getInverseRotatedVector(MVector3(0,0,-1)),camera_dx*100); //rotate vertical (Y mouse) camera->addAxisAngleRotation(MVector3(-1,0,0),camera_dy*100); //move the camera if(input->isKeyPressed("W")) camera->setPosition(camera->getPosition + camera->getRotatedVector(MVector3(0,0,-2))); if(input->isKeyPressed("S")) camera->setPosition(camera->getPosition + camera->getRotatedVector(MVector3(0,0,2))); if(input->isKeyPressed("A")) camera->setPosition(camera->getPosition + camera->getRotatedVector(MVector3(-1,0,0))); if(input->isKeyPressed("D")) camera->setPosition(camera->getPosition + camera->getRotatedVector(MVector3(1,0,0))); //get mouse direction camera_dx = mouseX - mouseX_prev; camera_dy = mouseY - mouseY_prev; //center cursor centerCursor; mouseX_prev = input->getAxis("MOUSE_X"); mouseY_prev = input->getAxis("MOUSE_Y");