|
@@ -374,6 +374,12 @@ void Octree::SetSize(const BoundingBox& box, unsigned numLevels)
|
|
|
|
|
|
|
|
void Octree::Update(const FrameInfo& frame)
|
|
void Octree::Update(const FrameInfo& frame)
|
|
|
{
|
|
{
|
|
|
|
|
+ if (!Thread::IsMainThread())
|
|
|
|
|
+ {
|
|
|
|
|
+ URHO3D_LOGERROR("Octree::Update() can not be called from worker threads");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// Let drawables update themselves before reinsertion. This can be used for animation
|
|
// Let drawables update themselves before reinsertion. This can be used for animation
|
|
|
if (!drawableUpdates_.Empty())
|
|
if (!drawableUpdates_.Empty())
|
|
|
{
|
|
{
|
|
@@ -412,6 +418,24 @@ void Octree::Update(const FrameInfo& frame)
|
|
|
scene->EndThreadedUpdate();
|
|
scene->EndThreadedUpdate();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // If any drawables were inserted during threaded update, update them now from the main thread
|
|
|
|
|
+ if (!threadedDrawableUpdates_.Empty())
|
|
|
|
|
+ {
|
|
|
|
|
+ URHO3D_PROFILE(UpdateDrawablesQueuedDuringUpdate);
|
|
|
|
|
+
|
|
|
|
|
+ for (PODVector<Drawable*>::ConstIterator i = threadedDrawableUpdates_.Begin(); i != threadedDrawableUpdates_.End(); ++i)
|
|
|
|
|
+ {
|
|
|
|
|
+ Drawable* drawable = *i;
|
|
|
|
|
+ if (drawable)
|
|
|
|
|
+ {
|
|
|
|
|
+ drawable->Update(frame);
|
|
|
|
|
+ drawableUpdates_.Push(drawable);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ threadedDrawableUpdates_.Clear();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// Notify drawable update being finished. Custom animation (eg. IK) can be done at this point
|
|
// Notify drawable update being finished. Custom animation (eg. IK) can be done at this point
|
|
|
Scene* scene = GetScene();
|
|
Scene* scene = GetScene();
|
|
|
if (scene)
|
|
if (scene)
|
|
@@ -540,7 +564,7 @@ void Octree::QueueUpdate(Drawable* drawable)
|
|
|
if (scene && scene->IsThreadedUpdate())
|
|
if (scene && scene->IsThreadedUpdate())
|
|
|
{
|
|
{
|
|
|
MutexLock lock(octreeMutex_);
|
|
MutexLock lock(octreeMutex_);
|
|
|
- drawableUpdates_.Push(drawable);
|
|
|
|
|
|
|
+ threadedDrawableUpdates_.Push(drawable);
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
drawableUpdates_.Push(drawable);
|
|
drawableUpdates_.Push(drawable);
|
|
@@ -550,6 +574,8 @@ void Octree::QueueUpdate(Drawable* drawable)
|
|
|
|
|
|
|
|
void Octree::CancelUpdate(Drawable* drawable)
|
|
void Octree::CancelUpdate(Drawable* drawable)
|
|
|
{
|
|
{
|
|
|
|
|
+ // This doesn't have to take into account scene being in threaded update, because it is called only
|
|
|
|
|
+ // when removing a drawable from octree, which should only ever happen from the main thread.
|
|
|
drawableUpdates_.Remove(drawable);
|
|
drawableUpdates_.Remove(drawable);
|
|
|
drawable->updateQueued_ = false;
|
|
drawable->updateQueued_ = false;
|
|
|
}
|
|
}
|