How to make a free camera

From MaratisWiki
Jump to: navigation, search

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.


Contents

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");
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox