I have done some more work on this problem.

I decided to use an orbit function. It is the opposite to the camera orbiting the avatar/object Instead I have a box orbiting the avatar/camera. However, the box should not follow the avatar/camera, or keep the same distance. But the distance between the object and the avatar/camera needs to be updated each time the camera/avatar moves so that when the box is moved it simply rotates about the new camer/avatar centroid coords.

The problem I have now is that it is not precise. When you move the camera/avatar around and then click/move the box it jumps a bit to a new cordinate.

What am I doing wrong?:


#include <acknex.h>
#include <default.c>

ENTITY* eBall;

var temp[3];

var rotspd=0.5; // cam movement speed

VECTOR vSpeed, vAngularSpeed, vForce, vMove;

float temp_x, temp_y, temp_z;
float temp_x2, temp_y2, temp_z2;
float tempx, tempy, tempz;

var cam_dist;

ANGLE cam_ang;

void main()
{
video_mode = 7;
shadow_stencil = 1;
// Load the level named "small.hmp"
level_load("small.hmp");
// Now create the "earth.mdl" model at x = 10, y = 20, z = 30 in our 3D world
eBall = ent_create("box.mdl",vector(0, 0, 0),NULL);
// Set an entity flag to cast a dynamic shadow
set(eBall,SHADOW);
// Use one of the default materials for giving it a shiny look
eBall.material = mat_metal;

//phent_settype(eBall,PH_RIGID,PH_SPHERE);
//phent_setmass(eBall,1,PH_SPHERE);
//phent_setfriction(eBall,90);
//phent_setelasticity(eBall,75,100);
//phent_setdamping(eBall,30,5);

// A ball game would be no fun without gravity.
//ph_setgravity(vector(0,0,-500));

while (1)
{


if(key_r)
{
if(mouse_left)
{

cam_ang.pan += rotspd*mouse_force.x;
cam_ang.tilt += rotspd*mouse_force.y;

eBall.x= (camera.x+cos(cam_ang.pan)*(cam_dist*cos(cam_ang.tilt)));
eBall.y= -1*(camera.y+sin(cam_ang.pan)*(cam_dist*cos(cam_ang.tilt)));
eBall.z= (camera.z+sin(cam_ang.tilt)*cam_dist);

vec_set(temp,eBall.x);
vec_sub(temp,camera.x);
vec_to_angle(eBall.pan,temp);

}

}

else {

temp_x2 = eBall.x - camera.x;
temp_y2 = eBall.y - camera.y;
temp_z2 = eBall.z - camera.z;
cam_dist = sqrt(temp_x2*temp_x2 + temp_y2*temp_y2 + temp_z2*temp_z2);

if(mouse_left)
{

vForce.x = -5*(mouse_force.x); // pan angle
vForce.y = 5*(mouse_force.y); // tilt angle
vForce.z = 0; // roll angle
vec_accelerate(vMove,vAngularSpeed,vForce,0.8);
vec_add(eBall.pan,vMove);

}
}

if(mouse_right)
{
vForce.x = -5*(key_force.x + mouse_force.x); // pan angle
vForce.y = 5*(key_force.y + mouse_force.y); // tilt angle
vForce.z = 0; // roll angle
vec_accelerate(vMove,vAngularSpeed,vForce,0.8);
vec_add(camera.pan,vMove);
}
vForce.x = 6 * (key_w - key_s); // forward
vForce.y = 6 * (key_a - key_d); // sideward
vForce.z = 6 * (key_home - key_end); // upward
vForce.z = 6 * (key_pgup - key_pgdn); // upward
vec_accelerate(vMove,vSpeed,vForce,0.5);
vec_rotate(vMove,camera.pan);
vec_add(camera.x,vMove);

wait(1);
}
}