aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/SimulationController/src/ScConstraintGroupNode.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/SimulationController/src/ScConstraintGroupNode.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/SimulationController/src/ScConstraintGroupNode.h')
-rw-r--r--PhysX_3.4/Source/SimulationController/src/ScConstraintGroupNode.h178
1 files changed, 178 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/SimulationController/src/ScConstraintGroupNode.h b/PhysX_3.4/Source/SimulationController/src/ScConstraintGroupNode.h
new file mode 100644
index 00000000..ddc426fa
--- /dev/null
+++ b/PhysX_3.4/Source/SimulationController/src/ScConstraintGroupNode.h
@@ -0,0 +1,178 @@
+// 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_SCP_CONSTRAINT_GROUP_NODE
+#define PX_PHYSICS_SCP_CONSTRAINT_GROUP_NODE
+
+#include "ScConstraintProjectionTree.h"
+#include "PsUtilities.h" // for Ps::to8()
+
+namespace physx
+{
+namespace Sc
+{
+ class ConstraintSim;
+ class BodySim;
+ class ConstraintProjectionManager;
+
+ // A 'simulation island' of constraints. Created by a union-find algorithm every time a new constraint is added to any of the involved bodies.
+ struct ConstraintGroupNode : public Ps::UserAllocated
+ {
+ enum StateFlags
+ {
+ eDISCOVERED = 1 << 0, // Used during projection tree generation to mark processed nodes.
+ eIN_PROJECTION_PASS_LIST = 1 << 1, // Temporarily used to avoid duplicate entries in the list of nodes that should project the pose after the solver
+ ePENDING_TREE_UPDATE = 1 << 2, // Marks the constraint groups that need their projection trees updated. Must only be set on the root group node.
+ eNEXT_FREE_SHIFT = 3,
+ eNEXT_FREE = 1 << eNEXT_FREE_SHIFT
+ };
+
+ // these flags should give a rough hint how many projecting constraints to expect in the constraint group. This will be used for
+ // load balancing when running projection in parallel. The intervals were chosen somewhat arbitrarily but the general motivation was
+ // to cover very simple constraint setups, simple ragdolls, complex ragdolls and very complex projection setups. Note that the load
+ // balancing is not waterproof since at the end it is the projection shader from the external constraint implementer (for example, a joint)
+ // which decides based on some thresholds whether projection runs or not.
+ enum ProjectionCountHintFlags
+ {
+ e1_TO_4 = eNEXT_FREE,
+ e5_TO_16 = eNEXT_FREE << 1,
+ e17_TO_64 = eNEXT_FREE << 2,
+ e65_TO_INF = eNEXT_FREE << 3,
+ eCLEAR_MASK = ~(0xffffffff << eNEXT_FREE_SHIFT)
+ };
+
+ ConstraintGroupNode(BodySim& b);
+ ~ConstraintGroupNode()
+ {
+ PX_ASSERT(!readFlag(ePENDING_TREE_UPDATE));
+ PX_ASSERT(projectionFirstRoot == NULL);
+ }
+
+ PX_FORCE_INLINE void raiseFlag(StateFlags f) { flags |= f; }
+ PX_FORCE_INLINE void clearFlag(StateFlags f) { flags &= ~f; }
+ PX_FORCE_INLINE bool readFlag(StateFlags f) const { return (flags & f) != 0; }
+ PX_FORCE_INLINE PxU32 getProjectionCountHint() const;
+ PX_FORCE_INLINE void setProjectionCountHint(PxU32 constraintsToProjectCount);
+
+ ConstraintGroupNode& getRoot();
+
+ PX_FORCE_INLINE void buildProjectionTrees(); //build the projection trees for a constraint group.
+ void markForProjectionTreeRebuild(ConstraintProjectionManager&);
+ PX_FORCE_INLINE void purgeProjectionTrees();
+ PX_FORCE_INLINE bool hasProjectionTreeRoot() { return projectionFirstRoot != NULL; }
+ PX_FORCE_INLINE void setProjectionTreeRoot(ConstraintGroupNode* root) { projectionFirstRoot = root; }
+
+ void initProjectionData(ConstraintGroupNode* parent, ConstraintSim* c);
+ void clearProjectionData();
+
+ static void projectPose(ConstraintGroupNode& root, Ps::Array<BodySim*>& projectedBodies);
+
+
+ BodySim* body; //the owner body of this node
+
+ //tree for union/find:
+ ConstraintGroupNode* parent;
+ ConstraintGroupNode* tail; //only valid if this is root of group, points to LList tail node.
+ PxU32 rank; //rank counter for union/find. Initially zero. Is number of hops from root to furthest leaf in tree. This is just a hint to create more balanced trees.
+
+ //linked list for traversal:
+ ConstraintGroupNode* next; //next in list, NULL at tail.
+
+ //projection tree information
+ ConstraintGroupNode* projectionFirstRoot; //pointer to first projection tree root node. Only set for constraint group roots
+ ConstraintGroupNode* projectionNextRoot; //pointer to next projection root node. Only set for constraint group roots
+ //a constraint group can consist of multiple projection trees if kinematics are involved! Because a kinematic doesn't split
+ //the constraint group as a static anchor does.
+ ConstraintGroupNode* projectionParent; //node to project to
+ ConstraintGroupNode* projectionFirstChild; //first node which gets projected to this one
+ ConstraintGroupNode* projectionNextSibling; //the next sibling which gets projected to the same node as this one. NULL if projectionParent is NULL.
+ ConstraintSim* projectionConstraint; //the constraint to project (constraint to projection parent)
+
+ private:
+ PxU8 flags;
+ };
+
+} // namespace Sc
+
+
+PX_FORCE_INLINE PxU32 Sc::ConstraintGroupNode::getProjectionCountHint() const
+{
+ // return the mean of the upper and lower bound
+
+ if (flags & ConstraintGroupNode::e65_TO_INF)
+ return 128;
+ else if (flags & ConstraintGroupNode::e17_TO_64)
+ return 40;
+ else if (flags & ConstraintGroupNode::e5_TO_16)
+ return 10;
+ else if (flags & ConstraintGroupNode::e1_TO_4)
+ return 2;
+
+ return 0;
+}
+
+
+PX_FORCE_INLINE void Sc::ConstraintGroupNode::setProjectionCountHint(PxU32 constraintsToProjectCount)
+{
+ PxU8 tmpFlags = flags;
+ tmpFlags &= PxU8(ConstraintGroupNode::eCLEAR_MASK);
+
+ if (constraintsToProjectCount >= 65)
+ tmpFlags |= ConstraintGroupNode::e65_TO_INF;
+ else if (constraintsToProjectCount >= 17)
+ tmpFlags |= ConstraintGroupNode::e17_TO_64;
+ else if (constraintsToProjectCount >= 5)
+ tmpFlags |= ConstraintGroupNode::e5_TO_16;
+ else if (constraintsToProjectCount >= 1)
+ tmpFlags |= ConstraintGroupNode::e1_TO_4;
+
+ flags = tmpFlags;
+}
+
+
+PX_FORCE_INLINE void Sc::ConstraintGroupNode::buildProjectionTrees()
+{
+ PX_ASSERT(this == parent); // Only call for group roots
+ PX_ASSERT(!hasProjectionTreeRoot());
+
+ ConstraintProjectionTree::buildProjectionTrees(*this);
+}
+
+
+PX_FORCE_INLINE void Sc::ConstraintGroupNode::purgeProjectionTrees()
+{
+ PX_ASSERT(this == parent); // Only call for group roots
+ PX_ASSERT(hasProjectionTreeRoot());
+ ConstraintProjectionTree::purgeProjectionTrees(*this);
+}
+
+}
+
+#endif