hkpWorld.h
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:60k
- /*
- *
- * 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_DYNAMICS2_WORLD_H
- #define HK_DYNAMICS2_WORLD_H
- #include <Common/Base/hkBase.h>
- #include <Common/Base/Config/hkConfigVersion.h>
- #include <Common/Base/DebugUtil/MultiThreadCheck/hkMultiThreadCheck.h>
- #include <Common/Base/Types/Physics/hkStepInfo.h>
- #include <Physics/ConstraintSolver/Solve/hkpSolverInfo.h>
- #include <Physics/Dynamics/World/hkpWorldCinfo.h>
- class hkpCollisionFilter;
- class hkpConvexListFilter;
- class hkpCollisionDispatcher;
- class hkpCollidable;
- struct hkpCollisionInput;
- struct hkpProcessCollisionInput;
- class hkpCollisionListener;
- class hkpTypedBroadPhaseDispatcher;
- struct hkpWorldRayCastInput;
- struct hkpWorldRayCastOutput;
- struct hkpLinearCastInput;
- class hkpRayHitCollector;
- class hkpCdPointCollector;
- class hkpCdBodyPairCollector;
- class hkpBroadPhase;
- class hkpBroadPhaseHandle;
- class hkAabb;
- class hkpWorldObject;
- class hkpEntity;
- class hkpEntityListener;
- class hkpRigidBody;
- class hkpPhantom;
- class hkpPhantomListener;
- class hkpPhantomBroadPhaseListener;
- class hkpEntityEntityBroadPhaseListener;
- class hkpBroadPhaseBorderListener;
- class hkpAction;
- class hkpActionListener;
- class hkpConstraintInstance;
- class hkpConstraintData;
- class hkpConstraintListener;
- class hkpPhysicsSystem;
- class hkpSimulationIsland;
- class hkpContactMgrFactory;
- struct hkpMtThreadStructure;
- class hkpWorldPostSimulationListener;
- class hkpWorldPostIntegrateListener;
- class hkpWorldPostCollideListener;
- class hkpWorldDeletionListener;
- class hkpIslandActivationListener;
- class hkpContactImpulseLimitBreachedListener;
- class hkpIslandPostIntegrateListener;
- class hkpIslandPostCollideListener;
- class hkStepInfo;
- class hkWorldPairwiseBackstepFilter;
- class hkpSimulation;
- class hkpWorldOperationQueue;
- struct hkpDebugInfoOnPendingOperationQueues;
- class hkpWorldMaintenanceMgr;
- class hkWorldMemoryAvailableWatchDog;
- class hkpBodyOperation;
- class hkJobQueue;
- class hkJobThreadPool;
- class hkdWorld;
- namespace hkWorldOperation { struct BaseOperation; class UserCallback; }
- struct hkOperationParameter;
- #if defined HK_DEBUG
- //# define HK_ENABLE_EXTENSIVE_WORLD_CHECKING
- #endif
- extern "C" void HK_CALL hkAgentNnMachine_AssertTrackValidity( struct hkpAgentNnTrack& track );
- //#define CHECK_TRACK(track) hkAgentNnMachine_AssertTrackValidity(track)
- #define CHECK_TRACK(track)
- /// Allows you optimize the hkpWorld::updateCollisionFilterOnWorld call
- enum hkpUpdateCollisionFilterOnWorldMode
- {
- /// Full filter filter
- HK_UPDATE_FILTER_ON_WORLD_FULL_CHECK,
- /// Recheck filter but only check for disabled entity-entity collisions
- /// which have been enabled before
- HK_UPDATE_FILTER_ON_WORLD_DISABLE_ENTITY_ENTITY_COLLISIONS_ONLY,
- };
- /// Allows you to optimize you hkpWorld::updateCollisionFilterOnEntity call
- enum hkpUpdateCollisionFilterOnEntityMode
- {
- /// Do a full check
- HK_UPDATE_FILTER_ON_ENTITY_FULL_CHECK,
- /// Recheck filter but only check for disabled entity-entity collisions
- /// which have been enabled before
- HK_UPDATE_FILTER_ON_ENTITY_DISABLE_ENTITY_ENTITY_COLLISIONS_ONLY
- };
- /// Activation hints when calling hkpWorld::addEntity
- enum hkpEntityActivation
- {
- /// Tries to add the body in an inactive state. However if the body overlaps with an
- /// active body, it gets activated
- HK_ENTITY_ACTIVATION_DO_NOT_ACTIVATE,
- /// Always activate this body and overlapping bodies
- HK_ENTITY_ACTIVATION_DO_ACTIVATE
- };
- /// The hkUpdateCollectionFilter specifies whether you want to reevaluate
- /// all the sub-shape collisions with the world's shape collection filter. Typical example of this is
- /// destructible terrain. So if you just disabled the collision of a bullet and a car, you do not
- /// need to recheck existing landscape collisions and can set
- /// updateShapeCollectionFilter to HK_UPDATE_COLLECTION_FILTER_IGNORE_SHAPE_COLLECTIONS
- enum hkpUpdateCollectionFilterMode
- {
- /// Assume that no single shapes in a shape collections changed their filter status
- HK_UPDATE_COLLECTION_FILTER_IGNORE_SHAPE_COLLECTIONS,
- /// Recheck all subshapes in a shape collection
- HK_UPDATE_COLLECTION_FILTER_PROCESS_SHAPE_COLLECTIONS
- };
- /// A structure used by the hkpWorld that groups together solver and step time information.
- struct hkpWorldDynamicsStepInfo
- {
- HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DYNAMICS, hkpWorldDynamicsStepInfo );
- hkStepInfo m_stepInfo;
- hkpSolverInfo m_solverInfo;
- };
- /// This structure is currently only used for multi threaded simulations. It controls how the multi threading is run.
- struct hkpMultithreadConfig
- {
- HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DYNAMICS, hkpMultithreadConfig );
- hkpMultithreadConfig();
- /// This variable is used to control when the constraints of a simulation island are solved in
- /// single threaded or multithreaded mode. On PC and XBOX360 this value is 70, which means that
- /// an island must have more than 70 constraints to be solved in multithreaded mode. If it
- /// is set to 0 then the constraints of all simulation islands will be solved in multithreaded mode.
- /// The reason it is not set to 0 by default is because there is a small overhead in setting up
- /// multithreading constraints for a simulation island, which can be significant for small islands.
- /// On the PLAYSTATION(R)3 this variable defaults to 4. SPU constraint setup only happens if the island
- /// has more constraints than are specified by this variable.
- hkUint32 m_maxNumConstraintsSolvedSingleThreaded;
- };
- /// See hkpWorld::stepDeltaTime for details
- enum hkpStepResult
- {
- /// The call to stepDelta time was a processed to the end
- HK_STEP_RESULT_SUCCESS,
- /// The engine predicted that it would run out of memory before doing any work
- HK_STEP_RESULT_MEMORY_FAILURE_BEFORE_INTEGRATION,
- /// The collide call failed as some collision agents were allocated too much memory
- HK_STEP_RESULT_MEMORY_FAILURE_DURING_COLLIDE,
- /// The advanceTime call failed during TOI solving
- HK_STEP_RESULT_MEMORY_FAILURE_DURING_TOI_SOLVE,
- };
- /// The hkpWorld is a container for the simulation's physical objects. It also steps the simulation forward in time.
- /// You add elements (including rigid bodies, actions, constraints, and listeners) to the simulation by adding them to the hkpWorld.
- class hkpWorld : public hkReferencedObject
- {
- public:
- //+vtable(true)
- //+serializable(false)
- HK_DECLARE_CLASS_ALLOCATOR(HK_MEMORY_CLASS_WORLD);
- HK_DECLARE_REFLECTION();
- /// Creates a world with the given construction information
- hkpWorld(const hkpWorldCinfo& info, unsigned int sdkversion = HAVOK_SDK_VERSION_NUMBER );
- /// Get construction info for this instance.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- void getCinfo(hkpWorldCinfo& info) const;
- //
- // hkpWorld Operations:
- //
- // Adding/Removing Instances/BatchesOfInstances of Entities/Constraints/Actions/Phantoms
- //
- /// Adds the specified entity to the world and returns its pointer
- /// or returns HK_NULL if adding the body is delayed.
- /// Lets you specify the desired activation state.
- /// Usage info: Note that even if you add a body inactive, it may be immediately automatically activated
- /// by the engine due to overlaps with other bodies.
- /// Note: When using HK_ENTITY_ACTIVATION_DO_ACTIVATE parameter, the entity is added in the active state,
- /// however no activationCallbacks are called.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- hkpEntity* addEntity( hkpEntity* entity, hkpEntityActivation initialActivationState = HK_ENTITY_ACTIVATION_DO_ACTIVATE);
- /// Removes the specified entity from the world
- /// During a simulation step the removal of the entity is delayed until it is safe to do so.
- /// returns true if removed immediately false if delayed.
- hkBool removeEntity( hkpEntity* entity);
- /// Efficiently add a group of entities at the same time. Will not be as efficient when
- /// adding a small number of entities, in that case use addEntity.
- /// Lets you specify the desired activation state.
- /// Warning: When adding entities inactive: all entities are added in the same island,
- /// therefore any overlap with an active entity (already inserted into the world)
- /// causes activation of the whole island.
- /// Note: When using HK_ENTITY_ACTIVATION_DO_ACTIVATE parameter, the entity is added in the active state,
- /// however no activationCallbacks are called.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void addEntityBatch( hkpEntity*const* entityBatch, int numEntities, hkpEntityActivation initialActivationState = HK_ENTITY_ACTIVATION_DO_ACTIVATE);
- /// Efficiently remove a group of entities at the same time. Will not be as efficient when
- /// removing a small number of entities, in that case use removeEntity.
- void removeEntityBatch( hkpEntity*const* entityBatch, int numEntities );
- //
- // Constraint addition and removal
- //
- /// Adds the specified constraint to the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- hkpConstraintInstance* addConstraint( hkpConstraintInstance* constraint);
- /// Removes the specified constraint from the world
- /// returns true if removed immediately false if delayed
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- hkBool removeConstraint( hkpConstraintInstance* constraint);
- /// Utility function for creating and adding a specified constraint instance to the world
- hkpConstraintInstance* createAndAddConstraintInstance( hkpRigidBody* bodyA, hkpRigidBody* bodyB, hkpConstraintData* constraintData );
- //
- // Actions
- //
- /// Adds the specified action to the world. A reference to the action is added to every entity on the action's list
- /// of entities. All those entities must already by placed in an hkpWorld.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- hkpAction* addAction( hkpAction* action );
- /// Remove the specified action from the world and removes its reference from each entity that it was connected to.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removeAction( hkpAction* action );
- /// Remove the specified action from the world and removes its reference from each entity that it was connected to.
- /// It bypasses the operation delay framework, there fore you _MUST_BE_SURE_ that _IT_IS_SAFE_ to use it.
- /// Info: use this only in hkpAction::entityRemovedCallback
- /// Non-symmetric function. Only needed to be used explicitly when removing an entity causes removal of an action in a callback.
- /// addActionImmediately not needed.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removeActionImmediately( hkpAction* action );
- //
- // Phantoms
- //
- /// Add the phantom to the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- hkpPhantom* addPhantom( hkpPhantom* phantom );
- /// Add multiple phantoms to the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void addPhantomBatch( hkpPhantom*const* phantomBatch, int numPhantoms );
- /// Remove the phantom from the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removePhantom( hkpPhantom* phantom );
- /// Remove multiple phantoms from the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removePhantomBatch( hkpPhantom*const* phantomBatch, int numPhantoms );
- /// Activates all entities whose aabb overlaps with the specified region
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void activateRegion( const hkAabb& aabb );
- //
- // Systems (bodies, actions and phantoms all together). For instance
- // a vehicle or a ragdoll.
- /// Add a hkpPhysicsSystem to the world. The world does not
- /// store or reference the system struct itself, just
- /// uses the data held to batch add to the world.
- void addPhysicsSystem( const hkpPhysicsSystem* sys );
- /// Remove a hkpPhysicsSystem from the world.
- /// The world will just look through the lists in the given system
- /// and remove all found. It does not alter the system struct itself.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removePhysicsSystem( const hkpPhysicsSystem* sys );
- //
- // Fixed rigid body
- //
- /// Gets the world's fixed rigid body. This is a fixed body that can be used to constrain an object to
- /// a position in world space without needing to create an additional fixed object. The world's fixed
- /// body differs from 'normal' rigid bodies in a number of ways, including but not limited to the
- /// following:<br>
- /// It doesn't have a shape/collision representation and so it never collides with anything.<br>
- /// It doesn't have a broadphase entry and so it cannot go outside the broadphase, resulting in a
- /// potential performance hit as 'normal' rigid bodies can.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- inline hkpRigidBody* getFixedRigidBody();
- /// Gets read access to the world's fixed rigid body.
- /// See the non-const version of this function for more information.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- inline const hkpRigidBody* getFixedRigidBody() const;
- //
- // Collision filter update methods
- //
- /// This method should be called if you have altered the collision filtering information for this entity.
- /// Note: this does not activate the entity.
- /// The collisionFilterUpdateMode allows you to do an optimization: Only previously enabled entity entity collisions are
- /// checked. However entity-phantom or new entity-entity collision are ignored.
- /// The updateShapeCollectionFilter specifies whether you want to reevaluate
- /// all the sub-shape collisions with the world's shape collection filter. Typical example of this is
- /// destructible terrain. So if you just disabled the collision of a bullet and a car, you do not
- /// need to recheck existing landscape collisions and can set
- /// updateShapeCollectionFilter to HK_UPDATE_COLLECTION_FILTER_IGNORE_SHAPE_COLLECTIONS
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] [entity,HK_ACCESS_RW] );
- void updateCollisionFilterOnEntity( hkpEntity* entity,
- hkpUpdateCollisionFilterOnEntityMode updateMode,
- hkpUpdateCollectionFilterMode updateShapeCollectionFilter);
- /// This method should be called if you have altered the collision filtering information for this pair of entities
- void reenableCollisionBetweenEntityPair( hkpEntity* entityA, hkpEntity* entityB );
- /// This method should be called if you have altered the collision filtering information for this phantom. Read updateCollisionFilterOnEntity() for details
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] [phantom,HK_ACCESS_RW] );
- void updateCollisionFilterOnPhantom( hkpPhantom* phantom,
- hkpUpdateCollectionFilterMode updateShapeCollectionFilter );
- /// This method should be called if you have changed the collision filter for the world.
- ///
- /// WARNING: This method is very slow. It involves re-evaluating all the broadphase aabbs in the system.
- /// You should only ever call this at startup time.
- /// updateMode allows you to use a shortcut if you only want to disable previously enabled entity entity
- /// collisions.
- /// The updateShapeCollectionFilter specifies whether you want to reevaluate
- /// all the sub-shape collisions with the world's shape collection filter. Typical example of this is
- /// destructible terrain. So if you just disabled the collision of a bullet and a car, you do not
- /// need to recheck existing landscape collisions and can set
- /// updateShapeCollectionFilter to HK_UPDATE_COLLECTION_FILTER_IGNORE_SHAPE_COLLECTIONS
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void updateCollisionFilterOnWorld( hkpUpdateCollisionFilterOnWorldMode updateMode,
- hkpUpdateCollectionFilterMode updateShapeCollectionFilter );
- enum ReintegrationRecollideMode
- {
- RR_MODE_REINTEGRATE = 1, // only reintegrates the motion in the middle of a physics step
- RR_MODE_RECOLLIDE_BROADPHASE = 2, // only reapplies the broadphase
- RR_MODE_RECOLLIDE_NARROWPHASE = 4, // only reapplies the narrowphase
- RR_MODE_ALL = 7
- };
- /// Reintegrates bodies immediately.
- /// This function allows for calling parts of the physics pipeline selectively
- /// in single rigid bodies. This is especially useful when you
- /// think the normal pipeline isn't good enough.
- /// Examples:
- /// - When physics and frame rate run at different rates (especially when the physics
- /// is run at a much lower rate), setting velocity of a rigid body will have no effect
- /// till the next physics step. This can lead to very small
- /// delays between a player action and the expected reaction. With this function
- /// you can force the reintegration of a set of entities at the current frame time (mode = RR_MODE_ALL)
- /// - When you add an object to the world, it will pick up contact information only at the
- /// end of the next physics step, so there are no contacts for the next frame. Calling this
- /// function immediately after adding the object with mode = RR_MODE_RECOLLIDE_NARROWPHASE finds the initial set of contacts
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void reintegrateAndRecollideEntities( hkpEntity** entityBatch, int numEntities, ReintegrationRecollideMode mode = RR_MODE_ALL );
- //
- // Phantoms
- //
- /// Get a list of all the phantoms which have been added to the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- inline const hkArray<hkpPhantom*>& getPhantoms() const;
- //
- // Gravity
- //
- /// Sets the gravity value for the world. This does not wake up objects
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void setGravity( const hkVector4& gravity );
- /// Gets the world's gravity value.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- inline const hkVector4& getGravity() const;
- //
- // Simulation Control
- //
- /// This utility function may be called to initialize the contact points for a set of entities added to the world.
- /// By default contact points are evaluated conservatively, for simulation efficiency.
- /// However this can lead to a slight initial jitter when objects are added. The same applies for
- /// objects which have had their collision agents deleted upon deactivation when they reactivate. (See
- /// the helper class hkpSuspendInactiveAgentsUtil for details. ) This function helps to remove this jitter by
- /// trying to find all the initial relevant contact points for a set of entities.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void findInitialContactPoints( hkpEntity** entities, int numEntities );
- /// This simply calls initializeContactPoints for all objects in the world. It is a utility function
- /// which can be called after the world has been initialized and all objects added to it.
- void findInitialContactPointsOfAllEntities( );
- /// Gets the memory usage required to complete the next integration step
- /// This function is called internally to prevent the memory usage breaching the critical memory limit in
- /// hkMemory.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- int getMemUsageForIntegration();
- /// Calculate the memory statistics for the world, and all objects owned by the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- void calcContentStatistics( hkStatisticsCollector* collector, const hkClass* cls ) const;
- /// checks the current state of the engine using the hkCheckDeterminismUtil
- /// ###ACCESS_CHECKS###( [island->m_world,HK_ACCESS_RO] [island,HK_ACCESS_RW] );
- void checkDeterminism();
- /// Get the memory "watch dog" used by the world. By default this is HK_NULL, i.e. the memory
- /// for the world is not checked. If this is set, hkpWorldMemoryWatchDog::watchMemory will be
- /// called every step, which gives the hkpWorldMemoryWatchDog a chance to prevent the memory
- /// exceeding a desired threshold.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- hkWorldMemoryAvailableWatchDog* getMemoryWatchDog( ) const;
- /// Set the memory "watch dog" used by the world. By default this is HK_NULL, i.e. the memory
- /// for the world is not checked. If this is set, hkpWorldMemoryWatchDog::watchMemory will be
- /// called every step, which gives the hkpWorldMemoryWatchDog a chance to prevent the memory
- /// exceeding a desired threshold.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void setMemoryWatchDog( hkWorldMemoryAvailableWatchDog* watchDog );
- //
- // Multithreaded Access
- //
- /// Locks the world in a multithreaded environment.
- /// This can only be called outside any step function and should
- /// only be used for asynchronous queries like raycast, etc.
- /// lock() and unlock() acquire and release critical sections, so they are quite slow.
- /// For this reason it is best to lock the world and do many operations on the world when you have
- /// acquired the lock before unlocking it.
- /// If you use your own synchronization mechanisms you don't need to call our implementation of lock / unlock,
- /// but you must ensure multiple threads don't access the world simultaneously.
- /// When using your own synchronization mechanisms you should also call markForRead or markForWrite
- /// to let our debugging utilities know that the world has been locked appropriately.
- /// Read the multithreading user guide about details
- void lock();
- /// Locks the world as read-only in a multithreaded environment.
- /// Needed when executing collision query jobs.
- /// See also lock().
- void lockReadOnly();
- /// Unlocks the world. Opposite of lock()
- void unlock();
- /// Unlocks the world. Opposite of lockReadOnly()
- void unlockReadOnly();
- /// checks if the world is in an unmarked, unlocked state
- bool checkUnmarked();
- // Internal function: Locks all entities in this simulation island and in the fixed island for constraint updates
- void lockIslandForConstraintUpdate( hkpSimulationIsland* island );
- // Internal function: Locks all entities in this simluation island and in the fixed island for constraint updates
- void lockForIslandSplit( hkpSimulationIsland* island );
- // Internal function: opposite of lockIslandForConstraintUpdate
- void unlockIslandForConstraintUpdate( hkpSimulationIsland* island );
- // Internal function: opposite of lockForIslandSplit
- void unlockForIslandSplit( hkpSimulationIsland* island );
- //
- // Multithreaded Access checks
- //
- enum MtAccessChecking
- {
- MT_ACCESS_CHECKING_ENABLED = 0,
- MT_ACCESS_CHECKING_DISABLED
- };
- /// Enable or disable multithreaded access checking
- /// By default this is enabled if the world simulation type is SIMULATION_TYPE_MULTITHREADED
- /// and false is it is anything else.
- inline void setMultithreadedAccessChecking( MtAccessChecking accessCheckState );
- /// Get whether multithreaded access checking is enabled
- /// By default this is enabled if the world simulation type is SIMULATION_TYPE_MULTITHREADED
- /// and false is it is anything else.
- inline MtAccessChecking getMultithreadedAccessChecking() const;
- /// Mark this class and all child classes for read only access for this thread
- /// Note: This is only for debugging and does not wait to get exclusive access,
- /// but simply assert if another thread marked the hkpWorld. You must read the
- /// user guide about multithreading to use this.
- void markForRead( ) const;
- /// Mark this class and all child classes for read write access for this thread
- /// Note: This is only for debugging and does not wait to get exclusive access,
- /// but simply assert if another thread marked the hkpWorld. You must read the
- /// user guide about multithreading to use this.
- void markForWrite( );
- /// Undo lockForRead
- /// Note: This is only for debugging and does not wait to get exclusive access,
- /// but simply assert if another thread locked the hkpWorld. You must read the
- /// user guide about multithreading to use this.
- void unmarkForRead( ) const;
- /// Unlock For write
- /// Note: This is only for debugging and does not wait to get exclusive access,
- /// but simply assert if another thread locked the hkpWorld. You must read the
- /// user guide about multithreading to use this.
- void unmarkForWrite();
- //
- // Event Handling
- //
- /// Adds the specified listener to the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void addActionListener( hkpActionListener* worldListener );
- /// Removes the specified listener from the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removeActionListener( hkpActionListener* worldListener );
- /// Adds the specified listener to the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void addConstraintListener( hkpConstraintListener* worldListener );
- /// Removes the specified listener from the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removeConstraintListener( hkpConstraintListener* worldListener );
- /// Adds the specified listener to the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void addEntityListener( hkpEntityListener* worldListener );
- /// Removes the specified listener from the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removeEntityListener( hkpEntityListener* worldListener );
- /// Adds the specified listener to the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void addPhantomListener( hkpPhantomListener* worldListener );
- /// Removes the specified listener from the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removePhantomListener( hkpPhantomListener* worldListener );
- /// Adds a listener which listens to ALL entity activations.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void addIslandActivationListener( hkpIslandActivationListener* worldListener );
- /// Removes the specified listener from the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removeIslandActivationListener( hkpIslandActivationListener* worldListener );
- /// Adds the specified listener to the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void addWorldPostCollideListener( hkpWorldPostCollideListener* worldListener );
- /// Removes the specified listener from the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removeWorldPostCollideListener( hkpWorldPostCollideListener* worldListener );
- /// Adds the specified listener to the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void addWorldPostSimulationListener( hkpWorldPostSimulationListener* worldListener );
- /// Removes the specified listener from the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removeWorldPostSimulationListener( hkpWorldPostSimulationListener* worldListener );
- /// Adds the specified listener to the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void addWorldPostIntegrateListener( hkpWorldPostIntegrateListener* worldListener );
- /// Removes the specified listener from the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removeWorldPostIntegrateListener( hkpWorldPostIntegrateListener* worldListener );
- /// Adds the specified listener to the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void addIslandPostCollideListener( hkpIslandPostCollideListener* islandListener );
- /// Removes the specified listener from the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removeIslandPostCollideListener( hkpIslandPostCollideListener* islandListener );
- /// Adds the specified listener to the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void addIslandPostIntegrateListener( hkpIslandPostIntegrateListener* islandListener );
- /// Removes the specified listener from the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removeIslandPostIntegrateListener( hkpIslandPostIntegrateListener* islandListener );
- /// Adds a listener which listens to ALL collisions.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void addCollisionListener( hkpCollisionListener* worldListener );
- /// Removes a world collision listener.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removeCollisionListener( hkpCollisionListener* worldListener);
- /// Add a listener which receives events when the world is deleted
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void addWorldDeletionListener( hkpWorldDeletionListener* worldListener );
- /// Remove a listener which receives events when the world is deleted
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removeWorldDeletionListener( hkpWorldDeletionListener* worldListener );
- /// Add a listener which receives events when contact impulses breach their limit
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void addContactImpulseLimitBreachedListener( hkpContactImpulseLimitBreachedListener* listener );
- /// Remove a listener which receives events when contact impulses breach their limit
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removeContactImpulseLimitBreachedListener( hkpContactImpulseLimitBreachedListener* listener );
- //
- // Collision detection
- //
- /// Gets write access the broadphase owned by the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- inline hkpBroadPhase* getBroadPhase();
- /// Gets read only access to the broadphase owned by the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- inline const hkpBroadPhase* getBroadPhase() const;
- /// Get read access to the collision input. This is needed to manually query collision agents.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- inline const hkpProcessCollisionInput* getCollisionInput() const;
- /// Get read/write access to the collision input. You should only need this function if you really intent to modify its values persistently, otherwise make a local modifier copy.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- inline hkpProcessCollisionInput* getCollisionInputRw();
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- inline hkpSolverInfo* getSolverInfo();
- /// Gets the collision dispatcher owned by the world.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- inline hkpCollisionDispatcher* getCollisionDispatcher() const;
- /// Gets the collision filter.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- inline const hkpCollisionFilter* getCollisionFilter() const;
- /// Set the collision filter. This is used by the world by default when it calls the collision detector.
- /// WARNING: This should only be done before any objects are added to this world.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void setCollisionFilter( hkpCollisionFilter* filter,
- hkBool runUpdateCollisionFilterOnWorld = true,
- hkpUpdateCollisionFilterOnWorldMode checkBroadPhaseMode = HK_UPDATE_FILTER_ON_WORLD_FULL_CHECK,
- hkpUpdateCollectionFilterMode updateShapeCollectionFilter = HK_UPDATE_COLLECTION_FILTER_PROCESS_SHAPE_COLLECTIONS );
- /// Cast a ray into the world and get the closest hit.
- /// Note: it uses the hkpWorld::getCollisionFilter() for filtering
- /// This function uses a ray-cast function for traversing the broadphase, so for
- /// long raycasts it is more applicable than hkpAabbPhantom::castRay
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- void castRay(const hkpWorldRayCastInput& input, hkpWorldRayCastOutput& output ) const;
- /// Cast a ray into the world and do a callback for every hit.
- /// Note: it uses the hkpWorld::getCollisionFilter() for filtering
- /// This function uses a ray-cast function for traversing the broadphase, so for
- /// long raycasts it is more applicable than hkpAabbPhantom::castRay
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- void castRay(const hkpWorldRayCastInput& input, hkpRayHitCollector& collector ) const;
- /// Cast a shape within the world.
- /// The castCollector collects all potential hits.<br>
- /// Note that the distance stored within the castCollector is a hitFraction (between 0 and 1.0) and
- /// not a distance.<br>
- /// This function uses an aabb-cast function for traversing the broadphase, so for
- /// long linear casts it will perform better than hkpShapePhantom::linearCast().
- /// The [optional] startPointCollector returns all the closest points
- /// at the start point of the linear cast. If you do not want this functionality, pass HK_NULL as the
- /// "startCollector".
- /// If you want to use this function using an hkpBroadPhaseAabbCache simply use the underlying hkpWorldLinearCaster
- /// (see implementation of hkpWorld::linearCast for details)
- /// Note that shape radius is considered - you may want to set the radius of the cast shape to zero.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- void linearCast( const hkpCollidable* collA, const hkpLinearCastInput& input, hkpCdPointCollector& castCollector, hkpCdPointCollector* startCollector = HK_NULL ) const;
- /// Get the closest points to a hkpCollidable (= [shape,transform,filterInfo] ).
- /// Note: If you have to call this function every step for a given object, use the hkpShapePhantom::getClosestPoints()
- /// By default, you should pass a pointer to world->getCollisionInput() via hkpCollisionInput* input. However you
- /// can use this parameter to pass in your own collision input
- /// structure, and change the shape collection collision filter, and the collision tolerance used.
- /// (Note: If using your own collision input, make sure you start by copying the world collision input, so that
- /// you use the default hkpCollisionDispatcher).
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- void getClosestPoints( const hkpCollidable* collA, const hkpCollisionInput& input, hkpCdPointCollector& collector) const;
- /// Get all shapes which are penetrating the collidable.
- /// Note: If you have to call this function every step for a given object, use the hkpShapePhantom version
- /// By default, you should pass a pointer to world->getCollisionInput() via hkpCollisionInput* input. However you
- /// can use this parameter to pass in your own collision input
- /// structure, and change the shape collection collision filter, and the collision tolerance used.
- /// (Note: If using your own collision input, make sure you start by copying the world collision input, so that
- /// you use the default hkpCollisionDispatcher).
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- void getPenetrations( const hkpCollidable* collA, const hkpCollisionInput& input, hkpCdBodyPairCollector& collector) const;
- /// Gets the current broadphase border, could be null.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- class hkpBroadPhaseBorder* getBroadPhaseBorder() const;
- /// Sets a custom broadphase border.
- /// By default the hkpWorld constructor checks the
- /// hkpWorldCinfo.m_broadPhaseBorderBehaviour field and will create a default
- /// broadphase border if needed. Real hkpWorldCinfo.m_broadPhaseBorderBehaviour for details
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void setBroadPhaseBorder( hkpBroadPhaseBorder* bpb );
- /// See hkpBroadPhase::shiftBroadPhase() for details.
- enum CachedAabbUpdate
- {
- SHIFT_BROADPHASE_UPDATE_ENTITY_AABBS,
- SHIFT_BROADPHASE_IGNORE_ENTITY_AABBS
- };
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void shiftBroadPhase( const hkVector4& shiftDistance, hkVector4& effectiveShiftDistanceOut, CachedAabbUpdate updateAabbs );
- //
- // Simulation Island access
- //
- /// Get the active simulation islands. You can use this function to access all the active entities, constraints and actions.
- /// NOTE: This should not be used during simulation, as it will generally result in sub-optimal performance.
- inline const hkArray<hkpSimulationIsland*>& getActiveSimulationIslands() const;
- /// Get the inactive simulation islands. You can use this function to access all the inactive entities, constraints and actions.
- /// NOTE: This should not be used during simulation, as it will generally result in sub-optimal performance.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- inline const hkArray<hkpSimulationIsland*>& getInactiveSimulationIslands() const;
- /// Get the fixed simulation island. You can use this function to access all the fixed entities.
- /// There is only one fixed island, and it contains no actions or constraints.
- /// NOTE: This should not be used during simulation, as it will generally result in sub-optimal performance.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- inline const hkpSimulationIsland* getFixedIsland() const;
- //
- // Stepping the world (Single threaded)
- //
- /// Advances the state of the simulation by the amount of time.
- /// This is a single threaded call.
- /// The interface to multi-threading simulation is below.
- hkpStepResult stepDeltaTime( hkReal physicsDeltaTime );
- //
- // "Half" stepping (Single threaded only)
- //
- /// Integrate and solve constraints between all bodies.
- /// Using this call instead of stepDeltaTime() allows you to distribute your
- /// physics computation for a single physics step between multiple game steps.
- /// Normally this returns HK_STEP_RESULT_SUCCES, but may return a failure code on memory failure.
- /// In this case memory should be freed (by removing objects from the world) and the function should be called again.
- /// Please consult the user guide for more details.
- hkpStepResult integrate( hkReal physicsDeltaTime );
- /// Perform collision detection.
- /// Using this call instead of stepDeltaTime() allows you to distribute your
- /// physics computation for a single physics step between multiple game steps.
- /// Normally this returns HK_STEP_RESULT_SUCCES, but may return a failure code on memory failure.
- /// In this case memory should be freed (by removing objects from the world) and the function should be called again.
- /// Please consult the user guide for more details.
- hkpStepResult collide();
- /// Advance the current time of the world.
- /// For discrete simulation, this simply advances the current time value,
- /// For continuous simulations, this will also perform the continuous physics calculations.
- /// Using this call instead of stepDeltaTime() allows you to distribute your
- /// physics computation for a single physics step between multiple game steps.
- /// This call is also used for asynchronous simulation:
- /// It will advance the time to the next PSI step, unless
- /// an earlier frame timer marker has been set (see setFrameTimeMarker).
- /// Normally this returns HK_STEP_RESULT_SUCCES, but may return a failure code on memory failure.
- /// In this case memory should be freed (by removing objects from the world) and the function should be called again.
- /// Please consult the user guide for more details.
- hkpStepResult advanceTime();
- //
- // Asynchronous Stepping
- //
- /// This call can be used to step the world asynchronously. If you set a marker, then
- /// when advanceTime is called, it will advance either to this marker, or the current
- /// psi time, which ever is earlier. This is illustrated by
- /// hkAsynchronousTimestepper::stepAsynchronously. It can also be used in conjunction with
- /// multithreading simulation.
- /// Once you start using setFrameTimeMarker, you must continue to use it for all subsequent
- /// stepping.
- /// Please consult the user guide for more details.
- void setFrameTimeMarker( hkReal frameDeltaTime );
- /// This call can be used to step the world asynchronously. It returns true if the simulation
- /// time is equal to the frame marker time. If the frameTimeMarker has not been set this returns
- /// false.
- /// Please consult the user guide for more details.
- bool isSimulationAtMarker() const;
- /// This call returns true if the simulation current time is equal to the simulation currentPsiTime.
- /// It can be used as a debug check when stepping the world asynchronously.
- /// Please consult the user guide for more details.
- bool isSimulationAtPsi() const;
- //
- // Multithreaded stepping
- //
- /// You must call this function prior to multi-threaded stepping. It registers internal
- /// functions to deal with physics jobs that will be placed on the job queue.
- static void HK_CALL registerWithJobQueue( hkJobQueue* jobQueue );
- /// Step the world multithreaded. You must pass in a jobQueue, and a threadPool. This
- /// will utilize the threads of the thread pool for all multi-threading parts of the
- /// step.
- void stepMultithreaded( hkJobQueue* jobQueue, hkJobThreadPool* threadPool, hkReal physicsDeltaTime );
- /// This function is called internally by stepMultiThreaded() and may be used instead, to
- /// get finer control over multithreading.
- /// It places the initial jobs on the job queue.
- /// This function leaves the world in a markForRead() state, for stepProcesMt(). This state is
- /// reset in finishMtStep().
- void initMtStep( hkJobQueue* jobQueue, hkReal physicsDeltaTime );
-
- /// This function is called internally by stepMultiThreaded() and may be used instead, to
- /// get finer control over multithreading.
- /// This function performs continuous simulation, and performs any single threaded cleanup necessary.
- /// The parameters allow you to control whether collision detection is performed in parallel during continuous simulation.
- /// If you pass in a jobQueue, and a threadPool, they will be used for this.
- /// Leaving these values at their defaults will mean all continuous simulation is performed single threaded.
- /// Only one thread must call this function. It must be
- /// called when all threads have returned from calling stepProcessMt.
- void finishMtStep( hkJobQueue* jobQueue = HK_NULL, hkJobThreadPool* threadPool = HK_NULL );
- //
- // Time accessors
- //
- /// This returns current time of the simulation. Use it to calculate current transforms of rigid bodies
- /// in between PSI steps (with hkpRigidBody::approxTransformAt). Note that this is not absolute time; its value is reset every 30 seconds or so.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- hkTime getCurrentTime() const;
- /// This returns the current "PSI" time of the simulation. The PSI time is always the same or greater than
- /// the current time. See the user guide for details.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- hkTime getCurrentPsiTime() const;
- //
- // Multithreaded simulation details accessors
- //
- /// This function is only valid for multithreading simulation. It allows you to access
- /// some settings used for PLAYSTATION(R)3 multithreading simulation.
- void getMultithreadConfig( hkpMultithreadConfig& config );
- /// This function is only valid for multithreading simulation. It allows you to control
- /// some settings used for PLAYSTATION(R)3 multithreading simulation.
- void setMultithreadConfig( const hkpMultithreadConfig& config, hkJobQueue* queue );
- hkMultiThreadCheck& getMultiThreadCheck() const { return m_multiThreadCheck; }
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- void checkAccessGetActiveSimulationIslands() const;
- //
- // Serialization Utilities
- //
- /// Get a hkpPhysicsSystem that represents the whole system
- /// contained in this world. This can be used as a serialization utility
- /// for taking a snapshot of the world.
- /// Release the physics system when you are finished using it.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- hkpPhysicsSystem* getWorldAsOneSystem() const;
- /// Get an array of hkpPhysicsSystem(s) that represents the whole system
- /// contained in this world. This can be used as a serialization utility
- /// for taking a snapshot of the world.
- /// Release the physics systems when you are finished using it.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- void getWorldAsSystems(hkArray<hkpPhysicsSystem*>& systemsOut) const;
- /*
- ** Protected Functions
- */
- // you should use removeReference() instead, however we allow you to force destroy the world
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- ~hkpWorld();
- /// Removes all entities, actions and phantoms from the world
- ///
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void removeAll();
- /*
- ** protected members: They are public so that people can get full control over the engine
- ** if they know what they are doing!!!
- */
- //
- // Extra action management
- //
- // Attaches an action to an entity -- this should be called for every entity being
- // attached to the action, when the action is already added to the world
- // Note: this does not manage the action's entity list.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void attachActionToEntity(hkpAction* action, hkpEntity* entity);
- // Detaches an action from an entity -- this should be called for every entity being
- // detached from the action, when the action is already added to the world.
- // Note: this does not manage the action's entity list.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void detachActionFromEntity(hkpAction* action, hkpEntity* entity);
- //
- // Locking and delaying of operations
- //
- public:
- // Locks the world, i.e. prevents all critical operations (like adding/removing entities or constraints) from being
- // executed immediately. The operations are put on an hkWorldOperationsQueue and should be executed at the earliest
- // safe time. See hkpWorldOperationQueue for the list of 'critical' operations which may be postponed by the system.
- // Subsequent lockCriticalOperations() calls accumulate.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- HK_FORCE_INLINE void lockCriticalOperations();
- // Allows critical operations to be executed immediately after unlockCriticalOperations() has been called or every corresponding lockCriticalOperations().
- // It is advised to call attemptToExecutePendingOperations right after unlockCriticalOperations() to keep the order of operations
- // the same as the order in which they were called.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- HK_FORCE_INLINE void unlockCriticalOperations();
- // Returns number of locks put on the hkpWorld. Critical operation will be postponed if areCriticalOperationsLocked() > 0
- // We assume that this function is called at a beginning of a critical operation.
- // So this function asserts if critical operations are not allowed at all
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- HK_FORCE_INLINE int areCriticalOperationsLocked() const;
- // like areCriticalOperationsLocked without the extra check
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- HK_FORCE_INLINE int areCriticalOperationsLockedUnchecked() const;
- // Concept: Locking of Phantoms is an add-on work-around.
- // It lets you execute phantom-related critical functions even when hkpWorld::areCriticalOperationsLocked() is called.
- // Note that recursive phantom operations will not be executed, and will be postponed just like other operations are.
- // Decreases lock count for phantom operations. The operations must query hkpWorld::areCriticalOperationsLockedForPhantoms()
- // instead of hkpWorld::areCriticalOperationsLocked().
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- HK_FORCE_INLINE void unlockCriticalOperationsForPhantoms();
- // Increases lock count for phantom operations..
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- HK_FORCE_INLINE void lockCriticalOperationsForPhantoms();
- // Queries lock count for phantom operations. hkpWorld::m_criticalOperationsLockCountForPhantoms is an offset value added to the primary hkpWorld::m_criticalOperationsLockCount.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RO] );
- HK_FORCE_INLINE int areCriticalOperationsLockedForPhantoms() const;
- // Concept: explained in hkpWorld.cpp. Search for: "concept: blocking of execution of pending operations"
- // Blocks or unblocks attempts of execution of pending operations.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- HK_FORCE_INLINE void blockExecutingPendingOperations(hkBool block);
- // See: hkpWorld::unlock + hkpWorld::attemptToExecutePendingOperations
- HK_FORCE_INLINE void unlockAndAttemptToExecutePendingOperations();
- // If the world is locked or execution of pending operations is blocked, then it does nothing.
- // Otherwise it processes the list of pending operations.
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- HK_FORCE_INLINE void attemptToExecutePendingOperations( bool executeBodyOperations = true);
- // Appends information about an operation request onto the world's hkpWorldOperationQueue.
- void queueOperation(const hkWorldOperation::BaseOperation& operation);
- // Queues an user callback onto operation queue.
- // If the world is not locked, the callback is executed immediately.
- hkWorldOperation::UserCallback* queueCallback(hkWorldOperation::UserCallback* callback, hkUlong userData = 0);
- void addBodyOperation( hkpRigidBody* breakingBody, hkpBodyOperation* operation, int priority, /*hkpBodyOperation::ExecutionState*/int hint );
- // This invalidates the tree containing the object.
- void markKdTreeDirty();
- /// Rebuilds to the world's kd tree
- /// If m_autoUpdateKdTree is set to true, this is called at the end of the world step.
- /// Otherwise it should be called manually.
- void updateKdTree( hkJobQueue* jobQueue = HK_NULL, hkJobThreadPool* jobThreadPool = HK_NULL );
- private:
- // Passes execution call to hkpWorldOperationQueue::attemptToExecuteAllPending()
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void internal_executePendingOperations();
- // Passes execution call to hkpWorldOperationQueue::executeAllPendingBodyOperations()
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- void internal_executePendingBodyOperations();
- public:
- // Debugging utility: see hkpWorld.cpp. Search for: "concept: allowing critical operations"
- /// ###ACCESS_CHECKS###( [this,HK_ACCESS_RW] );
- HK_FORCE_INLINE void allowCriticalOperations(hkBool allow);
- /// Finish constructor
- explicit hkpWorld( hkFinishLoadedObjectFlag flag );
- # ifdef HK_ENABLE_DETERMINISM_CHECKS
- static void HK_CALL checkDeterminismInAgentNnTracks(const class hkpWorld* world);
- static void HK_CALL checkDeterminismInAgentNnTracks(const class hkpSimulationIsland* island);
- # endif
- public:
- // A class controlling the simulation
- hkpSimulation* m_simulation;
- hkVector4 m_gravity;
- hkpSimulationIsland* m_fixedIsland; // +nosave
- hkpRigidBody* m_fixedRigidBody;
- hkArray<hkpSimulationIsland*> m_activeSimulationIslands; // +nosave
- hkArray<hkpSimulationIsland*> m_inactiveSimulationIslands; // +nosave
- // Dirty islands are scheduled for cleanup, performed by hkpWorldOperationUtil::cleanupDirtyIslands( )
- hkArray<hkpSimulationIsland*> m_dirtySimulationIslands; // +nosave
- hkpWorldMaintenanceMgr* m_maintenanceMgr; // +nosave
- hkWorldMemoryAvailableWatchDog* m_memoryWatchDog; // +nosave
- hkpBroadPhase* m_broadPhase; // +nosave
- class hkpKdTreeWorldManager* m_kdTreeManager; //+nosave
-
- /// Enables/disables automatic updating of the world's kd-tree after the world step.
- /// See comments in hkpWorldCinfo.h
- hkBool m_autoUpdateKdTree;
- // Broadphase handler - this is a class which links the broadphase to the simulation
- hkpTypedBroadPhaseDispatcher* m_broadPhaseDispatcher; // +nosave
- hkpPhantomBroadPhaseListener* m_phantomBroadPhaseListener; // +nosave
- hkpEntityEntityBroadPhaseListener* m_entityEntityBroadPhaseListener; // +nosave
- hkpBroadPhaseBorderListener* m_broadPhaseBorderListener; // +nosave
- hkpMtThreadStructure* m_multithreadedSimulationJobData; // +nosave
- hkpProcessCollisionInput* m_collisionInput; // +nosave
- hkpCollisionFilter* m_collisionFilter; // +nosave
- hkpCollisionDispatcher* m_collisionDispatcher; // +nosave
- hkpConvexListFilter* m_convexListFilter; // +nosave
- /// For delayed operations. Operations get delayed if they cannot be performed as the world is hkpWorld::locked()
- hkpWorldOperationQueue* m_pendingOperations; // +nosave
- int m_pendingOperationsCount;
- int m_pendingBodyOperationsCount; // +nosave
- int m_criticalOperationsLockCount;
- // It just holds a value offset which should be added to m_criticalOperationsLockCount when querying areCriticalOperationsLockedForPhantoms().
- int m_criticalOperationsLockCountForPhantoms;
- hkBool m_blockExecutingPendingOperations;
- hkBool m_criticalOperationsAllowed;
- // This points to structures used to debug operation postponing. Not used in release build.
- hkpDebugInfoOnPendingOperationQueues* m_pendingOperationQueues; // +nosave
- // Holds the number of pending queues (equal to the number of recursive calls to executeAllPendingOperations).
- int m_pendingOperationQueueCount;
- /// The thread index of the locking thread
- mutable class hkMultiThreadCheck m_multiThreadCheck; // +nosave
- /// Internal. Forces actions to be processed in a single thread.
- hkBool m_processActionsInSingleThread;
- // This allows to keep the islands size reasonable large. See hkpWorldCinfo::m_minDesiredIslandSize for details
- hkUint32 m_minDesiredIslandSize;
- // set if running a mt simulation
- // whenever a constraint is added, this critical section is used
- class hkCriticalSection* m_modifyConstraintCriticalSection; // +nosave
- int m_isLocked; // debugging only: to avoid deleting the world in a locked state
- // a critical section which may guard the island dirty list
- class hkCriticalSection* m_islandDirtyListCriticalSection; // +nosave
- class hkCriticalSection* m_propertyMasterLock; // +nosave
- hkBool m_wantSimulationIslands;
- // Welding parameters (just stored here for getCinfo())
- hkReal m_snapCollisionToConvexEdgeThreshold;
- hkReal m_snapCollisionToConcaveEdgeThreshold;
- hkBool m_enableToiWeldRejection;
- // Deactivation parameters
- hkBool m_wantDeactivation;
- hkBool m_shouldActivateOnRigidBodyTransformChange;
- // see hkpWorldCinfo::m_deactivationReferenceDistance
- hkReal m_deactivationReferenceDistance;
- hkReal m_toiCollisionResponseRotateNormal;
- int m_maxSectorsPerCollideTask;
- int m_maxEntriesPerToiCollideTask;
- hkEnum<hkpWorldCinfo::SimulationType,hkInt32> m_simulationType; //+nosave
- hkReal m_numToisTillAllowedPenetrationSimplifiedToi;
- hkReal m_numToisTillAllowedPenetrationToi;
- hkReal m_numToisTillAllowedPenetrationToiHigher;
- hkReal m_numToisTillAllowedPenetrationToiForced;
- // debug only and used by the havok demo framework
- static hkBool m_forceMultithreadedSimulation;
- // This helper class can be used by a demo's constructor to ignore m_forceMultithreadedSimulation. This is useful e.g. for demos
- // that won't work properly in forced-multithreaded mode. Creating a local instance at the constructor's beginning will backup
- // the original value, override it with 'false' and restore the original value when leaving the demo's constructor.
- // Make sure to 'delete' this instance before leaving the demo's constructor if you explicitly 'new' it!
- class IgnoreForceMultithreadedSimulation
- {
- public:
- HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DYNAMICS, hkpWorld::IgnoreForceMultithreadedSimulation );
- IgnoreForceMultithreadedSimulation() { m_originalForceMultithreadedSimulationValue = hkpWorld::m_forceMultithreadedSimulation; hkpWorld::m_forceMultithreadedSimulation = false; }
- ~IgnoreForceMultithreadedSimulation() { hkpWorld::m_forceMultithreadedSimulation = m_originalForceMultithreadedSimulationValue; }
- public:
- hkBool m_originalForceMultithreadedSimulationValue;
- };
- protected:
- // World-unique ids are assigned to entities. They're used to sort constraints deterministically when using hkMultithreadedSimulation.
- hkUint32 m_lastEntityUid;
- public:
- friend class hkpWorldOperationUtil;
- friend class hkpWorldCallbackUtil;
- friend class hkpSimulation;
- friend class hkHalfstepSimulation;
- friend class hkpContinuousSimulation;
- friend class hkpMultiThreadedSimulation;
- friend class hkpSimpleConstraintContactMgr;
- hkArray<hkpPhantom*> m_phantoms;
- hkArray<hkpActionListener*> m_actionListeners; // +nosave
- hkArray<hkpEntityListener*> m_entityListeners; // +nosave
- hkArray<hkpPhantomListener*> m_phantomListeners; // +nosave
- hkArray<hkpConstraintListener*> m_constraintListeners; // +nosave
- hkArray<hkpWorldDeletionListener*> m_worldDeletionListeners; // +nosave
- hkArray<hkpIslandActivationListener*> m_islandActivationListeners; // +nosave
- hkArray<hkpWorldPostSimulationListener*> m_worldPostSimulationListeners; // +nosave
- hkArray<hkpWorldPostIntegrateListener*> m_worldPostIntegrateListeners; // +nosave
- hkArray<hkpWorldPostCollideListener*> m_worldPostCollideListeners; // +nosave
- hkArray<hkpIslandPostIntegrateListener*> m_islandPostIntegrateListeners; // +nosave
- hkArray<hkpIslandPostCollideListener*> m_islandPostCollideListeners; // +nosave
- hkArray<hkpCollisionListener*> m_collisionListeners; // +nosave
- hkArray<hkpContactImpulseLimitBreachedListener*> m_contactImpulseLimitBreachedListeners; //+nosave
- class hkpBroadPhaseBorder* m_broadPhaseBorder; // +nosave
- class hkdWorld* m_destructionWorld; // +nosave
- public:
- //
- // These members are for internal use only
- //
- struct hkpWorldDynamicsStepInfo m_dynamicsStepInfo; //+reflected(false)
- // Min and Max extents of broadphase
- // Needed for when construction info is retrieved
- hkVector4 m_broadPhaseExtents[2];
- int m_broadPhaseNumMarkers;
- int m_sizeOfToiEventQueue;
- hkInt32 m_broadPhaseQuerySize;
- hkInt32 m_broadPhaseUpdateSize;
- hkEnum<hkpWorldCinfo::ContactPointGeneration, hkInt8> m_contactPointGeneration; // +nosave
- };
- #include <Physics/Dynamics/World/hkpWorld.inl>
- #endif // HK_DYNAMICS2_WORLD_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.
- *
- */