More or Character Controller

More or Character Controller

Hi All, we're now integrating our small AI/Pathfinding library with Havok.

Basically we've a function that resolve a path on a NavMesh

list = ResolvePath(A,B);

where "list" of 3d Points that represent a "path" for moving from position A to position B.

Now my question is abaout the Havok Character controller; unitl now we've used the "Rigid Body" CC for AI Enemies.
To move this CC along the path we'll have to set orientation and a speed. No problem here.

Questions are:
a) Is that the right way to move the "Rigid Body" CC along a precalculated path???
b) I suppose that the Rigid Body CC must be physical driven....so there is not a function like:
RBCC->Move(vector3 point); right?
c) Does the "Proxy" Character Controller have such function? PCC->Move(vector3 point);

I ask that becouse It could be useful to just "Move" the CC and set it's orientation. I'm wondering if the "Proxy CC" is better suited for moving AI Enemies along some precalculated path.

Thanks in advance for any response
Best Regards

16 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Ok after some test I've noticed that Proxy CC is not the answer to my question.

Right now I can drive the Rigid Body CC along the path using this member from hkpCharacterInput:

hkVector4 m_forward;
hkReal m_inputUD;

so the question is: could I drive the character using the member var of hkpCharacterInput ???:
hkVector4 m_position;

If this is not possible I could always use a keyframed obejct and move it using the points from the computed path.
But I'd like to knwo if I just can drive the Rigid Body CC in the way described above.

Thanks in advance

Hi,

As far as I know, the character controllers are controlled by setting the velocity.
There's a good reason for this, at least in the case of the rigid body controller, because setting the position of a world object directly necessitates an expensive update of the collision detection broadphase.

I think what you're asking me is a bit different though - you want a means to tell the character controller to go to the next position along your path, is that correct?

You'll probably have to roll your own solution here, but it shouldn't be too complicated.
Stick with the rigid body controller, there's no need to change over to the proxy controller.
All you need is a function that calculates the desired velocity Vd of the character given:
- character position P
- target (path) position T
- character current velocity Vc
Damped-spring type 'proportional-derivative' control should do the trick - something like:
Vd = k(P-T)/t - b(Vc)
where k and b are tuning constants, and t is the timestep.

This type of velocity control should smooth out the NPC motion, which is probably necessary considering the input is a series of discrete points along the path.

Hope this helps.

Cormac

Hi Cormac thanks for response.
I've currently implemented a solution that works with the Rigid Body CC (I'll post a video later).

I compute the velocity vectors and I currently set the CC forward vector and CC speed to move it along the path. The result is not bad.

I'll also try your solution couse I'm using something similar for the Camera movement :-)

Question is:
can be a good solution to use a Keyframed Object for NPC instead of the Rigid Body CC???
With a keyframed object I can set position on the world (not bad cosnidering that my paths are a list of points) and at the same time have physical properties of the object.

My only concern is that CC is better suited for NPC in respect to a keyframed object.

Regards

>All you need is a function that calculates the desired velocity Vd of the character given:
>- character position P
>- target (path) position T
>- character current velocity Vc
>Damped-spring type 'proportional-derivative' control should do the trick - something like:
>Vd = k(P-T)/t - b(Vc)
>where k and b are tuning constants, and t is the timestep.

so once computed that "spring damped" velocity I just set hkpCharacterInput->m_velocity parameter ??? or do I have to provide m_forward,m_inputLR,m_inputUD vectors also to the input structure???

Regards

Ah, I see what you're saying.
Yes, you should be able to set the linear velocity of the character using hkpCharacterRigidBody::setLinearVelocity()

mmmmm we use characterContext so basically we do:

hkpCharacterInput input;

hkpCharacterOutput output;

m_CharacterContext->update(input, output);
m_RBCC->setLinearVelocity(output.m_velocity, dt);

but do I must "set" desired "spring dumped" velocity here:

input.m_velocity = spring_dumped_velocity;

and perform an update or ignore the CharacterContext and set the velocity directly with setLinearVelocity???

Thx

Good point.

hkpCharacterContext::update() calculates the velocity the character should have based on its state, the current velocity and the control input.

When you're having your character follow a path you might just want to override (ie ignore) the
update() and directly set the velocity of the character.

But there are some useful functions performed by update() - most notably, it queries the current character state to determmine how the velocity should be updated.

Ok, you might have to try a couple of things:
- try setting the input.m_velocity to springDampedVelocity as you suggest
OR
- calculate a normalized vector that points in the direction of your target point from the character and set input.m_inputLR to the x-coordinate and input.m_inputUD to the y-coordinate (assuming your character is moving in the xy-plane) - do everything else as you would usually for a character controller

Now that I think of it, the second solution might work better.

Ok while your solution b) is good I'll explain my solution c) ^_^

let's m_Direction a hkVector "normalized tangent vector" to the motion path at update time t,
I'll set:

input.m_inputLR = 0.0f;
input.m_inputUD = 1.0f;
input.m_forward.set(m_Direction(0),m_Direction(1),m_Direction(2));

why this ? becouse if the path is curved the the capsule CC will orient in the right way with a smooth movement.

Don't get me wrong but I think that your solution b) will lack correct orientation.

I didn't try your solution a) but potentially this solution won't allow the CC to jump for example. Maybe I'll try it later just for exercise

Let me know your thoughts about this.

Regards,
Mauro

It did occur to me later that the forward direction wouldn't be set, and your solution is good from that point of view.

One thing I would add is some sort of correction for when the character is not exactly on the path.
So, let's combine b) and c) into d):

input.m_inputLR = error(0)
input.m_inputUD = 1.0f + error(1);
input.m_forward.set(direction(0),direction(1),direction(2));

where 'direction' is your normalized tangent to the path, and 'error' is the normalized direction from the character's current position to the target point on the path.
inputUD and LR might need to be rescaled to stay between 0 and 1. Best thing is to set it up and experiment.

Then shrink the error vector when the character gets close to the target point. If the character is right on the path, this will become equivalent to c).

I think you're right about a), but it might come in handy for situations like forcing a character to catch up if it falls too far behind.

Have you tested any of the solutions yet?

Cormac

Hi Cormac,already implemented c) It works very well.Now I'm investigation on d) and how to andle dynamic avoidance couse my A* compute a path on a navmesh.I'll post results and updates soon.Best Regards

That's great.
Do be sure to post some updates - it's always nice to see things working!

Cormac

Nice ^_^ I just tweaked my c) and I didn't use d) yet :-)

I've made it working even if the CC "encounters" some small "obstacles" like other CC during it's path . It will reach the goal even on collisions in few words.

Now I just want to add some "feeback control" and path recomputation if the CC move too far away from the original path (couse in that situation maybe there is a better path to reach the goal)

Best Regards & thanks for help

Here we're...I'm using the Havok Debugger couse I can't show the game as now :-/

this is a very simple example....as stated previosuly we're working on more robust solution.

Regards

Sweet.
Tuning the constants in the damped velocity calculation (smaller spring constant for instance) could smooth out the motion a bit, rounding off the sharp corners of the path.

Great to see some results!

Cheers,
Cormac

Hi Cormac on this side I'll use a Catmull-Rom Spline to get a smoother path. This + samller spring k should be perfect. Once again I'll post results soon.

See you later

Login to leave a comment.