| 193 | } |
| 194 | |
| 195 | bool AnimationController::animate(RenderContext* pRenderContext, double currentTime) |
| 196 | { |
| 197 | FALCOR_PROFILE(pRenderContext, "animate"); |
| 198 | |
| 199 | std::fill(mMatricesChanged.begin(), mMatricesChanged.end(), false); |
| 200 | |
| 201 | // Check for edited scene nodes and update local matrices. |
| 202 | const auto& sceneGraph = mpScene->mSceneGraph; |
| 203 | bool edited = false; |
| 204 | for (size_t i = 0; i < sceneGraph.size(); ++i) |
| 205 | { |
| 206 | if (mNodesEdited[i]) |
| 207 | { |
| 208 | mLocalMatrices[i] = sceneGraph[i].transform; |
| 209 | mNodesEdited[i] = false; |
| 210 | mMatricesChanged[i] = true; |
| 211 | edited = true; |
| 212 | } |
| 213 | } |
| 214 | |
| 215 | bool changed = false; |
| 216 | double time = mLoopAnimations ? std::fmod(currentTime, mGlobalAnimationLength) : currentTime; |
| 217 | |
| 218 | // Check if animation controller was enabled/disabled since last call. |
| 219 | // When enabling/disabling, all data for the current and previous frame is initialized, |
| 220 | // including transformation matrices, dynamic vertex data etc. |
| 221 | if (mFirstUpdate || mEnabled != mPrevEnabled) |
| 222 | { |
| 223 | std::fill(mMatricesChanged.begin(), mMatricesChanged.end(), true); |
| 224 | initLocalMatrices(); |
| 225 | if (mEnabled) |
| 226 | { |
| 227 | updateLocalMatrices(time); |
| 228 | mTime = mPrevTime = time; |
| 229 | } |
| 230 | updateWorldMatrices(true); |
| 231 | uploadWorldMatrices(true); |
| 232 | |
| 233 | if (!sceneGraph.empty()) |
| 234 | { |
| 235 | FALCOR_ASSERT(mpWorldMatricesBuffer && mpPrevWorldMatricesBuffer); |
| 236 | FALCOR_ASSERT(mpInvTransposeWorldMatricesBuffer && mpPrevInvTransposeWorldMatricesBuffer); |
| 237 | pRenderContext->copyResource(mpPrevWorldMatricesBuffer.get(), mpWorldMatricesBuffer.get()); |
| 238 | pRenderContext->copyResource(mpPrevInvTransposeWorldMatricesBuffer.get(), mpInvTransposeWorldMatricesBuffer.get()); |
| 239 | bindBuffers(); |
| 240 | executeSkinningPass(pRenderContext, true); |
| 241 | } |
| 242 | |
| 243 | if (mpVertexCache) |
| 244 | { |
| 245 | if (mEnabled && mpVertexCache->hasAnimations()) |
| 246 | { |
| 247 | // Recompute time based on the cycle length of vertex caches. |
| 248 | double vertexCacheTime = (mGlobalAnimationLength == 0) ? currentTime : time; |
| 249 | mpVertexCache->animate(pRenderContext, vertexCacheTime); |
| 250 | } |
| 251 | mpVertexCache->copyToPrevVertices(pRenderContext); |
| 252 | } |
no test coverage detected