Normand Briere
2018-05-22 42107f9a01652cb2f47228d20c1148a2a22f6a63
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package mocap.scene;
 
import java.awt.Font;
 
import javax.media.j3d.Appearance;
import javax.media.j3d.ColoringAttributes;
import javax.media.j3d.PolygonAttributes;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Color3f;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;
 
import com.sun.j3d.utils.geometry.Cone;
import com.sun.j3d.utils.geometry.Cylinder;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.geometry.Text2D;
 
/**
 * Coordinate cross to represent a joint.
 *
 * x = red
 * y = green
 * z = blue
 *
 * @author Michael Kipp
 */
public class CoordCross {
 
    private final float RADIUS = 0.02f;
    private TransformGroup _tg = new TransformGroup();
 
    public CoordCross(float length) {
        Appearance green = new Appearance();
        ColoringAttributes ca = new ColoringAttributes();
        ca.setColor(0f, 1f, 0f);
        ca.setShadeModel(ColoringAttributes.NICEST);
        green.setColoringAttributes(ca);
        Appearance blue = new Appearance();
        ca = new ColoringAttributes();
        ca.setColor(0f, 0f, 1f);
        blue.setColoringAttributes(ca);
        Appearance red = new Appearance();
        ca = new ColoringAttributes();
        ca.setColor(1f, 0f, 0f);
        red.setColoringAttributes(ca);
        Appearance grey = new Appearance();
        ca = new ColoringAttributes();
        ca.setColor(.8f, .8f, 0f);
        grey.setColoringAttributes(ca);
 
        Transform3D tf = new Transform3D();
        Vector3f vec = new Vector3f(0, length / 2, 0);
 
        Sphere center = new Sphere(RADIUS * 4);
        center.setAppearance(grey);
        _tg.addChild(center);
 
        // Y-AXIS
        tf = new Transform3D();
        tf.setTranslation(vec);
        TransformGroup ty = getTranslation(length);
        Cylinder cy = new Cylinder(RADIUS, length);
        cy.setAppearance(green);
        _tg.addChild(ty);
        ty.addChild(cy);
        ty.addChild(makeHead("y", green, length));
 
        // X-AXIS
        tf = new Transform3D();
        tf.setTranslation(vec);
        tf.rotZ(3 * Math.PI / 2);
        TransformGroup tx = new TransformGroup(tf);
        TransformGroup tx2 = getTranslation(length);
        _tg.addChild(tx);
        tx.addChild(tx2);
        cy = new Cylinder(RADIUS, length);
        cy.setAppearance(red);
        tx2.addChild(cy);
        tx2.addChild(makeHead("x", red, length));
 
        // Z-AXIS
        tf = new Transform3D();
        tf.setTranslation(vec);
        tf.rotX(Math.PI / 2);
        TransformGroup tz = new TransformGroup(tf);
        TransformGroup tz2 = getTranslation(length);
        _tg.addChild(tz);
        tz.addChild(tz2);
        cy = new Cylinder(RADIUS, length);
        cy.setAppearance(blue);
        tz2.addChild(cy);
        tz2.addChild(makeHead("z", blue, length));
 
        addLabels(length);
    }
 
    private void addLabels(float length) {
        float LABEL_OFFSET = length / 9;
        Vector3f v = new Vector3f(length + LABEL_OFFSET, 0, 0);
        Transform3D tf = new Transform3D();
        tf.setTranslation(v);
        TransformGroup tx = new TransformGroup(tf);
 
        v.set(0, length + LABEL_OFFSET, 0);
        tf.setTranslation(v);
        TransformGroup ty = new TransformGroup(tf);
 
        v.set(0, 0, length + LABEL_OFFSET);
        tf.setTranslation(v);
        TransformGroup tz = new TransformGroup(tf);
 
        _tg.addChild(tx);
        _tg.addChild(ty);
        _tg.addChild(tz);
 
        tx.addChild(makeLabel("x"));
        ty.addChild(makeLabel("y"));
        tz.addChild(makeLabel("z"));
    }
 
    private Text2D makeLabel(String label) {
        Text2D text = new Text2D(label, new Color3f(1, 1, 0), "Helvetica", 20, Font.BOLD);
        // make text 2-sided
        Appearance app = text.getAppearance();
        PolygonAttributes polyAttrib = new PolygonAttributes();
        polyAttrib.setCullFace(PolygonAttributes.CULL_NONE);
        polyAttrib.setBackFaceNormalFlip(true);
        app.setPolygonAttributes(polyAttrib);
        return text;
    }
 
    private TransformGroup getTranslation(float length) {
        Transform3D t = new Transform3D();
        t.setTranslation(new Vector3d(0, length / 2, 0));
        TransformGroup tf = new TransformGroup(t);
        return tf;
    }
 
    public TransformGroup getRoot() {
        return _tg;
    }
 
    private TransformGroup makeHead(String label, Appearance app, float length) {
        float headlength = length / 9;
        float headradius = RADIUS * 3.5f;
        Vector3f vec = new Vector3f(0, length / 2 + headlength / 2, 0);
        Transform3D tf = new Transform3D();
        tf.set(vec);
        TransformGroup tgH = new TransformGroup(tf);
        Cone head = new Cone(headradius, headlength);
        head.setAppearance(app);
        tgH.addChild(head);
        return tgH;
    }
}