hkpSpuCollisionCallbackUtil.h
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:11k
源码类别:
其他游戏
开发平台:
Visual C++
- /*
- *
- * Confidential Information of Telekinesys Research Limited (t/a Havok). Not for disclosure or distribution without Havok's
- * prior written consent. This software contains code, techniques and know-how which is confidential and proprietary to Havok.
- * Level 2 and Level 3 source code contains trade secrets of Havok. Havok Software (C) Copyright 1999-2009 Telekinesys Research Limited t/a Havok. All Rights Reserved. Use of this software is subject to the terms of an end user license agreement.
- *
- */
- #ifndef HK_SPU_COLLISION_CALLBACK_UTIL_H
- #define HK_SPU_COLLISION_CALLBACK_UTIL_H
- #include <Common/Base/Spu/Dma/Utils/hkSpuDmaUtils.h>
- #include <Physics/Dynamics/Collide/hkpCollisionListener.h>
- class hkpBvTreeShape;
- /// This is an utility class, which helps to export callback information from the spu to the ppu. This is just an example how to do this.
- /// Please copy the files for ppu and spu and create your own version.
- /// For future Havok physics versions this class is subject to change.
- ///
- /// The SPU is severely memory-limited, so to be able to properly handle collision events (without any restrictions) as soon as the collision
- /// detection is running on the SPU we need to forward those events to the PPU. This utility handles the forwarding of the events. Simply
- /// create an instance of this utility using the static createSpuCollisionCallbackUtil() function. Pass in the total amount of memory you want
- /// the utility to have. Note that this includes the buffer for the events, so don't make it too small. You then have to attach this utility
- /// to each entity you want the events forwarded for. During collision detection this utility will now collect all 3 types of collision events
- /// (added, processed and removed), repack them, add them to the utility's event queue and write this event data back to the PPU. On the PPU
- /// you now only have to call fireCallbacks() with a pointer to your user-implemented callback functions. This will fire the appropriate
- /// callback function for each collision event and pass in the corresponding event data. Make sure to reset the event queue on your last call
- /// to fireCallbacks() (in case you should call it several times) or otherwise the queue will fill up pretty fast, preventing any further events
- /// to be forwarded from SPU to PPU.
- HK_CLASSALIGN16(class) hkSpuCollisionCallbackUtil : public hkReferencedObject
- {
- public:
- /// register its spu functions
- static void HK_CALL registerSpuFunctions();
- public:
- /// Event base class.
- ///
- /// This is the base class for all 3 collision events. It has a type that can be used
- /// to identify the actual event. It also holds the total size for the event (used for
- /// advancing to the next event in the queue) and PPU pointers to the colliding entities.
- HK_ALIGN16(struct) Event
- {
- HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DYNAMICS, hkSpuCollisionCallbackUtil::Event );
- public:
- enum EventType
- {
- CONTACT_POINT_ADDED,
- CONTACT_POINT_PROCESS,
- CONTACT_POINT_REMOVED
- };
- public:
- /// Safely get the contact mgr, returns zero if the collision agent has been removed in the meantime
- hkpDynamicsContactMgr* getContactManager();
- /// Gets the next event in the list
- /// If there isn't an entry after this one, will return rubbish
- /// Use the getTerminator method to give you the first invalid entry
- Event* getNext() { return hkAddByteOffset(this, m_size); }
- hkUint16 m_size;
- hkEnum<EventType, hkUint16> m_type;
- hkpEntity* m_entityA;
- hkpEntity* m_entityB;
- hkpDynamicsContactMgr* m_contactMgr;
- };
- /// This callback event is fired whenever a new contact point is added.
- ///
- /// It stores the contact point information.
- struct ContactPointAddedEvent : public hkSpuCollisionCallbackUtil::Event
- {
- HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DYNAMICS, hkSpuCollisionCallbackUtil::ContactPointAddedEvent );
- hkpShapeKey m_shapeKeyA;
- hkpShapeKey m_shapeKeyB;
- hkContactPointId m_contactId;
- hkReal m_projectedVelocity;
- hkContactPoint m_contactPoint;
- };
- /// This callback event is fired for a colliding pair of entities during collision detection.
- ///
- /// It holds all existing contact points between the two entities. This array of contact points
- /// is dynamically expanded and the total number of contact points is stored separately.
- /// Note: if you want to add custom members to this event make sure to only add them BEFORE
- /// m_contactPoints or otherwise you risk them to be overwritten!
- struct ContactPointProcessEvent : public hkSpuCollisionCallbackUtil::Event
- {
- HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DYNAMICS, hkSpuCollisionCallbackUtil::ContactPointProcessEvent );
- struct ContactPoint: public hkContactPoint
- {
- HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_MATH, hkSpuCollisionCallbackUtil::ContactPointProcessEvent::ContactPoint );
- HK_FORCE_INLINE hkUint32 getContactPointId() { return m_position.getInt24W(); }
- };
- public:
- int m_numContactPoints;
- //
- // Add any additional custom members here...
- // Note: never append them after m_contactPoints!
- // Keep in mind that m_contactPoints is 16byte aligned!
- //
- // this array is dynamically allocated when creating the utility
- ContactPoint m_contactPoints[1];
- };
- /// This callback event is fired whenever an existing contact point is removed.
- ///
- /// It stores the contact point's id.
- struct ContactPointRemovedEvent : public hkSpuCollisionCallbackUtil::Event
- {
- HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DYNAMICS, hkSpuCollisionCallbackUtil::ContactPointRemovedEvent );
- hkContactPointId m_contactPointId;
- };
- /// This structure serves as a kind of interface to user-implemented callback functions.
- ///
- /// Create a dedicated object of this type (or derive an existing one from it) and implement
- /// the callback functions to your likings. Each function is passed its individual event
- /// structure holding all relevant data.
- struct Callbacks
- {
- public:
- virtual ~Callbacks() {}
- virtual void contactPointAddedCallbackFromSpu (ContactPointAddedEvent* event) {}
- virtual void contactPointProcessCallbackFromSpu(ContactPointProcessEvent* event) {}
- virtual void contactPointRemovedCallbackFromSpu(ContactPointRemovedEvent* event) {}
- };
- /// Use these flags to decide whether a call to fireCallbacks() should reset the event queue or not.
- ///
- /// Resetting the event queue will delete all existing events. So if you want to process these events a second time
- /// (e.g. first for some visualization, then for actual processing) you can call fireCallbacks() twice, once without
- /// resetting the queue, the second time with resetting the queue.
- /// Note: you should make sure to reset the queue once you are done with it or otherwise it will fill up pretty fast
- /// and no further events will be able to be forwarded from SPU to PPU
- enum ResetEventQueue
- {
- RESET_EVENT_QUEUE,
- DO_NOT_RESET_EVENT_QUEUE,
- };
- /// Empties out the list, resetting it
- void reset() { m_nextFreeEvent = m_events; }
- /// Get the first in the list
- Event* getFirst() { return m_events; }
- /// Get one past the end element in the list. An event pointer must be less then this to be valid
- Event* getTerminator();
- public:
- /// Call this function to create a new collision callback utility.
- ///
- /// The totalSizeOfUtil parameter specifies the total(!) size of the utility, not the event buffer size. The event
- /// buffer size is 16 bytes less.
- // This is done to have more control over the amount of memory that might be wasted when allocating a buffer size that
- // is exactly the same size as one pool memory page. In such a case the whole utility would be just 16 bytes too large
- // and would allocate one whole additional memory page just for 16 bytes.
- static hkSpuCollisionCallbackUtil* HK_CALL createSpuCollisionCallbackUtil(int totalSizeOfUtil);
- /// Call this function to fire your user-implemented event callback functions.
- ///
- /// See ResetEventQueue for some information on the resetFlag parameter.
- /// See Callbacks fr some information on the user-implemented callback functions.
- void fireCallbacks(hkpWorld* world, Callbacks* m_callbacks, ResetEventQueue resetFlag = RESET_EVENT_QUEUE);
- // internal functions
- static void contactPointAddedEvent (hkpEntity* entityA, hkpEntity* entityB, hkpContactPointAddedEvent& event);
- static void contactPointProcessEvent(hkpEntity* entityA, hkpEntity* entityB, hkpContactProcessEvent& event);
- static void contactPointRemovedEvent(hkpEntity* entityA, hkpEntity* entityB, hkpContactPointRemovedEvent& event);
- static hkBool shapeContainerIsCollisionEnabled(const hkpProcessCollisionInput* input, const hkpCdBody* bodyA, const hkpCdBody* bodyB, const HK_SHAPE_CONTAINER* shapeCollectionB, hkpShapeKey shapeKeyB);
- static hkBool shapeContainer2IsCollisionEnabled(const hkpProcessCollisionInput* input, const hkpCdBody* bodyA, const hkpCdBody* bodyB, const HK_SHAPE_CONTAINER* shapeCollectionA, const HK_SHAPE_CONTAINER* shapeCollectionB, hkpShapeKey shapeKeyA, hkpShapeKey shapeKeyB);
- static int numShapeKeyHitsLimitBrached( const hkpProcessCollisionInput* input,
- const hkpCdBody* bodyA, const hkpCdBody* bodyB,
- const hkpBvTreeShape* bvTreeShapeB, hkAabb& aabb,
- hkpShapeKey* shapeKeysInOut,
- int shapeKeysCapacity);
- protected:
- static void writeBackEvent(hkpEntity* entity, const Event& event);
- public:
- // sizeof(hkReferencedObject) : 8 bytes
- hkUint32 m_capacity; // number of 16byte blocks, i.e. actual size in bytes = m_capacity * 16
- void* m_nextFreeEvent;
- // this array is dynamically allocated when creating the utility
- Event m_events[1];
- };
- #endif // HK_SPU_COLLISION_CALLBACK_UTIL_H
- /*
- * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
- *
- * Confidential Information of Havok. (C) Copyright 1999-2009
- * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
- * Logo, and the Havok buzzsaw logo are trademarks of Havok. Title, ownership
- * rights, and intellectual property rights in the Havok software remain in
- * Havok and/or its suppliers.
- *
- * Use of this software for evaluation purposes is subject to and indicates
- * acceptance of the End User licence Agreement for this product. A copy of
- * the license is included with this software and is also available at www.havok.com/tryhavok.
- *
- */