Skip to main content

How to draw a line appearing a cylinder ?

11 replies [Last post]
aina
Offline
Joined: 2006-05-05
Points: 0

Hi all,

I have a scene composed by lots of objects linked by lines.
Now I want that these lines have an appearance of a cylinder. Is it possible or I have to replace a line directly by a cylinder ?

With LineArray it is easy to link two objects but I don't know how to do it by using a cylinder.

All suggests are welcome,

Thanks,

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
aina
Offline
Joined: 2006-05-05
Points: 0

Hello,

Below a portion of code that I want to modify, you can run it and see what I want to do. I haven't been able to link the objects because they are attched to the same transformgroup (as they don't form a tree).

I need your help please !

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;

import javax.media.j3d.AmbientLight;
import javax.media.j3d.Appearance;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Material;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.AxisAngle4f;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.geometry.Cylinder;
import com.sun.j3d.utils.universe.SimpleUniverse;

public class TGLink extends Applet {
private static final long serialVersionUID = 1;
private SimpleUniverse u = null;
private TransformGroup tg ;

public BranchGroup createSceneGraph() {

// Create the root of the branch graph

BranchGroup objRoot = new BranchGroup();

AmbientLight al=new AmbientLight();
al.setInfluencingBounds(new BoundingSphere(new Point3d(), 5));

objRoot.addChild(al);

DirectionalLight dl=new DirectionalLight();
dl.setDirection(-1,-1,-10);
dl.setInfluencingBounds(new BoundingSphere(new Point3d(), 5));

objRoot.addChild(dl);

Transform3D transform=new Transform3D();
transform.setTranslation(new Vector3f(0,0,0));

// The principal transformgroup is tg ------------------

tg = new TransformGroup(transform);
tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

objRoot.addChild(tg);

transform.set(new Vector3f(0,0.5f,-3));
TransformGroup tg1 = new TransformGroup(transform);
tg1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

tg.addChild(tg1); // adding tg1

transform.set(new Vector3f(0.5f,-0.5f,0));
TransformGroup tg2 = new TransformGroup(transform);
tg2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

tg.addChild(tg2); // adding tg2

transform.set(new Vector3f(-0.5f,-0.5f,0));
TransformGroup tg3 = new TransformGroup(transform);
tg3.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

tg.addChild(tg3); // adding tg3

float radius=0.025f;

createConnectionCylinder(tg1, tg2, radius);
createConnectionCylinder(tg3, tg1, radius);
createConnectionCylinder(tg2, tg3, radius);

tg1.addChild(new ColorCube(0.1));
tg2.addChild(new ColorCube(0.1));
tg3.addChild(new ColorCube(0.1));

return objRoot;
}

private void createConnectionCylinder(TransformGroup tg1,
TransformGroup tg2,
float radius) {

Transform3D transform=new Transform3D();

Point3f zero = new Point3f();
Point3f tg4p = new Point3f();

tg2.getTransform(transform);
transform.transform(tg4p);

Vector3f dir1 = new Vector3f(0,1,0);
Vector3f dir2 = new Vector3f(tg4p);
dir2.sub(zero);

Vector3f axis=new Vector3f();
axis.cross(dir1,dir2);

AxisAngle4f aa = new AxisAngle4f(axis, dir1.angle(dir2));

Transform3D cylTransform=new Transform3D();
cylTransform.setRotation(aa);

float length=dir2.length();

dir2.scale(0.5f);
cylTransform.setTranslation(dir2);

TransformGroup cylTG=new TransformGroup(cylTransform);
Appearance app=new Appearance();
Material m=new Material();
m.setAmbientColor(new Color3f(1,0,0));
m.setDiffuseColor(new Color3f(0.7f,0.3f,0));
app.setMaterial(m);

cylTG.addChild(new Cylinder(radius, length, app));

tg1.addChild(cylTG);
}

public TGLink() {
}

public void init() {
setLayout(new BorderLayout());
GraphicsConfiguration config = SimpleUniverse
.getPreferredConfiguration();
Canvas3D c = new Canvas3D(config);
add("Center", c);
BranchGroup scene = createSceneGraph();
u = new SimpleUniverse(c);
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}

public void destroy() {
u.cleanup();
}

public static void main(String[] args) {
new MainFrame(new TGLink(), 512, 512);
}
}

Thanks advance !

Aina

nitro
Offline
Joined: 2004-09-12
Points: 0

[code]

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;

import javax.media.j3d.AmbientLight;
import javax.media.j3d.Appearance;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Material;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.AxisAngle4f;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.geometry.Cylinder;
import com.sun.j3d.utils.universe.SimpleUniverse;

public class ASDF extends Applet {
private static final long serialVersionUID = 1;

private SimpleUniverse u = null;

private TransformGroup tg;

public BranchGroup createSceneGraph() {

// Create the root of the branch graph

BranchGroup objRoot = new BranchGroup();

AmbientLight al = new AmbientLight();
al.setInfluencingBounds(new BoundingSphere(new Point3d(), 5));

objRoot.addChild(al);

DirectionalLight dl = new DirectionalLight();
dl.setDirection(-1, -1, -10);
dl.setInfluencingBounds(new BoundingSphere(new Point3d(), 5));

objRoot.addChild(dl);

Transform3D transform = new Transform3D();
transform.setTranslation(new Vector3f(0, 0, 0));

// The principal transformgroup is tg ------------------

tg = new TransformGroup(transform);
tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

objRoot.addChild(tg);

transform.set(new Vector3f(0, 0.5f, -3));
TransformGroup tg1 = new TransformGroup(transform);
tg1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

tg.addChild(tg1); // adding tg1

transform.set(new Vector3f(0.5f, -0.5f, 0));
TransformGroup tg2 = new TransformGroup(transform);
tg2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

tg.addChild(tg2); // adding tg2

transform.set(new Vector3f(-0.5f, -0.5f, 0));
TransformGroup tg3 = new TransformGroup(transform);
tg3.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

tg.addChild(tg3); // adding tg3

float radius = 0.025f;

createConnectionCylinder(tg1, tg2, radius);
createConnectionCylinder(tg3, tg1, radius);
createConnectionCylinder(tg2, tg3, radius);

tg1.addChild(new ColorCube(0.1));
tg2.addChild(new ColorCube(0.1));
tg3.addChild(new ColorCube(0.1));

return objRoot;
}

private void createConnectionCylinder(TransformGroup tg1, TransformGroup tg2, float radius) {
Transform3D transform = new Transform3D();
tg2.getTransform(transform);
Transform3D t3d=new Transform3D();
tg1.getTransform(t3d);
transform.sub(t3d);

Point3f zero = new Point3f();
Point3f tg4p = new Point3f();

transform.transform(tg4p);

Vector3f dir1 = new Vector3f(0, 1, 0);
Vector3f dir2 = new Vector3f(tg4p);
dir2.sub(zero);

Vector3f axis = new Vector3f();
axis.cross(dir1, dir2);

AxisAngle4f aa = new AxisAngle4f(axis, dir1.angle(dir2));

Transform3D cylTransform = new Transform3D();
cylTransform.setRotation(aa);

float length = dir2.length();

dir2.scale(0.5f);
cylTransform.setTranslation(dir2);

TransformGroup cylTG = new TransformGroup(cylTransform);
Appearance app = new Appearance();
Material m = new Material();
m.setAmbientColor(new Color3f(1, 0, 0));
m.setDiffuseColor(new Color3f(0.7f, 0.3f, 0));
app.setMaterial(m);

cylTG.addChild(new Cylinder(radius, length, app));

tg1.addChild(cylTG);
}

public ASDF() {
}

public void init() {
setLayout(new BorderLayout());
GraphicsConfiguration config = SimpleUniverse
.getPreferredConfiguration();
Canvas3D c = new Canvas3D(config);
add("Center", c);
BranchGroup scene = createSceneGraph();
u = new SimpleUniverse(c);
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}

public void destroy() {
u.cleanup();
}

public static void main(String[] args) {
new MainFrame(new TGLink(), 512, 512);
}
}
[/code]

But it won't work if you have a lien from TG under the mainTG to a TG not under the main TG. For that you need to calculate the transformation path's from Top to the connected objects.

aina
Offline
Joined: 2006-05-05
Points: 0

Hello nitro,

I have a little worry there. In fact when the nodes are structured in tree all work fine, I can modify the size of edge, move it via Pick behavior.

My problem is the nodes are not structured in tree but in graph, that means every node is attached to the main transformGroup ; example : TG the main TransformGroup under the Branchgroup and if there are obj1, obj2, obj3, obj4 as objects with respectively tg1, tg2, tg3, tg4 as transformGroup, I'll have :

TG.addChild(tg1);
TG.addChild(tg2);
TG.addChild(tg3);
TG.addChild(tg4);

Now I have to draw the link between them, I tried to modify the algorithm that you gave but it doesan't work.

As they(nodes) form a graph but not tree then each node may have a link to all others (complet graph).

Can you help me ?

Thanks.

Aina

nitro
Offline
Joined: 2004-09-12
Points: 0

You need to store for each object which lines are affected by changing the object. And for each line you need to know which is the start TG and the end TG. then recalculate each line that was affected by the change. The line knows it start and end TG so you can easily recalculate the line.
For that I would suggest that you create an class Line which knows the start and end TransformGroup and you create a class Vertex that holds your object and the lines it is connected to.

aina
Offline
Joined: 2006-05-05
Points: 0

For the moment the problem is not how to move the objects but how to link them. Exactely I have a class named "Lien" having as variables two transformgroups "tgStart" and "tgEnd". Then as they form a graph I don't know how to build the cylinder link between two objects. I already have modified many times but it is not good. All links are well created and start from the start-object but they don't point to the end-object. All my objects are attached to the principal TG and I thought I have to make all links the same way.

nitro
Offline
Joined: 2004-09-12
Points: 0

[code]
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GraphicsConfiguration;

import javax.media.j3d.AmbientLight;
import javax.media.j3d.Appearance;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.ColoringAttributes;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.LineArray;
import javax.media.j3d.Material;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.AxisAngle4f;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.geometry.Cylinder;
import com.sun.j3d.utils.universe.SimpleUniverse;

public class TGLink extends Applet {
private static final long serialVersionUID = 1L;
private SimpleUniverse u = null;

public BranchGroup createSceneGraph() {
// Create the root of the branch graph
BranchGroup objRoot = new BranchGroup();
AmbientLight al=new AmbientLight();
al.setInfluencingBounds(new BoundingSphere(new Point3d(), 5));
objRoot.addChild(al);

DirectionalLight dl=new DirectionalLight();
dl.setDirection(-1,-1,-10);
dl.setInfluencingBounds(new BoundingSphere(new Point3d(), 5));
objRoot.addChild(dl);

Transform3D transform=new Transform3D();
transform.setTranslation(new Vector3f(0,1,-3));
TransformGroup tg1 = new TransformGroup(transform);
tg1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objRoot.addChild(tg1);

transform.set(new Vector3f(1,-1,0));
TransformGroup tg2 = new TransformGroup(transform);
tg2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
tg1.addChild(tg2);

transform.set(new Vector3f(-1,-1,0));
TransformGroup tg3 = new TransformGroup(transform);
tg3.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
tg1.addChild(tg3);

transform.set(new Vector3f(-1,-1,0));
TransformGroup tg4 = new TransformGroup(transform);
tg4.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
tg3.addChild(tg4);

// createConnectionLine(tg1, tg2);
// createConnectionLine(tg1, tg3);
// createConnectionLine(tg3, tg4);

float radius=0.025f;
createConnectionCylinder(tg1, tg2, radius);
createConnectionCylinder(tg1, tg3, radius);
createConnectionCylinder(tg3, tg4, radius);

tg1.addChild(new ColorCube(0.1));
tg2.addChild(new ColorCube(0.1));
tg3.addChild(new ColorCube(0.1));
tg4.addChild(new ColorCube(0.1));

return objRoot;
}

private void createConnectionLine(TransformGroup tg1, TransformGroup tg2) {
Transform3D transform=new Transform3D();
LineArray la=new LineArray(2, LineArray.COORDINATES);
la.setCoordinate(0, new Point3f());
Point3f tg4p=new Point3f();
tg2.getTransform(transform);
transform.transform(tg4p);
la.setCoordinate(1, tg4p);
Appearance app=new Appearance();
app.setColoringAttributes(new ColoringAttributes(new Color3f(Color.RED), ColoringAttributes.NICEST));
tg1.addChild(new Shape3D(la, app));
}

private void createConnectionCylinder(TransformGroup tg1, TransformGroup tg2, float radius) {
Transform3D transform=new Transform3D();
Point3f zero=new Point3f();
Point3f tg4p=new Point3f();
tg2.getTransform(transform);
transform.transform(tg4p);
Vector3f dir1=new Vector3f(0,1,0);
Vector3f dir2=new Vector3f(tg4p);
dir2.sub(zero);
Vector3f axis=new Vector3f();
axis.cross(dir1,dir2);
AxisAngle4f aa=new AxisAngle4f(axis, dir1.angle(dir2));
Transform3D cylTransform=new Transform3D();
cylTransform.setRotation(aa);
float length=dir2.length();
dir2.scale(0.5f);
cylTransform.setTranslation(dir2);
TransformGroup cylTG=new TransformGroup(cylTransform);
Appearance app=new Appearance();
Material m=new Material();
m.setAmbientColor(new Color3f(1,0,0));
m.setDiffuseColor(new Color3f(0.7f,0.3f,0));
app.setMaterial(m);
cylTG.addChild(new Cylinder(radius, length, app));
tg1.addChild(cylTG);
}

public TGLink() {
}

public void init() {
setLayout(new BorderLayout());
GraphicsConfiguration config = SimpleUniverse
.getPreferredConfiguration();
Canvas3D c = new Canvas3D(config);
add("Center", c);
BranchGroup scene = createSceneGraph();
u = new SimpleUniverse(c);
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}

public void destroy() {
u.cleanup();
}

public static void main(String[] args) {
new MainFrame(new TGLink(), 256, 256);
}
}
[/code]

aina
Offline
Joined: 2006-05-05
Points: 0

Many thanks netro, it works fine !

When I used LineArray to connect my objects I used PickTranslate for the translation. At this time I added a LineArray to parent object and in my PickingCallbackClass I modify the line at every movement of one object in the extremity, it worked fine,

Now I do like this, I re-instantiate the Cylinder but I didn't re-add the cylTG to tg1 (risk of exception). But only the object picked moves, the link stays in its place while its lentgh is well modified when I print it.

I created a methode that works similarly the createConnectionCylinder, the unique difference is I don't re-add the cylTG to tg1.

Can you tell me what is wrong ?

nitro
Offline
Joined: 2004-09-12
Points: 0

You need to change the transformation of cylTG based upon the connection (the two transform group). Will say you have to recalculate the rotation, position and scaling (you dont need to create a new cylinder just scale it in the y direction in the cylTG).

aina
Offline
Joined: 2006-05-05
Points: 0

Hello netro,

Here is how I did it :
Before all tg1, cylTransform, myCylinder(the cylinder) are public variables in my class.

To modify the position of the cylinder when I move one object in extremity I get the new position (tg2) of the object, recalculate the rotation, position, etc as you mentionned.

Bellow a portion of my method :

public void modifCordonne (TransformGroup tg2, float radius){

Transform3D transform=new Transform3D();
Point3f zero = new Point3f();
Point3f destination = new Point3f();

tg2.getTransform(transform);

transform.transform(destination);

Vector3f dir1=new Vector3f(0,1,0);

Vector3f dir2=new Vector3f(destination);

dir2.sub(zero);

Vector3f axis=new Vector3f();
axis.cross(dir1,dir2);
AxisAngle4f aa = new AxisAngle4f(axis, dir1.angle(dir2));

// cylTransform was created in my method to create the link, I have just modified it here

cylTransform.setRotation(aa);
float length=dir2.length();

dir2.scale(0.5f);
cylTransform.setTranslation(dir2);

Appearance app=new Appearance();
Material m=new Material();
m.setAmbientColor(new Color3f(1,1,1));
m.setDiffuseColor(new Color3f(1,1,1));
app.setMaterial(m);

// the cylinder, I have just modify its length
myCylinder = new Cylinder(radius, length, app) ;

}

nitro
Offline
Joined: 2004-09-12
Points: 0

the new Cylinder that you create isn't attached to the scengraph. If you change the method as following and set the cylinder you create the link to one to length 1 (and scale the tg where you attach the cylinder as I did below) it should work (I hope):
[code]
public void modifCordonne (TransformGroup tg2, float radius){

Transform3D transform=new Transform3D();
Point3f zero = new Point3f();
Point3f destination = new Point3f();

tg2.getTransform(transform);

transform.transform(destination);

Vector3f dir1=new Vector3f(0,1,0);

Vector3f dir2=new Vector3f(destination);

dir2.sub(zero);

Vector3f axis=new Vector3f();
axis.cross(dir1,dir2);
AxisAngle4f aa = new AxisAngle4f(axis, dir1.angle(dir2));

// cylTransform was created in my method to create the link, I have just modified it here

cylTransform.setRotation(aa);
float length=dir2.length();
cylTransform.setScale(new Vector3d(1, length, 1);//Scale to new length

dir2.scale(0.5f);
cylTransform.setTranslation(dir2);

Appearance app=new Appearance();
Material m=new Material();
m.setAmbientColor(new Color3f(1,1,1));
m.setDiffuseColor(new Color3f(1,1,1));
app.setMaterial(m);

}
[/code]

Below is my code use right mouse btn to pick cube and move.
[code]

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GraphicsConfiguration;
import java.util.Enumeration;

import javax.media.j3d.AmbientLight;
import javax.media.j3d.Appearance;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.ColoringAttributes;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Geometry;
import javax.media.j3d.LineArray;
import javax.media.j3d.Material;
import javax.media.j3d.Node;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.AxisAngle4f;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.geometry.Cylinder;
import com.sun.j3d.utils.picking.PickTool;
import com.sun.j3d.utils.picking.behaviors.PickTranslateBehavior;
import com.sun.j3d.utils.picking.behaviors.PickingCallback;
import com.sun.j3d.utils.universe.SimpleUniverse;

public class TGLink extends Applet {
private static final long serialVersionUID = 1L;

private SimpleUniverse u = null;

public BranchGroup createSceneGraph() {
// Create the root of the branch graph
BranchGroup objRoot = new BranchGroup();
AmbientLight al = new AmbientLight();
al.setInfluencingBounds(new BoundingSphere(new Point3d(), 5));
objRoot.addChild(al);

DirectionalLight dl = new DirectionalLight();
dl.setDirection(-1, -1, -10);
dl.setInfluencingBounds(new BoundingSphere(new Point3d(), 5));
objRoot.addChild(dl);

final Transform3D transform = new Transform3D();
transform.setTranslation(new Vector3f(0, 1, -3));
TransformGroup tg1 = new TransformGroup(transform);
tg1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
tg1.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
tg1.setCapability(TransformGroup.ALLOW_CHILDREN_READ);
tg1.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
objRoot.addChild(tg1);

transform.set(new Vector3f(1, -1, 0));
TransformGroup tg2 = new TransformGroup(transform);
tg2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
tg2.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
tg2.setCapability(TransformGroup.ALLOW_CHILDREN_READ);
tg2.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
tg1.addChild(tg2);

transform.set(new Vector3f(-1, -1, 0));
final TransformGroup tg3 = new TransformGroup(transform);
tg3.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
tg3.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
tg3.setCapability(TransformGroup.ALLOW_CHILDREN_READ);
tg3.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
tg1.addChild(tg3);

transform.set(new Vector3f(-1, -1, 0));
TransformGroup tg4 = new TransformGroup(transform);
tg4.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
tg4.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
tg4.setCapability(TransformGroup.ALLOW_CHILDREN_READ);
tg4.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
tg3.addChild(tg4);

// createConnectionLine(tg1, tg2);
// createConnectionLine(tg1, tg3);
// createConnectionLine(tg3, tg4);

float radius = 0.025f;
createConnectionCylinder(tg1, tg2, radius);
createConnectionCylinder(tg1, tg3, radius);
createConnectionCylinder(tg3, tg4, radius);

tg1.addChild(createColorCube());
tg2.addChild(createColorCube());
tg3.addChild(createColorCube());
tg4.addChild(createColorCube());

return objRoot;
}

private ColorCube createColorCube(){
ColorCube cc = new ColorCube(0.1);
cc.setPickable(true);
Enumeration en=cc.getAllGeometries();
while(en.hasMoreElements()){
((Geometry)en.nextElement()).setCapability(Geometry.ALLOW_INTERSECT);
}
return cc;
}

private void createConnectionLine(TransformGroup tg1, TransformGroup tg2) {
Transform3D transform = new Transform3D();
LineArray la = new LineArray(2, LineArray.COORDINATES);
la.setCoordinate(0, new Point3f());
Point3f tg4p = new Point3f();
tg2.getTransform(transform);
transform.transform(tg4p);
la.setCoordinate(1, tg4p);
Appearance app = new Appearance();
app.setColoringAttributes(new ColoringAttributes(
new Color3f(Color.RED), ColoringAttributes.NICEST));
tg1.addChild(new Shape3D(la, app));
}

private void createConnectionCylinder(TransformGroup tg1,
TransformGroup tg2, float radius) {
TransformGroup cylTG = new TransformGroup();
cylTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
cylTG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
updateCylTG(tg1, tg2, cylTG);

cylTG.addChild(createCylinder(radius));
tg1.addChild(cylTG);
}

private Cylinder createCylinder(float radius){
Appearance app = new Appearance();
Material m = new Material();
m.setAmbientColor(new Color3f(1, 0, 0));
m.setDiffuseColor(new Color3f(0.7f, 0.3f, 0));
app.setMaterial(m);
Cylinder cyl=new Cylinder(radius, 1, app);
cyl.setPickable(false);
return cyl;
}

private void updateCylTG(TransformGroup tg1, TransformGroup tg2,
TransformGroup cylTG) {
Transform3D transform = new Transform3D();
Point3f zero = new Point3f();
Point3f tg2p = new Point3f();
tg2.getTransform(transform);
transform.transform(tg2p);
Vector3f dir1 = new Vector3f(0, 1, 0);
Vector3f dir2 = new Vector3f(tg2p);
dir2.sub(zero);
Vector3f axis = new Vector3f();
axis.cross(dir1, dir2);
AxisAngle4f aa = new AxisAngle4f(axis, dir1.angle(dir2));
Transform3D cylTransform = new Transform3D();
cylTransform.setRotation(aa);
float length = dir2.length();
dir2.scale(0.5f);
cylTransform.setTranslation(dir2);
cylTransform.setScale(new Vector3d(1, length, 1));
cylTG.setTransform(cylTransform);
tg2.setUserData(new TGInfo(cylTG, tg1));
}

private class TGInfo {
private TransformGroup cylTG;

private TransformGroup parentTG;

private TransformGroup myTG;

public TGInfo(TransformGroup cylTG, TransformGroup parentTG) {
this.cylTG = cylTG;
this.parentTG = parentTG;
}

public void updateCylinder(TransformGroup tg) {
updateCylTG(parentTG, tg, cylTG);
Enumeration en = tg.getAllChildren();
while (en.hasMoreElements()) {
Node n = (Node) en.nextElement();
if (n instanceof TransformGroup) {
Object x = n.getUserData();
if (x instanceof TGInfo) {
TGInfo tgi = (TGInfo) x;
updateCylTG(tg, (TransformGroup) n, tgi.cylTG);
}
}
}

}
}

public TGLink() {
super();
}

public void init() {
setLayout(new BorderLayout());
GraphicsConfiguration config = SimpleUniverse
.getPreferredConfiguration();
Canvas3D c = new Canvas3D(config);
add("Center", c);

BranchGroup scene = createSceneGraph();

PickTranslateBehavior ptb = new PickTranslateBehavior(scene, c,
new BoundingSphere(new Point3d(), 5));
ptb.setupCallback(new PickingCallback() {
public void transformChanged(int arg0, TransformGroup tg) {
if (tg != null) {
Object x = tg.getUserData();
if (x instanceof TGInfo) {
((TGInfo) x).updateCylinder(tg);
}
}
}
});
ptb.setMode(PickTool.GEOMETRY);
scene.addChild(ptb);
u = new SimpleUniverse(c);
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}

public void destroy() {
u.cleanup();
}

public static void main(String[] args) {
new MainFrame(new TGLink(), 256, 256);
}
}

[/code]

aina
Offline
Joined: 2006-05-05
Points: 0

I'm very grateful nitro,

I have been able to adapt it to my needs after a few modifications.

Thanks again.

aina