Browse Source

Fix BillboardSet & Text3D fixed screen size with multiple views. Remove unused variable. Fix potential bug with BillboardSet update LOD timer & fixed screen size (always force update)

Lasse Öörni 9 years ago
parent
commit
ef212b9290

+ 41 - 33
Source/Urho3D/Graphics/BillboardSet.cpp

@@ -185,31 +185,7 @@ void BillboardSet::UpdateBatches(const FrameInfo& frame)
 
 
         // Calculate fixed screen size scale factor for billboards if needed
         // Calculate fixed screen size scale factor for billboards if needed
         if (fixedScreenSize_)
         if (fixedScreenSize_)
-        {
-            bufferDirty_ = true;
-            worldBoundingBoxDirty_ = true;
-            float invViewHeight = 1.0f / frame.viewSize_.y_;
-            float halfViewWorldSize = frame.camera_->GetHalfViewSize();
-
-            if (!frame.camera_->IsOrthographic())
-            {
-                Matrix4 viewProj(frame.camera_->GetProjection(false) * frame.camera_->GetView());
-                const Matrix3x4& worldTransform = node_->GetWorldTransform();
-                Matrix3x4 billboardTransform = relative_ ? worldTransform : Matrix3x4::IDENTITY;
-                Vector3 billboardScale = scaled_ ? worldTransform.Scale() : Vector3::ONE;
-
-                for (unsigned i = 0; i < billboards_.Size(); ++i)
-                {
-                    Vector4 projPos(viewProj * Vector4(billboardTransform * billboards_[i].position_, 1.0f));
-                    billboards_[i].screenScaleFactor_ = invViewHeight * halfViewWorldSize * projPos.w_;
-                }
-            }
-            else
-            {
-                for (unsigned i = 0; i < billboards_.Size(); ++i)
-                    billboards_[i].screenScaleFactor_ = invViewHeight * halfViewWorldSize;
-            }
-        }
+            CalculateFixedScreenSize(frame);
     }
     }
 
 
     distance_ = frame.camera_->GetDistance(GetWorldBoundingBox().Center());
     distance_ = frame.camera_->GetDistance(GetWorldBoundingBox().Center());
@@ -233,11 +209,9 @@ void BillboardSet::UpdateBatches(const FrameInfo& frame)
 
 
 void BillboardSet::UpdateGeometry(const FrameInfo& frame)
 void BillboardSet::UpdateGeometry(const FrameInfo& frame)
 {
 {
-    if (bufferSizeDirty_ || indexBuffer_->IsDataLost())
-        UpdateBufferSize();
-
-    if (bufferDirty_ || sortThisFrame_ || vertexBuffer_->IsDataLost())
-        UpdateVertexBuffer(frame);
+    // If rendering from multiple views and fixed screen size is in use, re-update scale factors before each render
+    if (fixedScreenSize_ && viewCameras_.Size() > 1)
+        CalculateFixedScreenSize(frame);
 
 
     // If using camera facing, re-update the rotation for the current view now
     // If using camera facing, re-update the rotation for the current view now
     if (faceCameraMode_ != FC_NONE)
     if (faceCameraMode_ != FC_NONE)
@@ -245,15 +219,20 @@ void BillboardSet::UpdateGeometry(const FrameInfo& frame)
         transforms_[1] = Matrix3x4(Vector3::ZERO, frame.camera_->GetFaceCameraRotation(node_->GetWorldPosition(),
         transforms_[1] = Matrix3x4(Vector3::ZERO, frame.camera_->GetFaceCameraRotation(node_->GetWorldPosition(),
             node_->GetWorldRotation(), faceCameraMode_), Vector3::ONE);
             node_->GetWorldRotation(), faceCameraMode_), Vector3::ONE);
     }
     }
+
+    if (bufferSizeDirty_ || indexBuffer_->IsDataLost())
+        UpdateBufferSize();
+
+    if (bufferDirty_ || sortThisFrame_ || vertexBuffer_->IsDataLost())
+        UpdateVertexBuffer(frame);
 }
 }
 
 
 UpdateGeometryType BillboardSet::GetUpdateGeometryType()
 UpdateGeometryType BillboardSet::GetUpdateGeometryType()
 {
 {
     // If using camera facing, always need some kind of geometry update, in case the billboard set is rendered from several views
     // If using camera facing, always need some kind of geometry update, in case the billboard set is rendered from several views
-    if (bufferDirty_ || bufferSizeDirty_ || vertexBuffer_->IsDataLost() || indexBuffer_->IsDataLost() || sortThisFrame_)
+    if (bufferDirty_ || bufferSizeDirty_ || vertexBuffer_->IsDataLost() || indexBuffer_->IsDataLost() || sortThisFrame_ ||
+        faceCameraMode_ != FC_NONE || fixedScreenSize_)
         return UPDATE_MAIN_THREAD;
         return UPDATE_MAIN_THREAD;
-    else if (faceCameraMode_ != FC_NONE)
-        return UPDATE_WORKER_THREAD;
     else
     else
         return UPDATE_NONE;
         return UPDATE_NONE;
 }
 }
@@ -764,4 +743,33 @@ void BillboardSet::MarkPositionsDirty()
     bufferDirty_ = true;
     bufferDirty_ = true;
 }
 }
 
 
+void BillboardSet::CalculateFixedScreenSize(const FrameInfo& frame)
+{
+    float invViewHeight = 1.0f / frame.viewSize_.y_;
+    float halfViewWorldSize = frame.camera_->GetHalfViewSize();
+
+    if (!frame.camera_->IsOrthographic())
+    {
+        Matrix4 viewProj(frame.camera_->GetProjection(false) * frame.camera_->GetView());
+        const Matrix3x4& worldTransform = node_->GetWorldTransform();
+        Matrix3x4 billboardTransform = relative_ ? worldTransform : Matrix3x4::IDENTITY;
+        Vector3 billboardScale = scaled_ ? worldTransform.Scale() : Vector3::ONE;
+
+        for (unsigned i = 0; i < billboards_.Size(); ++i)
+        {
+            Vector4 projPos(viewProj * Vector4(billboardTransform * billboards_[i].position_, 1.0f));
+            billboards_[i].screenScaleFactor_ = invViewHeight * halfViewWorldSize * projPos.w_;
+        }
+    }
+    else
+    {
+        for (unsigned i = 0; i < billboards_.Size(); ++i)
+            billboards_[i].screenScaleFactor_ = invViewHeight * halfViewWorldSize;
+    }
+
+    bufferDirty_ = true;
+    forceUpdate_ = true;
+    worldBoundingBoxDirty_ = true;
+}
+
 }
 }

+ 2 - 2
Source/Urho3D/Graphics/BillboardSet.h

@@ -173,6 +173,8 @@ private:
     void UpdateBufferSize();
     void UpdateBufferSize();
     /// Rewrite billboard vertex buffer.
     /// Rewrite billboard vertex buffer.
     void UpdateVertexBuffer(const FrameInfo& frame);
     void UpdateVertexBuffer(const FrameInfo& frame);
+    /// Calculate billboard scale factors in fixed screen size mode.
+    void CalculateFixedScreenSize(const FrameInfo& frame);
 
 
     /// Geometry.
     /// Geometry.
     SharedPtr<Geometry> geometry_;
     SharedPtr<Geometry> geometry_;
@@ -196,8 +198,6 @@ private:
     unsigned sortFrameNumber_;
     unsigned sortFrameNumber_;
     /// Previous offset to camera for determining whether sorting is necessary.
     /// Previous offset to camera for determining whether sorting is necessary.
     Vector3 previousOffset_;
     Vector3 previousOffset_;
-    /// Scale factor for fixed screen size mode.
-    float fixedScaleFactor_;
     /// Billboard pointers for sorting.
     /// Billboard pointers for sorting.
     Vector<Billboard*> sortedBillboards_;
     Vector<Billboard*> sortedBillboards_;
     /// Attribute buffer for network replication.
     /// Attribute buffer for network replication.

+ 31 - 24
Source/Urho3D/UI/Text3D.cpp

@@ -116,29 +116,7 @@ void Text3D::UpdateBatches(const FrameInfo& frame)
     distance_ = frame.camera_->GetDistance(GetWorldBoundingBox().Center());
     distance_ = frame.camera_->GetDistance(GetWorldBoundingBox().Center());
 
 
     if (faceCameraMode_ != FC_NONE || fixedScreenSize_)
     if (faceCameraMode_ != FC_NONE || fixedScreenSize_)
-    {
-        Vector3 worldPosition = node_->GetWorldPosition();
-        Vector3 worldScale = node_->GetWorldScale();
-
-        if (fixedScreenSize_)
-        {
-            float textScaling = 2.0f / TEXT_SCALING / frame.viewSize_.y_;
-            float halfViewWorldSize = frame.camera_->GetHalfViewSize();
-
-            if (!frame.camera_->IsOrthographic())
-            {
-                Matrix4 viewProj(frame.camera_->GetProjection(false) * frame.camera_->GetView());
-                Vector4 projPos(viewProj * Vector4(worldPosition, 1.0f));
-                worldScale *= textScaling * halfViewWorldSize * projPos.w_;
-            }
-            else
-                worldScale *= textScaling * halfViewWorldSize;
-        }
-
-        customWorldTransform_ = Matrix3x4(worldPosition, frame.camera_->GetFaceCameraRotation(
-            worldPosition, node_->GetWorldRotation(), faceCameraMode_), worldScale);
-        worldBoundingBoxDirty_ = true;
-    }
+        CalculateFixedScreenSize(frame);
 
 
     for (unsigned i = 0; i < batches_.Size(); ++i)
     for (unsigned i = 0; i < batches_.Size(); ++i)
     {
     {
@@ -166,6 +144,10 @@ void Text3D::UpdateGeometry(const FrameInfo& frame)
         fontDataLost_ = false;
         fontDataLost_ = false;
     }
     }
 
 
+    // In case is being rendered from multiple views, recalculate camera facing & fixed size
+    if (faceCameraMode_ != FC_NONE || fixedScreenSize_)
+        CalculateFixedScreenSize(frame);
+
     if (geometryDirty_)
     if (geometryDirty_)
     {
     {
         for (unsigned i = 0; i < batches_.Size() && i < uiBatches_.Size(); ++i)
         for (unsigned i = 0; i < batches_.Size() && i < uiBatches_.Size(); ++i)
@@ -189,7 +171,7 @@ void Text3D::UpdateGeometry(const FrameInfo& frame)
 
 
 UpdateGeometryType Text3D::GetUpdateGeometryType()
 UpdateGeometryType Text3D::GetUpdateGeometryType()
 {
 {
-    if (geometryDirty_ || fontDataLost_ || vertexBuffer_->IsDataLost())
+    if (geometryDirty_ || fontDataLost_ || vertexBuffer_->IsDataLost() || faceCameraMode_ != FC_NONE || fixedScreenSize_)
         return UPDATE_MAIN_THREAD;
         return UPDATE_MAIN_THREAD;
     else
     else
         return UPDATE_NONE;
         return UPDATE_NONE;
@@ -698,4 +680,29 @@ void Text3D::UpdateTextMaterials(bool forceUpdate)
     }
     }
 }
 }
 
 
+void Text3D::CalculateFixedScreenSize(const FrameInfo& frame)
+{
+    Vector3 worldPosition = node_->GetWorldPosition();
+    Vector3 worldScale = node_->GetWorldScale();
+
+    if (fixedScreenSize_)
+    {
+        float textScaling = 2.0f / TEXT_SCALING / frame.viewSize_.y_;
+        float halfViewWorldSize = frame.camera_->GetHalfViewSize();
+
+        if (!frame.camera_->IsOrthographic())
+        {
+            Matrix4 viewProj(frame.camera_->GetProjection(false) * frame.camera_->GetView());
+            Vector4 projPos(viewProj * Vector4(worldPosition, 1.0f));
+            worldScale *= textScaling * halfViewWorldSize * projPos.w_;
+        }
+        else
+            worldScale *= textScaling * halfViewWorldSize;
+    }
+
+    customWorldTransform_ = Matrix3x4(worldPosition, frame.camera_->GetFaceCameraRotation(
+        worldPosition, node_->GetWorldRotation(), faceCameraMode_), worldScale);
+    worldBoundingBoxDirty_ = true;
+}
+
 }
 }

+ 2 - 0
Source/Urho3D/UI/Text3D.h

@@ -175,6 +175,8 @@ protected:
     void UpdateTextBatches();
     void UpdateTextBatches();
     /// Create materials for text rendering. May only be called from the main thread. Text %UI batches must be up-to-date.
     /// Create materials for text rendering. May only be called from the main thread. Text %UI batches must be up-to-date.
     void UpdateTextMaterials(bool forceUpdate = false);
     void UpdateTextMaterials(bool forceUpdate = false);
+    /// Recalculate camera facing and fixed screen size.
+    void CalculateFixedScreenSize(const FrameInfo& frame);
     
     
     /// Internally used text element.
     /// Internally used text element.
     Text text_;
     Text text_;