hi
history:
i want to produce hovercraft flight, so I am using hitbeam using the start point as the position of the ship and extending the beam downwards by a certain amount (my cutoff point when force is so small I ignore it).
I was using inverse square law (which is probably more accurate) but it was explosive when you neared ground so you needed a small multiplier (but it made higher distances more neglible).
So now I'm using
Force upwards on ship = multiplier / height to ground point.
Problem is, applying a force to a single center point on an object is a very bad idea as it will rock about when on uneven ground (unstable), so I came up with instead stabilising the four center points along the base sides of the quad of the ships collision box.
--------X----------
| |
| |
X X
| |
| |
--------X----------
like so (if thats the bottom quad of the ships Mechanics system's collision bounding box)
in the program the box has dimensions 2x0x2 (using cs co-ord system), therefore we need 'stabilisers' at
0,2--------1,2----------2,2
| |
| |
0,1 2,1
| |
| |
0,0 --------1,0----------2,0 on XZ plane (y = 0)
csVector3(1,0,0)
csVector3(1,0,2)
csVector3(0,0,1)
csVector3(2,0,1)
but for some reason, the stabilisers 'fight' and the ship goes mental! eventually flying off into space. here is my stabilising code
Stabiliser::Stabiliser(csRef<iCelEntity> world,csRef<iCelEntity> aship,float mult,float min, float max, csTicks dur)
: multiplier(mult) , cutoff_height_min(min) , cutoff_height_max(max) , duration(dur)
{
SCF_CONSTRUCT_IBASE(NULL);
ship_mech = CEL_QUERY_PROPCLASS_ENT(aship , iPcMechanicsObject);
world_mesh = CEL_QUERY_PROPCLASS_ENT(world , iPcMesh);
}
Stabiliser::~Stabiliser()
{
SCF_DESTRUCT_IBASE();
}
bool Stabiliser::Perform(iTimerEvent *ev)
{
ForceCheck(csVector3(1,0,0));
ForceCheck(csVector3(1,0,2));
ForceCheck(csVector3(0,0,1));
ForceCheck(csVector3(2,0,1));
return true;
}
void Stabiliser::ForceCheck(csVector3 offset)
{
float distance = Height(offset);
// if distance is extremely small then force upwards will be extremely large
if(distance > cutoff_height_min)
AddForce( multiplier / (distance) , offset );
else
AddForce( multiplier / (cutoff_height_min) , offset );
}
void Stabiliser::AddForce(float force , csVector3 &offset)
{
ship_mech->AddForceDuration(csVector3(0,force,0),false,offset,duration);
}
float Stabiliser::Height(csVector3 &offset)
{
csVector3 start = ship_mech->GetBody()->GetPosition() + offset;
csVector3 end = start + csVector3(0,-cutoff_height_max,0);
csHitBeamResult bres = world_mesh->GetMesh()->HitBeam(start , end);
if(bres.hit) printf("beam hit!\n"); else printf("beam fail!\n");
if(bres.hit)
return cutoff_height_max * bres.r;
else
return 999999999;
}
Thank you