Revision | 8def3866579709b02d3a8ec6a7d77a49385696dd (tree) |
---|---|
Time | 2024-07-01 01:52:45 |
Author | sebastian_bugiu |
Commiter | sebastian_bugiu |
Moved mMoved and mUpdated to SoA in Transform instead of bools in each PCZSceneNode.
@@ -299,6 +299,10 @@ | ||
299 | 299 | WorldMat, |
300 | 300 | InheritOrientation, |
301 | 301 | InheritScale, |
302 | +#ifdef USE_PCZ | |
303 | + Moved, | |
304 | + Updated, | |
305 | +#endif | |
302 | 306 | NumMemoryTypes |
303 | 307 | }; |
304 | 308 |
@@ -73,6 +73,11 @@ | ||
73 | 73 | /// Stores whether this node inherits scale from it's parent. |
74 | 74 | /// Ours is mInheritScale[mIndex] |
75 | 75 | bool * RESTRICT_ALIAS mInheritScale; |
76 | + | |
77 | +#ifdef USE_PCZ | |
78 | + bool * RESTRICT_ALIAS mMoved; | |
79 | + bool * RESTRICT_ALIAS mUpdated; | |
80 | +#endif | |
76 | 81 | |
77 | 82 | Transform() : |
78 | 83 | mIndex( 0 ), |
@@ -87,6 +92,10 @@ | ||
87 | 92 | mDerivedTransform( 0 ), |
88 | 93 | mInheritOrientation( 0 ), |
89 | 94 | mInheritScale( 0 ) |
95 | +#ifdef USE_PCZ | |
96 | + , mMoved( 0 ) | |
97 | + , mUpdated( 0 ) | |
98 | +#endif | |
90 | 99 | { |
91 | 100 | } |
92 | 101 |
@@ -138,6 +147,11 @@ | ||
138 | 147 | |
139 | 148 | mInheritOrientation[mIndex] = inCopy.mInheritOrientation[inCopy.mIndex]; |
140 | 149 | mInheritScale[mIndex] = inCopy.mInheritScale[inCopy.mIndex]; |
150 | + | |
151 | +#ifdef USE_PCZ | |
152 | + mMoved[mIndex] = inCopy.mMoved[inCopy.mIndex]; | |
153 | + mUpdated[mIndex] = inCopy.mUpdated[inCopy.mIndex]; | |
154 | +#endif | |
141 | 155 | } |
142 | 156 | |
143 | 157 | /** Rebases all the pointers from our SoA structs so that they point to a new location |
@@ -174,6 +188,13 @@ | ||
174 | 188 | newBasePtrs[NodeArrayMemoryManager::InheritOrientation] + diff ); |
175 | 189 | mInheritScale = reinterpret_cast<bool*>( |
176 | 190 | newBasePtrs[NodeArrayMemoryManager::InheritScale] + diff ); |
191 | + | |
192 | +#ifdef USE_PCZ | |
193 | + mMoved = reinterpret_cast<bool*>( | |
194 | + newBasePtrs[NodeArrayMemoryManager::Moved] + diff ); | |
195 | + mUpdated = reinterpret_cast<bool*>( | |
196 | + newBasePtrs[NodeArrayMemoryManager::Updated] + diff ); | |
197 | +#endif | |
177 | 198 | } |
178 | 199 | |
179 | 200 | /** Advances all pointers to the next pack, i.e. if we're processing 4 elements at a time, move to |
@@ -192,6 +213,11 @@ | ||
192 | 213 | mDerivedTransform += ARRAY_PACKED_REALS; |
193 | 214 | mInheritOrientation += ARRAY_PACKED_REALS; |
194 | 215 | mInheritScale += ARRAY_PACKED_REALS; |
216 | + | |
217 | +#ifdef USE_PCZ | |
218 | + mMoved += ARRAY_PACKED_REALS; | |
219 | + mUpdated += ARRAY_PACKED_REALS; | |
220 | +#endif | |
195 | 221 | } |
196 | 222 | |
197 | 223 | void advancePack( size_t numAdvance ) |
@@ -207,6 +233,11 @@ | ||
207 | 233 | mDerivedTransform += ARRAY_PACKED_REALS * numAdvance; |
208 | 234 | mInheritOrientation += ARRAY_PACKED_REALS * numAdvance; |
209 | 235 | mInheritScale += ARRAY_PACKED_REALS * numAdvance; |
236 | + | |
237 | +#ifdef USE_PCZ | |
238 | + mMoved += ARRAY_PACKED_REALS * numAdvance; | |
239 | + mUpdated += ARRAY_PACKED_REALS * numAdvance; | |
240 | +#endif | |
210 | 241 | } |
211 | 242 | }; |
212 | 243 | } |
@@ -237,6 +237,24 @@ | ||
237 | 237 | { |
238 | 238 | } |
239 | 239 | }; |
240 | + | |
241 | +#ifdef USE_PCZ | |
242 | + struct ResetUpdateFlagsRequest | |
243 | + { | |
244 | + Transform t; | |
245 | + /// Number of nodes to process for each thread. Must be multiple of ARRAY_PACKED_REALS | |
246 | + size_t numNodesPerThread; | |
247 | + size_t numTotalNodes; | |
248 | + | |
249 | + ResetUpdateFlagsRequest() : | |
250 | + numNodesPerThread( 0 ), numTotalNodes( 0 ) {} | |
251 | + | |
252 | + ResetUpdateFlagsRequest( const Transform &_t, size_t _numNodesPerThread, size_t _numTotalNodes ) : | |
253 | + t( _t ), numNodesPerThread( _numNodesPerThread ), numTotalNodes( _numTotalNodes ) | |
254 | + { | |
255 | + } | |
256 | + }; | |
257 | +#endif | |
240 | 258 | |
241 | 259 | struct InstanceBatchCullRequest |
242 | 260 | { |
@@ -916,6 +934,9 @@ | ||
916 | 934 | PCZ_CULL_FRUSTUM, |
917 | 935 | UPDATE_ALL_ANIMATIONS, |
918 | 936 | UPDATE_ALL_TRANSFORMS, |
937 | +#ifdef USE_PCZ | |
938 | + RESET_ALL_UPDATE_FLAGS, | |
939 | +#endif | |
919 | 940 | UPDATE_ALL_BONE_TO_TAG_TRANSFORMS, |
920 | 941 | UPDATE_ALL_TAG_ON_TAG_TRANSFORMS, |
921 | 942 | UPDATE_ALL_BOUNDS, |
@@ -935,6 +956,9 @@ | ||
935 | 956 | PCZCullFrustumRequest mCurrentPCZCullFrustumRequest; |
936 | 957 | UpdateLodRequest mUpdateLodRequest; |
937 | 958 | UpdateTransformRequest mUpdateTransformRequest; |
959 | +#ifdef USE_PCZ | |
960 | + ResetUpdateFlagsRequest mResetUpdateFlagsRequest; | |
961 | +#endif | |
938 | 962 | ObjectMemoryManagerVec const *mUpdateBoundsRequest; |
939 | 963 | InstancingThreadedCullingMethod mInstancingThreadedCullingMethod; |
940 | 964 | InstanceBatchCullRequest mInstanceBatchCullRequest; |
@@ -1027,6 +1051,10 @@ | ||
1027 | 1051 | Must be unique for each worker thread |
1028 | 1052 | */ |
1029 | 1053 | void updateAllTransformsThread( const UpdateTransformRequest &request, size_t threadIdx ); |
1054 | + | |
1055 | +#ifdef USE_PCZ | |
1056 | + void resetAllUpdateFlagsThread( const ResetUpdateFlagsRequest &request, size_t threadIdx ); | |
1057 | +#endif | |
1030 | 1058 | |
1031 | 1059 | /// @see TagPoint::updateAllTransformsBoneToTag |
1032 | 1060 | void updateAllTransformsBoneToTagThread( const UpdateTransformRequest &request, |
@@ -1917,6 +1945,10 @@ | ||
1917 | 1945 | could deadlock in the best of cases). |
1918 | 1946 | */ |
1919 | 1947 | void updateAllTransforms(); |
1948 | + | |
1949 | +#ifdef USE_PCZ | |
1950 | + void resetAllUpdateFlags(); | |
1951 | +#endif | |
1920 | 1952 | |
1921 | 1953 | /** Updates all TagPoints, both TagPoints that are children of bones, and TagPoints that |
1922 | 1954 | are children of other TagPoints. |
@@ -49,6 +49,10 @@ | ||
49 | 49 | 16 * sizeof( Ogre::Real ), //ArrayMemoryManager::WorldMat |
50 | 50 | sizeof( bool ), //ArrayMemoryManager::InheritOrientation |
51 | 51 | sizeof( bool ) //ArrayMemoryManager::InheritScale |
52 | +#ifdef USE_PCZ | |
53 | + , sizeof( bool ) //ArrayMemoryManager::Moved | |
54 | + , sizeof( bool ) //ArrayMemoryManager::Updated | |
55 | +#endif | |
52 | 56 | }; |
53 | 57 | const CleanupRoutines NodeArrayMemoryManager::NodeInitRoutines[NumMemoryTypes] = |
54 | 58 | { |
@@ -63,6 +67,10 @@ | ||
63 | 67 | 0, //ArrayMemoryManager::WorldMat |
64 | 68 | 0, //ArrayMemoryManager::InheritOrientation |
65 | 69 | 0 //ArrayMemoryManager::InheritScale |
70 | +#ifdef USE_PCZ | |
71 | + , 0 //ArrayMemoryManager::Moved | |
72 | + , 0 //ArrayMemoryManager::Updated | |
73 | +#endif | |
66 | 74 | }; |
67 | 75 | const CleanupRoutines NodeArrayMemoryManager::NodeCleanupRoutines[NumMemoryTypes] = |
68 | 76 | { |
@@ -77,6 +85,10 @@ | ||
77 | 85 | cleanerFlat, //ArrayMemoryManager::WorldMat |
78 | 86 | cleanerFlat, //ArrayMemoryManager::InheritOrientation |
79 | 87 | cleanerFlat //ArrayMemoryManager::InheritScale |
88 | +#ifdef USE_PCZ | |
89 | + , cleanerFlat //ArrayMemoryManager::Moved | |
90 | + , cleanerFlat //ArrayMemoryManager::Updated | |
91 | +#endif | |
80 | 92 | }; |
81 | 93 | //----------------------------------------------------------------------------------- |
82 | 94 | NodeArrayMemoryManager::NodeArrayMemoryManager( uint16 depthLevel, size_t hintMaxNodes, |
@@ -132,6 +144,13 @@ | ||
132 | 144 | nextSlotBase * mElementsMemSizes[InheritOrientation] ); |
133 | 145 | outTransform.mInheritScale = reinterpret_cast<bool*>( mMemoryPools[InheritScale] + |
134 | 146 | nextSlotBase * mElementsMemSizes[InheritScale] ); |
147 | + | |
148 | +#ifdef USE_PCZ | |
149 | + outTransform.mMoved = reinterpret_cast<bool*>( mMemoryPools[Moved] + | |
150 | + nextSlotBase * mElementsMemSizes[Moved] ); | |
151 | + outTransform.mUpdated = reinterpret_cast<bool*>( mMemoryPools[Updated] + | |
152 | + nextSlotBase * mElementsMemSizes[Updated] ); | |
153 | +#endif | |
135 | 154 | |
136 | 155 | //Set default values |
137 | 156 | outTransform.mParents[nextSlotIdx] = mDummyNode; |
@@ -145,6 +164,10 @@ | ||
145 | 164 | outTransform.mDerivedTransform[nextSlotIdx] = Matrix4::IDENTITY; |
146 | 165 | outTransform.mInheritOrientation[nextSlotIdx] = true; |
147 | 166 | outTransform.mInheritScale[nextSlotIdx] = true; |
167 | +#ifdef USE_PCZ | |
168 | + outTransform.mMoved[nextSlotIdx] = true; | |
169 | + outTransform.mUpdated[nextSlotIdx] = false; | |
170 | +#endif | |
148 | 171 | } |
149 | 172 | //----------------------------------------------------------------------------------- |
150 | 173 | void NodeArrayMemoryManager::destroyNode( Transform &inOutTransform ) |
@@ -175,6 +198,11 @@ | ||
175 | 198 | outTransform.mDerivedTransform = reinterpret_cast<Matrix4*>( mMemoryPools[WorldMat] ); |
176 | 199 | outTransform.mInheritOrientation= reinterpret_cast<bool*>( mMemoryPools[InheritOrientation] ); |
177 | 200 | outTransform.mInheritScale = reinterpret_cast<bool*>( mMemoryPools[InheritScale] ); |
201 | + | |
202 | +#ifdef USE_PCZ | |
203 | + outTransform.mMoved = reinterpret_cast<bool*>( mMemoryPools[Moved] ); | |
204 | + outTransform.mUpdated = reinterpret_cast<bool*>( mMemoryPools[Updated] ); | |
205 | +#endif | |
178 | 206 | |
179 | 207 | return mUsedMemory; |
180 | 208 | } |
@@ -2095,6 +2095,75 @@ | ||
2095 | 2095 | ++itor; |
2096 | 2096 | } |
2097 | 2097 | } |
2098 | +#ifdef USE_PCZ | |
2099 | +//----------------------------------------------------------------------- | |
2100 | +void SceneManager::resetAllUpdateFlagsThread( const ResetUpdateFlagsRequest &request, size_t threadIdx ) | |
2101 | +{ | |
2102 | + Transform t( request.t ); | |
2103 | + const size_t toAdvance = std::min( threadIdx * request.numNodesPerThread, | |
2104 | + request.numTotalNodes ); | |
2105 | + | |
2106 | + //Prevent going out of bounds (usually in the last threadIdx, or | |
2107 | + //when there are less nodes than ARRAY_PACKED_REALS | |
2108 | + const size_t numNodes = std::min( request.numNodesPerThread, request.numTotalNodes - toAdvance ); | |
2109 | + t.advancePack( toAdvance / ARRAY_PACKED_REALS ); | |
2110 | + | |
2111 | + for( size_t i=0; i<numNodes; i += ARRAY_PACKED_REALS ) | |
2112 | + { | |
2113 | + | |
2114 | + t.mMoved[0] = true; | |
2115 | + t.mMoved[1] = true; | |
2116 | + t.mMoved[2] = true; | |
2117 | + t.mMoved[3] = true; | |
2118 | + | |
2119 | + t.mUpdated[0] = false; | |
2120 | + t.mUpdated[1] = false; | |
2121 | + t.mUpdated[2] = false; | |
2122 | + t.mUpdated[3] = false; | |
2123 | + | |
2124 | + t.advancePack(); | |
2125 | + } | |
2126 | +} | |
2127 | +//----------------------------------------------------------------------- | |
2128 | +void SceneManager::resetAllUpdateFlags() | |
2129 | +{ | |
2130 | + mRequestType = RESET_ALL_UPDATE_FLAGS; | |
2131 | + NodeMemoryManagerVec::const_iterator it = mNodeMemoryManagerUpdateList.begin(); | |
2132 | + NodeMemoryManagerVec::const_iterator en = mNodeMemoryManagerUpdateList.end(); | |
2133 | + | |
2134 | + while( it != en ) | |
2135 | + { | |
2136 | + NodeMemoryManager *nodeMemoryManager = *it; | |
2137 | + const size_t numDepths = nodeMemoryManager->getNumDepths(); | |
2138 | + | |
2139 | + size_t start = nodeMemoryManager->getMemoryManagerType() == SCENE_STATIC ? | |
2140 | + mStaticMinDepthLevelDirty : 0; | |
2141 | + | |
2142 | + //Start from the zeroth level (root) unless static (start from first dirty) | |
2143 | + for( size_t i=start; i<numDepths; ++i ) | |
2144 | + { | |
2145 | + Transform t; | |
2146 | + const size_t numNodes = nodeMemoryManager->getFirstNode( t, i ); | |
2147 | + | |
2148 | + //nodesPerThread must be multiple of ARRAY_PACKED_REALS | |
2149 | + size_t nodesPerThread = ( numNodes + (mNumWorkerThreads-1) ) / mNumWorkerThreads; | |
2150 | + nodesPerThread = ( (nodesPerThread + ARRAY_PACKED_REALS - 1) / ARRAY_PACKED_REALS ) * | |
2151 | + ARRAY_PACKED_REALS; | |
2152 | + | |
2153 | + if( numNodes ) | |
2154 | + { | |
2155 | + //Send them to worker threads. We need to go depth by depth because | |
2156 | + //we may depend on parents which could be processed by different threads. | |
2157 | + mResetUpdateFlagsRequest = ResetUpdateFlagsRequest( t, nodesPerThread, numNodes ); | |
2158 | + fireWorkerThreadsAndWait(); | |
2159 | + //Node::updateAllTransforms( numNodes, t ); | |
2160 | + } | |
2161 | + } | |
2162 | + | |
2163 | + ++it; | |
2164 | + } | |
2165 | +} | |
2166 | +#endif | |
2098 | 2167 | //----------------------------------------------------------------------- |
2099 | 2168 | void SceneManager::updateAllTagPoints() |
2100 | 2169 | { |
@@ -2825,6 +2894,9 @@ | ||
2825 | 2894 | highLevelCull(); |
2826 | 2895 | _applySceneAnimations(); |
2827 | 2896 | updateAllTransforms(); |
2897 | +#ifdef USE_PCZ | |
2898 | + resetAllUpdateFlags(); | |
2899 | +#endif | |
2828 | 2900 | updateAllAnimations(); |
2829 | 2901 | updateAllTagPoints(); |
2830 | 2902 | #ifdef OGRE_LEGACY_ANIMATIONS |
@@ -5364,6 +5436,11 @@ | ||
5364 | 5436 | case UPDATE_ALL_TRANSFORMS: |
5365 | 5437 | updateAllTransformsThread( mUpdateTransformRequest, threadIdx ); |
5366 | 5438 | break; |
5439 | +#ifdef USE_PCZ | |
5440 | + case RESET_ALL_UPDATE_FLAGS: | |
5441 | + resetAllUpdateFlagsThread( mResetUpdateFlagsRequest, threadIdx ); | |
5442 | + break; | |
5443 | +#endif | |
5367 | 5444 | case UPDATE_ALL_BONE_TO_TAG_TRANSFORMS: |
5368 | 5445 | updateAllTransformsBoneToTagThread( mUpdateTransformRequest, threadIdx ); |
5369 | 5446 | break; |
@@ -120,11 +120,11 @@ | ||
120 | 120 | void updateZoneData(void); |
121 | 121 | void enable(bool yesno) {mEnabled = yesno;} |
122 | 122 | bool isEnabled(void) {return mEnabled;} |
123 | - bool isMoved(void) {return mMoved;} | |
124 | - void setMoved(bool value) {mMoved = value;} | |
123 | + bool isMoved(void) const; | |
124 | + void setMoved(bool value); | |
125 | 125 | void nodeUpdated(const Node*); |
126 | - void setUpdated( bool updated ) { mUpdated = updated; } | |
127 | - bool isUpdated() { return mUpdated; } | |
126 | + void setUpdated( bool updated ); | |
127 | + bool isUpdated() const; | |
128 | 128 | protected: |
129 | 129 | mutable Vector3 mNewPosition; |
130 | 130 | PCZone * mHomeZone; |
@@ -136,8 +136,8 @@ | ||
136 | 136 | PCZCamera* mLastVisibleFromCamera; |
137 | 137 | ZoneDataMap mZoneData; |
138 | 138 | bool mEnabled; |
139 | - mutable bool mMoved; | |
140 | - bool mUpdated; // Only once per frame. | |
139 | +// mutable bool mMoved; | |
140 | +// mutable bool mUpdated; // Only once per frame. | |
141 | 141 | }; |
142 | 142 | } |
143 | 143 |
@@ -552,7 +552,7 @@ | ||
552 | 552 | return; |
553 | 553 | } |
554 | 554 | // TODO ugly workaround to not update multiple times per frame. |
555 | - _resetPCZSceneNodes(); | |
555 | +// _resetPCZSceneNodes(); | |
556 | 556 | // First do the standard scene graph update |
557 | 557 | SceneManager::updateSceneGraph(); |
558 | 558 | // Update the portal positions |
@@ -561,7 +561,8 @@ | ||
561 | 561 | // check for portal zone-related changes (portals intersecting other portals) |
562 | 562 | _updatePortalZoneData(); |
563 | 563 | // mark nodes dirty base on portals that changed. |
564 | - _dirtyNodeByMovingPortals(); | |
564 | + // TODO is it faster to just dirty up everything instead of actually checking? Does this make sense for Octree based zones? | |
565 | +// _dirtyNodeByMovingPortals(); | |
565 | 566 | // update all scene nodes |
566 | 567 | _updatePCZSceneNodes(); |
567 | 568 | // calculate zones affected by each light |
@@ -45,6 +45,12 @@ | ||
45 | 45 | #include "OgreSceneNode.h" |
46 | 46 | #include "OgrePCZone.h" |
47 | 47 | |
48 | +#if OGRE_DEBUG_MODE >= OGRE_DEBUG_MEDIUM | |
49 | + #define CACHED_TRANSFORM_OUT_OF_DATE() this->_setCachedTransformOutOfDate() | |
50 | +#else | |
51 | + #define CACHED_TRANSFORM_OUT_OF_DATE() ((void)0) | |
52 | +#endif | |
53 | + | |
48 | 54 | namespace Ogre |
49 | 55 | { |
50 | 56 | PCZSceneNode::PCZSceneNode( IdType id, SceneManager* creator, NodeMemoryManager *nodeMemoryManager, |
@@ -55,8 +61,7 @@ | ||
55 | 61 | mAllowedToVisit(true), |
56 | 62 | mLastVisibleFrame(0), |
57 | 63 | mLastVisibleFromCamera(0), |
58 | - mEnabled(true), | |
59 | - mMoved(false) | |
64 | + mEnabled(true) | |
60 | 65 | { |
61 | 66 | setListener( this ); |
62 | 67 | } |
@@ -298,12 +303,37 @@ | ||
298 | 303 | |
299 | 304 | void PCZSceneNode::nodeUpdated(const Node*) |
300 | 305 | { |
301 | - if ( !mUpdated ) | |
306 | + if ( !isUpdated() ) | |
302 | 307 | { |
303 | 308 | mPrevPosition = mNewPosition; |
304 | 309 | mNewPosition = _getDerivedPosition(); // TODO make sure that the position has been updated before any calls here. |
305 | - mMoved = true; | |
306 | - mUpdated = true; | |
310 | + setMoved( true ); | |
311 | + setUpdated( true ); | |
307 | 312 | } |
308 | 313 | } |
314 | + | |
315 | + //----------------------------------------------------------------------- | |
316 | + void PCZSceneNode::setMoved(bool moved) | |
317 | + { | |
318 | + mTransform.mMoved[mTransform.mIndex] = moved; | |
319 | +// CACHED_TRANSFORM_OUT_OF_DATE(); | |
320 | + } | |
321 | + //----------------------------------------------------------------------- | |
322 | + bool PCZSceneNode::isMoved(void) const | |
323 | + { | |
324 | +// OGRE_ASSERT_MEDIUM( !mCachedTransformOutOfDate ); | |
325 | + return mTransform.mMoved[mTransform.mIndex]; | |
326 | + } | |
327 | + //----------------------------------------------------------------------- | |
328 | + void PCZSceneNode::setUpdated(bool updated) | |
329 | + { | |
330 | + mTransform.mUpdated[mTransform.mIndex] = updated; | |
331 | +// CACHED_TRANSFORM_OUT_OF_DATE(); | |
332 | + } | |
333 | + //----------------------------------------------------------------------- | |
334 | + bool PCZSceneNode::isUpdated(void) const | |
335 | + { | |
336 | +// OGRE_ASSERT_MEDIUM( !mCachedTransformOutOfDate ); | |
337 | + return mTransform.mUpdated[mTransform.mIndex]; | |
338 | + } | |
309 | 339 | } |