After working on a pet project where I used a lot of vector math, I took a second look at the the space code in SWR and realized the calculations are ranging from imprecise to outright wrong. Example:
Code:
if( abs( target->vx - ship->vx ) <= 1000
&& abs( target->vy - ship->vy ) <= 1000
&& abs( target->vz - ship->vz ) <= 1000 )
{
// Some code here ...
}
SWR is full of ifchecks like this, and the intent is clearly to find out if the distance between two ships are 1000 or less. However, this is not the correct way to do it. The result will actually be more than 1000. For better precision we want the following. First I'm replacing the vx, vy and vz variables with a structure like this:
Code:
typedef struct vector3 Vector3;
struct vector3
{
float x, y, z;
};
For reasons that will soon become apparent I also use this structure for hx/y/z, and for the positions of planets and starsystems as well. So after putting 'Vector3 *pos;' inside ship_data we can access the values like this: ship->pos->x (remember to allocate memory before accessing!). Now, next step is to make a function that (correctly) returns the distance between two vectors:
Code:
float vector_distance( Vector3 *a, Vector3 *b )
{
return sqrt((a->x - b->x) * (a->x - b->x)
+(a->y - b->y) * (a->y - b->y)
+(a->z - b->z) * (a->z - b->z));
}
So we'll rewrite the above ifcheck as follows:
Code:
if( vector_distance( ship->pos, target->pos ) <= 1000 )
{
// Some code here...
}
Not only is it correct, it looks better and is easier to read as well! Now, the point of using the Vector3 structure is that now we can use the vector_distance() function to get the distance between anything in space. Examples:
Code:
// distance between a planet and a ship
dist = vector_distance(planet->pos, ship->pos);
// though in SWRFuss 1.2 it'll be something like this (assuming p1 is a Vector3)
dist = vector_distance(ship->starsystem->p1, ship->pos);
// distance between two starsystems
dist = vector_distance(starsystem1->pos, starsystem2->pos);
// or even the distance between two ship in different systems:
dist = vector_distance(ship->starsystem->pos, target->starsystem->pos);
// between a missile and a ship:
dist = vector_distance(ship->pos, missile->pos);
// etc, etc...
Unfortunately distances aren't the only thing handled either clumsily or incorrectly. Which brings me to the point of this post. Now, since I've already worked with vectors for a little while, I could go through the code and make it behave as expected. Normally it'd make sense to write a snippet or something, but in this case the sheer number of little changes would make a snippet unwieldy. Therefore: If the community is interested in an SWR codebase (and SWFotE, I suppose) that handles vector calculations correctly, I can work on a stock SWRFuss1.2 and supply a diff file of the changes I've done (and properly commented of course).
So, are you interested in this? And Samson, would you put it into the official release? I'm not sure I'd do this if it didn't get put into good use.
.........................
SWR2 Refactor - The improved SWR 2.0 codebase.