views:

154

answers:

2

What I am trying to create is a rocket that will hug the track in a straight direction. ie) The rocket travels in a straight direction and can orientate based on its local x axis. This is so it can go up/down ramps and never hit the ground.

Currently I am using PhysX opengl and C++.

This is the method I'm trying right now: 1. Ray cast from ahead of the missile (ray casting downwards) 2. If the ray cast is less then the expected ray cast length, then I have to orientate up. 3. If the ray cast is more then the expected ray cast length, then I have to orientate down.

Now the problem, I am having is that my missile is orientating at an arbitary angle (I'm giving it 1 degrees.) Though I think this is a bad approach because the amount of frames in the game is not as much as I would think there would be. So the rocket would run into a ramp.

My main question is: is there a better way of approaching this and how?

NxVec3 frontRayLoc = m_rocketConfig->getValueForKey<NxVec3>("r_frontRayCastLocation");
float threshhold = m_rocketConfig->getValueForKey<float>("r_angleThreshhold");
float predRayCastHeight = m_rocketConfig->getValueForKey<float>("r_predRayCastHeight");

NxVec3 rayGlobalPos_1 = m_actor->getGlobalPosition() + m_actor->getGlobalOrientation() * frontRayLoc;
NxVec3 dir = m_actor->getGlobalOrientation() * NxVec3(0,-1.0,0);
NxReal dist1 = castRay(rayGlobalPos_1, dir);

// Get the percentage difference
float actualFrontHeight = abs(1 - (dist1/predRayCastHeight));

// See if the percentage difference is greater then threshold
// Also check if we are being shot off track
if ((actualFrontHeight > threshhold) && (dist1 != m_rayMaxDist)){
    // Dip Down
    if (dist1 > predRayCastHeight){
        printf("DOWN - Distance 1: %f\n", dist1);
        // Get axis of rotation
        NxVec3 newAxis = m_actor->getGlobalOrientation() * NxVec3(1.0,0,0.0);
        // Rotate based on that axis
        m_orientateAngle = -1.0 * m_orientateAngle; // For rotating clockwise
        NxQuat newOrientation(m_orientateAngle, newAxis);
        NxMat33 orientation(newOrientation);
        m_orientation = m_orientation * orientation;
        // Orientate the linear velocity to keep speed of rocket and direct away from road
        NxVec3 linVel = m_actor->getLinearVelocity();
        m_actor->setLinearVelocity(m_orientation * linVel);
    }
    // Go Up
    else if (dist1 < predRayCastHeight){
        printf("UP - Distance 1: %f\n", dist1);
        // Get axis of rotation
        NxVec3 newAxis = m_actor->getGlobalOrientation() * NxVec3(1.0,0,0.0);
        // Rotate around axis
        NxQuat newOrientation(m_orientateAngle, newAxis);
        m_actor->setGlobalOrientationQuat(newOrientation);
        NxMat33 orientation(newOrientation);
        m_orientation = m_orientation * orientation;
        // Orientate the linear velocity to keep speed of rocket and direct away from road
        NxVec3 linVel = m_actor->getLinearVelocity();
        m_actor->setLinearVelocity(m_orientation*linVel);
    }
        m_actor->setGlobalOrientation(m_orientation);
}

Thanks for the support :)

+3  A: 

If your ray trace can determine the height of the terrain at some point out ahead, why couldn't you just determine the height of the terrain at the current horizontal coordinates of the rocket, and render the rocket at a fixed height above that?

I.e., you seem to be trying to invent a guidance system for the rocket, when it sounds like all you really need is to figure out where to draw it.

Actually, you probably could get the orientation for the rocket by making it match the slope of the terrain underneath it, so that it doesn't appear dead level all the time. It would look sort of strange if it were level while tracking over noticeable slopes.

JustJeff
Yeah, I was trying to avoid making the rocket stay at a fixed height because I thought it would make it look jerky when it approached a ramp. But I think I will try doing that again. Lets say the I raycast from the front of the rocket ( raycasting perpindicular to the rockets direction). If the number is less than lets say a unit of 1, then should I rotate until the raycast becomes of length 1 again?Thanks for all the help.
confusedEj
the more you try to simulate real physics, the more real it will look, at the cost of chewing up more cpu and lowering your frame rate.
JustJeff
Should I be ray casting twice? once from the back of the rocket, and once in front of the rocket. Downwards? So then I can rotate and try to make the lenths the same?
confusedEj
A: 

How about doing it the way the military does with terrain following:

Look ahead distance and find the highest terrain between the craft and . Add the desired height above ground to this value and you have the altitude the rocket should be at. If it's below this climb, if it's above this descend.

Choose to get the desired behavior of the rocket. It can probably be pretty small.

There's a very good chance the heights can be precalculated and thus this reduces to a simple array lookup. (Even if you have near-infinite resolution terrain you don't need perfect granularity in the height data.)

Loren Pechtel