OP
User
Joined: Oct 2008
Posts: 513
|
Tried your new function, also tried adding the "&" and it didn't solve it. I was reading the manuall for that "&" behaviour and added some "*" to your function for ent_Ang, but that didn't solve it either. modified alignToVec:
function alignToVec(ANGLE* entAng, VECTOR* vec, VECTOR* axis, var factor) {
VECTOR locVec, locAxis;
vec_set(locVec, vec);
vec_set(locAxis, axis);
vec_rotate(locAxis, *entAng);
vec_normalize(locAxis, 1);
vec_normalize(locVec, 1);
VECTOR rotAxis;
vec_cross(rotAxis, locVec, locAxis);
//USE ONLY ONE OF THE FOLLOWING TWO LINES!!!!!!!
var angle = -acos((float)vec_dot(locAxis, locVec)) * factor; // instant rotation
//var angle = -acos((float)vec_dot(locAxis, locVec)) * factor * vec_length(rotAxis); //smooth rotation
ANGLE rotAngle;
ang_for_axis(rotAngle, rotAxis, angle);
ang_add(*entAng, rotAngle);
}
I have also been thinking around that direction... what difference is there between accesing an entitie's angle or a declared ANGLE one? I tried taking V_Ang out of look_at() to turn it into a global variable, but that didn't fix it either. Also tried adding in some wait instructions into my movement code so it will wait between each step (just in case mutiple modifications of our pan were causeing this), but that didn't fix it either. movement code:
void vehicle_movement(ENTITY* Vehicle, ENTITY* Planet)
{
while(1)
{
//set pathfinding objective
if(mouse_left)
{
if(mouse_ent==Planet)
{
vec_set(vehicle_objective,mouse_3D);
}
}
if(key_w||key_s||key_a||key_d)//MANUAL DRIVING OVERRIDE
{
vec_fill(vehicle_objective,0);//cancel pathfinding
ang_rotate(Vehicle.pan,vector(10*(key_a-key_d)*time_step,0,0));//manual steering
c_move(Vehicle,vector(2*(key_w-key_s)*time_step,0,0),nullvector,IGNORE_MODELS | IGNORE_PASSABLE | IGNORE_SPRITES);//manual movement
align_to_surface(Planet, Vehicle);
}
else if(vec_dist(Vehicle.x,vehicle_objective)>5)//AUTO PATHFINDING
{
if(vehicle_objective.x!=0&&vehicle_objective.y!=0&&vehicle_objective.z!=0)//if there is an objective
{
wait(1);//<-----
look_at(Vehicle,vehicle_objective,Planet);//automatic steering
wait(1);//<-----
c_move(Vehicle,vector(2*time_step,0,0),nullvector,IGNORE_MODELS | IGNORE_PASSABLE | IGNORE_SPRITES);//automatic movement
wait(1);//<-----
align_to_surface(Planet, Vehicle);
wait(1);//<-----
}
}
wait(1);
}
}
Just as a test I modified the last instruction in the align_to_surface function to not take into account surface normals.
void align_to_surface(ENTITY* Planet, ENTITY* Vehicle)
{
VECTOR start_trace;
VECTOR Temp_Vec;
var safeguard;
//get the surface position
vec_set(start_trace,Vehicle.x);
vec_sub(start_trace,Planet.x);
vec_normalize(start_trace,vec_length(start_trace)*2);
vec_add(start_trace,Planet.x);
me=Vehicle;
safeguard=c_trace(start_trace, Planet.x,IGNORE_ME|IGNORE_PASSABLE|IGNORE_SPRITES);
if(safeguard<=0)
{
return;
}
//place vehicle on surface
//(taking into account vehicle min_z)
vec_set(Temp_Vec,hit.x);
vec_sub(Temp_Vec,Planet.x);
vec_normalize(Temp_Vec,vec_length(Temp_Vec.x)-Vehicle.min_z);
vec_add(Temp_Vec,Planet.x);
vec_set(Vehicle.x,Temp_Vec);
//rotate towards surface normal
vec_sub(Temp_Vec,Planet.x);
//USE ONLY ONE OF THE TWO INSTRUCTIONS BELOW
//alignToVec(Vehicle.pan, hit.nx, vector(0, 0, 1), 1); //align to surface normal
alignToVec(Vehicle.pan, Temp_Vec, vector(0, 0, 1), 1); //align to perfect sphere
}
That fixed it, but it was a really nice feature i would like to keep. Withough it, it looks like my vehicle is just gliding/hovering on ice. And it dosn't explain why alignToVec dosn't work in the other function anyway... Still trying to think why it would modify entity.pan but not a declared ANGLE variable, what could the difference be? Also thinking of other workarounds, but none have worked so far... EDIT: I tried to directly use the vehicle angles in the calculations instead of V_Ang to see if alignToVec() just dosn't like anything that is not entity related... Changes had no effect, same problem in valleys.
void look_at(ENTITY* Vehicle, VECTOR* Destination, ENTITY* Planet)
{
VECTOR V_Nrml;
ANGLE V_Ang;
VECTOR V_Path;
ANGLE Path_Ang;
//this time I store angles (for later) and directly modify the vehicle's pan in the calculations
vec_set(V_Ang, Vehicle.pan);
//get our vehicle's normal from the planet core
vec_diff(V_Nrml, Vehicle.x, Planet.x);
// orient angle by planet normal (perfect sphere)
alignToVec(&Vehicle.pan, &V_Nrml, vector(0, 0, 1), 1);
// get destination position relative to the vehicle
vec_diff(V_Path, Destination, Vehicle.x);
//rotate relative destination by absolute orientation
vec_rotateback(V_Path, Vehicle.pan);
// convert to an angle
vec_to_angle(Path_Ang, V_Path);
//DEBUG path
vec_set(testv1,V_Path);
vec_normalize(testv1,1000);
vec_add(testv1,Planet.x);
draw_line3d(testv1,NULL,100);
draw_line3d(testv1,COLOR_GREEN,100);
draw_line3d(Planet.x,COLOR_GREEN,100);
//avoid gimbal lock
if(Path_Ang.tilt>89||Path_Ang.tilt<-89)
{
vec_set(Vehicle.pan,V_Ang);//restore saved angle
return;//don't rotate
}
// rotate angle by Path_Ang
ang_rotate(Vehicle.pan, vector(Path_Ang.pan, 0, 0));
}
Last edited by Carlos3DGS; 01/19/12 17:12.
|