Hard Light Productions Forums

Modding, Mission Design, and Coding => FS2 Open Coding - The Source Code Project (SCP) => Topic started by: WMCoolmon on January 04, 2008, 11:21:43 pm

Title: Camera code update
Post by: WMCoolmon on January 04, 2008, 11:21:43 pm
As part of an upgrade to the camera code I was planning on using these two functions to give me access to the three angles, which I could then interpolate separately. Unfortunately it seems that the process used by the two functions is inaccurate or flawed; the camera jumps at certain spots when the ship is rotated. Replacing these two calls with a matrix variable that is stored and retrieved seems to fix the problem, so it looks like it's something to do with the calls to these two functions rather than anything to do with the camera code itself.

The two key functions which handle angle<->matrix conversion are vm_extract_angles_matrix and vm_angles_2_matrix.

Does anyone know of a way to get these two functions to work as reliably as the stored matrix?

Code: [Select]
//extract angles from a matrix
angles *vm_extract_angles_matrix(angles *a,matrix *m)
{
float sinh,cosh,cosp;

if (m->vec.fvec.xyz.x==0.0f && m->vec.fvec.xyz.z==0.0f) //zero head
a->h = 0.0f;
else
// a->h = (float)atan2(m->vec.fvec.xyz.z,m->vec.fvec.xyz.x);
a->h = atan2_safe(m->vec.fvec.xyz.x,m->vec.fvec.xyz.z);

sinh = sinf(a->h); cosh = cosf(a->h);

if (fl_abs(sinh) > fl_abs(cosh)) //sine is larger, so use it
cosp = m->vec.fvec.xyz.x*sinh;
else //cosine is larger, so use it
cosp = m->vec.fvec.xyz.z*cosh;

if (cosp==0.0f && m->vec.fvec.xyz.y==0.0f)
a->p = 0.0f;
else
// a->p = (float)atan2(cosp,-m->vec.fvec.xyz.y);
a->p = atan2_safe(-m->vec.fvec.xyz.y, cosp);


if (cosp == 0.0f) //the cosine of pitch is zero.  we're pitched straight up. say no bank

a->b = 0.0f;

else {
float sinb,cosb;

sinb = m->vec.rvec.xyz.y/cosp;
cosb = m->vec.uvec.xyz.y/cosp;

if (sinb==0.0f && cosb==0.0f)
a->b = 0.0f;
else
// a->b = (float)atan2(cosb,sinb);
a->b = atan2_safe(sinb,cosb);
}


return a;
}
matrix *sincos_2_matrix(matrix *m,float sinp,float cosp,float sinb,float cosb,float sinh,float cosh)
{
float sbsh,cbch,cbsh,sbch;


sbsh = sinb*sinh;
cbch = cosb*cosh;
cbsh = cosb*sinh;
sbch = sinb*cosh;

m->vec.rvec.xyz.x = cbch + sinp*sbsh; //m1
m->vec.uvec.xyz.z = sbsh + sinp*cbch; //m8

m->vec.uvec.xyz.x = sinp*cbsh - sbch; //m2
m->vec.rvec.xyz.z = sinp*sbch - cbsh; //m7

m->vec.fvec.xyz.x = sinh*cosp; //m3
m->vec.rvec.xyz.y = sinb*cosp; //m4
m->vec.uvec.xyz.y = cosb*cosp; //m5
m->vec.fvec.xyz.z = cosh*cosp; //m9

m->vec.fvec.xyz.y = -sinp; //m6


return m;

}

//computes a matrix from a set of three angles.  returns ptr to matrix
matrix *vm_angles_2_matrix(matrix *m,angles *a)
{
matrix * t;
float sinp,cosp,sinb,cosb,sinh,cosh;

sinp = sinf(a->p); cosp = cosf(a->p);
sinb = sinf(a->b); cosb = cosf(a->b);
sinh = sinf(a->h); cosh = cosf(a->h);

t = sincos_2_matrix(m,sinp,cosp,sinb,cosb,sinh,cosh);

return t;
}

Sample build, just load a mission and try moving around:
http://fs2source.warpcore.org/exes/wmc/fs2_open_cam_d.zip
Title: Re: Camera code update
Post by: Talon 1024 on January 05, 2008, 01:58:37 pm
So is this a kind of thing that will allow you to do Unreal Tournament 2004/Starlancer/Age of Mythology style cutscenes in the Freespace engine? I don't really get what you're talking about...
Title: Re: Camera code update
Post by: Zacam on January 05, 2008, 02:45:50 pm
I think he's talking about perspective jumping when the camera is panned at certain angles. You can not smoothly rotate the camera a full 360 around your ship.
Title: Re: Camera code update
Post by: haloboy100 on January 05, 2008, 03:33:18 pm
I can....
your talking about when you press the numpad delete button right?
Title: Re: Camera code update
Post by: WMCoolmon on January 06, 2008, 02:28:53 am
Just fly around for a bit like you would normally. It should be pretty obvious. The HUD jumps with the view as well.

That being said, I know that the bug exists, I just want some way of fixing it without having to redo the method that I'm currently using. :p I could switch to using a normal vector for direction and a measure in degrees for a ship's role, but that would require interpolating four variables instead of three to smoothly change a ship's orientation.

Interpolating matrices is a solution, but it's one that I'm not familiar with (I'd have to start from scratch and add the math function as well) and I would also lose the individual control over the three rotational axes that I have now. There's a Freespace 2 matrix interpolate function, but it's very specialized and not compatible at all with the method I'm using right now.

Once this is ironed out, the camera system should work flawlessly, with none of the problems as before, and it should also be possible to play around with the main camera modes and add movement based on them (eg transition from the chase view to a free camera by reading off the main camera position and starting the free camera from there)

Cameras also have FOV functionality that takes the same arguments as the rotation and position variables (value, time to complete, time to spend accelerating) so BSG style zooms should be possible.

I don't have any more features planned, save for a couple of scripting hooks, but if anyone wants some I could probably add them...provided they aren't too elaborate. I've thought that some predefined shake functions would be nice, but that's lower priority for me atm. Unless somebody else wants to come up with functions. :D

Anyway, mostly I was curious to know if anyone was familiar with these functions or not to provide an 'upgrade' solution to the problem.