Why hkpCharacterProxy has physical effect with hkpSimpleShapePhantom?

Why hkpCharacterProxy has physical effect with hkpSimpleShapePhantom?

I understand that the phantom is just used to query. I test RigidBody and CharacterRigidBody, they has no physical effect with hkpSimpleShapePhantom, but why hkpCharacterProxy has physical effect with hkpSimpleShapePhantom?

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

Hi,
This is actually a known issue with phantoms and character proxies. By default, the hkpShapePhantom of a hkpCharacterProxy will receive collidable callbacks from other phantoms and react to them. You could write a custom hkpCollisionFilter, but then all your Phantoms would have to be on the same layer as the non-Phantoms, which is pretty restricting. Another, preferable, way is to create a custom hkpPhantomOverlapListener and implement the collidableAddedCallback such that when a collision event with a phantom happens, m_collidableAccept is set to HK_COLLIDABLE_REJECT. Here is a slightly modified example tested in CharacterPhantomInteractionDemo.cpp:

class IgnorePhantomOverlapListener: public hkReferencedObject, public hkpPhantomOverlapListener

{

public:
	HK_DECLARE_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DEMO );
	IgnorePhantomOverlapListener()

	{

	}
	~IgnorePhantomOverlapListener()

	{

	}
	virtual void collidableAddedCallback(const hkpCollidableAddedEvent& event)

	{

		const hkpCollidable *collidable = event.m_collidable;

		int type = collidable->getType();
		if ( type == hkpRigidBody::BROAD_PHASE_ENTITY ||

			 type == hkpRigidBody::BROAD_PHASE_PHANTOM )

		{

			hkpWorldObject* wo = hkpGetWorldObject(collidable);

			if ( wo->hasProperty(OBJECT_MARKED_FOR_DETECTION) )

			{

				event.m_collidableAccept = HK_COLLIDABLE_REJECT;

			}

		}

	}
	virtual void collidableRemovedCallback(const hkpCollidableRemovedEvent& event)

	{

	}

};
The condition for what to ignore may vary, but that should give you an idea. And the usage:
IgnorePhantomOverlapListener* pl = new IgnorePhantomOverlapListener();

m_phantom->addPhantomOverlapListener(pl);
Another good option is to create your own hkpSimpleShapePhantom and override the addOverlappingCollidable function. In that case, you will want to do the same check but to ignore a given collidable just don't call the base function:
hkpSimpleShapePhantom::addOverlappingCollidable(collidable);
Hope that helps!
--Joel

Thank you for your answers
I tried your code, but it seemed that this can only ignore the broadphase collision, the narrowphase collision still occur.
The demo TriggerVolumeComparison(hk2011_2_0_r1) shows this problem. See the red box in the following diagram

Hi,
For that demo, you don't want/need the extra propery check forOBJECT_MARKED_FOR_DETECTION. You just want:

virtual void collidableAddedCallback(const hkpCollidableAddedEvent& event)

{

	const hkpCollidable *collidable = event.m_collidable;

	int type = collidable->getType();  
	if ( type == hkpRigidBody::BROAD_PHASE_ENTITY ||

			type == hkpRigidBody::BROAD_PHASE_PHANTOM )

	{

		event.m_collidableAccept = HK_COLLIDABLE_REJECT;

	}

}  
Just tested it myself and it's giving the results I believe you want.
Take care,
--Joel

I modify the demo TriggerVolumeComparison(hk2011_2_0_r1), add your code, and the problem persists, please look at my code, what went wrong?

class IgnorePhantomOverlapListener: public hkReferencedObject, public hkpPhantomOverlapListener

{

public:  
    HK_DECLARE_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DEMO );  
    IgnorePhantomOverlapListener()

    {

    }  
    ~IgnorePhantomOverlapListener()

    {

    }  
    virtual void collidableAddedCallback(const hkpCollidableAddedEvent& event)

    {

        const hkpCollidable *collidable = event.m_collidable;

        int type = collidable->getType();    
        if ( type == hkpRigidBody::BROAD_PHASE_ENTITY ||

             type == hkpRigidBody::BROAD_PHASE_PHANTOM )

        {

            event.m_collidableAccept = HK_COLLIDABLE_REJECT;

        }

    } 
    virtual void collidableRemovedCallback(const hkpCollidableRemovedEvent& event)

    {

    }

}; 
TriggerVolumeComparisonDemo::DemoShapePhantom::DemoShapePhantom( const hkpShape* shape, const hkTransform& transform, hkUint32 m_collisionFilterInfo )

: hkpSimpleShapePhantom(shape, transform)

{

    addPhantomOverlapListener(new IgnorePhantomOverlapListener);
    // other code

}
====================================================================

In addition, I use the following code to avoid physic effect of hkpCharacterProxy and hkpSimpleShapePhantom, it's ok;

    class MyCollector : public hkpAllCdPointCollector

    {

        // implements the hkpCdPointCollector interface.

        virtual void addCdPoint( const hkpCdPoint& event )

        {

            // Do not add the collision point

        }

    };

    MyCollector mc;

    m_characterProxies[i]->integrateWithCollectors(csi, m_world->getGravity(), mc, mc);

Hi,

The problem is that inaddGridCharacterProxy (where it creates the character proxy) it doesn't use that custom shape phantom. You want to do:

IgnoreAllPhantomOverlapListener* pl = new IgnoreAllPhantomOverlapListener();

proxyShapePhantom->addPhantomOverlapListener(pl);
That should do it for you!

--Joel

Thank you for your answers
Following is my code,but the physic effect still occur.

    m_fixedShapePhantom = new DemoShapePhantom( boxShape, transf );

    m_fixedShapePhantom->addPhantomOverlapListener(new IgnorePhantomOverlapListener);

Attached is the demo with the changes I gave you earlier.

--Joel

Attachments: 

AttachmentSize
Download TriggerVolumeComparisonDemo.cpp35.91 KB

Thank you very much!
I add the listener to error phantom.
And I also want to know, what is the difference between my method and your method? Whether my method is not desirable?
Follow is my method.

    class MyCollector : public hkpAllCdPointCollector

    {

        // implements the hkpCdPointCollector interface.

        virtual void addCdPoint( const hkpCdPoint& event )

        {

            // Do not add the collision point

        }

    };

    MyCollector mc;

    m_characterProxies[i]->integrateWithCollectors(csi, m_world->getGravity(), mc, mc);

Using a custom point collector that ignores all points means you will not get -any- contact points, not just phantoms. This would result in your character proxies walking through anything, not just phantoms.

Cheers,
Tyler

Thank you, I learned a lot.

CHerrs,
rikpan

Leave a Comment

Please sign in to add a comment. Not a member? Join today