Advertisement

[PhysX] Move controller + getting its velocity

Started by February 28, 2014 11:01 PM
3 comments, last by Silverlan 10 years, 11 months ago

I'm trying to use a PxController for my player character, but I'm having a bit of trouble.

This is how I'm creating the controller:


local mat = physx.CreateMaterial(0.5,0.5,0.1)
local controller = physx.CreateCapsuleController({
	height = 64,
	radius = 18,
	material = mat,
	contactOffset = 0.01
})
local actor = controller:GetActor()

The code snippets are in lua, but all these functions do internally is call the equivalent physx-functions.

After the controller has been created, it's being moved every time the world is simulated:


local dir = Vector(math.sin(CurTime()),0,math.cos(CurTime())) -- Move the controller in a circle; CurTime() is the time that has passed since the program start
dir = dir *10
local disp = dir *DeltaTime() -- DeltaTime() = time since last world simulation
controller:Move(
	disp,
	0.01,
	DeltaTime()
)
local vel = actor:GetLinearVelocity()
local speed = vel:Length()
print(math.abs(speed -dir:Length())) -- Should be 0, but fluctuates quite a bit

The actual movement works as intended. If I compare the new position, after the whole PxScene was simulated, to the old position (before the "Move"-Call), the difference is exactly the displacement vector.

The velocity, however, is behaving strangely. The way I see it, getLinearVelocity should return the same as the displacement vector, but there's a small, random, deviation, but it's too large to be a precision error of some sort. What am I missing?

One more thing:

I can move the controller in any direction, even upwards from the ground. How would I actually restrict the movement so the controller actually sticks to the ground? And what exactly is the point of the 'setUpDirection'-function for PxControllers if it doesn't already do that?

You can't rely on the actor's velocity in this case... The character controller framework does so much more under the hood. You should track the velocity manually. Using that "dir" in your code should be perfectly fine (e: unless the controller touches something - you have to check for these conditions).

One way to handle the gravity is to manually apply the acceleration. The cc framework provides the raycast result flags. If the bottom of the cc touches ground (or something else), just reset the velocity's z-component or modify it according to conservation laws. The up direction is used to do these raycasts and to determine the orientation of the cc shape.

Advertisement

Thanks for the response, it's hard to get help with anything PhysX related.

Anyway, I'm unsure how I'm supposed to track the velocity myself accurately. As you've said, as long as there's no collisions it would probably be fine, but if there is a collision that's a whole different story.

The flags I get from the 'Move'-Call only tell me whether there was a collision above / below / to one of the sides of the controller, I need more information about the collision than that. And even then I'd have to know exactly how physx does the collision response (e.g. sliding against a wall) to calculate the new exact velocity.

Also, if the difference between the new position and the old position is exactly my displacement vector, how is it possible that getLinearVelocity returns something else? I mean, even if the controller framework does some additional calculations, the velocity should be exactly the vector by which it has moved, should it not?

Internally the controller framework uses setKinematicTarget() so one can only guess what PhysX does beyond that point. I don't know if it's even valid to use getLinearVelocity with kinematic actors...

However, since the displacement is accurate, why not use it to calculate the velocity yourself? Just keep the previous and current position between updates and divide the displacement with your timestep.

It just seems to me more like a workaround than an actual solution, but I guess it will do, thanks. The only problem I see is that I can't differentiate whether the actor has been forcibly teleported to a specific position, or moved there regularly, but I guess I'll have to live with that. Thanks again!

This topic is closed to new replies.

Advertisement