aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/PhysX/src/buffering/ScbShape.h
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Source/PhysX/src/buffering/ScbShape.h
downloadphysx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz
physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip
Initial commit:
PhysX 3.4.0 Update @ 21294896 APEX 1.4.0 Update @ 21275617 [CL 21300167]
Diffstat (limited to 'PhysX_3.4/Source/PhysX/src/buffering/ScbShape.h')
-rw-r--r--PhysX_3.4/Source/PhysX/src/buffering/ScbShape.h452
1 files changed, 452 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/PhysX/src/buffering/ScbShape.h b/PhysX_3.4/Source/PhysX/src/buffering/ScbShape.h
new file mode 100644
index 00000000..697017bf
--- /dev/null
+++ b/PhysX_3.4/Source/PhysX/src/buffering/ScbShape.h
@@ -0,0 +1,452 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 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_SHAPE
+#define PX_PHYSICS_SCB_SHAPE
+
+#include "NpMaterial.h"
+#include "NpPhysics.h"
+#include "ScbNpDeps.h"
+#include "ScShapeCore.h"
+#include "ScRigidCore.h"
+
+#include "PsUtilities.h"
+
+// PX_SERIALIZATION
+#include "PxSerialFramework.h"
+//~PX_SERIALIZATION
+
+#include "ScbDefs.h"
+
+namespace physx
+{
+
+#if PX_SUPPORT_PVD
+ #define UPDATE_PVD_MATERIALS() \
+ if(getControlState() == ControlState::eIN_SCENE) \
+ { \
+ getScbScene()->getScenePvdClient().updateMaterials(this); \
+ }
+#else
+ #define UPDATE_PVD_MATERIALS() {}
+#endif
+
+namespace Scb
+{
+
+class RigidObject;
+
+struct ShapeBuffer
+{
+ template <PxU32 I, PxU32 dummy> struct Fns {}; // TODO: make the base class traits visible
+ typedef Sc::ShapeCore Core;
+ typedef ShapeBuffer Buf;
+
+ ShapeBuffer() : materialBufferIndex(0), materialCount(0) {}
+
+ SCB_REGULAR_ATTRIBUTE_ALIGNED(2, PxTransform, Shape2Actor, 16)
+ SCB_REGULAR_ATTRIBUTE(3, PxFilterData, SimulationFilterData)
+ SCB_REGULAR_ATTRIBUTE(4, PxReal, ContactOffset)
+ SCB_REGULAR_ATTRIBUTE(5, PxReal, RestOffset)
+ SCB_REGULAR_ATTRIBUTE(6, PxShapeFlags, Flags)
+
+ Gu::GeometryUnion geometry;
+
+ union
+ {
+ PxU16 materialIndex; // for single material shapes
+ PxU32 materialBufferIndex; // for multi material shapes
+ };
+ PxU16 materialCount;
+
+ enum
+ {
+ BF_Geometry = 1<<0,
+ BF_Material = 1<<1
+ };
+
+};
+
+class Shape : 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.
+//==================================================================================================
+
+ typedef Sc::ShapeCore Core;
+ typedef ShapeBuffer Buf;
+public:
+// PX_SERIALIZATION
+ Shape(const PxEMPTY) : Base(PxEmpty), mShape(PxEmpty) {}
+ static void getBinaryMetaData(PxOutputStream& stream);
+//~PX_SERIALIZATION
+
+ PX_INLINE Shape(const PxGeometry& geometry,
+ PxShapeFlags shapeFlags,
+ const PxU16* materialIndices,
+ PxU16 materialCount,
+ bool isExclusive);
+
+ PX_INLINE PxGeometryType::Enum getGeometryType() const;
+
+ PX_INLINE const PxGeometry& getGeometry() const;
+ PX_INLINE const Gu::GeometryUnion&getGeometryUnion() const;
+ PX_INLINE Scb::ShapeBuffer* setGeometry(const PxGeometry& geom);
+
+ PX_INLINE PxU16 getNbMaterials() const;
+ PX_INLINE PxMaterial* getMaterial(PxU32 index) const;
+ PX_INLINE PxU32 getMaterials(PxMaterial** buffer, PxU32 bufferSize, PxU32 startIndex=0) const;
+ PX_INLINE bool setMaterials(PxMaterial*const* materials, PxU16 materialCount);
+
+ PX_INLINE const PxTransform& getShape2Actor() const { return read<Buf::BF_Shape2Actor>(); }
+ PX_INLINE void setShape2Actor(const PxTransform& v) { write<Buf::BF_Shape2Actor>(v); }
+
+ PX_INLINE PxFilterData getSimulationFilterData() const { return read<Buf::BF_SimulationFilterData>(); }
+ PX_INLINE void setSimulationFilterData(const PxFilterData& v) { write<Buf::BF_SimulationFilterData>(v); }
+
+ PX_INLINE PxReal getContactOffset() const { return read<Buf::BF_ContactOffset>(); }
+ PX_INLINE void setContactOffset(PxReal v);
+
+ PX_INLINE PxReal getRestOffset() const { return read<Buf::BF_RestOffset>(); }
+ PX_INLINE void setRestOffset(PxReal v) { write<Buf::BF_RestOffset>(v); }
+
+ PX_INLINE PxShapeFlags getFlags() const { return read<Buf::BF_Flags>(); }
+ PX_INLINE void setFlags(PxShapeFlags v) { write<Buf::BF_Flags>(v); }
+
+
+ //---------------------------------------------------------------------------------
+ // Data synchronization
+ //---------------------------------------------------------------------------------
+ void syncState();
+
+
+ //---------------------------------------------------------------------------------
+ // Miscellaneous
+ //---------------------------------------------------------------------------------
+ PX_FORCE_INLINE const PxU16* getScMaterialIndices() const { return mShape.getMaterialIndices(); } // Only use if you know what you're doing!
+
+ PX_FORCE_INLINE Sc::ShapeCore& getScShape() { return mShape; } // Only use if you know what you're doing!
+ PX_FORCE_INLINE const Sc::ShapeCore& getScShape() const { return mShape; }
+
+ PX_FORCE_INLINE bool isExclusive() const { return getScbType() == ScbType::SHAPE_EXCLUSIVE; }
+ PX_FORCE_INLINE void setControlStateIfExclusive(Scene* s, ControlState::Enum cs); // for exclusive shapes
+
+ template<bool sync> PX_FORCE_INLINE void checkUpdateOnRemove(Scene* s);
+
+ static size_t getScOffset()
+ {
+ return reinterpret_cast<size_t>(&reinterpret_cast<Shape*>(0)->mShape);
+ }
+
+private:
+ bool setMaterialsHelper(PxMaterial* const* materials, PxU16 materialCount);
+
+ Sc::ShapeCore mShape;
+
+ PX_FORCE_INLINE const Scb::ShapeBuffer* getBufferedData() const { return reinterpret_cast<const Scb::ShapeBuffer*>(getStream()); }
+ PX_FORCE_INLINE Scb::ShapeBuffer* getBufferedData() { return reinterpret_cast<Scb::ShapeBuffer*>(getStream()); }
+
+
+ PX_FORCE_INLINE const PxU16* getMaterialBuffer(const Scb::Scene& scene, const Scb::ShapeBuffer& sb) const
+ {
+ if (sb.materialCount == 1)
+ return &sb.materialIndex;
+ else
+ return scene.getShapeMaterialBuffer(sb.materialBufferIndex);
+ }
+
+ //---------------------------------------------------------------------------------
+ // Infrastructure for regular attributes
+ //---------------------------------------------------------------------------------
+
+ struct Access: public BufferedAccess<Buf, Core, Shape>
+ {
+ template<typename Fns>
+ static PX_FORCE_INLINE void write(Shape& base, Core& core, typename Fns::Arg v)
+ {
+ if (!base.isBuffering())
+ {
+ PxShapeFlags oldShapeFlags = core.getFlags();
+ Fns::setCore(core, v);
+
+ // shared shapes return NULL. But shared shapes aren't mutable when attached to an actor, so no notification needed.
+ Sc::RigidCore* rigidCore = NpShapeGetScRigidObjectFromScbSLOW(base);
+ if(rigidCore && base.getControlState() != ControlState::eINSERT_PENDING)
+ rigidCore->onShapeChange(core, Sc::ShapeChangeNotifyFlags(Fns::flag), oldShapeFlags);
+#if PX_SUPPORT_PVD
+ Scb::Scene* scene = base.getScbSceneForAPI(); // shared shapes also return zero here
+ if(scene && !base.insertPending())
+ scene->getScenePvdClient().updatePvdProperties(&base);
+#endif
+ }
+ else
+ {
+ Fns::setBuffered(*reinterpret_cast<Buf*>(base.getStream()), v);
+ base.markUpdated(Fns::flag);
+ }
+ }
+
+ };
+ template<PxU32 f> PX_FORCE_INLINE typename Buf::Fns<f,0>::Arg read() const { return Access::read<Buf::Fns<f,0> >(*this, mShape); }
+ template<PxU32 f> PX_FORCE_INLINE void write(typename Buf::Fns<f,0>::Arg v) { Access::write<Buf::Fns<f,0> >(*this, mShape, v); }
+ template<PxU32 f> PX_FORCE_INLINE void flush(const Buf& buf) { Access::flush<Buf::Fns<f,0> >(*this, mShape, buf); }
+
+};
+
+
+PX_INLINE Shape::Shape(const PxGeometry& geometry,
+ PxShapeFlags shapeFlags,
+ const PxU16* materialIndices,
+ PxU16 materialCount,
+ bool isExclusive) :
+ mShape(geometry, shapeFlags, materialIndices, materialCount)
+{
+ // paranoia: the notify flags in Sc have to match up
+
+ PX_COMPILE_TIME_ASSERT(PxU32(ShapeBuffer::BF_Geometry) == PxU32(Sc::ShapeChangeNotifyFlag::eGEOMETRY));
+ PX_COMPILE_TIME_ASSERT(PxU32(ShapeBuffer::BF_Material) == PxU32(Sc::ShapeChangeNotifyFlag::eMATERIAL));
+ PX_COMPILE_TIME_ASSERT(PxU32(ShapeBuffer::BF_Shape2Actor) == PxU32(Sc::ShapeChangeNotifyFlag::eSHAPE2BODY));
+ PX_COMPILE_TIME_ASSERT(PxU32(ShapeBuffer::BF_SimulationFilterData) == PxU32(Sc::ShapeChangeNotifyFlag::eFILTERDATA));
+ PX_COMPILE_TIME_ASSERT(PxU32(ShapeBuffer::BF_ContactOffset) == PxU32(Sc::ShapeChangeNotifyFlag::eCONTACTOFFSET));
+ PX_COMPILE_TIME_ASSERT(PxU32(ShapeBuffer::BF_RestOffset) == PxU32(Sc::ShapeChangeNotifyFlag::eRESTOFFSET));
+ PX_COMPILE_TIME_ASSERT(PxU32(ShapeBuffer::BF_Flags) == PxU32(Sc::ShapeChangeNotifyFlag::eFLAGS));
+ PX_COMPILE_TIME_ASSERT(PxU32(ShapeBuffer::BF_Geometry) == PxU32(Sc::ShapeChangeNotifyFlag::eGEOMETRY));
+
+ if (isExclusive)
+ setScbType(ScbType::SHAPE_EXCLUSIVE);
+ else
+ setScbType(ScbType::SHAPE_SHARED);
+}
+
+
+PX_INLINE PxGeometryType::Enum Shape::getGeometryType() const
+{
+ return mShape.getGeometryType();
+}
+
+PX_INLINE const PxGeometry& Shape::getGeometry() const
+{
+ if (isBuffered(Buf::BF_Geometry))
+ return getBufferedData()->geometry.getGeometry();
+ else
+ return mShape.getGeometry();
+}
+
+PX_INLINE const Gu::GeometryUnion& Shape::getGeometryUnion() const
+{
+ if (isBuffered(Buf::BF_Geometry))
+ return getBufferedData()->geometry;
+ else
+ return mShape.getGeometryUnion();
+}
+
+
+PX_INLINE Scb::ShapeBuffer* Shape::setGeometry(const PxGeometry& geom)
+{
+ Scb::ShapeBuffer* shapeBuffer = NULL;
+ if (!isBuffering())
+ {
+ Scb::Scene* sc = getScbScene();
+
+ if (sc)
+ {
+ sc->getScScene().unregisterShapeFromNphase(mShape);
+ }
+
+ mShape.setGeometry(geom);
+
+ if (sc)
+ {
+ sc->getScScene().registerShapeInNphase(mShape);
+ }
+
+ Sc::RigidCore* rigidCore = NpShapeGetScRigidObjectFromScbSLOW(*this);
+ if(rigidCore)
+ rigidCore->onShapeChange(mShape, Sc::ShapeChangeNotifyFlag::eGEOMETRY, PxShapeFlags());
+
+#if PX_SUPPORT_PVD
+ Scb::Scene* scbScene = getScbSceneForAPI();
+ if(scbScene)
+ {
+ scbScene->getScenePvdClient().releaseAndRecreateGeometry( this );
+ }
+#endif
+ }
+ else
+ {
+ markUpdated(Buf::BF_Geometry);
+ shapeBuffer = getBufferedData();
+ shapeBuffer->geometry.set(geom);
+ }
+
+ return shapeBuffer;
+}
+
+
+PX_INLINE PxU16 Shape::getNbMaterials() const
+{
+ if (isBuffered(Buf::BF_Material))
+ return getBufferedData()->materialCount;
+ else
+ return mShape.getNbMaterialIndices();
+}
+
+
+PX_INLINE PxMaterial* Shape::getMaterial(PxU32 index) const
+{
+ PX_ASSERT(index < getNbMaterials());
+
+ NpMaterialManager& matManager = NpPhysics::getInstance().getMaterialManager();
+ if (isBuffered(Buf::BF_Material))
+ {
+ const PxU16* materialIndices = getMaterialBuffer(*getScbScene(), *getBufferedData());
+ return matManager.getMaterial(materialIndices[index]);
+ }
+ else
+ {
+ PxU16 matTableIndex = mShape.getMaterialIndices()[index];
+ return matManager.getMaterial(matTableIndex);
+ }
+}
+
+
+PX_INLINE PxU32 Shape::getMaterials(PxMaterial** buffer, PxU32 bufferSize, PxU32 startIndex) const
+{
+ const PxU16* materialIndices;
+ PxU32 matCount;
+ NpMaterialManager& matManager = NpPhysics::getInstance().getMaterialManager();
+ if (isBuffered(Buf::BF_Material))
+ {
+ // IMPORTANT:
+ // As long as the material pointers get copied to a user buffer, this works fine.
+ // Never give direct access to the internal material buffer because in the
+ // double buffered case the pointer changes on resize.
+
+ const Scb::ShapeBuffer* PX_RESTRICT bufferedData = getBufferedData();
+
+ materialIndices = getMaterialBuffer(*getScbScene(), *bufferedData);
+ matCount = bufferedData->materialCount;
+ }
+ else
+ {
+ materialIndices = mShape.getMaterialIndices();
+ matCount = mShape.getNbMaterialIndices();
+ }
+
+ // PT: this is copied from Cm::getArrayOfPointers(). We cannot use the Cm function here
+ // because of the extra indirection needed to access the materials.
+ PxU32 size = matCount;
+ const PxU32 remainder = PxU32(PxMax<PxI32>(PxI32(size - startIndex), 0));
+ const PxU32 writeCount = PxMin(remainder, bufferSize);
+ materialIndices += startIndex;
+ for(PxU32 i=0;i<writeCount;i++)
+ buffer[i] = matManager.getMaterial(materialIndices[i]);
+
+ return writeCount;
+}
+
+
+PX_INLINE bool Shape::setMaterials(PxMaterial* const* materials, PxU16 materialCount)
+{
+ if (!isBuffering())
+ {
+ bool ret = setMaterialsHelper(materials, materialCount);
+ UPDATE_PVD_MATERIALS()
+ return ret;
+ }
+ else
+ {
+ Scb::ShapeBuffer* PX_RESTRICT bufferedData = getBufferedData();
+
+ PxU16* materialIndices;
+ if (materialCount == 1)
+ materialIndices = &bufferedData->materialIndex;
+ else
+ {
+ PxU32 bufferIdx;
+ materialIndices = getScbScene()->allocShapeMaterialBuffer(materialCount, bufferIdx);
+ bufferedData->materialBufferIndex = bufferIdx;
+ }
+ bufferedData->materialCount = materialCount;
+
+ NpMaterial::getMaterialIndices(materials, materialIndices, materialCount);
+
+ markUpdated(Buf::BF_Material);
+
+ return true;
+ }
+}
+
+PX_INLINE void Shape::setContactOffset(PxReal v)
+{
+ write<Buf::BF_ContactOffset>(v);
+}
+
+
+PX_FORCE_INLINE void Shape::setControlStateIfExclusive(Scene* s, ControlState::Enum cs)
+{
+ if (isExclusive())
+ {
+ setControlState(cs);
+ setScbScene(s);
+ }
+}
+
+
+template<bool sync>
+PX_FORCE_INLINE void Shape::checkUpdateOnRemove(Scene* s)
+{
+ // special code to cover the case where a shape has a pending update and gets released. The following operations have to be done
+ // before the ref-counter of the shape gets decremented because that could cause the shape to be deleted in which case it must not
+ // be in the pending update list any longer.
+ if (getControlFlags() & Scb::ControlFlag::eIS_UPDATED)
+ {
+ if (sync)
+ syncState();
+ s->removeShapeFromPendingUpdateList(*this);
+ }
+}
+
+
+//--------------------------------------------------------------
+//
+// Data synchronization
+//
+//--------------------------------------------------------------
+
+
+} // namespace Scb
+
+}
+
+#endif