Design Strategy

Whats the best way to detect all tris within a bounding volume ??



The scenario :-

An arbitary shape hits a terrain page ( say a comet ), the shape may be square, maybe circular or just odd looking ( like a bear foot ).

Goal is to depress the terrain page with an inprint of the shape at the angle of collision.



Brains tick over - many approaches ( yes - have been through some )



Started with geometry within page.findCollisions(trimesh, myCollisionResults), ( original code taken from TestOBBTree)

The joys of learning



OK - from the bounding volume i can get the centre, if i multiply the centre.x * 2 and the centre.z * 2 - i get the width and length of the shape which can be iterated through, that gives me each point to test a ray for.


Any chance you could use RenderToTexture to generate an image of your incoming object from the perspective of the ground, and then use that texture to modify the height field? You might need an Ortho3D camera.

Nice idea pakfront.



However, have managed to get it to work via the following :-



find all triangles on the shape that are to make an impression, store in new Vector3f's which have been locallyTranslated, locallyRotated, worldTranslated and worldRotated



find the top vertices of the shapes(trimesh)

I don’t need it at the moment, but I would find it interesting.

Yeah, that could make an "impressive" demo :slight_smile:



and could be interesting to the monkeyworld team for brush like editing of terrain ?

Not the demo as intended, i hit a problem when translating the shape. Not sure what it is but might have something to do with scale.



The code on altering the terrainpage looks for intersection of rays of the box's bounding to the box itself. This allows for detection of the box being rotated.



The code allows you to move a box over the terrain and click on raise or lower to alter the heightmap.

It works fine if you rotate the shape, but something wrong when you resize or move the box.

There is also a culling issue. Could maybe do with the box being transparant also.

Have added the Show Normals and Bounds using N and B, helps to zoom up close to see where the box is in relation.



Due to the size - its over 2 parts



Also needed will be the terrainpage and terrainblock fixes

http://www.jmonkeyengine.com/jmeforum/index.php?topic=2233.15



import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import jmetest.terrain.TestTerrain;
import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.input.FirstPersonHandler;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.input.MouseInput;
import com.jme.intersection.PickResults;
import com.jme.intersection.TrianglePickResults;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Ray;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.scene.shape.Box;
import com.jme.scene.state.AlphaState;
import com.jme.scene.state.CullState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.jme.util.geom.Debugger;
import com.jmex.awt.JMECanvas;
import com.jmex.awt.JMECanvasImplementor;
import com.jmex.awt.SimpleCanvasImpl;
import com.jmex.awt.input.AWTKeyInput;
import com.jmex.awt.input.AWTMouseInput;
import com.jmex.terrain.TerrainPage;
import com.jmex.terrain.util.FaultFractalHeightMap;
import com.jmex.terrain.util.ProceduralTextureGenerator;

/**
 * <code>TerrainImpressionTest</code> is a test is showing the changing of terrain height to a specified shape after rotation
 */

public class TerrainImpressionTest {
   int width = 640, height = 480;
   TerrainPage page;
   FaultFractalHeightMap heightMap;
   ProceduralTextureGenerator pt;
   Texture t1, t2;
   TextureState landTs;   
   Box impressionBox;   
   Vector3f impressionBoxMax = new Vector3f(10, 50, 10);


   // Add a listener for all controls
   class LocalListener implements ActionListener, ChangeListener {
      // reference to controller
      SwingFrame controller;
      
      public LocalListener(SwingFrame controller) {
         this.controller = controller;
      }
      
      // add action for buttons
      public void actionPerformed(ActionEvent e) {
         String command = e.getActionCommand();
                  
         if(command.equals(TRANSLATE_X_PLUS)) {         
            controller.translate(X_AXIS, true);
         }else if(command.equals(TRANSLATE_X_MINUS)) {         
            controller.translate(X_AXIS, false);
         }else if(command.equals(TRANSLATE_Z_PLUS)) {
            controller.translate(Z_AXIS, true);
         }else if(command.equals(TRANSLATE_Z_MINUS)) {
            controller.translate(Z_AXIS, false);
         }else if(command.equals(SIZE_PLUS)) {
            controller.boxSizer(1f);
         }else if(command.equals(SIZE_MINUS)) {
            controller.boxSizer(-1f);
         }else if(command.equals(IMPRINT_UP)) {
            controller.imprint(true);
         }else if(command.equals(IMPRINT_DOWN)) {
            controller.imprint(false);
         }         
      }
      // add action for slider
      public void stateChanged(ChangeEvent e) {
         Object src = e.getSource();
         controller.rotate(((JSlider)src).getValue());                  
      }      
   }
   
class MyImplementor extends SimpleCanvasImpl {
   boolean showBounds = false;
   boolean showNormals = false;
   long startTime = 0;
   long fps = 0;
   FirstPersonHandler input;
   Canvas canvas;

   public MyImplementor(int width, int height,Canvas canvas) {
      super(width, height);
      this.canvas = canvas;
   }
   
   public void simpleSetup() {
// Stand back from afar

Strange, looks like you are casting the ray at the position plus localtranslation, ill try and crack it later



Good to see run time terrain editing - have you thought of just editing the relevant part of the procedural texture also, would improove performance

Have a prototype of the PTE that works as far as the problem per the code above. Will post it once the above is working


Dah



Ok - thanks, have found the problem -



Lesson learnt - if in doubt draw what it is to the screen to see if it matches where you thought it was.



I was not applying the scaling in the right place…