About Store Forum Documentation Contact



Post Reply 
Changing character method: getDesiredSpeed
Author Message
Gian-Reto Offline
Member

Post: #1
Changing character method: getDesiredSpeed
I try to change the getDesiredSpeed Method of the Character class, but I have hit a brick wall here after several hours:

Code:
Flt Chr::desiredSpeed() // get desired speed
{
    // We try to calculate the height at the current position and
    // The position 1 meter ahead in move direction. From these
    // 2 Points we calculate a height difference, which we then
    // use to increase or decrease the speed according to slope
    Vec2 oldPos = Vec2(pos().x, pos().z);
    Flt currHeight = Game::World.hmHeight(oldPos, true);
    Vec2 offset = Vec2();
    offset.rotate(angle.x);
    offset.rotate(DegToRad(180.0f));
    offset.setLength(1.0f);
    //oldPos = Vec2(pos().x+1000.0f, pos().z+1000.0f);
    Vec2 newPos = oldPos + offset;
    //newPos = Vec2(newPos.x-1000.0f, newPos.y-1000.0f);
    Flt newHeight = Game::World.hmHeight(newPos, true);
            
    Flt diffHeight = (Flt) (currHeight - newHeight);
    if (diffHeight > 1.0f) diffHeight = 1.0f;
    else if (diffHeight < -1.0f) diffHeight = -1.0f;


   Flt    speed =(ctrl.flying() ? T.flying_speed : T.speed);
          speed*=Lerp(0.33f, 1.0f, anim.walk_run); // slow down when walking
          speed += diffHeight*(speed/2);
   return speed;
}

What I try to do is the following: get the current Height, calculate a new position 1 meter ahead in the walking direction, calculate height there, get the height difference, cap it to a range (1 .. -1) and use it to modify the speed.... but:

It doesn't works right no matter how I try. It always seems that even if 3 direction work fine, one is off. And I really lost track of how the Esenthel Engine tracks its positions and angles. Especially as the pos seem to not start at 0, instead the point 0 is somewhere in the middle of the map.

anyone having a better idea how to solve this problem?

Also, my second problem is performance (noticing a huge FPS drop of sometime 10 Frames)... this method seems to be called every frame, even if the character is stationary. Where is it called? Is there a possibility to change the call to not trigger so often, or to move my own code to a different method where it only triggers when the character is moving?
(This post was last modified: 04-10-2012 01:10 AM by Gian-Reto.)
04-10-2012 01:08 AM
Find all posts by this user Quote this message in a reply
Salival Offline
Member

Post: #2
RE: Changing character method: getDesiredSpeed
Try something like this, not tested..

Code:
// Get current height
float oldHeight = Game::World.hmHeight(pos().xz(), 1);

// Get direction.
float range = 1.0f; // range infront of player.

Vec dir;
SinCos(dir.z, dir.x, angle.x + PI_2);

// Get position pos + dir * range
Vec dirPos = pos() + (dir * range);

// Get height from current position
float newHeight = Game::World.hmHeight(dirPos.xz(), 1);

// Calculate diff
float diff = ( newHeight - oldHeight );

// Do stuff with diff...
(This post was last modified: 04-10-2012 07:42 AM by Salival.)
04-10-2012 07:38 AM
Find all posts by this user Quote this message in a reply
Gian-Reto Offline
Member

Post: #3
RE: Changing character method: getDesiredSpeed
Okay I found a solution:

Code:
Flt Chr::desiredSpeed() // get desired speed
{
    // We try to calculate the height at the current position and
    // compare it to the height at the las position.... as this
    // method gets called every fram, we need to make sure to
    // divide the result by the amount of fps. Its a cheap
    // approximation, but it works fine and is less computational
    // than the lookahead

    Flt fps = Time.fps();
    Vec2 currPos = Vec2(pos().x, pos().z);
    Flt currHeight = Game::World.hmHeight(currPos, true);
    Flt diffHeight = (Flt) (currHeight - oldHeight);
    oldHeight = currHeight;
    if (diffHeight > 1/fps) diffHeight = (Flt) 1/fps;
    else if (diffHeight < -1/fps) diffHeight = (Flt) -1/fps;
   Flt    speed =(ctrl.flying() ? T.flying_speed : T.speed);
          speed*=Lerp(0.33f, 1.0f, anim.walk_run); // slow down when walking
          speed -= diffHeight*fps*(speed/2);
   return speed;
}

Its a quick and dirty hack, and the resulting slow down / speed up by terrain is not as smoth as I'd like it to be, but its easy to do and needs less computations. The Framerate is back to normal.

EDIT:
Whooops, just seen your response, Salival. I'll give it a try for sure to see how it does compared to my current solution.
Thanks for the response, its appreciated

EDIT 2:
Your solution seems to work fine, Salival. Now I can't decide which of the two possibilities to use smile
I think I'll keep yours for the moment, but leave my solution commented out as I have the faint feeling that it might be a little bit faster (though not giving such a smooth speed change, but this most probably the fault of the way the Engine calculates the height (EDIT 3: no its not, its the fault of not looking ahead, and gradually increasing the slope)) and I might need it later when my framerate drops because of other stuff going on by then.
(This post was last modified: 04-10-2012 05:36 PM by Gian-Reto.)
04-10-2012 08:06 AM
Find all posts by this user Quote this message in a reply
Post Reply