Showing posts with label Java3d. Show all posts
Showing posts with label Java3d. Show all posts

Wednesday, 2 July 2014

JavaFX 2 vs Java3D

Java3D

  • The Java 3D API is a high-level library for creating 3D-graphics including animation and transformation of 3D-objects.
  • The Java 3D API operates with objects that are placed in the scene graph that is the tree of 3D-objects and is intended to render.
  • Java3D application can run as a desktop application or as an applet or as a desktop application and an applet.
  • The Java 3D API is presented by the basic package javax.media.j3d and support packages com.sun.j3d.utils, java.awt, javax.vecmath.
  • In fact, the Java 3D API is a wrapper of the graphic systems OpenGL and DirectX.

Java3D installation

  • Download the distributive at http://www.oracle.com/technetwork/java/javase/tech/index-jsp-138252.html.
  • Run the installation program. The result will appear in the JDK directory as the folder Java3D.
  • The installed files on the Java3D folder work as the runtime over JDK for programs that use the Java 3D API.
  • To develop programs using the Java 3D API download the NetBeans plugin at http://plugins.netbeans.org/plugin/32144/java-3d and install it using the option Tools | Plugins | Downloaded | Add Plugins.
  • You can then include the import of the Java 3D API libraries in a Java application project.

Java3D programming model

  • To create a Java3D application first creates the VirtualUniverse object.
  • Each Java3D application has only one object VirtualUniverse, which represents a virtual space that is associated with a scene graph.
  • Further create the BranchGroup object that represents the root node of the branch of the scene graph.
  • Create the Transform3D object representing the three-dimensional transformations and, based on it, create the TransformGroup object that represents the node of the scene graph.
  • Create a 3D-object, which is added to the node TransformGroup.
  • The TransformGroup node is added to the node BranchGroup and the BranchGroup node is added to the virtual space VirtualUniverse.
  • In the BranchGroup node, besides 3D-objects, you can add light sources illuminating 3D-objects.
  • For 3D-objects it is possible to define the appearance by adding colors, materials, textures and effects.
  • With the Canvas3D object it is possible to create 3D-graphics in the program way.
  • Animations of the 3D-object are controlled by changing the object Transform3D in time.
  • The following code is a simple Java3D-program that displays the rotated cube:

JavaFX 2

  • The JavaFX technology provides a powerful graphical user interface for large-scale data-oriented applications, media-rich applications that deliver diverse media content to users, Mashup applications that integrate a variety of web resources for users, high-quality graphical components and animation to web sites, various types of custom programs that saturated graphics, animation and interactive elements.
  • The same Java code created on the basis of the JavaFX platform can be launched as the desktop application or it can be deployed as the Java Web Start application or it can be displayed in the web browser as the JavaFX applet embedded in an HTML page.
  • The JavaFX 2 Platform provides modern GUI-components, the rich set of graphics and media libraries, and the high-performance execution environment for applications.
  • For an alternative declarative description of the GUI the JavaFX platform offers the FXML language.
  • Also, the JavaFX 2 platform provides the new graphical and media engines, which improve the display of graphics and playback of multimedia content, embedding HTML-content in the application, the new plugin for web browsers, and the wide range of the GUI components with the support of CSS3.
  • Currently JavaFX 2 provides:
  1.  JavaFX SDK that provides the JavaFX Packager tool for compiling, packaging, and deploying JavaFX applications, Ant library for building JavaFX applications, the JavaFX doclet for Javadoc, JavaFX API, and documentation.
  2.   JavaFX Runtime for desktop applications and JavaFX applets.
  3. Support of the JavaFX 2 platform for NetBeans IDE 7.
  4. Examples of JavaFX applications.
  • The JavaFX 2 platform is integrated into the platform JDK 7 and does not require separate installation.
  • The site of the JavaFX 2 platform is located at http://javafx.com/.
  • The JavaFX 2 browser plugin is not browser add-ons and its work is provided by the JavaScript-code that embeds the JavaFX-code as a JavaFX-applet on the web page, connecting the JavaFX Runtime installed on the local computer.

Comparison JavaFX 2 and Java3D

  • Both JavaFX 2 and Java3D include API and runtime.
  • Java3D requires a separate installation. JavaFX 2 is included in JDK 7.
  • Both JavaFX 2 and Java3D can create 3D-graphics.
  • Java3D provides ready 3D-objects. JavaFX 2 allows creating 3D-objects from 2D-primitives.
  • JavaFX 2 provides GUI-components, but Java3D is not.
  • Both JavaFX 2 and Java3D provide transformation and animation facilities.
  • The JavaFX 2 code automatically compiled into the desktop application and the applet. For Java3D-applet creation the additional code is required.
  • Both JavaFX 2 and Java3D operate a scene graph.
  • JavaFX 2 provides a declarative description of the scene graph and the visual editor of the scene graph, but Java3D is not.
  • Java3D supports textures, but JavaFX 2 is not.
  • The JavaFX 2 code should be performed in a separate JavaFX Application Thread. The Java3D code runs in the main thread.
  • The entry point of the JavaFX-application is a Java-class that extends the abstract class javafx.application.Application and contains the method main(). The entry point of Java3D-application is the usual Java-class with the method main().

Wednesday, 1 January 2014

Create Tube(Pipe) in Java3D and also apply curve




/*
This method create ellipse at given x,y,z  point
*/

LineArray buildEllipse1(double x, double y, double z, double semiMajorAxis,
double semiMinorAxis) {
// build geometry
int totalLines = 50;
int totalPoints = totalLines * 2;
double tInc = 1.0 / (double) totalLines;

Point3d p0 = new Point3d();
Point3d p1 = new Point3d();

LineArray lineArray = new LineArray(totalPoints, LineArray.COORDINATES);

double t = 0.0;
int lineIndex = 0;
for (int i = 0; i < totalLines; i++) {
p0.x = (semiMinorAxis * Math.cos(2.0 * Math.PI * t)) + x;
p0.y = y;
p0.z = (semiMajorAxis * Math.sin(2.0 * Math.PI * t)) + z;
lineArray.setCoordinate(lineIndex++, p0);

p1.x = (semiMinorAxis * Math.cos(2.0 * Math.PI * (t + tInc))) + x;
p1.y = y;
p1.z = (semiMajorAxis * Math.sin(2.0 * Math.PI * (t + tInc))) + z;
// p1.z=10;
lineArray.setCoordinate(lineIndex++, p1);
t += tInc;
}



return lineArray;

}
/ *
Add tube function add tube by merging of circle and make 3d tube(Pipe)
 */
private void addTube_onAction() {

Shape3D circleShape3d = new Shape3D();
// build appearance
Appearance appearance = new Appearance();

LineAttributes lineAttrib = new LineAttributes(2.0f,
LineAttributes.PATTERN_SOLID, true);
appearance.setLineAttributes(lineAttrib);

ColoringAttributes colorAttributes = new ColoringAttributes( new Color3f(Color.YELLOW),
ColoringAttributes.SHADE_GOURAUD);
appearance.setColoringAttributes(colorAttributes);

RenderingAttributes renderAttrib = new RenderingAttributes();
renderAttrib.setDepthBufferEnable(false);
renderAttrib.setDepthBufferWriteEnable(false);
appearance.setRenderingAttributes(renderAttrib);
BranchGroup branchGroup1 = new BranchGroup();



BranchGroup branchGroup = new BranchGroup();
branchGroup.setCapability(Content.ALLOW_DETACH);

Shape3D shape3d = new Shape3D();
Color3f color3f = new Color3f(Color.red);

Point3f pt1 = new Point3f(strToFloat(pt1_x_textField.getText()),
strToFloat(pt1_y_textField.getText()),
strToFloat(pt1_z_textField.getText()));
Point3f pt2 = new Point3f(strToFloat(pt2_x_textField.getText()),
strToFloat(pt2_y_textField.getText()),
strToFloat(pt2_z_textField.getText()));

ArrayList<Point2D> point2ds = generateCurve(
new Point2D.Double(pt1.getX(), pt1.getY()), new Point2D.Double(
pt2.getX(), pt2.getY()), 2000, 1);



Point3d[] coords = new Point3d[point2ds.size()];
int cnt = 0;
for (Point2D point2d : point2ds) {
coords[cnt] = new Point3d(point2d.getX(), point2d.getY(), 250);
circleShape3d.addGeometry(buildEllipse1(point2d.getX(),
point2d.getY(), 250,3,3));
cnt++;
}
//circleShape3d.setAppearance(appearance);
branchGroup1.addChild(circleShape3d);
image3DUniverse.getScene().addChild(branchGroup1);
// // Point3f[] coords = { onX, onY };
//
int N = coords.length;

Color3f colors[] = new Color3f[N];
for (int i = 0; i < N; i++) {
colors[i] = color3f;
}

int[] strip = { N };

LineStripArray ta = new LineStripArray(N, LineStripArray.COORDINATES
| LineStripArray.COLOR_3, strip);
ta.setCoordinates(0, coords);
ta.setColors(0, colors);

shape3d.addGeometry(ta);
branchGroup.addChild(shape3d);
image3DUniverse.getScene().addChild(branchGroup);

}

private static double GetAngle(Point2D x, Point2D o, double R) {
double cosa = (x.getX() - o.getX()) / R;
double sina = (x.getY() - o.getY()) / R;

double angle = Math.acos(cosa);

return Math.sin(angle) * sina >= 0 ? angle : 2 * Math.PI - angle;
}


     /*
      This method apply curve on tube depend on radius value 
      */
private static ArrayList<Point2D> generateCurve(Point2D pFrom, Point2D pTo,
float pRadius, float pMinDistance) {

ArrayList<Point2D> pOutPut = new ArrayList<Point2D>();

double dist = pFrom.distance(pTo);
double h = Math.sqrt(pRadius * pRadius - (dist * dist / 4.0));
double angleStep = pMinDistance / pRadius;

System.out.println(" #### dist ::" + dist);
System.out.println(" #### pRadius ::" + pRadius);

// pRadius = (float) ((dist/ 2 ) + 100) ;

if (2 * pRadius <= dist)
throw new Error("Radius is too small");

// find center
double x1 = pFrom.getX(), x2 = pFrom.getY();
double y1 = pTo.getX(), y2 = pTo.getY();
double m1 = (x1 + y1) / 2, m2 = (x2 + y2) / 2;
double u1 = -(y2 - x2) / dist, u2 = (y1 - x1) / dist;
double o1 = m1 + h * u1, o2 = m2 + h * u2;
Point2D o = new Point2D.Double(o1, o2);

double startAngle = GetAngle(pFrom, o, pRadius);
double endAngle = GetAngle(pTo, o, pRadius);

if (endAngle < startAngle)
endAngle += 2 * Math.PI;

for (double a = startAngle; a < endAngle; a += angleStep) {
pOutPut.add(new Point2D.Double(o1 + pRadius * Math.cos(a), o2
+ pRadius * Math.sin(a)));
}

pOutPut.add(pTo);

return pOutPut;
}

Wednesday, 25 December 2013

How to draw simple 3D points(x,y,z) in java using Java3D API?

Create SimpleUniverse and Canvas3D usingSimpleUniverse.getPreferredConfiguration() GraphicsConfiguration class. Then create a BranchGraph. Add a TransformGraph as a child of BranchGraph. Then add your Shape3D as a child of TransformGraph. Shape3D must have 2 things: geometry(your point array) and appearance. From appearance, you make many specifications of material and lighting.
If you just use point array, you see only points. Should use TriangleStripArray or similar thing if you want to fill polygons or LineStripArray if you want lines.
Use TransformGroup to rotate&translate. Dont forget to add light too.
TransformGroup needs a Transform3D class as parameter to rotate and translate or scale.
If your Shape3D is a surface, you may give custom-color to it or use material and put a light near it otherwise you cannot see it. Dont forget to set lightsource bound range so light reaches the object.
  • PointArray--->Cloud-like shapes
  • LineArray--->For dashed-line
  • LineStripArray-->for lines
  • TriangleArray--->divorced triangles(for a surface)
  • TriangleStripArray--->neighboring triangles(for a surface)
  • TriangleFanArray---->like building triangles arount a point(for a surface)
  • QuadArray---->Need six quads to have a cube
  • QuadStripArray--->Can construct a cube with a smaller coordinate array
Another important thing:
simpleU.getViewingPlatform().getViewPlatform().setActivationRadius(300);
    SimpleU.getViewer().getView().setBackClipDistance ( 300.0 );
makes your viewing range even more far so object dont disappear when you move.
Attach mouse-interactions to your transform-group
    MouseRotate m1=new MouseRotate();
    MouseZoom m2=new MouseZoom();
    MouseTranslate m3=new MouseTranslate();
If you want to map your 1580 x 1050 image into your default 3D view range, you should divide the point coordinates by 1000. (or scale down to 1000th in transformgroup)
Look for tutorials:
Here, i tweaked your tutorial into energon.class
//skipped imports(char limit in this post)
public final class energon extends JPanel {


    int s = 0, count = 0;

    public energon() {
        setLayout(new BorderLayout());
        GraphicsConfiguration gc=SimpleUniverse.getPreferredConfiguration();
        Canvas3D canvas3D = new Canvas3D(gc);//See the added gc? this is a preferred config
        add("Center", canvas3D);

        BranchGroup scene = createSceneGraph();
        scene.compile();

        // SimpleUniverse is a Convenience Utility class
        SimpleUniverse simpleU = new SimpleUniverse(canvas3D);


        // This moves the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        simpleU.getViewingPlatform().setNominalViewingTransform();

        simpleU.addBranchGraph(scene);
    }
    public BranchGroup createSceneGraph() {
        BranchGroup lineGroup = new BranchGroup();
        Appearance app = new Appearance();
        ColoringAttributes ca = new ColoringAttributes(new Color3f(204.0f, 204.0f,          204.0f), ColoringAttributes.SHADE_FLAT);
        app.setColoringAttributes(ca);

        Point3f[] plaPts = new Point3f[4];

        for (int i = 0; i < 2; i++) {
            for (int j = 0; j <2; j++) {
                plaPts[count] = new Point3f(i/10.0f,j/10.0f,0);
                //Look up line, i and j are divided by 10.0f to be able to
                //see the points inside the view screen
                count++;
            }
        }
        PointArray pla = new PointArray(4, GeometryArray.COORDINATES);
        pla.setCoordinates(0, plaPts);
        Shape3D plShape = new Shape3D(pla, app);
        TransformGroup objRotate = new TransformGroup();
        objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRotate.addChild(plShape);
        lineGroup.addChild(objRotate);
        return lineGroup;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(new energon()));
        frame.setSize(300, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
Output:
enter image description here
Okay, lets add a point-size so we can see them clearly(will add in a minute)
New code(just added 2-3 lines)
import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;

import com.sun.j3d.utils.universe.*;

import java.awt.image.BufferedImage;
import javax.media.j3d.*;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.vecmath.Color3f;
import javax.vecmath.Point3f;

public final class energon extends JPanel {


    int s = 0, count = 0;

    public energon() {
        setLayout(new BorderLayout());
        GraphicsConfiguration gc=SimpleUniverse.getPreferredConfiguration();
        Canvas3D canvas3D = new Canvas3D(gc);
        add("Center", canvas3D);

        BranchGroup scene = createSceneGraph();
        scene.compile();

        // SimpleUniverse is a Convenience Utility class
        SimpleUniverse simpleU = new SimpleUniverse(canvas3D);


        // This moves the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        simpleU.getViewingPlatform().setNominalViewingTransform();

        simpleU.addBranchGraph(scene);
    }
    public BranchGroup createSceneGraph() {
        BranchGroup lineGroup = new BranchGroup();
        Appearance app = new Appearance();
        ColoringAttributes ca = new ColoringAttributes(new Color3f(204.0f, 204.0f,          204.0f), ColoringAttributes.SHADE_FLAT);
        app.setColoringAttributes(ca);

        Point3f[] plaPts = new Point3f[4];

        for (int i = 0; i < 2; i++) {
            for (int j = 0; j <2; j++) {
                plaPts[count] = new Point3f(i/10.0f,j/10.0f,0);
                count++;
            }
        }
        PointArray pla = new PointArray(4, GeometryArray.COORDINATES);

        pla.setCoordinates(0, plaPts);
        //between here!
        PointAttributes a_point_just_bigger=new PointAttributes();
        a_point_just_bigger.setPointSize(10.0f);//10 pixel-wide point
        a_point_just_bigger.setPointAntialiasingEnable(true);//now points are sphere-like(not a cube)
        app.setPointAttributes(a_point_just_bigger);
        //and here! sets the point-attributes so it is easily seen.
        Shape3D plShape = new Shape3D(pla, app);
        TransformGroup objRotate = new TransformGroup();
        objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRotate.addChild(plShape);
        lineGroup.addChild(objRotate);
        return lineGroup;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(new energon()));
        frame.setSize(300, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
output:
enter image description here
Here is another using trianglestriparray to draw a kind of arrow-shape while you can zoom-in-out, rotate and translate with using mouse buttons(3 of them).
//skipped imports beause of char limit in this post
public final class energon extends JPanel {



    int s = 0, count = 0;

    public energon() {
        setLayout(new BorderLayout());
        GraphicsConfiguration gc=SimpleUniverse.getPreferredConfiguration();
        Canvas3D canvas3D = new Canvas3D(gc);
        add("Center", canvas3D);

        BranchGroup scene = createSceneGraph();
        scene.compile();

        // SimpleUniverse is a Convenience Utility class
        SimpleUniverse simpleU = new SimpleUniverse(canvas3D);


        // This moves the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        simpleU.getViewingPlatform().setNominalViewingTransform();

        simpleU.addBranchGraph(scene);
    }
    public BranchGroup createSceneGraph() {
        BranchGroup lineGroup = new BranchGroup();
        Appearance app = new Appearance();
        ColoringAttributes ca = new ColoringAttributes(new Color3f(204.0f, 204.0f,204.0f), ColoringAttributes.SHADE_FLAT);
        app.setColoringAttributes(ca);
        Point3f[] plaPts = new Point3f[5];
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j <2; j++) {
                plaPts[count] = new Point3f(i/10.0f,j/10.0f,0);
                count++;
            }
        }
        plaPts[count] = new Point3f(3.0f/10.0f,2.0f/10.0f,0);
        int[]intArr=new int[5];
        intArr[0]=3;intArr[1]=4;intArr[2]=4;intArr[3]=3;intArr[4]=3;

        TriangleStripArray pla =new TriangleStripArray(20, GeometryArray.COLOR_3|GeometryArray.NORMALS|GeometryArray.COORDINATES,intArr);
        pla.setCoordinates(0, plaPts);
        PointAttributes a_point_just_bigger=new PointAttributes();
        a_point_just_bigger.setPointSize(10.0f);//10 pixel-wide point
        a_point_just_bigger.setPointAntialiasingEnable(true);//now points are sphere-like(not a cube)
        app.setPointAttributes(a_point_just_bigger);
        PolygonAttributes la=new PolygonAttributes();
        la.setPolygonMode(PolygonAttributes.POLYGON_FILL);
        la.setCullFace(PolygonAttributes.CULL_NONE);
        app.setPolygonAttributes(la);
        Material matt=new Material();
        matt.setAmbientColor(new Color3f(1,1,1));
        matt.setDiffuseColor(new Color3f(0.5f,0.5f,0.7f));
        matt.setEmissiveColor(new Color3f(0.2f,0.2f,0.3f));
        matt.setShininess(0.5f);
        matt.setSpecularColor(new Color3f(0.4f,0.6f,0.9f));
        matt.setLightingEnable(true);

        app.setMaterial(matt);
        RenderingAttributes ra=new RenderingAttributes();
        ra.setIgnoreVertexColors(true);
        app.setRenderingAttributes(ra);
        Shape3D plShape = new Shape3D(pla, app);

        TransformGroup objRotate = new TransformGroup();

        MouseRotate mr=new MouseRotate();
        mr.setTransformGroup(objRotate);
        mr.setSchedulingBounds(new BoundingSphere());
        lineGroup.addChild(mr);
        MouseZoom mz=new MouseZoom();
        mz.setTransformGroup(objRotate);
        mz.setSchedulingBounds(new BoundingSphere());
        lineGroup.addChild(mz);
        MouseTranslate msl=new MouseTranslate();
        msl.setTransformGroup(objRotate);
        msl.setSchedulingBounds(new BoundingSphere());
        lineGroup.addChild(msl);


        objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRotate.addChild(plShape);
        AmbientLight al=new AmbientLight();
      //  al.addScope(objRotate);
        al.setBounds(new BoundingSphere());
        al.setEnable(true);
        al.setColor(new Color3f(1,1,1));

        lineGroup.addChild(objRotate);
        lineGroup.addChild(al);
        return lineGroup;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(new energon()));
        frame.setSize(300, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
output:
enter image description here
You want to change color of points? Here is the new version:
//skipping imports..
public final class energon extends JPanel {


    int s = 0, count = 0;

    public energon() {
        setLayout(new BorderLayout());
        GraphicsConfiguration gc=SimpleUniverse.getPreferredConfiguration();
        Canvas3D canvas3D = new Canvas3D(gc);
        add("Center", canvas3D);

        BranchGroup scene = createSceneGraph();
        scene.compile();
        // SimpleUniverse is a Convenience Utility class
        SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
        // This moves the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        simpleU.getViewingPlatform().setNominalViewingTransform();
        simpleU.addBranchGraph(scene);
    }
    public BranchGroup createSceneGraph() {
        BranchGroup lineGroup = new BranchGroup();
        Appearance app = new Appearance();
        ColoringAttributes ca = new ColoringAttributes(new Color3f(204.0f, 204.0f,          204.0f), ColoringAttributes.SHADE_FLAT);
        app.setColoringAttributes(ca);

        Point3f[] plaPts = new Point3f[4];
        Color3f[] colPts=new Color3f[4]; //parallel to coordinates, colors.
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j <2; j++) {
                plaPts[count] = new Point3f(i/10.0f,j/10.0f,0);
                colPts[count]=new Color3f(i/3.0f,j/3.0f,(float) ((i+j)/3.0));//my arbitrary color set :)
                count++;
            }
        }
        PointArray pla = new PointArray(4, GeometryArray.COORDINATES|GeometryArray.COLOR_3);
        pla.setColors(0,colPts); //this is the color-array setting
        pla.setCoordinates(0, plaPts); 
        //between here!
        PointAttributes a_point_just_bigger=new PointAttributes();
        a_point_just_bigger.setPointSize(10.0f);//10 pixel-wide point

        a_point_just_bigger.setPointAntialiasingEnable(true);//now points are sphere-like(not a cube)
        app.setPointAttributes(a_point_just_bigger);
        //and here! sets the point-attributes so it is easily seen.
        Shape3D plShape = new Shape3D(pla, app);
        TransformGroup objRotate = new TransformGroup();
        objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRotate.addChild(plShape);
        lineGroup.addChild(objRotate);
        return lineGroup;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(new energon()));
        frame.setSize(300, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
Output:
enter image description here
New example with custom-cube-shape and two directional-lights with lft-mouse button interaction:
//skipped imports relating with char limit in this post
public final class energon extends JPanel {
    int s = 0, count = 0;

    public energon() {

        setLayout(new BorderLayout());
        GraphicsConfiguration gc=SimpleUniverse.getPreferredConfiguration();
        Canvas3D canvas3D = new Canvas3D(gc);
        add("Center", canvas3D);

        BranchGroup scene = createSceneGraph();
        scene.compile();

        // SimpleUniverse is a Convenience Utility class
        SimpleUniverse simpleU = new SimpleUniverse(canvas3D);


        // This moves the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        simpleU.getViewingPlatform().setNominalViewingTransform();

        simpleU.addBranchGraph(scene);
    }
    public BranchGroup createSceneGraph() {
        BranchGroup lineGroup = new BranchGroup();
        Appearance app = new Appearance();

        QuadArray lsa = new QuadArray(48,QuadArray.COORDINATES|QuadArray.NORMALS);
        Vector3f [] normals=new Vector3f[24];
        for(int i=0;i<24;i++)normals[i]=new Vector3f();
        Point3f [] pts=new Point3f[24];
        for(int i=0;i<24;i++)pts[i]=new Point3f();
        Color3f [] clrs=new Color3f[24];
        for(int i=0;i<24;i++)clrs[i]=new Color3f(0.5f,0.5f,0.5f);
        //cube=6 quads 
        //first quad
        pts[0].x=-0.5f;pts[0].y=-0.5f;pts[0].z=-0.5f;
        pts[1].x=-0.5f;pts[1].y=-0.5f;pts[1].z=0.5f;
        pts[2].x=-0.5f;pts[2].y=0.5f;pts[2].z=0.5f;
        pts[3].x=-0.5f;pts[3].y=0.5f;pts[3].z=-0.5f;
        normals[0].x=-1;normals[1].x=-1;normals[2].x=-1;normals[3].x=-1;
        //second quad
        pts[4].x=0.5f;pts[4].y=-0.5f;pts[4].z=-0.5f;
        pts[5].x=0.5f;pts[5].y=-0.5f;pts[5].z=0.5f;
        pts[6].x=0.5f;pts[6].y=0.5f;pts[6].z=0.5f;
        pts[7].x=0.5f;pts[7].y=0.5f;pts[7].z=-0.5f;
        normals[4].x=1;normals[5].x=1;normals[6].x=1;normals[7].x=1;

        //third quad
        pts[8].x=-0.5f;pts[8].y=-0.5f;pts[8].z=-0.5f;
        pts[9].x=0.5f;pts[9].y=-0.5f;pts[9].z=-0.5f;
        pts[10].x=0.5f;pts[10].y=0.5f;pts[10].z=-0.5f;
        pts[11].x=-0.5f;pts[11].y=0.5f;pts[11].z=-0.5f;
        normals[8].z=-1;normals[9].z=-1;normals[10].z=-1;normals[11].z=-1;
        //fourth quad
        pts[12].x=-0.5f;pts[12].y=-0.5f;pts[12].z=0.5f;
        pts[13].x=0.5f;pts[13].y=-0.5f;pts[13].z=0.5f;
        pts[14].x=0.5f;pts[14].y=0.5f;pts[14].z=0.5f;
        pts[15].x=-0.5f;pts[15].y=0.5f;pts[15].z=0.5f;
        normals[12].z=1;normals[13].z=1;normals[14].z=1;normals[15].z=1;
        //fifth quad
        pts[16].x=-0.5f;pts[16].y=-0.5f;pts[16].z=-0.5f;
        pts[17].x=-0.5f;pts[17].y=-0.5f;pts[17].z=0.5f;
        pts[18].x=0.5f;pts[18].y=-0.5f;pts[18].z=0.5f;
        pts[19].x=0.5f;pts[19].y=-0.5f;pts[19].z=-0.5f;
        normals[16].y=-1;normals[17].y=-1;normals[18].y=-1;normals[19].y=-1;
        //sixth quad
        pts[20].x=-0.5f;pts[20].y=0.5f;pts[20].z=-0.5f;
        pts[21].x=-0.5f;pts[21].y=0.5f;pts[21].z=0.5f;
        pts[22].x=0.5f;pts[22].y=0.5f;pts[22].z=0.5f;
        pts[23].x=0.5f;pts[23].y=0.5f;pts[23].z=-0.5f;
        normals[20].y=1;normals[21].y=1;normals[22].y=1;normals[23].y=1;
        lsa.setNormals(0, normals);
        lsa.setCoordinates(0, pts);
        Shape3D sh=new Shape3D();
        PolygonAttributes pa=new PolygonAttributes();
        pa.setPolygonMode(PolygonAttributes.POLYGON_FILL);
        pa.setCullFace(PolygonAttributes.CULL_NONE);
        Material mat=new Material();
        mat.setEmissiveColor(new Color3f(0.5f,0.5f,0.5f));
        mat.setAmbientColor(new Color3f(0.1f,0.1f,0.1f));
        mat.setDiffuseColor(new Color3f(0.2f,0.3f,0.4f));
        mat.setSpecularColor(new Color3f(0.6f,0.3f,0.2f));
        mat.setLightingEnable(true);
        RenderingAttributes ra=new RenderingAttributes();
        ra.setIgnoreVertexColors(true);
        ColoringAttributes ca=new ColoringAttributes();
        ca.setShadeModel(ColoringAttributes.SHADE_GOURAUD);
        ca.setColor(new Color3f(0.2f,0.5f,0.9f));
        app.setColoringAttributes(ca);
        app.setRenderingAttributes(ra);   
        app.setMaterial(mat);
        app.setPolygonAttributes(pa);
        sh.setGeometry(lsa);
        sh.setAppearance(app);
        sh.setPickable(true); 
        TransformGroup objRotate = new TransformGroup();
        objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRotate.addChild(sh);

        DirectionalLight light1=new DirectionalLight();
        light1.setInfluencingBounds(new BoundingSphere(new Point3d(-5.0,0,0),10.0));
        light1.setColor(new Color3f(1f,1f,1f));
        light1.setDirection(new Vector3f(0,1,0));
        objRotate.addChild(light1);
        DirectionalLight light2=new DirectionalLight();
        light2.setInfluencingBounds(new BoundingSphere(new Point3d(5.0,0,0),10.0));
        light2.setColor(new Color3f(0.5f,1f,0.5f));
        light2.setDirection(new Vector3f(0,-1,0));
        objRotate.addChild(light2);
        MouseRotate f1=new MouseRotate();
        f1.setSchedulingBounds(new BoundingSphere());
        f1.setTransformGroup(objRotate);
        lineGroup.addChild(f1);
        objRotate.addChild(new Sphere(0.60f,1,128));
        lineGroup.addChild(objRotate);
        return lineGroup;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(new energon()));
        frame.setSize(300, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
Output:
enter image description here
Most important part is, you can use triangulator to get a real 3D shape using just point coordinates
        GeometryInfo ginfo=new GeometryInfo(GeometryInfo.POLYGON_ARRAY);
        Triangulator tr = new Triangulator();
        NormalGenerator normalGenerator = new NormalGenerator();
        Stripifier st = new Stripifier();  
        int [] iint=new int[]{4,4,4,4,4,4};-->each face of cube has 4 points
        ginfo.setStripCounts(iint);
        ginfo.setCoordinates(pts); 
        tr.triangulate(ginfo); // ginfo contains the geometry     
        normalGenerator.generateNormals( ginfo );
        st.stripify(ginfo);
        sh.setGeometry(ginfo.getGeometryArray()); // shape is a Shape3D.
        //now you can use Shape3D-type sh as a 3D-surface-containing shape
In the last example, you had to use the quadarray but now, you can do same with only using points and the triangulator:
//skipping imports since char limit is reached in this answer
public final class energon extends JPanel {
    int s = 0, count = 0;
    public energon() {
        setLayout(new BorderLayout());
        GraphicsConfiguration gc=SimpleUniverse.getPreferredConfiguration();
        Canvas3D canvas3D = new Canvas3D(gc);
        add("Center", canvas3D);
        BranchGroup scene = createSceneGraph();
        scene.compile();
        // SimpleUniverse is a Convenience Utility class
        SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
        // This moves the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        simpleU.getViewingPlatform().setNominalViewingTransform();
        simpleU.addBranchGraph(scene);
    }
    public BranchGroup createSceneGraph() {
        BranchGroup lineGroup = new BranchGroup();
        Appearance app = new Appearance();
        Vector3f [] normals=new Vector3f[24];
        for(int i=0;i<24;i++)normals[i]=new Vector3f();
        Point3f [] pts=new Point3f[24];
        for(int i=0;i<24;i++)pts[i]=new Point3f();
        Color3f [] clrs=new Color3f[24];
        for(int i=0;i<24;i++)clrs[i]=new Color3f(0.5f,0.5f,0.5f);
        //cube=6 quads 
        //first quad
        pts[0].x=-0.5f;pts[0].y=-0.5f;pts[0].z=-0.5f;
        pts[1].x=-0.5f;pts[1].y=-0.5f;pts[1].z=0.5f;
        pts[2].x=-0.5f;pts[2].y=0.5f;pts[2].z=0.5f;
        pts[3].x=-0.5f;pts[3].y=0.5f;pts[3].z=-0.5f;
        normals[0].x=-1;normals[1].x=-1;normals[2].x=-1;normals[3].x=-1;
        //second quad
        pts[4].x=0.5f;pts[4].y=-0.5f;pts[4].z=-0.5f;
        pts[5].x=0.5f;pts[5].y=-0.5f;pts[5].z=0.5f;
        pts[6].x=0.5f;pts[6].y=0.5f;pts[6].z=0.5f;
        pts[7].x=0.5f;pts[7].y=0.5f;pts[7].z=-0.5f;
        normals[4].x=1;normals[5].x=1;normals[6].x=1;normals[7].x=1;
        //third quad
        pts[8].x=-0.5f;pts[8].y=-0.5f;pts[8].z=-0.5f;
        pts[9].x=0.5f;pts[9].y=-0.5f;pts[9].z=-0.5f;
        pts[10].x=0.5f;pts[10].y=0.5f;pts[10].z=-0.5f;
        pts[11].x=-0.5f;pts[11].y=0.5f;pts[11].z=-0.5f;
        normals[8].z=-1;normals[9].z=-1;normals[10].z=-1;normals[11].z=-1;
        //fourth quad
        pts[12].x=-0.5f;pts[12].y=-0.5f;pts[12].z=0.5f;
        pts[13].x=0.5f;pts[13].y=-0.5f;pts[13].z=0.5f;
        pts[14].x=0.5f;pts[14].y=0.5f;pts[14].z=0.5f;
        pts[15].x=-0.5f;pts[15].y=0.5f;pts[15].z=0.5f;
        normals[12].z=1;normals[13].z=1;normals[14].z=1;normals[15].z=1;
        //fifth quad
        pts[16].x=-0.5f;pts[16].y=-0.5f;pts[16].z=-0.5f;
        pts[17].x=-0.5f;pts[17].y=-0.5f;pts[17].z=0.5f;
        pts[18].x=0.5f;pts[18].y=-0.5f;pts[18].z=0.5f;
        pts[19].x=0.5f;pts[19].y=-0.5f;pts[19].z=-0.5f;
        normals[16].y=-1;normals[17].y=-1;normals[18].y=-1;normals[19].y=-1;
        //sixth quad
        pts[20].x=-0.5f;pts[20].y=0.5f;pts[20].z=-0.5f;
        pts[21].x=-0.5f;pts[21].y=0.5f;pts[21].z=0.5f;
        pts[22].x=0.5f;pts[22].y=0.5f;pts[22].z=0.5f;
        pts[23].x=0.5f;pts[23].y=0.5f;pts[23].z=-0.5f;
        normals[20].y=1;normals[21].y=1;normals[22].y=1;normals[23].y=1;
        Shape3D sh=new Shape3D();
        PolygonAttributes pa=new PolygonAttributes();
        pa.setPolygonMode(PolygonAttributes.POLYGON_FILL);
        pa.setCullFace(PolygonAttributes.CULL_NONE);
        Material mat=new Material();
        mat.setEmissiveColor(new Color3f(0.5f,0.5f,0.5f));
        mat.setAmbientColor(new Color3f(0.1f,0.1f,0.1f));
        mat.setDiffuseColor(new Color3f(0.2f,0.3f,0.4f));
        mat.setSpecularColor(new Color3f(0.6f,0.3f,0.2f));
        mat.setLightingEnable(true);
        RenderingAttributes ra=new RenderingAttributes();
        ra.setIgnoreVertexColors(true);
        ColoringAttributes ca=new ColoringAttributes();
        ca.setShadeModel(ColoringAttributes.SHADE_GOURAUD);
        ca.setColor(new Color3f(0.2f,0.5f,0.9f));
        app.setColoringAttributes(ca);
        app.setRenderingAttributes(ra);
        app.setMaterial(mat);
        app.setPolygonAttributes(pa);
        sh.setAppearance(app);
        sh.setPickable(true);
        GeometryArray ga=null;
        GeometryInfo ginfo=new GeometryInfo(GeometryInfo.POLYGON_ARRAY);
        Triangulator tr = new Triangulator();
        NormalGenerator normalGenerator = new NormalGenerator();
        Stripifier st = new Stripifier();  
        int [] iint=new int[]{4,4,4,4,4,4};
        ginfo.setStripCounts(iint);
        ginfo.setCoordinates(pts); 
        tr.triangulate(ginfo); // ginfo contains the geometry     
        normalGenerator.generateNormals( ginfo );
        st.stripify(ginfo);
        sh.setGeometry(ginfo.getGeometryArray()); // shape is a Shape3D.
        TransformGroup objRotate = new TransformGroup();
        objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRotate.addChild(sh);   
        DirectionalLight light1=new DirectionalLight();
        light1.setInfluencingBounds(new BoundingSphere(new Point3d(-5.0,0,0),10.0));
        light1.setColor(new Color3f(1f,1f,1f));
        light1.setDirection(new Vector3f(0,1,0));
        objRotate.addChild(light1);
        DirectionalLight light2=new DirectionalLight();
        light2.setInfluencingBounds(new BoundingSphere(new Point3d(5.0,0,0),10.0));
        light2.setColor(new Color3f(0.5f,1f,0.5f));
        light2.setDirection(new Vector3f(0,-1,0));
        objRotate.addChild(light2);
        MouseRotate f1=new MouseRotate();
        f1.setSchedulingBounds(new BoundingSphere());
        f1.setTransformGroup(objRotate);
        lineGroup.addChild(f1);
        objRotate.addChild(new Sphere(0.60f,1,128));
        lineGroup.addChild(objRotate);
        return lineGroup;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(new energon()));
        frame.setSize(300, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
Output:Same! you just give the coordinates of points and the face-vertex numbers
enter image description hereenter image description here
  • set the strip counts
  • set the coordinates(from your tiff)
  • triangulate
  • generate normals
  • stripify
  • .getGeometry(finished)