]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - tim/prune/threedee/Java3DWindow.java
Version 19.2, December 2018
[GpsPrune.git] / tim / prune / threedee / Java3DWindow.java
index 579245db62eb2d07a08d005529f234ea13fa4bb4..f5b324390139f6f4af96271e19ce702a87ee52af 100644 (file)
@@ -13,9 +13,11 @@ import java.awt.geom.GeneralPath;
 
 import javax.media.j3d.AmbientLight;
 import javax.media.j3d.Appearance;
+import javax.media.j3d.Billboard;
 import javax.media.j3d.BoundingSphere;
 import javax.media.j3d.BranchGroup;
 import javax.media.j3d.Canvas3D;
+import javax.media.j3d.DirectionalLight;
 import javax.media.j3d.Font3D;
 import javax.media.j3d.FontExtrusion;
 import javax.media.j3d.GeometryArray;
@@ -40,6 +42,7 @@ import javax.vecmath.Point3d;
 import javax.vecmath.Point3f;
 import javax.vecmath.TexCoord2f;
 import javax.vecmath.Vector3d;
+import javax.vecmath.Vector3f;
 
 import tim.prune.DataStatus;
 import tim.prune.FunctionLibrary;
@@ -373,45 +376,61 @@ public class Java3DWindow implements ThreeDWindow
                // N, S, E, W
                GeneralPath bevelPath = new GeneralPath();
                bevelPath.moveTo(0.0f, 0.0f);
-               for (int i=0; i<91; i+= 5) {
+               for (int i=0; i<91; i+= 5)
+               {
                        bevelPath.lineTo((float) (0.1 - 0.1 * Math.cos(Math.toRadians(i))),
                          (float) (0.1 * Math.sin(Math.toRadians(i))));
                }
-               for (int i=90; i>0; i-=5) {
+               for (int i=90; i>0; i-=5)
+               {
                        bevelPath.lineTo((float) (0.3 + 0.1 * Math.cos(Math.toRadians(i))),
                          (float) (0.1 * Math.sin(Math.toRadians(i))));
                }
                Font3D compassFont = new Font3D(
                        new Font(CARDINALS_FONT, Font.PLAIN, 1),
                        new FontExtrusion(bevelPath));
-               objTrans.addChild(createCompassPoint(I18nManager.getText("cardinal.n"), new Point3f(0f, 0f, -10f), compassFont));
-               objTrans.addChild(createCompassPoint(I18nManager.getText("cardinal.s"), new Point3f(0f, 0f, 10f), compassFont));
-               objTrans.addChild(createCompassPoint(I18nManager.getText("cardinal.w"), new Point3f(-11f, 0f, 0f), compassFont));
-               objTrans.addChild(createCompassPoint(I18nManager.getText("cardinal.e"), new Point3f(10f, 0f, 0f), compassFont));
+               objTrans.addChild(createCompassPoint(I18nManager.getText("cardinal.n"), new Point3f(0f, 0f, -11.5f), compassFont));
+               objTrans.addChild(createCompassPoint(I18nManager.getText("cardinal.s"), new Point3f(0f, 0f, 11.5f), compassFont));
+               objTrans.addChild(createCompassPoint(I18nManager.getText("cardinal.w"), new Point3f(-11.5f, 0f, 0f), compassFont));
+               objTrans.addChild(createCompassPoint(I18nManager.getText("cardinal.e"), new Point3f(11.5f, 0f, 0f), compassFont));
 
                // Add points to model
                objTrans.addChild(createDataPoints(_model));
 
-               // Create lights
-               BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+               // Create lights - always add ambient light
+               BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
                AmbientLight aLgt = new AmbientLight(new Color3f(1.0f, 1.0f, 1.0f));
                aLgt.setInfluencingBounds(bounds);
                objTrans.addChild(aLgt);
 
-               PointLight pLgt = new PointLight(new Color3f(1.0f, 1.0f, 1.0f),
-                       new Point3f(0f, 0f, 2f), new Point3f(0.25f, 0.05f, 0.0f) );
-               pLgt.setInfluencingBounds(bounds);
-               objTrans.addChild(pLgt);
-
-               PointLight pl2 = new PointLight(new Color3f(0.8f, 0.9f, 0.4f),
-                       new Point3f(6f, 1f, 6f), new Point3f(0.2f, 0.1f, 0.05f) );
-               pl2.setInfluencingBounds(bounds);
-               objTrans.addChild(pl2);
-
-               PointLight pl3 = new PointLight(new Color3f(0.7f, 0.7f, 0.7f),
-                       new Point3f(0.0f, 12f, -2f), new Point3f(0.1f, 0.1f, 0.0f) );
-               pl3.setInfluencingBounds(bounds);
-               objTrans.addChild(pl3);
+               // Additional lights depend on whether there's a terrain or not
+               if (showTerrain)
+               {
+                       // If there's a terrain, just have directional light from northwest
+                       DirectionalLight dl = new DirectionalLight(true,
+                               new Color3f(1.0f, 1.0f, 1.0f),
+                               new Vector3f(1.0f, -1.0f, 1.0f));
+                       dl.setInfluencingBounds(bounds);
+                       objTrans.addChild(dl);
+               }
+               else
+               {
+                       // There is no terrain, so use point lights as before
+                       PointLight pLgt = new PointLight(new Color3f(1.0f, 1.0f, 1.0f),
+                               new Point3f(0f, 0f, 2f), new Point3f(0.25f, 0.05f, 0.0f) );
+                       pLgt.setInfluencingBounds(bounds);
+                       objTrans.addChild(pLgt);
+
+                       PointLight pl2 = new PointLight(new Color3f(0.8f, 0.9f, 0.4f),
+                               new Point3f(6f, 1f, 6f), new Point3f(0.2f, 0.1f, 0.05f) );
+                       pl2.setInfluencingBounds(bounds);
+                       objTrans.addChild(pl2);
+
+                       PointLight pl3 = new PointLight(new Color3f(0.7f, 0.7f, 0.7f),
+                               new Point3f(0.0f, 12f, -2f), new Point3f(0.1f, 0.1f, 0.0f) );
+                       pl3.setInfluencingBounds(bounds);
+                       objTrans.addChild(pl3);
+               }
 
                // Have Java 3D perform optimizations on this scene graph.
                objRoot.compile();
@@ -422,12 +441,12 @@ public class Java3DWindow implements ThreeDWindow
 
        /**
         * Create a text object for compass point, N S E or W
-        * @param text text to display
-        * @param locn position at which to display
-        * @param font 3d font to use
-        * @return Shape3D object
+        * @param inText text to display
+        * @param inLocn position at which to display
+        * @param inFont 3d font to use
+        * @return compound object
         */
-       private Shape3D createCompassPoint(String inText, Point3f inLocn, Font3D inFont)
+       private TransformGroup createCompassPoint(String inText, Point3f inLocn, Font3D inFont)
        {
                Text3D txt = new Text3D(inFont, inText, inLocn, Text3D.ALIGN_FIRST, Text3D.PATH_RIGHT);
                Material mat = new Material(new Color3f(0.5f, 0.5f, 0.55f),
@@ -437,7 +456,16 @@ public class Java3DWindow implements ThreeDWindow
                Appearance app = new Appearance();
                app.setMaterial(mat);
                Shape3D shape = new Shape3D(txt, app);
-               return shape;
+
+               // Make transform group with billboard behaviour
+               TransformGroup subGroup = new TransformGroup();
+               subGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+               subGroup.addChild(shape);
+               Billboard billboard = new Billboard(subGroup, Billboard.ROTATE_ABOUT_POINT, inLocn);
+               BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+               billboard.setSchedulingBounds(bounds);
+               subGroup.addChild(billboard);
+               return subGroup;
        }