API Question Reversing the "direction" of a velocity in VECTOR3

escapetomsfate

OBSP Developer
Addon Developer
Joined
Jun 21, 2008
Messages
282
Reaction score
0
Points
0
Location
GB
So, in the next version of OBSP, I will use actual force for damage instead of a simple "You've died" message. This means I need to move a vessel away from the explosion, perfectly outward.

My first thought for doing this is to use GetRelativePos to get the position in vector3, and then reverse it by multiplying x,y and z all by -1, and then multiplying that by the force of the explosion - this would give me the vector that I will call in AddForce() each timestep.

My other question is, how should I work out the "r" parameter in AddForce()? should that just be getrelativepos?

I hope my question made sense, and thanks for the help.
 
I don't have the docs to hand, but assuming that r is range, then it'll be the length of your vector. I think that there's a call to length(vec) or len(vec) or veclen or something like that. If not then just make r=sqrt(x*x + y*y + z*z) as that's all length is doing
 
So, in the next version of OBSP, I will use actual force for damage instead of a simple "You've died" message. This means I need to move a vessel away from the explosion, perfectly outward.

My first thought for doing this is to use GetRelativePos to get the position in vector3, and then reverse it by multiplying x,y and z all by -1, and then multiplying that by the force of the explosion - this would give me the vector that I will call in AddForce() each timestep.

My other question is, how should I work out the "r" parameter in AddForce()? should that just be getrelativepos?

I hope my question made sense, and thanks for the help.
I don't have the docs in front of me, but isn't the vector parameter to AddForce supposed to be a unit vector in the direction of the force, with the scalar parameter being the magnitude of the force?
 
I don't have the docs to hand, but assuming that r is range, then it'll be the length of your vector. I think that there's a call to length(vec) or len(vec) or veclen or something like that. If not then just make r=sqrt(x*x + y*y + z*z) as that's all length is doing

I don't mean the diagonal length of the vector - I mean the opposite of the direction - hard to explain. Here's a diagram to help explain it-

explosion-vessel.JPG

Basically, I want to move the vessel away from the explosion (as if it was a blast) using addforce.
 
I've just taken a look at the docs, and r is the force attack point (m). I assume that this is in the local vessel coordinate system. As such, you want it to be the position of the CoM of the vessel, otherwise you'll impart a spin on the vessel. Try putting different values in and see what happens.
 
Thanks for the help.

So what should I do for the first parameter, the actual force/direction vector? It's the one called "F".
 
Thanks for the help.

So what should I do for the first parameter, the actual force/direction vector? It's the one called "F".
That should be in the direction the force, and have a length being the magnitude of the force.
 
That should be in the direction the force, and have a length being the magnitude of the force.
Ok, and what would the direction be? Just x,y,z of Explosion->GetRelativePos(Vessel) all multiplied by -1? I tried that and made it fractional of the force (so that the length of the vector = force) and it moved off in 90 degrees to the explosion.
 
Ok, and what would the direction be? Just x,y,z of Explosion->GetRelativePos(Vessel) all multiplied by -1? I tried that and made it fractional of the force (so that the length of the vector = force) and it moved off in 90 degrees to the explosion.
You don't need to multiply each component by -1, you can just multiply the vector by -1.

As for the direction it's moving...I don't know, read the docs on that function, what do they say?
 
So, I just tried this:

Code:
VECTOR3 f,v;
oapiGetRelativePos(hVessel,GetHandle(),&v);
double ftot = v.x + v.y + v.z;
    f.x = sqrt(((Force*Force)/ftot)*v.x);
    f.y = sqrt(((Force*Force)/ftot)*v.y);
    f.z = sqrt(((Force*Force)/ftot)*v.z);
    f=f*-1;
That should make the length of f equal to Force, right?

Compiled and ran it. When it explodes, my ship just flies really far out into space, and then orbiter crashes. The force is 1000N, which is definitely not enough to do that!

Is it because x,y or z is negative, so it can't have a square root?
 
I'm coming in late to this thread so maybe I missed something (I sure don't understand the basis for the math you presented above). You have two vessels, one is an explosion and the other is the vessel affected by the explosion. You want to add a force to the effected vessel along the radial from the explosion. Right so far? Don't you just do this (I assume the code is to go in the explosion vessel):

Code:
const double explosionForce = 1000; // constant force - would really be better if the force dropped of with the square of the distance from the explosion but we'll keep it simple for now
VECTOR3 f,pos;
GetRelativePos(hVessel,&pos); // hVessel is a handle to the vessel affected by the explosion. This returns a vector from hVessel to the explosion.
pos = -pos/length(pos); // reverses the direction so the vector points from the explosion to hVessel, ie, the direction of the explosion force, and unitises the vector
f = explosionForce*pos;
oapiGetVesselInterface(hVessel)->AddForce(f,_V(0,0,0));
 
I'm coming in late to this thread so maybe I missed something (I sure don't understand the basis for the math you presented above). You have two vessels, one is an explosion and the other is the vessel affected by the explosion. You want to add a force to the effected vessel along the radial from the explosion. Right so far? Don't you just do this (I assume the code is to go in the explosion vessel):

Code:
const double explosionForce = 1000; // constant force - would really be better if the force dropped of with the square of the distance from the explosion but we'll keep it simple for now
VECTOR3 f,pos;
GetRelativePos(hVessel,&pos); // hVessel is a handle to the vessel affected by the explosion. This returns a vector from hVessel to the explosion.
pos = -pos/length(pos); // reverses the direction so the vector points from the explosion to hVessel, ie, the direction of the explosion force, and unitises the vector
f = explosionForce*pos;
oapiGetVesselInterface(hVessel)->AddForce(f,_V(0,0,0));

Thanks for the help.

The basis for that maths was simply to make the length of f equal to the magnitude of the force, like Hielor said it should be.

That code just moves the vessel at 90 degrees to the way it should be going, like my method. :(

---------- Post added at 07:42 PM ---------- Previous post was at 03:10 PM ----------

Turns out it was going the right way after all <_<
I was testing it by firing a missile at ISS. Bad thing to do, because obviuously ISS will move aswell, since it's iterating through all vessels.

I've gone with:
Code:
double explosionForce = Weapon.BlastForce; // constant force - would really be better if the force dropped of with the square of the distance from the explosion but we'll keep it simple for now
VECTOR3 f,pos;
GetRelativePos(hVessel,pos); // hVessel is a handle to the vessel affected by the explosion. This returns a vector from hVessel to the explosion.
pos = -pos/length(pos); // reverses the direction so the vector points from the explosion to hVessel, ie, the direction of the explosion force, and unitises the vector

f = pos*explosionForce;
And it seems to work OK. I actually managed to blast myself into escape velocity from the moon with an overpowered nuke :rofl:
 
So now try this:

Code:
VECTOR3 f,pos;
GetRelativePos(hVessel,pos); // hVessel is a handle to the vessel affected by the explosion. This returns a vector from hVessel to the explosion.
double explosionForce = Weapon.BlastForce*pow(length(pos),-2.0); // BlastForce is the force that would be received at 1m from the explosion
pos = -pos/length(pos); // reverses the direction so the vector points from the explosion to hVessel, ie, the direction of the explosion force, and unitises the vector
f = pos*explosionForce;
 
Does that gradually decrease force as distance increases, or just makes it only work at one meter away?

If Weapon.BlastRange is maximum range, how would I do that?

I persume this:
Code:
double explosionForce = Weapon.BlastForce*pow(length(pos),-Weapon.BlastRange*2);

EDIT: Also, I just tried detonating a bomb at brighton beach in the centre of the pads, with a vessel on each pad. Some vessels didn't move at all, some were knocked into sub orbit.
I don't understand why, because I'm iterating through all vessels on explosion.
 
Does that gradually decrease force as distance increases, or just makes it only work at one meter away?
It decreases with the square of the distance from the explosion. So if you get 1000N at 1m, you get 250N at 2m, 111N at 3m, etc.

If Weapon.BlastRange is maximum range, how would I do that?
Code:
double explosionForce;
if (length(pos) < Weapon.BlastRange)
  explosionForce  = Weapon.BlastForce*pow(length(pos),-Weapon.BlastRange*2);
else
  explosionForce = 0;

EDIT: Also, I just tried detonating a bomb at brighton beach in the centre of the pads, with a vessel on each pad. Some vessels didn't move at all, some were knocked into sub orbit.
I don't understand why, because I'm iterating through all vessels on explosion.
Were the vessels that didn't move large? If the force was less than the friction force, that is expected.
 
Ah, I see. So there is no point in the "BlastRange" parameter?

The vessel that didn't move was a ShuttleA, yeah, but if the blast could knock a ShuttlePB into a suborbital trajectory, it would at least movethe ShuttleA a few meters?
 
Ah, I see. So there is no point in the "BlastRange" parameter?
Maybe. I probably wouldn't bother calling AddForce on vessels where the force is less than say 10N. If you have a lot of vessels a long way from the explosions, that will save a few CPU cycles.

The vessel that didn't move was a ShuttleA, yeah, but if the blast could knock a ShuttlePB into a suborbital trajectory, it would at least movethe ShuttleA a few meters?
By my estimation you would need about 64kN to overcome the surface friction on a ShuttleA, compared to about 1kN for the ShuttlePB.
 
Maybe. I probably wouldn't bother calling AddForce on vessels where the force is less than say 10N. If you have a lot of vessels a long way from the explosions, that will save a few CPU cycles.


By my estimation you would need about 64kN to overcome the surface friction on a ShuttleA, compared to about 1kN for the ShuttlePB.
Thanks for the help. I'm now using this:

Code:
VECTOR3 f,pos;
GetRelativePos(hVessel,pos); // hVessel is a handle to the vessel affected by the explosion. This returns a vector from hVessel to the explosion.
double explosionForce = Weapon.BlastForce*pow(length(pos),-2.0); // BlastForce is the force that would be received at close range to the explosion
if(explosionForce < 10) continue;
if(Weapon.Implode == true){pos = pos/length(pos);} //Allow for implosions
else {pos = -pos/length(pos);}
f = pos*explosionForce;
oapiGetVesselInterface(hVessel)->AddForce(f,_V(0,0,0));
..Which I'm calling every timestep. Should call it on creation or am I already doing it right? AddForce doesn't do anything if it's only called once.
 
AddForce doesn't do anything if it's only called once.
Well, it does but the integration period is very short (ie, one time step) so the amount of energy transferred to the affected vessels would be quite small. I would call it every time step for as long as the weapon is "exploding". I'm no weapons expert but I expect that the amount of time that the shock wave lasts for is quite short, but the force very large.
 
Back
Top