237 lines
8.1 KiB
C++
237 lines
8.1 KiB
C++
//
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions
|
|
// are met:
|
|
// * Redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer.
|
|
// * Redistributions in binary form must reproduce the above copyright
|
|
// notice, this list of conditions and the following disclaimer in the
|
|
// documentation and/or other materials provided with the distribution.
|
|
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
|
// contributors may be used to endorse or promote products derived
|
|
// from this software without specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
|
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
//
|
|
// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved.
|
|
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
|
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
|
|
|
#ifndef PX_PHYSICS_SCB_AGGREGATE
|
|
#define PX_PHYSICS_SCB_AGGREGATE
|
|
|
|
#include "common/PxSerialFramework.h"
|
|
#include "PxAggregate.h"
|
|
#include "CmPhysXCommon.h"
|
|
#include "ScbActor.h"
|
|
#include "ScbAggregate.h"
|
|
#include "ScbBase.h"
|
|
|
|
|
|
namespace physx
|
|
{
|
|
namespace Scb
|
|
{
|
|
|
|
class Actor;
|
|
|
|
struct AggregateBuffer
|
|
{
|
|
AggregateBuffer() : addBufferIdx(0xffffffff), addCount(0), removeBufferIdx(0xffffffff), removeCount(0) {}
|
|
|
|
PxU32 addBufferIdx;
|
|
PxU32 addCount;
|
|
PxU32 removeBufferIdx;
|
|
PxU32 removeCount;
|
|
};
|
|
|
|
class Aggregate : public Base
|
|
{
|
|
//= ATTENTION! =====================================================================================
|
|
// Changing the data layout of this class breaks the binary serialization format. See comments for
|
|
// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
|
|
// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
|
|
// accordingly.
|
|
//==================================================================================================
|
|
private:
|
|
enum BufferFlag
|
|
{
|
|
BF_ADD_ACTOR = (1 << 0),
|
|
BF_REMOVE_ACTOR = (1 << 1)
|
|
};
|
|
|
|
public:
|
|
|
|
// PX_SERIALIZATION
|
|
Aggregate(const PxEMPTY) : Base(PxEmpty) {}
|
|
static void getBinaryMetaData(PxOutputStream& stream);
|
|
//~PX_SERIALIZATION
|
|
PX_INLINE Aggregate(PxAggregate* px, PxU32 maxActors, bool selfCollision);
|
|
PX_INLINE ~Aggregate();
|
|
|
|
void addActor(Scb::Actor&);
|
|
void removeActor(Scb::Actor& actor, bool reinsert);
|
|
|
|
//---------------------------------------------------------------------------------
|
|
// Data synchronization
|
|
//---------------------------------------------------------------------------------
|
|
PX_INLINE void syncState(Scb::Scene& scene);
|
|
|
|
//---------------------------------------------------------------------------------
|
|
// Miscellaneous
|
|
//---------------------------------------------------------------------------------
|
|
PX_FORCE_INLINE PxU32 getMaxActorCount() const { return mMaxNbActors; }
|
|
PX_FORCE_INLINE bool getSelfCollide() const { return mSelfCollide; }
|
|
PX_FORCE_INLINE PxU32 getAggregateID() const { return mAggregateID; }
|
|
PX_FORCE_INLINE void setAggregateID(PxU32 cid) { mAggregateID = cid; }
|
|
|
|
PX_FORCE_INLINE bool isBufferingSpecial(ControlState::Enum state) const;
|
|
|
|
PxAggregate* mPxAggregate; // Back pointer
|
|
private:
|
|
PxU32 mAggregateID;
|
|
PxU32 mMaxNbActors;
|
|
bool mSelfCollide;
|
|
|
|
PX_FORCE_INLINE const Scb::AggregateBuffer* getBufferedData() const { return reinterpret_cast<const Scb::AggregateBuffer*>(getStream()); }
|
|
PX_FORCE_INLINE Scb::AggregateBuffer* getBufferedData() { return reinterpret_cast<Scb::AggregateBuffer*>(getStream()); }
|
|
};
|
|
|
|
PX_INLINE Aggregate::Aggregate(PxAggregate* px, PxU32 maxActors, bool selfCollision) :
|
|
mPxAggregate (px),
|
|
mAggregateID (PX_INVALID_U32),
|
|
mMaxNbActors (maxActors),
|
|
mSelfCollide (selfCollision)
|
|
{
|
|
setScbType(ScbType::eAGGREGATE);
|
|
}
|
|
|
|
PX_INLINE Aggregate::~Aggregate()
|
|
{
|
|
}
|
|
|
|
PX_FORCE_INLINE bool Aggregate::isBufferingSpecial(ControlState::Enum state) const
|
|
{
|
|
// A special version of the buffer check is needed for aggregates because it is not fine for adding/removing
|
|
// an actor to be not double buffered if the aggregate is pending for insertion.
|
|
// For example: Adding an actor can not be processed if the aggregate is pending for insertion because the aggregateID
|
|
// is not yet available (an there is no Sc::Aggregate object to store the actors)
|
|
|
|
Scb::Scene* scbScene = getScbSceneForAPI();
|
|
return state == ControlState::eREMOVE_PENDING || // pending remove not possible if not buffered
|
|
(scbScene && scbScene->isPhysicsBuffering());
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
//
|
|
// PVD Events
|
|
//
|
|
//--------------------------------------------------------------
|
|
|
|
namespace
|
|
{
|
|
#if PX_SUPPORT_PVD
|
|
PX_FORCE_INLINE void PvdAttachActorToAggregate(Scb::Aggregate* pAggregate, Scb::Actor* pScbActor)
|
|
{
|
|
Scb::Scene* scbScene = pAggregate->getScbSceneForAPI();
|
|
if(scbScene/* && scbScene->getScenePvdClient().isInstanceValid(pAggregate)*/)
|
|
scbScene->getScenePvdClient().attachAggregateActor( pAggregate, pScbActor );
|
|
}
|
|
|
|
PX_FORCE_INLINE void PvdDetachActorFromAggregate(Scb::Aggregate* pAggregate, Scb::Actor* pScbActor)
|
|
{
|
|
Scb::Scene* scbScene = pAggregate->getScbSceneForAPI();
|
|
if(scbScene/*&& scbScene->getScenePvdClient().isInstanceValid(pAggregate)*/)
|
|
scbScene->getScenePvdClient().detachAggregateActor( pAggregate, pScbActor );
|
|
}
|
|
|
|
PX_FORCE_INLINE void PvdUpdateProperties(Scb::Aggregate* pAggregate)
|
|
{
|
|
Scb::Scene* scbScene = pAggregate->getScbSceneForAPI();
|
|
if(scbScene /*&& scbScene->getScenePvdClient().isInstanceValid(pAggregate)*/)
|
|
scbScene->getScenePvdClient().updatePvdProperties( pAggregate );
|
|
}
|
|
#else
|
|
#define PvdAttachActorToAggregate(aggregate, scbActor) {}
|
|
#define PvdDetachActorFromAggregate(aggregate, scbActor) {}
|
|
#define PvdUpdateProperties(aggregate) {}
|
|
#endif
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
//
|
|
// Data synchronization
|
|
//
|
|
//--------------------------------------------------------------
|
|
|
|
PX_INLINE void Aggregate::syncState(Scb::Scene& scene)
|
|
{
|
|
const PxU32 flags = getBufferFlags();
|
|
|
|
enum AggregateSyncDirtyType
|
|
{
|
|
DIRTY_NONE = 0,
|
|
DIRTY_ADD_ACTOR = 1<<0,
|
|
DIRTY_REMOVE_ACTOR = 1<<1
|
|
};
|
|
|
|
PxU32 dirtyType = DIRTY_NONE;
|
|
|
|
if(flags)
|
|
{
|
|
const Scb::AggregateBuffer* PX_RESTRICT bufferedData = getBufferedData();
|
|
|
|
if(flags & BF_ADD_ACTOR)
|
|
{
|
|
dirtyType |= DIRTY_ADD_ACTOR;
|
|
|
|
Scb::Actor* const* actorBuffer = scene.getActorBuffer(bufferedData->addBufferIdx);
|
|
|
|
PX_ASSERT(mAggregateID != PX_INVALID_U32);
|
|
for(PxU32 i=0; i<bufferedData->addCount; i++)
|
|
{
|
|
actorBuffer[i]->getActorCore().setAggregateID(mAggregateID);
|
|
PvdAttachActorToAggregate( this, actorBuffer[i] );
|
|
}
|
|
}
|
|
|
|
if(flags & BF_REMOVE_ACTOR)
|
|
{
|
|
dirtyType |= DIRTY_REMOVE_ACTOR;
|
|
Scb::Actor* const* actorBuffer = scene.getActorBuffer(bufferedData->removeBufferIdx);
|
|
|
|
for(PxU32 i=0; i<bufferedData->removeCount; i++)
|
|
{
|
|
const ControlState::Enum state = actorBuffer[i]->getControlState();
|
|
|
|
Sc::ActorCore& ac = actorBuffer[i]->getActorCore();
|
|
ac.setAggregateID(PX_INVALID_U32);
|
|
if(state != ControlState::eREMOVE_PENDING)
|
|
PvdDetachActorFromAggregate( this, actorBuffer[i] );
|
|
if(state == ControlState::eINSERT_PENDING || state == ControlState::eIN_SCENE)
|
|
ac.reinsertShapes();
|
|
}
|
|
}
|
|
|
|
if(dirtyType != DIRTY_NONE)
|
|
PvdUpdateProperties( this );
|
|
}
|
|
|
|
postSyncState();
|
|
}
|
|
|
|
}// namespace Scb
|
|
}// namespace physx
|
|
|
|
#endif
|