Browse Source

Optimized GetBatch() in StaticModel & AnimatedModel by caching the current LOD geometries into a flat array.
Optimized network client smoothing update by unsubscribing from the smoothing event if nothing to do.
Minor optimizations in View.

Lasse Öörni 13 years ago
parent
commit
00522a44a7

+ 30 - 28
Bin/Data/Scripts/TestScene.as

@@ -22,6 +22,8 @@ void Start()
     else
         OpenConsoleWindow();
 
+    ParseNetworkArguments();
+
     InitScene();
 
     SubscribeToEvent("Update", "HandleUpdate");
@@ -33,8 +35,7 @@ void Start()
     SubscribeToEvent("SpawnBox", "HandleSpawnBox");
 
     network.RegisterRemoteEvent("SpawnBox");
-    
-    ParseNetworkArguments();
+
     if (runServer)
     {
         network.StartServer(serverPort);
@@ -50,8 +51,6 @@ void Start()
     }
     if (runClient)
     {
-        testScene.Clear();
-
         // Test package download. Remove existing Data.pak from resource cache so that it will be downloaded
         // However, be sure to add the Data directory so that resource requests do not fail in the meanwhile
         String packageName = fileSystem.programDir + "Data.pak";
@@ -94,6 +93,33 @@ void InitScene()
 {
     testScene = Scene("TestScene");
 
+    // Enable access to this script file & scene from the console
+    script.defaultScene = testScene;
+    script.defaultScriptFile = scriptFile;
+
+    // Create the camera outside the scene so it is unaffected by scene load/save
+    cameraNode = Node();
+    camera = cameraNode.CreateComponent("Camera");
+    cameraNode.position = Vector3(0, 2, 0);
+
+    if (!engine.headless)
+    {
+        edgeFilter = PostProcess();
+        edgeFilter.parameters = cache.GetResource("XMLFile", "PostProcess/EdgeFilter.xml");
+        edgeFilter.active = false; // Start out disabled
+
+        bloom = PostProcess();
+        bloom.parameters = cache.GetResource("XMLFile", "PostProcess/Bloom.xml");
+        bloom.active = false;
+
+        renderer.viewports[0] = Viewport(testScene, camera);
+        renderer.viewports[0].AddPostProcess(edgeFilter);
+        renderer.viewports[0].AddPostProcess(bloom);
+    }
+    
+    if (runClient)
+        return;
+
     PhysicsWorld@ world = testScene.CreateComponent("PhysicsWorld");
     testScene.CreateComponent("Octree");
     testScene.CreateComponent("DebugRenderer");
@@ -196,30 +222,6 @@ void InitScene()
         AnimationController@ ctrl = objectNode.CreateComponent("AnimationController");
         ctrl.Play("Models/Jack_Walk.ani", 0, true, 0.0f);
     }
-
-    // Enable access to this script file & scene from the console
-    script.defaultScene = testScene;
-    script.defaultScriptFile = scriptFile;
-
-    // Create the camera outside the scene so it is unaffected by scene load/save
-    cameraNode = Node();
-    camera = cameraNode.CreateComponent("Camera");
-    cameraNode.position = Vector3(0, 2, 0);
-
-    if (!engine.headless)
-    {
-        edgeFilter = PostProcess();
-        edgeFilter.parameters = cache.GetResource("XMLFile", "PostProcess/EdgeFilter.xml");
-        edgeFilter.active = false; // Start out disabled
-
-        bloom = PostProcess();
-        bloom.parameters = cache.GetResource("XMLFile", "PostProcess/Bloom.xml");
-        bloom.active = false;
-
-        renderer.viewports[0] = Viewport(testScene, camera);
-        renderer.viewports[0].AddPostProcess(edgeFilter);
-        renderer.viewports[0].AddPostProcess(bloom);
-    }
 }
 
 void HandleUpdate(StringHash eventType, VariantMap& eventData)

+ 1 - 1
Engine/Graphics/AnimatedModel.cpp

@@ -257,7 +257,7 @@ UpdateGeometryType AnimatedModel::GetUpdateGeometryType()
 void AnimatedModel::GetBatch(Batch& batch, const FrameInfo& frame, unsigned batchIndex)
 {
     batch.distance_ = geometryDistances_[batchIndex];
-    batch.geometry_ = geometries_[batchIndex][lodLevels_[batchIndex]];
+    batch.geometry_ = currentGeometries_[batchIndex];
     batch.geometryType_ = GEOM_SKINNED;
     batch.worldTransform_ = &GetWorldTransform();
     batch.material_ = materials_[batchIndex];

+ 4 - 1
Engine/Graphics/StaticModel.cpp

@@ -165,7 +165,7 @@ unsigned StaticModel::GetNumBatches()
 void StaticModel::GetBatch(Batch& batch, const FrameInfo& frame, unsigned batchIndex)
 {
     batch.distance_ = geometryDistances_[batchIndex];
-    batch.geometry_ = geometries_[batchIndex][lodLevels_[batchIndex]];
+    batch.geometry_ = currentGeometries_[batchIndex];
     batch.worldTransform_ = &GetWorldTransform();
     batch.material_ = materials_[batchIndex];
 }
@@ -354,11 +354,13 @@ void StaticModel::ResetLodLevels()
 {
     // Ensure that each subgeometry has at least one LOD level, and reset the current LOD level
     lodLevels_.Resize(geometries_.Size());
+    currentGeometries_.Resize(geometries_.Size());
     for (unsigned i = 0; i < geometries_.Size(); ++i)
     {
         if (!geometries_[i].Size())
             geometries_[i].Resize(1);
         lodLevels_[i] = 0;
+        currentGeometries_[i] = geometries_[i][0];
     }
     
     // Find out the real LOD levels on next geometry update
@@ -376,6 +378,7 @@ void StaticModel::CalculateLodLevels()
                 break;
         }
         lodLevels_[i] = j - 1;
+        currentGeometries_[i] = geometries_[i][lodLevels_[i]];
     }
 }
 

+ 3 - 1
Engine/Graphics/StaticModel.h

@@ -98,7 +98,7 @@ protected:
     SharedPtr<Model> model_;
     /// Bounding box.
     BoundingBox boundingBox_;
-    /// Geometries.
+    /// All geometries.
     Vector<Vector<SharedPtr<Geometry> > > geometries_;
     /// Geometry centers.
     PODVector<Vector3> geometryCenters_;
@@ -106,6 +106,8 @@ protected:
     PODVector<float> geometryDistances_;
     /// LOD levels.
     PODVector<unsigned> lodLevels_;
+    /// Current geometries chosen with LOD.
+    PODVector<Geometry*> currentGeometries_;
     /// Materials.
     Vector<SharedPtr<Material> > materials_;
     /// Software LOD level, used in raycast and occlusion.

+ 10 - 7
Engine/Graphics/View.cpp

@@ -799,6 +799,7 @@ void View::GetBatches()
                             allGeometries_.Push(drawable);
                         }
                         
+                        Zone* zone = GetZone(drawable);
                         unsigned numBatches = drawable->GetNumBatches();
                         
                         for (unsigned l = 0; l < numBatches; ++l)
@@ -817,7 +818,7 @@ void View::GetBatches()
                             
                             // Fill the rest of the batch
                             shadowBatch.camera_ = shadowCamera;
-                            shadowBatch.zone_ = GetZone(drawable);
+                            shadowBatch.zone_ = zone;
                             shadowBatch.lightQueue_ = &lightQueue;
                             
                             FinalizeBatch(shadowBatch, tech, pass);
@@ -900,7 +901,9 @@ void View::GetBatches()
         for (PODVector<Drawable*>::ConstIterator i = geometries_.Begin(); i != geometries_.End(); ++i)
         {
             Drawable* drawable = *i;
+            Zone* zone = GetZone(drawable);
             unsigned numBatches = drawable->GetNumBatches();
+            
             const PODVector<Light*>& drawableVertexLights = drawable->GetVertexLights();
             if (!drawableVertexLights.Empty())
                 drawable->LimitVertexLights();
@@ -921,7 +924,7 @@ void View::GetBatches()
                 
                 // Fill the rest of the batch
                 baseBatch.camera_ = camera_;
-                baseBatch.zone_ = GetZone(drawable);
+                baseBatch.zone_ = zone;
                 baseBatch.isBase_ = true;
                 
                 Pass* pass = 0;
@@ -1125,12 +1128,12 @@ void View::UpdateGeometries()
 void View::GetLitBatches(Drawable* drawable, LightBatchQueue& lightQueue)
 {
     Light* light = lightQueue.light_;
-    Light* firstLight = drawable->GetFirstLight();
     Zone* zone = GetZone(drawable);
+    
+    bool hasAmbientGradient = zone->GetAmbientGradient() && zone->GetAmbientStartColor() != zone->GetAmbientEndColor();
     // Shadows on transparencies can only be rendered if shadow maps are not reused
     bool allowTransparentShadows = !renderer_->GetReuseShadowMaps();
-    bool hasVertexLights = drawable->GetVertexLights().Size() > 0;
-    bool hasAmbientGradient = zone->GetAmbientGradient() && zone->GetAmbientStartColor() != zone->GetAmbientEndColor();
+    bool allowLitBase = light == drawable->GetFirstLight() && drawable->GetVertexLights().Empty() && !hasAmbientGradient;
     unsigned numBatches = drawable->GetNumBatches();
     
     for (unsigned i = 0; i < numBatches; ++i)
@@ -1151,7 +1154,7 @@ void View::GetLitBatches(Drawable* drawable, LightBatchQueue& lightQueue)
         
         // Check for lit base pass. Because it uses the replace blend mode, it must be ensured to be the first light
         // Also vertex lighting or ambient gradient require the non-lit base pass, so skip in those cases
-        if (i < 32 && light == firstLight && !hasVertexLights && !hasAmbientGradient && !drawable->HasBasePass(i))
+        if (i < 32 && allowLitBase)
         {
             pass = tech->GetPass(PASS_LITBASE);
             if (pass)
@@ -1171,7 +1174,7 @@ void View::GetLitBatches(Drawable* drawable, LightBatchQueue& lightQueue)
         // Fill the rest of the batch
         litBatch.camera_ = camera_;
         litBatch.lightQueue_ = &lightQueue;
-        litBatch.zone_ = GetZone(drawable);
+        litBatch.zone_ = zone;
         
         // Check from the ambient pass whether the object is opaque or transparent
         Pass* ambientPass = tech->GetPass(PASS_BASE);

+ 24 - 6
Engine/Scene/SmoothedTransform.cpp

@@ -40,7 +40,8 @@ SmoothedTransform::SmoothedTransform(Context* context) :
     targetRotation_(Quaternion::IDENTITY),
     smoothingConstant_(DEFAULT_SMOOTHING_CONSTANT),
     snapThreshold_(DEFAULT_SNAP_THRESHOLD),
-    smoothingMask_(SMOOTH_NONE)
+    smoothingMask_(SMOOTH_NONE),
+    subscribed_(false)
 {
 }
 
@@ -92,12 +93,27 @@ void SmoothedTransform::Update(float constant, float squaredSnapThreshold)
             node_->SetRotation(rotation);
         }
     }
+    
+    // If smoothing has completed, unsubscribe from the update event
+    if (!smoothingMask_)
+    {
+        UnsubscribeFromEvent(GetScene(), E_UPDATESMOOTHING);
+        subscribed_ = false;
+    }
 }
 
 void SmoothedTransform::SetTargetPosition(const Vector3& position)
 {
     targetPosition_ = position;
     smoothingMask_ |= SMOOTH_POSITION;
+    
+    // Subscribe to smoothing update if not yet subscribed
+    if (!subscribed_)
+    {
+        SubscribeToEvent(GetScene(), E_UPDATESMOOTHING, HANDLER(SmoothedTransform, HandleUpdateSmoothing));
+        subscribed_ = true;
+    }
+    
     SendEvent(E_TARGETPOSITION);
 }
 
@@ -105,6 +121,13 @@ void SmoothedTransform::SetTargetRotation(const Quaternion& rotation)
 {
     targetRotation_ = rotation;
     smoothingMask_ |= SMOOTH_ROTATION;
+    
+    if (!subscribed_)
+    {
+        SubscribeToEvent(GetScene(), E_UPDATESMOOTHING, HANDLER(SmoothedTransform, HandleUpdateSmoothing));
+        subscribed_ = true;
+    }
+    
     SendEvent(E_TARGETROTATION);
 }
 
@@ -147,11 +170,6 @@ void SmoothedTransform::OnNodeSet(Node* node)
         // Copy initial target transform
         targetPosition_ = node->GetPosition();
         targetRotation_ = node->GetRotation();
-        
-        // Subscribe to smoothing update
-        Scene* scene = GetScene();
-        if (scene)
-            SubscribeToEvent(scene, E_UPDATESMOOTHING, HANDLER(SmoothedTransform, HandleUpdateSmoothing));
     }
 }
 

+ 2 - 0
Engine/Scene/SmoothedTransform.h

@@ -85,4 +85,6 @@ private:
     float snapThreshold_;
     /// Active smoothing operations bitmask.
     unsigned char smoothingMask_;
+    /// Subscribed to smoothing update event flag.
+    bool subscribed_;
 };