RavEngine
Loading...
Searching...
No Matches
ScConstraintGroupNode.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2008-2022 NVIDIA Corporation. All rights reserved.
26// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
27// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
28
29#ifndef SC_CONSTRAINT_GROUP_NODE_H
30#define SC_CONSTRAINT_GROUP_NODE_H
31
32#include "ScConstraintProjectionTree.h"
33#include "foundation/PxUtilities.h" // for PxTo8()
34
35namespace physx
36{
37namespace Sc
38{
39 class ConstraintSim;
40 class BodySim;
41 class ConstraintProjectionManager;
42
43 // A 'simulation island' of constraints. Created by a union-find algorithm every time a new constraint is added to any of the involved bodies.
45 {
46 enum StateFlags
47 {
48 eDISCOVERED = 1 << 0, // Used during projection tree generation to mark processed nodes.
49 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
50 ePENDING_TREE_UPDATE = 1 << 2, // Marks the constraint groups that need their projection trees updated. Must only be set on the root group node.
51 eNEXT_FREE_SHIFT = 3,
52 eNEXT_FREE = 1 << eNEXT_FREE_SHIFT
53 };
54
55 // these flags should give a rough hint how many projecting constraints to expect in the constraint group. This will be used for
56 // load balancing when running projection in parallel. The intervals were chosen somewhat arbitrarily but the general motivation was
57 // to cover very simple constraint setups, simple ragdolls, complex ragdolls and very complex projection setups. Note that the load
58 // balancing is not waterproof since at the end it is the projection shader from the external constraint implementer (for example, a joint)
59 // which decides based on some thresholds whether projection runs or not.
60 enum ProjectionCountHintFlags
61 {
62 e1_TO_4 = eNEXT_FREE,
63 e5_TO_16 = eNEXT_FREE << 1,
64 e17_TO_64 = eNEXT_FREE << 2,
65 e65_TO_INF = eNEXT_FREE << 3,
66 eCLEAR_MASK = ~(0xffffffff << eNEXT_FREE_SHIFT)
67 };
68
71 {
72 PX_ASSERT(!readFlag(ePENDING_TREE_UPDATE));
73 PX_ASSERT(projectionFirstRoot == NULL);
74 }
75
76 PX_FORCE_INLINE void raiseFlag(StateFlags f) { flags |= f; }
77 PX_FORCE_INLINE void clearFlag(StateFlags f) { flags &= ~f; }
78 PX_FORCE_INLINE bool readFlag(StateFlags f) const { return (flags & f) != 0; }
79 PX_FORCE_INLINE PxU32 getProjectionCountHint() const;
80 PX_FORCE_INLINE void setProjectionCountHint(PxU32 constraintsToProjectCount);
81
82 ConstraintGroupNode& getRoot();
83
84 PX_FORCE_INLINE void buildProjectionTrees(); //build the projection trees for a constraint group.
85 void markForProjectionTreeRebuild(ConstraintProjectionManager&);
86 PX_FORCE_INLINE void purgeProjectionTrees();
87 PX_FORCE_INLINE bool hasProjectionTreeRoot() { return projectionFirstRoot != NULL; }
88 PX_FORCE_INLINE void setProjectionTreeRoot(ConstraintGroupNode* root) { projectionFirstRoot = root; }
89
90 void initProjectionData(ConstraintGroupNode* parent, ConstraintSim* c);
91 void clearProjectionData();
92
93 static void projectPose(ConstraintGroupNode& root, PxArray<BodySim*>& projectedBodies);
94
95
96 BodySim* body; //the owner body of this node
97
98 //tree for union/find:
99 ConstraintGroupNode* parent;
100 ConstraintGroupNode* tail; //only valid if this is root of group, points to LList tail node.
101 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.
102
103 //linked list for traversal:
104 ConstraintGroupNode* next; //next in list, NULL at tail.
105
106 //projection tree information
107 ConstraintGroupNode* projectionFirstRoot; //pointer to first projection tree root node. Only set for constraint group roots
108 ConstraintGroupNode* projectionNextRoot; //pointer to next projection root node. Only set for constraint group roots
109 //a constraint group can consist of multiple projection trees if kinematics are involved! Because a kinematic doesn't split
110 //the constraint group as a static anchor does.
111 ConstraintGroupNode* projectionParent; //node to project to
112 ConstraintGroupNode* projectionFirstChild; //first node which gets projected to this one
113 ConstraintGroupNode* projectionNextSibling; //the next sibling which gets projected to the same node as this one. NULL if projectionParent is NULL.
114 ConstraintSim* projectionConstraint; //the constraint to project (constraint to projection parent)
115
116 private:
117 PxU8 flags;
118 };
119
120} // namespace Sc
121
122
123PX_FORCE_INLINE PxU32 Sc::ConstraintGroupNode::getProjectionCountHint() const
124{
125 // return the mean of the upper and lower bound
126
127 if (flags & ConstraintGroupNode::e65_TO_INF)
128 return 128;
129 else if (flags & ConstraintGroupNode::e17_TO_64)
130 return 40;
131 else if (flags & ConstraintGroupNode::e5_TO_16)
132 return 10;
133 else if (flags & ConstraintGroupNode::e1_TO_4)
134 return 2;
135
136 return 0;
137}
138
139
140PX_FORCE_INLINE void Sc::ConstraintGroupNode::setProjectionCountHint(PxU32 constraintsToProjectCount)
141{
142 PxU8 tmpFlags = flags;
143 tmpFlags &= PxU8(ConstraintGroupNode::eCLEAR_MASK);
144
145 if (constraintsToProjectCount >= 65)
146 tmpFlags |= ConstraintGroupNode::e65_TO_INF;
147 else if (constraintsToProjectCount >= 17)
148 tmpFlags |= ConstraintGroupNode::e17_TO_64;
149 else if (constraintsToProjectCount >= 5)
150 tmpFlags |= ConstraintGroupNode::e5_TO_16;
151 else if (constraintsToProjectCount >= 1)
152 tmpFlags |= ConstraintGroupNode::e1_TO_4;
153
154 flags = tmpFlags;
155}
156
157
158PX_FORCE_INLINE void Sc::ConstraintGroupNode::buildProjectionTrees()
159{
160 PX_ASSERT(this == parent); // Only call for group roots
161 PX_ASSERT(!hasProjectionTreeRoot());
162
163 ConstraintProjectionTree::buildProjectionTrees(*this);
164}
165
166
167PX_FORCE_INLINE void Sc::ConstraintGroupNode::purgeProjectionTrees()
168{
169 PX_ASSERT(this == parent); // Only call for group roots
170 PX_ASSERT(hasProjectionTreeRoot());
171 ConstraintProjectionTree::purgeProjectionTrees(*this);
172}
173
174}
175
176#endif
Definition PxArray.h:53
Definition PxUserAllocated.h:43
Definition ScBodySim.h:60
Definition ScConstraintProjectionManager.h:47
Definition ScConstraintSim.h:48
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
Definition ScConstraintGroupNode.h:45