Gamestudio Links
Zorro Links
Newest Posts
Data from CSV not parsed correctly
by dr_panther. 05/06/24 18:50
Help with plotting multiple ZigZag
by degenerate_762. 04/30/24 23:23
M1 Oversampling
by 11honza11. 04/30/24 08:16
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
4 registered members (AndrewAMD, dr_panther, 2 invisible), 1,056 guests, and 0 spiders.
Key: Admin, Global Mod, Mod
Newest Members
firatv, wandaluciaia, Mega_Rod, EternallyCurious, howardR
19050 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Mobile Object Orbital Camera #271119
06/11/09 10:44
06/11/09 10:44
Joined: Jun 2009
Posts: 1
S
Soup Offline OP
Guest
Soup  Offline OP
Guest
S

Joined: Jun 2009
Posts: 1
I spent a good two hours looking for information on how to do this before I decided to sit down and do the math out myself. All things considered, it was actually much less complicated than I thought it was going to be.

The concept here is to have a mobile object around which the camera rotates.

First, here's the math:

Code:
We're going to get the relative coordinates that the Camera
must occupy in three dimensional space by mapping it onto
two seperate two dimensional planes where the origin is our
target object. We know the two angles we wish the camera to be at
and the total distance from the object we would like it to be.

For our first plane we will view the object on the X and Y axes.
We will draw a right triangle with a hypotenuse the length of 
nCamDist and the angle adjacent to the origin being nCamAngle degrees.
Using Sine and Cosine, we can determine the length  along the X and Y.
Sine gives us Y/nCamDist and Cosine gives us X/nCamDist.

Since:
	sin(nCamAngle) = Y/nCamDist
	cos(nCamAngle) = X/nCamDist
Thus:
	Y = sin(nCamAngle) * nCamDist
	X = cos(nCamAngle) * nCamDist

This is wonderful if we would like a static Z position, but I personally
would like to be able to change my vertical vantage point. Before we can
go any further, we need to determine where on the Z axis we reside.

Similar to our other operation, we're going to specify an angle initially,
as opposed to a position. We would like the camera to tilt at nCamTilt degrees.
Once again, we know our distance from the object and we know our angle, but this
time we're only going after one side.

In this case, since:
	sin(nCamAngle) = Z/nCamDist
Thus:
	Z = sin(nCamTilt) * nCamDist
	
Which is all jolly good and wonderful. Unfortunately, if you attempt to use these
values straight up you'll find that it doesn't quite work. The reson for this
is that we need to adjust the X and Y values to accomodate the distance used
in the third dimension. Luckily enough, all we need is a ratio to determine how
much of the total distance was used, and even more luckily, the ration is the cosine
of nCamTilt.

So, all said and done, the position of the camera relative to our hero is:
	Y = sin(nCamAngle) * nCamDist * cos(nCamTilt)
	X = cos(nCamAngle) * nCamDist * cos(nCamTilt)
	Z = sin(nCamTilt) * nCamDist


Now, here's the code:

Code:
#include <acknex.h>;
#include <default.c>;
ENTITY* entPlayer;
var nCamAngle = 0;
var nCamDist = 300;
var nCamTilt = 20;
var nCamX = 0;
var nCamY = 0;

TEXT* txtCamAngle = {
	pos_x = 10;
	pos_y = 10;
	layer = 0;
	font = "Arial#15";
	string(szCameraAngle, szCamX, szCamY);
	flags = SHOW;
}

STRING* szCameraAngle = "0";
STRING* szCamX = "0";
STRING* szCamY = "0";
STRING* szRunningNum = "";

function HandleCameraInput()
{
	// Handle Camera Input /////////////////////////
	nCamTilt += mouse_force.y;
	nCamAngle += mouse_force.x;
	nCamDist += mickey.z*-.1;
	
	// Create some boundaries for our variables to hopefully avoid some issues

	if(nCamAngle >= 360)
	{
		nCamAngle = 0 + (nCamAngle - 360);
	}
	if(nCamAngle <= 0)
	{
		nCamAngle = 360 + nCamAngle;
	}
	if(nCamTilt < 10)
	{
		nCamTilt = 10;
	}
	if(nCamTilt > 90)
	{
		nCamTilt = 90;
	}
	if(nCamDist < 10)
	{
		nCamDist = 10;
	}
	
	vec_set(mouse_pos, vector(50,50,50));
	mouse_mode = 0;
}

action actPlayer()
{
	wait(1);
	set(my,POLYGON);
 
	phent_settype(my,PH_RIGID,PH_SPHERE);
	phent_setmass(my,1,PH_SPHERE);
	phent_setfriction(my,90);
	phent_setelasticity(my,79,100);
	phent_setdamping(my,30,5);
	ph_setgravity(vector(0,0,-500));
	while(1)
	{	
		phent_addcentralforce ( me, vector((key_d - key_a)*500*time_step,(key_w - key_s)*500*time_step,0) );
		wait(1);
	}
}

function main()
{
	video_window(vector(60,100,0),vector(640,480,0),48,NULL);
	video_mode = 8;
	level_load("terrain.hmp");
	camera->arc = 45;
	wait(2);
	
	entPlayer = ent_create("ball.mdl", vector(0,0,20), actPlayer);
	
	while(1)
	{
		// Handle Camera ///////////////////////////////
		nCamX = cosv(nCamAngle) * nCamDist * cosv(nCamTilt);
		nCamY = sinv(nCamAngle) * nCamDist * cosv(nCamTilt);
		
		// Since these values are relative we need to adjust them to world coordinates
		camera.x = entPlayer.x - nCamX;
		camera.y = entPlayer.y + nCamY;
		
		camera.z = entPlayer.z + (sinv(nCamTilt) * nCamDist);
		// We need the reciprocal angle to look at the object, so subtract from 360 to find it
		camera.pan = 360 - nCamAngle;
		// The tilt should be negative since the camera is above the object
		camera.tilt = -1 * nCamTilt;
		
		// Just some debugging text
		str_for_num(szCameraAngle, nCamAngle);
		str_for_num(szCamX, nCamX);
		str_for_num(szCamY, nCamY);
		
		HandleCameraInput();
		wait(1);
	}
}


(Edit: Commenting some of the code)

Last edited by Soup; 06/12/09 20:03.
Re: Mobile Object Orbital Camera [Re: Soup] #271126
06/11/09 12:11
06/11/09 12:11
Joined: Apr 2009
Posts: 298
Southern Oceans
KiwiBoy Offline
Member
KiwiBoy  Offline
Member

Joined: Apr 2009
Posts: 298
Southern Oceans
Thanks Soup, sounds just the thing to look at smile


Use the 'manual' Luke, the manual is your friend. 'Self reminder' smile

My WebPage

Moderated by  HeelX, Lukas, rayp, Rei_Ayanami, Superku, Tobias, TWO, VeT 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1