TestOutlinePass terrain wireframe

There seems to be an issue with TestOutlinePass, if a terrain model is added to the scene.

Here follows the TestOutlinePass test, with added terrain creation lines (which are shown in the second piece of code).



/*
 * Copyright (c) 2003-2006 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package jmetest.renderer;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.jme.app.SimplePassGame;
import com.jme.light.PointLight;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.pass.OutlinePass;
import com.jme.scene.Node;
import com.jme.scene.SharedNode;
import com.jme.scene.state.CullState;
import com.jme.util.export.binary.BinaryImporter;
import com.jme.bounding.BoundingBox;
import com.jmex.model.converters.Md2ToJme;
import com.jmex.terrain.util.HillHeightMap;
import com.jmex.terrain.TerrainPage;

/**
 * Started Date: Jan 21, 2006<br>
 *
 * This class test the Outline RenderPass.
 *
 * @author Beskid Lucian Cristian
 * @version $Id: TestOutlinePass.java,v 1.5 2007/08/17 22:04:20 nca Exp $
 */
public class TestOutlinePass extends SimplePassGame {
    private static final Logger logger = Logger.getLogger(TestOutlinePass.class
            .getName());
   
   private Node model = null;

   protected void simpleInitGame() {
      display.setTitle("Outline render pass test");
      display.getRenderer().setBackgroundColor(new ColorRGBA(0.5f, 0.7f, 1f, 1f));

      cam.setFrustumPerspective(55.0f, (float) display.getWidth() / (float) display.getHeight(), 1, 1000);
      cam.setLocation(new Vector3f(50, 0, 0));
      cam.lookAt(new Vector3f(0, 0, 0), new Vector3f(0, 1, 0));

      PointLight light = new PointLight();
      light.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
      light.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
      light.setLocation(new Vector3f(0, 30, 0));
      light.setEnabled(true);
      lightState.attach(light);

      Node outlinedObjects = new Node("outlined");

      OutlinePass outlineRenderPass = new OutlinePass();
      outlineRenderPass.add(outlinedObjects);
      outlineRenderPass.setEnabled(true);

      pManager.add(outlineRenderPass);

      rootNode.attachChild(outlinedObjects);

      try {
         // load/convert the model
         Md2ToJme converter = new Md2ToJme();
         ByteArrayOutputStream stream = new ByteArrayOutputStream();
         converter
               .convert(getClass().getClassLoader().getResourceAsStream("jmetest/data/model/drfreak.md2"), stream);
         model = (Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(stream.toByteArray()));

         // don't forget to set the proper cull state otherwise you might get
         // weird effects
         CullState cullState = display.getRenderer().createCullState();
         cullState.setCullMode(CullState.CS_FRONT);
         cullState.setEnabled(true);
         model.setRenderState(cullState);
      } catch (Exception e) {
         logger.log(Level.SEVERE, "Failed to load Md2 file", e);
      }

      if (model != null) {
         SharedNode outlinedModel = new SharedNode("outlined.model", model);

         outlinedObjects.attachChild(outlinedModel);
      }

        //



        HillHeightMap heightMap = new HillHeightMap(129, 200, 5.0f, 30.0f, (byte)3, 4443);
        heightMap.setHeightScale(0.001f);
        Vector3f terrainScale = new Vector3f(10, 1, 10);
        TerrainPage terrain = new TerrainPage("World", 33, heightMap.getSize(), terrainScale, heightMap.getHeightMap(), false);

        terrain.setModelBound(new BoundingBox());
        terrain.updateModelBound();

        SharedNode outlinedModel = new SharedNode("outlined.model", terrain);
        outlinedObjects.attachChild(outlinedModel);

        //

        rootNode.updateGeometricState(0, true);
      rootNode.updateRenderState();
   }

   public static void main(String[] args) {
      TestOutlinePass app = new TestOutlinePass();
      app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG);
      app.start();
   }
   
   public TestOutlinePass() {
      /* un-comment the line below line to enable AA */
      this.samples = 2;
   }
}



The lines added to the test are:


        HillHeightMap heightMap = new HillHeightMap(129, 200, 5.0f, 30.0f, (byte)3, 4443);
        heightMap.setHeightScale(0.001f);
        Vector3f terrainScale = new Vector3f(10, 1, 10);
        TerrainPage terrain = new TerrainPage("World", 33, heightMap.getSize(), terrainScale, heightMap.getHeightMap(), false);

        terrain.setModelBound(new BoundingBox());
        terrain.updateModelBound();

        SharedNode outlinedModel = new SharedNode("outlined.model", terrain);
        outlinedObjects.attachChild(outlinedModel);



The result is:

Spoofing in the code of the OutlineRenderPass, I read:




  • NOTE: It is important you set the correct CullState for your geometry when
  • using this Pass.





    so I tried to change CullState to CS_FRONT, CS_BACK, CS_FRONT_AND_BACK, CS_NONE, with no improvements.