Jump to content

  • Log In with Google      Sign In   
  • Create Account


Silverlan

Member Since 02 May 2013
Offline Last Active Yesterday, 07:35 AM
-----

Topics I've Started

PhysX - Stick controllers to kinematic actors

12 July 2014 - 02:54 PM

By default kinematic actors in PhysX will simply push controllers out of the way or ignore them:

 

This is obviously not the desired behavior for things like elevators or escalators.

I'm unsure on how to actually 'stick' the controller to the platform to make sure the player doesn't fall off.

I tried adding the kinematic target offset of the platform to the displacement vector when moving the controller every simulation step, however that doesn't prevent the 'pushing' from the kinematic actor and wasn't very accurate either.

 

How is this usually accomplished? The documentation mentions using obstacles for moving platforms, but I don't see how that would help in this case.

 

I'm using PhysX 3.3.0.


Trouble with quaternions / euler angles (3D) and player rotations

05 July 2014 - 04:43 AM

I'm working on a 3D game engine and I'm having some trouble with the math behind player orientations / rotations.

My coordinate system is right-handed with (1,0,0) = right,(0,1,0) = up and (0,0,-1) = forward.

 

I have the following data available for the player character:

viewOrientation - A quaternion representing the way the player is currently facing

upDirection - A vector representing the up-direction of the player, by default it's the same as the world's up vector (0,1,0), but the player is able to walk on walls as well, in which case the up direction would be perpendicular to the surface below the player

forwardDirection,rightDirection - If the up-direction is changed, these change respectively. By default all three direction vectors correspond to the world axes

upRotation - Quaternion representing the rotation from the world's up vector to the upDirection of the player

 

Now, what I need to do is:

- Limit the player's pitch axis to 90 degree up and down (Can't look further than straight down / up)

- Extract a movement direction from the player's orientation

 

As long as the player's direction vectors correspond to the world axes, both of these are easy to implement.

But problems arise if the up direction is anything else but (0,1,0).

 

Let's start with limiting the player's pitch axis.

Usually I would just transform the viewOrientation by the inverse of the upRotation, convert that to euler angles, apply the limit and then convert them back to a quaternion and transform them back via the upRotation.

Unfortunately this is prone to errors, since different euler angles can represent the same rotation. For example if I have the euler angles (pitch=0,yaw=0,roll=0), then pitch is obviously 0. On the other hand, if I have the euler angles (180,180,180), which is essentially the same rotation, I get the pitch as 180, which is obviously not what I want. Since I'm working with quaternions, and convert them to euler angles, I can't be sure which ones I get.

Are there any alternative ways to do this?

 

As for the second problem, it's supposed to be like this:

If the player looks straight forward, he's supposed to move at full speed in that direction. If he looks 45 degree downwards, he's supposed to move at half the speed, but no downwards force should be applied, so the direction vector should stay the same.

Problem is, I'm unsure on how to extract the direction vector from the viewOrientation. Again, usually I'd just grab the euler angles same way as above, remove the pitch and roll components, and use the yaw, but the above problem applies here as well.

 

I'm at a loss, any nudge in the right direction would be very much appreciated.


PhysX - StartTouch/EndTouch/Trigger Events?

14 June 2014 - 04:03 AM

I'm using PhysX 3.3.0.

I need to know when two actors have started touching and ended touching, but can't figure out how to properly implement that.

 

This is my filter shader for testing purposes:

static physx::PxFilterFlags testFilterShader(
		physx::PxFilterObjectAttributes attributes0,physx::PxFilterData filterData0,
		physx::PxFilterObjectAttributes attributes1,physx::PxFilterData filterData1,
		physx::PxPairFlags &pairFlags,const void *constantBlock,physx::PxU32 constantBlockSize
	)
{
	if(physx::PxFilterObjectIsTrigger(attributes0) || physx::PxFilterObjectIsTrigger(attributes1))
	{
		pairFlags = physx::PxPairFlag::eTRIGGER_DEFAULT;
		return physx::PxFilterFlag::eDEFAULT;
	}
	pairFlags = physx::PxPairFlag::eCONTACT_DEFAULT;
	if(((filterData0.word0 &filterData1.word1) == 0) || ((filterData1.word0 &filterData0.word1) == 0))
		return physx::PxFilterFlag::eKILL;
	if(filterData0.word2 || filterData1.word2)
		pairFlags |= physx::PxPairFlag::eNOTIFY_TOUCH_FOUND;
	
	return physx::PxFilterFlag::eDEFAULT;
}

If word2 is set to anything but 0 (Which is the case for my test-actors), the PxPairFlag::eNOTIFY_TOUCH_FOUND flag is set. According to the physx documentation, this should invoke the 'onContact' method of my event callback:

class WVPxEventCallback : public physx::PxSimulationEventCallback
{
public:
	WVPxEventCallback();
	virtual void onContact(const physx::PxContactPairHeader &pairHeader,const physx::PxContactPair *pairs,physx::PxU32 nbPairs);
	virtual void onTrigger(physx::PxTriggerPair *pairs,physx::PxU32 count);
	virtual void onConstraintBreak(physx::PxConstraintInfo *constraints,physx::PxU32 count);
	virtual void onWake(physx::PxActor **actors,physx::PxU32 count);
	virtual void onSleep(physx::PxActor **actors,physx::PxU32 count);
};

However 'onContact' is never called, no matter what.

In case of a trigger, it's calling the 'onTrigger' event if an object is touching it, as it should, but it's also called at seemingly random times while the object (capsule controller) is moving around within the trigger.

 

I've set both the PxSceneFlag::eENABLE_KINEMATIC_PAIRS and PxSceneFlag::eENABLE_KINEMATIC_STATIC_PAIRS flags for the scene.

Is there anything else I forgot/need?

 

I'd also like to know if there's a way to check if two actors are touching at any time, or if I have to keep track of that myself?

 

Thanks.


PhysX - PxRigidDynamic clip through other actors (CCD enabled)

03 March 2014 - 12:26 AM

This is a re-creation of my old thread here. I haven't been able to solve this issue and the thread got closed, so here's attempt 2:

 

My PxRigidDynamic actors intersect with other actors and I can't figure out why. There are still collisions between them, but the rigid dynamic slightly clips through them and is 'pushed' back. Here's a video of it ingame/in the PVD:

http://youtu.be/X0oyDtCTsuQ

 

The box is a PxRigidDynamic actor.

The player is a PxCapsuleController.

All other actors are PxRigidStatic.

 

Having CCD disabled or enabled seems to make no difference. (CCD should only affect high-velocity objects anyway, so I doubt that's the cause here)

 

The collisions between the controller and the static actors are fine, so I don't see why the rigid dynamic would behave any differently.

 

I'm using PhysX-3.3.0


[PhysX] Move controller + getting its velocity

28 February 2014 - 05:01 PM

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?


PARTNERS