Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 10 Nov 2005
Offline Last Active Yesterday, 08:39 PM

Posts I've Made

In Topic: PhysX - handling picked up/carried objects

22 November 2015 - 05:27 PM

And here's the second follow-up.


I did get it working, although I haven't tested it too rigorously yet. Still, I wrote a journal entry outlining what I ended up doing. Hope someone finds it useful.

In Topic: PhysX - handling picked up/carried objects

18 November 2015 - 04:18 PM

Follow-up #1. I'm writing this in case it will be useful to someone.


In short, things changed after I started experimenting with gravity and substepping.


My initial test settings were:


scale = ~30 units per box axis (30 pixels/units in  my case)

step_delta = 16.6 ms (~60 Hz)

numSubsteps = 4

gravity = -9.81f * (step_delta / (1000.f * numSubsteps))


This did not work. Substepping forced the actor to perform better at collision, but it also caused it to lag behind the player. To be honest, substepping seemed unneccessary in the first place, since I was running the simulation at a fixed 60 Hz interval, which isn't extreme any way you look at it. That being said, substepping helped a ton, as it visibly verified that the actors were actually colliding - the carried object didn't penetrate completely into static geometry. But it did still jostle and wobble as outlined in my previous posts.


My initial idea was to undo the rotational offset by rotating the carried object to an upright position during each simulation step using setAngularVelocity(). This didn't work and on closer inspection it shouldn't. I tried setGlobalPose() on the actor by setting only its rotational component, but this would expectedly cause the actor to clip into geometry. It was a step in the right direction, though, as the actor would no longer go completely through statics. After some more googling I learnt about the existence of frozen rotational axes in PhysX 2.7, which seemed like a really convenient solution. As it happens, however, there is no equivalent to this in PhysX 3.2.2, which, in turn, led me to this. While the rotational fix worked, the D6 joint fixed the actor to a single position in space, disallowing any movement imposed by setLinearVelocity(). As far as I can tell, it would work as intended if the body is kinematic (and you're using setKinematicTarget()), though. Which mine isn't.


All the while gravity was causing all kinds of weird behavior, which I cannot fully explain, mostly because I (think I) don't really have enough experience with the PhysX API to start with (and also because it didn't click for me that it was gravity what was causing these problems in the first place). Firstly, dynamic objects would become unstable and start fluctuating arbitrarily across the scene. I'm guessing this can be attributed to my poor choice of or possibly missing mass/inertia/material parameters, although I did try a variety of values as best I could. Secondly, if I set the spawn point for dynamic objects high enough (500 or more on the abovementioned scale), dynamic actors would no longer end up jittering erratically, but would rather fall to the ground and end up stationary (they would not from lower heights for some reason). However, they would stop at odd angles without settling on a level plane like one would expect them to. Which still baffles me.


So finally I disabled gravity by setting the PxActorFlag::eDISABLE_GRAVITY flag on all dynamic objects.


Which changed a lot. I no longer get any jitter/rotational unstability and my carried object is no longer penetrating any solids. That being said, I still have much more tweaking to do to define whether or how the it can move through the player (this needs addressing, since I have a top down camera, and the player can flip the CCT by moving the mouse across its origin).


While all that makes sense, I don't really know what happened. It's one of those times when "that next build" fixed everything (well, not everything) without me changing all that much (notably, because I'd tried disabling gravity before!). What I did notice, though, is that setting the carried actor's mass to zero causes it to go through static geometry and setting it to something really small (like 0.1) still causes much heavier dynamic actors to move out of the way as if they're made of aerogel. So that's something I still need to figure out.


As far as gravity goes, I personally don't need it for this game, since my game is perceptually 2D. However, I would imagine either setting/unsetting the eDISABLE_GRAVITY flag when an object is picked up/set down, or applying a custom gravity vector for each dynamic actor would solve the problem of not having gravity enabled implicitly.


PS - I'm calling this the follow-up post #1, because I'm fairly sure my problems aren't over. Since this does not seem like a too uncommon issue and I couldn't find any substantial sources of information when searching, I'll try to post updates if and as needed.

In Topic: PhysX - handling picked up/carried objects

17 November 2015 - 10:10 AM

Hmpf. This is seriously getting to me.


Here are what I think are all relevant bits of code that should set up collision between all actors. Perhaps someone would not mind skimming through it and maybe point out a mistake in case I've made any.


Filter setup at scene creation:

    PxU32 groupCollisionFlags[32]

    //everything collides with everything
    for(unsigned i = 0; i < 32; i++)
    { groupCollisionFlags[i] = 0xffffffff; }

    //disable with the disabled group - leaving this in for reference

    sceneDesc.filterShaderData = groupCollisionFlags;


void IPhysXPhysicsEnvironment::setGroupPairCollisionFlag(PxU32 groups1, PxU32 groups2, bool enable)
    PX_ASSERT(groups1 < 32 && groups2 < 32);
        groupCollisionFlags[groups1] |= (1 << groups2);
        groupCollisionFlags[groups2] |= (1 << groups1);
        groupCollisionFlags[groups1] &= ~(1 << groups2);
        groupCollisionFlags[groups2] &= ~(1 << groups1);

Actor creation and filter mask setting:

void IPhysXPhysicsEnvironment::CreateRigidActor(...)
   PxRigidActor* rigidActor = NULL;

        rigidActor = physics->createRigidDynamic(PxTransform(PxReal(vPositionInRegion[0]), PxReal(40), PxReal(vPositionInRegion[2])));
        vHalfExt.y = 15;

        PxRigidBodyExt::updateMassAndInertia(*(PxRigidBody*)rigidActor, 10.0f);
    { rigidActor = physics->createRigidStatic(PxTransform(PxReal(vPositionInRegion[0]), PxReal(vPositionInRegion[1]), PxReal(vPositionInRegion[2]))); }

    PxShape* rigidShape = NULL;

    if(!STRCMP(actor.mesh->descMesh->sBasicType, "sphere"))
        rigidShape = rigidActor->createShape(PxCapsuleGeometry(actor.mesh->descMesh->vSize.x * PxReal(0.5), 20), *aMaterial);
        PxTransform relativePose(PxQuat(PxHalfPi, PxVec3(0, 0, 1)));
        rigidActor->setGlobalPose(PxTransform(PxVec3(vPositionInRegion[0], 0, vPositionInRegion[2])));
        rigidShape = rigidActor->createShape(PxBoxGeometry(vHalfExt.x, vHalfExt.y, vHalfExt.z), *aMaterial);

    rigidActor->setActorFlags(PxActorFlag::eDISABLE_GRAVITY | PxActorFlag::eVISUALIZATION);

    { SetCollisionFlagsForAllShapes(*rigidActor, PHYSICS_GROUP_PICKUP); }
    { SetCollisionFlagsForAllShapes(*rigidActor, PHYSICS_GROUP_STATIC); }

    rigidShape->setFlag(PxShapeFlag::eVISUALIZATION, true);
    rigidShape->setFlag(PxShapeFlag::eSCENE_QUERY_SHAPE, true);
    rigidShape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, true);

template<typename T>
void IPhysXPhysicsEnvironment::SetCollisionFlagsForAllShapes(IN const T& actor, IN const DWORD flags) const
    PxShape* shapes[32];

    for(int32 j = 0; ; j++)
        ZeroMemory(shapes, sizeof(PxShape*) * 32);

        if(actor.getShapes(shapes, 32, j * 32) == 0)
            { goto _doneSetFlags; }

        for(int32 i = 0; i < (int32)32; ++i)
            if(shapes[i] == NULL)
                { goto _doneSetFlags; }

            PxFilterData filterData;
            filterData.word0 = flags;



Collision filter shader:

PxFilterFlags MySimulationFilterShader(PxFilterObjectAttributes attributes0, PxFilterData filterData0,
                                       PxFilterObjectAttributes attributes1, PxFilterData filterData1,
                                       PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize)
    //some reference code commented out

    //PxFilterFlags filterFlags = PxDefaultSimulationFilterShader(attributes0,
                                filterData0, attributes1, filterData1, pairFlags, constantBlock, constantBlockSize);

    //pairFlags |= PxPairFlag::eSOLVE_CONTACT;

    pairFlags = PxPairFlag::eSOLVE_CONTACT;
    pairFlags |= PxPairFlag::eCONTACT_DEFAULT;
    pairFlags |= PxPairFlag::eDETECT_DISCRETE_CONTACT;
    pairFlags |= PxPairFlag::eDETECT_CCD_CONTACT;

    return PxFilterFlag::eDEFAULT;

Handling the carried actor during a physics sim step:

    PxRigidDynamic dynBody* = GetCarriedObject();
    vecToHoldPosition = GetPosInFrontOfPlayer() - PosCurrent(dynBody);

    if(vecToHoldPosition.LengthSquared() > 0)
        vecToHoldPosition *= timeScale;
        //don't do any rotational adjustment for now
        //reset all movement if already in correct place
        dynBody->setLinearVelocity(PxVec3(0, 0, 0));
        dynBody->setAngularVelocity(PxVec3(0, 0, 0));
        dynBody = NULL;


        dynBody->setLinearVelocity(PxVec3(0, 0, 0));
        dynBody->setAngularVelocity(PxVec3(0, 0, 0));

In Topic: PhysX - handling picked up/carried objects

17 November 2015 - 04:22 AM

Does the carried object need to simulate physics?

Unless it is a must for a good reason, I would simply disable physics for any carried object. Once you drop it you can re enable physics.


That's the problem with 3rd person camera - I can't just have it go through solids and render it with depth disabled. So yeah, it really needs to respond to physics...


The thing is, I've been experimenting with this for several days now and I can't figure out why it's interpenetrating static solids. The carried object is definitely reporting collision in the filter shader and does push other dynamics out of the way. But I don't understand why it's clipping into static geometry (while also acting like it's colliding, eg wobbling) or why it's not getting completely blocked by other dynamics when I set its mass to zero.


Truth be told, this solution seems ridiculously simple and foolproof as it only takes advantage of regular collision response and relies on no gimmicks at all. Which is why I really want to think that I'm missing something simple somewhere. 

In Topic: Blackhole internal space

05 November 2015 - 06:11 PM

Gravity force




I'm not sure what it is you think you've plotted out there, but there's a reason why black hole physics is not part of high school curriculum. Since the link isn't immediately clear about it, a singularity is what you will find at the center of a black hole.


As far as "coordinates" go - you might be able to mathematically assign coordinates to a point "inside the volume" of a black hole when viewed from the outside, but once you start approaching a black hole, things stop adding up pretty darn quickly. Because under the force of gravity (of which you will have not shortage near a black hole) space starts to bend.