Hard Light Productions Forums
Modding, Mission Design, and Coding => FS2 Open Coding - The Source Code Project (SCP) => Topic started by: WMCoolmon on December 14, 2005, 03:15:19 am
-
This is partly for odd thoughts, mostly in hope that someone better educated in 3D math can maybe give a helpful suggestion.
I think that the function that needs to be changed is the function that generates the turret's rotation matrix. (This is multiplied against the orientation matrix to find the find the final rotation, along with other messy calculations.)
The relevant function, model_make_turrent_matrix. Note that sm-> represents the barrel, and sm_turret-> represents the gun base.
Both base and gun barrel have three rotation compoents, pitch, bank, and heading.
//Clear all turret angles
model_clear_instance(model_num);
//Find turret's 'f' vector (?) component of rotation matrix in world coordinates
model_find_world_dir(&fvec, &turret->turret_norm, model_num, turret->turret_gun_sobj, &vmd_identity_matrix, NULL );
//Set base heading to -PI/2 radians (or -90 degrees)
sm_parent->angs.h = -PI/2.0f;
//Set gun pitch to -Pi/2 radians (or -90 degrees)
sm->angs.p = -PI/2.0f;
//Find the 'r' vector (?) component of the rotation matrix using these two angle changes
model_find_world_dir(&rvec, &turret->turret_norm, model_num, turret->turret_gun_sobj, &vmd_identity_matrix, NULL );
//Set base heading to 0 radians (or 0 degrees)
sm_parent->angs.h = 0.0f;
//Set base heading to -Pi/2 radians (or -90 degrees)
sm->angs.p = -PI/2.0f;
//Get 'u' vector (?) compoent of rotation matrix using angle changes.
model_find_world_dir(&uvec, &turret->turret_norm, model_num, turret->turret_gun_sobj, &vmd_identity_matrix, NULL );
//Normalize all three vector components
vm_vec_normalize(&fvec);
vm_vec_normalize(&rvec);
vm_vec_normalize(&uvec);
//Copy normalized vectors to permanent location
turret->turret_matrix.vec.fvec = fvec;
turret->turret_matrix.vec.rvec = rvec;
turret->turret_matrix.vec.uvec = uvec;
My guess (after writing that up) is that for side turrets, I need to set te gun barrel to initially have a heading of -90 degrees (left side facing out) or 90 degrees (right side facing out) and use the difference for the 'r' and 'u' vectors. And for the base, start it out with the same.
As in, the default position would be the gun barrel sticking out to the side, and able to twist fore and aft. (But in order to twist up or down at all, the base would have to turn). Although the model I'm working with now seems to have it as the reverse; the barrel can twist up and down without the base moving, but not fore and aft.
Edit: Can't test this now, as fs2_open has started crashing every time I launch the test mission (seems to be an unrelated bug). However the headings have been changed, although I don't feel too confident of it being the solution. (Not to mention I also have to figure out which turrets are side turrets to apply this).
Edit 2: Here's my p/b/h chart. I keep getting them mixed up, so I'm not 100% sure of this, either. :rolleyes:
(http://fs2source.warpcore.org/temp/diagram.png)
-
model_make_turrent_matrix
Deliberate or accidental? :p
I wonder, could the bank be used to create side-mounted multi-part turrets? Or indeed, placed at any angle on the hull?
-
that function only deals with the inital state of the turret, model_rotate_gun (wich is just below it) is were most of your work is likely to be.
(and yes people, that is how the function is spelled, this is the ONLY instance in the code were it was spelled like this (there are four references, one for the function definition, one for the declairation and two for the coment above each))
for the inital matrix you just need to remember what the three vectors of the matrix are fvec(forward vector, the vector along wich the guns will shoot), uvec(up vector, should generaly be pointing up (0,1,0) if the fvec is pointing out to the side), and the rvec(right vector, should be pointing to the back on turrets on the tight side of the ship, forward on turrets on the left side of the ship). if you want to assume that the turret will always be pointing directly to the side of the ship it will make things infinitely easier, but haveing code for any orientation is perfictly posable.
pitch is rotation around the x axis (around rvec), heading is rotation around the y axis (around uvec), and bank is rotation around the z axis (arounf fvec).
I think you are going to have to add stuff to the submodel properties allowing for a custum made orientation matix, and flagging the turret as useing new rotation code.
-
any chance of having turret rotation limits, so you could make a turret that can only rotate about 90 defrees in either direction. you could use that to put turrets on the side that rotate the same way normal turrets do, but wouldnt turn so the barrel points inward. sorta like the side turrets you see on early ww1 tanks.
(http://www.worldwar1.com/arms/tank002.jpg)
i always thought of those kind of turrets as astheitcally pleasing and would only require rotation limits. simply implementing turret angle limitations now would greatly improve the versitility of turrets. im not saying dont do side turrets, im saying do this too :D and if you got time, gatling turrets please :D
-
You and your gatling obsession :rolleyes:
While I think proper 2-dimensional fov arguments are worth implimenting, I feel that I need to point out something. There's a world of difference between changing the (retarded) hard-coded way that multiparts are handled in order to generalize them to side turrets, etc. and allowing truly arbitrary rotation. They are almost not even related. And apparently, :v: can't spell "turret" either. :p
-
Searching for 'turrent'...
C:\projects\fs2_open\code\model\model.h(1341):// Tries to move joints so that the turrent points to the point dst.
C:\projects\fs2_open\code\model\modelread.cpp(3883):void model_make_turrent_matrix(int model_num, model_subsystem * turret )
C:\projects\fs2_open\code\model\modelread.cpp(3926):// Tries to move joints so that the turrent points to the point dst.
C:\projects\fs2_open\code\model\modelread.cpp(3947): model_make_turrent_matrix(model_num, turret );
4 occurrence(s) have been found.
edit:
Commiter : fs2source
CVSROOT : /home/fs2source/cvsroot
Module : fs2_open
Commit time: 2005-12-15 04:31:15 UTC
Log message:
[V] can't spell 'turret'
Modified files:
code/model/modelread.cpp code/model/model.h
-
I so almost put in a comment about being suprised no one had done a find and replace on that yet, but decided not to because I was afraid someone would actually go and do it. Guess I didn't even need to say it :p
-
:V:'s spelling is law :eek:
Heathen!!!
Edit: Oh, and before I de-rail my own thread :rolleyes: while it'd be nice to have turrets rotatable on any orientation, that's probably a little beyond me at this point...I thought I could use turret normals to determine turret orientation and generate a rotation matrix on that, but some of the 'straight' turrets on the Galactica have bizarre normals.
-
:lol: I always thought it was because people got confused between turret and torrent that caused that spelling mistake. It must be some kind of strange universal mental block...
It'd be great to see side turrets working, I must admit :)
-
if a rotation axis vector is given for the two models it should be posable to set up a matrix like that easily
-
Hmm...OK, I took another look at this. I'm a bit confused though - where do the values for the turret normal come from?
Erg...at the moment all that I'm really sure of is that I need to change this section of code:
angles desired_angles;
desired_angles.p = (float)acos(of_dst.xyz.z);
desired_angles.h = PI - atan2_safe(of_dst.xyz.x, of_dst.xyz.y);
desired_angles.b = 0.0f;
// mprintf(( "Z = %.1f, atan= %.1f\n", of_dst.xyz.z, desired_angles.p ));
//------------
// Gradually turn the turret towards the desired angles
float step_size = turret->turret_turning_rate * flFrametime;
vm_interp_angle(&base_angles->h,desired_angles.h,step_size);
vm_interp_angle(&gun_angles->p,desired_angles.p,step_size);
Possibly using vm_extract_angles_vector on of_dst instead of the manual calcs...
At this point I think I'm pretty lost :sigh:
As near as I can tell, the "normal" field on turrets either means something, or means something different than orientation. vm_extract_angles works, but does not fix the side turret on the BSG. Presumeably I'm missing something, and need to translate the "b" component into the "p" and "h" components of the side turrets somehow.
-
hmmm... the "desired_angles.b = 0.0f;" says it to not change rotation around one of the axes, I'd say - doesn't it? :confused: Then that would be one point that'd certainly need changing. (maybe creat a copy of the function for side turrets that says something like 90 degrees there? could eventually work...)
Btw, what does "of_dst.xyz.z" do? Give you the specified component of the vector?
(sorry, not much time now for calculating; maybe sometime (read: days) later :( )
-
i think hes got a point.
i figure on a side turret youd just need to swap
desired_angles.p = (float)acos(of_dst.xyz.z);
desired_angles.h = PI - atan2_safe(of_dst.xyz.x, of_dst.xyz.y);
desired_angles.b = 0.0f;
with
desired_angles.p = PI - atan2_safe(of_dst.xyz.x, of_dst.xyz.y);
desired_angles.h = (float)acos(of_dst.xyz.z);
desired_angles.b = 0.0f;
essentially swapping pitch for heading. likewise if you wanted a rotating turret on front back you could probibly use
desired_angles.p = (float)acos(of_dst.xyz.z);
desired_angles.h = 0.0f;
desired_angles.b = PI - atan2_safe(of_dst.xyz.x, of_dst.xyz.y);
only problem is i bet it would alter all turrets youd have to do an if to check where the turret is (based probibly off a subobject property value) and then run the proper arangement for that type. but im not a coder and im just talking out of my ass.
-
Yeah, it would alter all turrets. At first I thought I could use the turret normals to check if a turret is on the side or not, but apparently not...
-
perhaps ad a subsystem property for side turrets like $turret pos: with values like side and front. of course top would be default.
also it looks like if you wanted to have a turret rotation limit feature, whis would be where to put it. just a mater of changing the math abit.
-
Yeah, it would alter all turrets. At first I thought I could use the turret normals to check if a turret is on the side or not, but apparently not...
Why not? Shouldn't you be able to just compare the turret base normal with the normal of the ship hull?
-
this looks like a job for!!!
...the subobjects properties feild.
just add a '+rotation_axis:' thing to there. y is default, x would be side, z would be a weird thing that probly would never get used.
-
this looks like a job for!!!
...the subobjects properties feild.
just add a '+rotation_axis:' thing to there. y is default, x would be side, z would be a weird thing that probly would never get used.
no forwar facing multi-part turrets?
(mulit part turrents! :D)
-
well I guess I could see them being used for some sort of odd offencive thing, but realy I doubt it would get much use, though you might as well through it in there if your going to do the rest.
-
this looks like a job for!!!
...the subobjects properties feild.
just add a '+rotation_axis:' thing to there. y is default, x would be side, z would be a weird thing that probly would never get used.
I don't recall seeing that one in the WiKi.
-
that's because he has yet to add it in there, I was just sugesting a course of action.
-
That's what I was thinking. This isn't something that you'd want in the tables, as it's more pertinant to the POF itself. I'd actually say you could use the existing rotation axis value, though most models butcher how that's actually done since turrets ignore it. At any rate, I can see two different "default" configurations for side turrets, so either that would have to be cleared up explicitly or you'd need both a major (base) and minor (barrels) rotation axis to cover all possible combinations.
And a z-based turret would probably look a little strange on the front of a ship, but it'd make an excellent configuration for a bomber turret facing backwards.
-
it would make a good slasher :D
id like to see guns like the ones in the turret of the tank i posted. also sence people are looking at this i think it would be a good time to bring up.....
GATLING TURRETS!!!!!!!
-
Would it be possible to make turrets that dont have a defined direction their barrels should face, ex- the main body of the turret has no front, and the barrles can rotate through a full 180 arc instead of just 90 degrees.
That would make front turrets actualy semi-sensical.
-
That makes sense...When you think about it, the turret base rotates only around one axis, and hte turret barrels areound another (that is, IF the side turrets are positioned in a fixed 90° angle)
A good default position would have the barrels of hte side turrets (and hte base) facing towards the front of the ship. then you'd use the base z axis (or was it Y...the one that points towarsd hte top anyway) to determine how far the base has to rotate to track the target, and move the barrels.
Of course, the procedure would be different if the barels can move 180°
-
id like to see single object turrets that can pivit on both the x and y axes. they would look cool and you could use alot of them withought using too many subobjects.
-
i think hes got a point.
i figure on a side turret youd just need to swap
desired_angles.p = (float)acos(of_dst.xyz.z);
desired_angles.h = PI - atan2_safe(of_dst.xyz.x, of_dst.xyz.y);
desired_angles.b = 0.0f;
with
desired_angles.p = PI - atan2_safe(of_dst.xyz.x, of_dst.xyz.y);
desired_angles.h = (float)acos(of_dst.xyz.z);
desired_angles.b = 0.0f;
essentially swapping pitch for heading.
Thanks :) . But that's not completely it. These fields set the angles the turret will try to face (or so I think). You'd more need to change
" vm_interp_angle(&base_angles->h,desired_angles.h,step_size);
vm_interp_angle(&gun_angles->p,desired_angles.p,step_size); "
to something like
" vm_interp_angle(&base_angles->p,desired_angles.p,step_size);
vm_interp_angle(&gun_angles->h,desired_angles.h,step_size); "
for the side turrets. These seem (to me at least) to do the actual rotation. Note how they refer to "base" and "gun" (i.e. barrel) . :)
This is still not very well thought through, but it is something that could be tested (if one of the coders decides to do so). :)
@Nuke: Nose-mounted slashers? Hmm, nice idea - can't wait to see some... :drevil: ;)
-
Are you saying, swap both? Or just do your change and not Nuke's?
-
i think this line here
(float)acos(of_dst.xyz.z)
represents a 90 degree motion while this puppy
PI - atan2_safe(of_dst.xyz.x, of_dst.xyz.y)
is for the full 360
both are just simply using the normal vector to calculate the angular rotation of the various parts of the turret. or at least i think, you might try swithcing the math, do a build, and just watch what the turrets do. it might give you a bette idea of how everything works.
*edit*
i was just contemplating the vector math abit more. if i was right this might be the only thing youd need to change. the other parts of the code are for positionng the normal somewhere within the turret's fof (at least thats what im thinking). if you make this code smarter, that it can sence the kind of turret being used, you could give it different vector maths for different turret configurations.
-
@WMC: I'd say only my change... explanation below.
@Nuke: Surely I could be wrong, but as I am viewing it, the "desired_angles.X = XXX" calculates from the vector to the target what angles the turret should try to face - they don't do something to the turret itself. Then, the turrets rotation speed is read ("float step_size = turret->turret_turning_rate * flFrametime;") and used in the following commands which then actually move the turret parts around to point to the previously calculated target angles.
I see, I didn't realize that myself in the first post I made in this thread... :o Still, if the lines you're proposing were changed, that might quite possibly result in the turret trying to face 90 degree AWAY from its target (or something even more crazy :wtf: ), still only rotating around the old axes...
My assumptions might be wrong, but they seem rather plausible to me. As I said, I didn't realize it myself at the start, but now I think that first statement of mine was way too rushed... :/ Hope the new one's better though... :nervous:
[edit1] Oh, and the "(float)acos(of_dst.xyz.z)"-line gives me a major headache - shouldn't an acos take TWO lengths as argument??? :confused:
-
my assuption is based entirely on the vector math and my limited understanding of trig functions, not on the actual code. also im only looking at the code snippet that was shown by wmc, not the whole of the turret code. so i assume you have more insight into those aspects. its not really a matter of whose right and whos wrong, just youre looking at one perspective while im looking at another.
im assuming that of_dst.xyz.z is the turret normal's forward distance from the turret center. the vector math sugests to be that it is caculating the rotational angle off of that distance. this indicates to me that single part turrets behave the same exact way that multipart turrets do, by rotating the normal around the fire point. the difference with multiparts is only in that they move and theese lines return the angles that they should try to move to i may of course be entirely wrong there. now that piece of vector math i understand reasonably well. the PI - atan2_safe(of_dst.xyz.x, of_dst.xyz.y) calculation i understand less. but i think it calculates the heading angle of the turret. im trying to figure out how. so im looking at some trig on wikipedia to try to understand what it does a little better. if i figure it out il draw up some diagrams of how the turret angles are calculated so that we all can undersstand it better.
[edit1] Oh, and the "(float)acos(of_dst.xyz.z)"-line gives me a major headache - shouldn't an acos take TWO lengths as argument??? :confused:
acos is really a 1 dimentinal thing, but its suffietent to calculate the angle (in degrees or radians, im not sure) of pitch for the gun objec. this tells to code that does the moving where to go (at least for the gun's pitch). it works so long as the normal length is capped at 1 somewhere else in the code. im assuming all turret, gun, dock normals are capped at 1 on model load. there should be something like (nl /1)*nl in there (nl = normal length) in the loading cod to cap normals. seeing as normal conformity is rather important in a 3d game to keep them consistant. so if the normals been capped, and it pitches forward so its 45 degrees from its center, then acos on the distance of the normal 's z cood from the turret center should equil 45. so if the capped normal is 45 degrees off center, then the distance of the normal's z axis from its center would equil 0.70710678118654752440084436210485. and the acos of that number returns 45, i think the same is true no matter if you use radians or degrees.