Normand Briere
2018-07-01 89c1ad67bc65d24ceadfa9e95f8c5515283f1e97
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
package mocap.figure;
 
import javax.media.j3d.Appearance;
import javax.media.j3d.LineArray;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Switch;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.AxisAngle4d;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
 
import com.sun.j3d.utils.geometry.Box;
import com.sun.j3d.utils.geometry.Cylinder;
import com.sun.j3d.utils.geometry.Sphere;
 
/**
 * Actual geometry of the bone (various options).
 * 
 * @author Michael Kipp
 */
public class BoneGeom implements java.io.Serializable
{
 
    public static final int NONE = -1, LINE = 0, CYLINDER = 1, QUAD = 2;
    public static double CYLINDER_RADIUS = .1;
    private Switch _switch;
    //private Box _quad;
    private double _length;
 
    public BoneGeom(TransformGroup parent, Vector3d direction)
    {
        _length = direction.length();
        TransformGroup tgRot = new TransformGroup();
        tgRot.setTransform(computeRotation(direction));
        _switch = new Switch();
        _switch.setCapability(Switch.ALLOW_SWITCH_WRITE);
//        _switch.addChild(createLineLimb(_length));
        TransformGroup cyl = createCylinder(CYLINDER_RADIUS, _length);
//        _switch.addChild(createQuad(_length));
        _switch.setWhichChild(CYLINDER);
        parent.addChild(tgRot);
//        tgRot.addChild(_switch);
        tgRot.addChild(cyl);
//        _switch.addChild(cyl);
    }
 
//    public void detach() {
//        ((TransformGroup)_switch.getParent().getParent()).removeChild(_switch.getParent());
//    }
    public double getLength()
    {
        return _length;
    }
 
    public void select(int style)
    {
        _switch.setWhichChild(style == NONE ? Switch.CHILD_NONE : style);
    }
 
    private TransformGroup createCylinder(double radius, double length)
    {
        Sphere c = new Sphere(1);
        //Cylinder c = new Cylinder((float) radius, (float) length);
        TransformGroup tg = new TransformGroup();
        Transform3D tf = new Transform3D();
        tf.setTranslation(new Vector3d(0, length / 2, 0));
        tf.setScale(new Vector3d(radius*length, length/2, radius*length));
        tg.setTransform(tf);
        tg.addChild(c);
        return tg;
    }
 
//    private TransformGroup createQuad(double length)
//    {
//        Box c = new Box(.2f, (float) length / 2, .2f, new Appearance());
//        TransformGroup tg = new TransformGroup();
//        Transform3D tf = new Transform3D();
//        tf.setTranslation(new Vector3d(0, length / 2, 0));
//        tg.setTransform(tf);
//        tg.addChild(c);
//        _quad = c;
//        _quad.setCapability(Box.ENABLE_APPEARANCE_MODIFY);
//        for (int i = 0; i < 6; i++)
//        {
//            _quad.getShape(i).setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
//        }
//        return tg;
//    }
 
    private Shape3D createLineLimb(double length)
    {
        LineArray line = new LineArray(2, LineArray.COORDINATES | LineArray.COLOR_3);
        line.setCoordinate(0, new Point3d(0, 0, 0));
        line.setCoordinate(1, new Point3d(0, length, 0));
        line.setColor(0, new Color3f(0, 0, 1));
        line.setColor(1, new Color3f(0, 0, 1));
        return new Shape3D(line);
    }
 
    protected void setSelected(boolean val)
    {
//        if (val)
//        {
//            _quad.setAppearance(JointAppearance.getSelectedInstance());
//        } else
//        {
//            _quad.setAppearance(JointAppearance.getInstance());
//        }
    }
 
    /**
     * Given a direction, computes the necessary rotation to let the y-axis
     * point in that direction.
     */
    private Transform3D computeRotation(Vector3d direction)
    {
        Transform3D tf = new Transform3D();
        double x2 = direction.x * direction.x;
        double z2 = direction.z * direction.z;
        if (x2 < .00001 && z2 < .00001)
        {
            if (direction.y < 0)
            {
                tf.rotX(Math.PI);
            }
        } else
        {
            Vector3d vec = new Vector3d();
            vec.cross(new Vector3d(0d, 1d, 0d), new Vector3d(direction));
            double angle = Math.asin(Math.sqrt(x2 + z2) / direction.length());
            if (direction.y < 0)
            {
                angle = Math.PI - angle;
            }
            tf.setRotation(new AxisAngle4d(vec, angle));
        }
        return tf;
    }
}