Culling, Controllers and performance!

Hi all,

One possible performance improvement in jme is to disable all controllers when the object gets culled, obvious performance improvements can be obtained there…



However, certain controllers might change the location and thus bring back the object into the scene. If those are disabled, this behaviour cannot occur.



Thus, i suggest a field (setCullDisable), whereby if true, this controller’s update will not be called again when the object is culled.



This can be easily integrated by adding the following:



Controller:


   /**
    * True if this controller is to be disabled through culling
    */
   private boolean cullDisable = false;

   /**
    * Set whether this controller will be disabled when the spatial that is
    * this controller's parent is culled.
    *
    * @param cull
    */
   public void setCullDisable(boolean cull) {
      cullDisable = cull;
   }

   /**
    * Return whether this controller will be disabled when the spatial that
    * owns this controller is culled.
    *
    * @return
    */
   public boolean getCullDisable() {
      return cullDisable;
   }



And in spatial:

Spatial:


   /**
    * <code>updateWorldData</code> updates the world transforms from the
    * parent down to the leaf.
    *
    * @param time
    *            the frame time.
    */
   protected void updateWorldData(float time) {
      boolean culled = false;
      if (getLastFrustumIntersection() == Camera.OUTSIDE_FRUSTUM) {
         culled = true;
      }
      // see if this object has been culled
      // update spatial state via controllers
      Controller controller;
      for (int i = 0, gSize = geometricalControllers.size(); i < gSize; i++) {
         if ((controller = (Controller) geometricalControllers.get(i)) != null) {
            if (culled == true && controller.getCullDisable() == false) {
               controller.setActive(true);
               controller.update(time);
            } else if (culled == false) {
               controller.setActive(true);
               controller.update(time);
            } else {
               controller.setActive(false);
            }
         }
      }

      if (parent != null) {
         worldScale.set(parent.getWorldScale()).multLocal(localScale);
         parent.getWorldRotation().mult(localRotation, worldRotation);
         worldTranslation = parent.getWorldRotation().mult(localTranslation, worldTranslation)
               .multLocal(parent.getWorldScale()).addLocal(parent.getWorldTranslation());
      } else {
         worldScale = localScale;
         worldRotation = localRotation;
         worldTranslation = localTranslation;
      }
   }



I have tested this and it works flawlessly. This is good for animation controllers that dont need to run if the spatial itself is culled...Things like that. Im also using it to disable the physics object when the spatial is being culled (via a controller).

DP

Sounds like a smart idea to me.