Normand Briere
2018-07-07 09ddd38fd4a8a7100c834a5e976f4796fae53541
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
package mocap.figure;
 
import java.awt.Color;
import javax.media.j3d.Appearance;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Material;
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.Sphere;
 
/**
 * Represents a trail point of a given joint.
 *
 * @author Quan Nguyen
 */
public class MotionTrailPoint
{
 
    private double _dTime;
    private Point3d _position;
    private double _dVelocity = 0.0;
    private Color _color;
    private float _fRadius = 0.01f;
//    private float _fVelocityHeight = 0.001f;
    //    private BranchGroup _bgPoint;
    private BranchGroup _bgMotionTrailPoint;
    private double _dScale;
    private double _velocityScale = 1d;
    private String _sBoneName;
    private TransformGroup _tgSphere;
    private Sphere _sphere;
    //    private BranchGroup _bgVelocity;
//    private Cylinder _cylinderVelocity;
    private Circle _circleVelocity;
    private TransformGroup _tgVelocity;
    private TransformGroup _tgMotionTrailPoint;
    private Switch _velocitySwitch;
 
    /**
     * Represents the position of the given bone at a specific time.
     *
     * @param bone
     * @param time
     * @param color
     * @param scale
     */
    private MotionTrailPoint(String bone, double time, 
            double velocity, Color color, double scale)
    {
        _sBoneName = bone;
        _dVelocity = velocity;
        _dTime = time;
        _position = new Point3d();
        _color = color;
        _dScale = scale;
        _dVelocity = _fRadius + (velocity * 0.05);
 
        initSceneObjects();
        createMotionTrailSphere();
        createVelocityVisualisation();
        _velocitySwitch.setWhichChild(Switch.CHILD_ALL);
    }
 
    
    public MotionTrailPoint(String bone, double time, Color color)
    {
 
        this(bone, time, 0, color, 1);
    }
 
    public MotionTrailPoint(String bone, double time, double velocity,
            Color color)
    {
 
        this(bone, time, velocity, color, 1);
    }
 
    public MotionTrailPoint(String bone, double time, Color color, double scale)
    {
 
        this(bone, time, 0, color, scale);
    }
 
    private void initSceneObjects()
    {
        _bgMotionTrailPoint = new BranchGroup();
        _bgMotionTrailPoint.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
        _bgMotionTrailPoint.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
        _bgMotionTrailPoint.setCapability(BranchGroup.ALLOW_DETACH);
 
        _tgMotionTrailPoint = new TransformGroup();
        _tgMotionTrailPoint.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        _tgMotionTrailPoint.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
        _tgMotionTrailPoint.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
        Transform3D t3dMotionTrailPointTranslation = new Transform3D();
        t3dMotionTrailPointTranslation.setTranslation(new Vector3d(_position));
        _tgMotionTrailPoint.setTransform(t3dMotionTrailPointTranslation);
        Transform3D t3dMotionTrailPointScale = new Transform3D();
        t3dMotionTrailPointScale.setScale(_dScale);
 
        _bgMotionTrailPoint.addChild(_tgMotionTrailPoint);
 
        _velocitySwitch = new Switch(Switch.CHILD_MASK);
        _velocitySwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);
        _tgMotionTrailPoint.addChild(_velocitySwitch);
    }
 
    /**
     * Attaches sphere representation (geometry) to the point in space.
     */
    private void createMotionTrailSphere()
    {
        Material materialStandard = new Material(new Color3f(_color),
                new Color3f(_color), new Color3f(_color), new Color3f(0.7f, 0.7f,
                0.7f), 10.0f);
        Appearance appearance = new Appearance();
        appearance.setMaterial(materialStandard);
 
        _sphere = new Sphere(_fRadius);
        _sphere.setAppearance(appearance);
        _tgSphere = new TransformGroup();
        _tgSphere.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        _tgSphere.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
        _tgSphere.setCapability(TransformGroup.ALLOW_LOCAL_TO_VWORLD_READ);
        Transform3D t3dSphereTranslation = new Transform3D();
        t3dSphereTranslation.setTranslation(new Vector3d(_position));
        _tgSphere.setTransform(t3dSphereTranslation);
        Transform3D t3dSphereScale = new Transform3D();
        t3dSphereScale.setScale(_dScale);
        _tgSphere.addChild(_sphere);
        // set to null for garbage collector
        _velocitySwitch.addChild(_tgSphere); // add the sphere
 
        materialStandard = null;
        appearance = null;
        t3dSphereTranslation = null;
        t3dSphereScale = null;
 
    }
 
    /**
     * Creates a 2D circle to represent velocity.
     *
     * @param pos
     * @param color
     * @param velocity
     * @param scale
     */
    private void createVelocityVisualisation()
    {
        _circleVelocity = new Circle((float) (_velocityScale * _dVelocity), 100, _color);
        _tgVelocity = new TransformGroup();
        _tgVelocity.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        _tgVelocity.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
        _tgVelocity.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
        _tgVelocity.setCapability(TransformGroup.ALLOW_LOCAL_TO_VWORLD_READ);
        Transform3D t3dVelocityTranslation = new Transform3D();
        t3dVelocityTranslation.setTranslation(new Vector3d(_position));
        _tgVelocity.setTransform(t3dVelocityTranslation);
        Transform3D t3dVelocityScale = new Transform3D();
        t3dVelocityScale.setScale(_dScale);
        _tgVelocity.addChild(_circleVelocity);
        _velocitySwitch.addChild(_tgVelocity);
        t3dVelocityTranslation = null;
        t3dVelocityScale = null;
 
    }
 
    public BranchGroup getObject()
    {
        return _bgMotionTrailPoint;
    }
 
    public String getBone()
    {
        return _sBoneName;
    }
 
    public double getTimePointInSeconds()
    {
        return _dTime;
    }
 
    public Color getColor()
    {
        return _color;
    }
 
    public void setScale(double scale)
    {
        _dScale = scale;
        Transform3D t3dSphere = new Transform3D();
        _tgMotionTrailPoint.getTransform(t3dSphere);
        t3dSphere.setScale(_dScale);
        _tgMotionTrailPoint.setTransform(t3dSphere);
        t3dSphere = null;
    }
 
    public double getScale()
    {
        return _dScale;
    }
 
    public void setVelocityScale(double s) {
        _velocityScale = s;
    }
 
    public void setPosition(Point3d positionInWorld)
    {
        _position = positionInWorld;
        Transform3D t3dPosition = new Transform3D();
        _tgMotionTrailPoint.getTransform(t3dPosition);
        t3dPosition.setTranslation(new Vector3d(_position));
        _tgMotionTrailPoint.setTransform(t3dPosition);
        //        drawLine(_tgMotionTrailPoint, new Vector3d(0,0,0),
        //                new Vector3d(_p3dPosition), new Color3f(Color.MAGENTA), 0.1f);
        t3dPosition = null;
    }
 
    public void getPosition(Vector3d positionInWorld)
    {
        Transform3D t3dSphere = new Transform3D();
        _tgMotionTrailPoint.getTransform(t3dSphere);
        t3dSphere.get(positionInWorld);
    }
 
    public void angleVelocityVisualisation(Point3d positionNextPointInWorld)
    {
        //        Transform3D t3dPosition = new Transform3D();
        //        _tgMotionTrailPoint.setTransform(t3dPosition);
        positionNextPointInWorld.sub(_position);
        Point3d p3dOrigin = new Point3d(0, 0, 0);
        Vector3d v3dNewYAxis = new Vector3d();
        Vector3d v3dOldYAxis = new Vector3d();
        Vector3d v3dCrossProduct_RotationAxis = new Vector3d();
 
        v3dOldYAxis.add(p3dOrigin, new Vector3d(0, 1, 0));
        v3dOldYAxis.sub(v3dOldYAxis, p3dOrigin);
 
        // Create the Vector to the current effector pos
        v3dNewYAxis.sub(positionNextPointInWorld, p3dOrigin);
 
        // normalize the vectors
        v3dNewYAxis.normalize();
        v3dNewYAxis.normalize();
 
        // the dot product gives me the cosine of the desired angle
        double dCosinus = v3dOldYAxis.angle(v3dNewYAxis);
        //        drawLine(_tgVelocity, new Vector3d(p3dOrigin),
        //                v3dNewYAxis, new Color3f(Color.RED), 0.1f);
        //        drawLine(_tgVelocity, new Vector3d(p3dOrigin),
        //                v3dOldYAxis, new Color3f(Color.BLUE), 0.1f);
        //        drawLine(_tgVelocity, new Vector3d(0,0,0),
        //                new Vector3d(p3dOrigin), new Color3f(Color.GREEN), 0.1f);
        //
        //        drawLine(_tgVelocity, new Vector3d(positionNextPointInWorld),
        //                new Vector3d(p3dOrigin), new Color3f(Color.CYAN), 0.1f);
 
        // use the cross product to check which way to rotate
        v3dCrossProduct_RotationAxis.cross(v3dOldYAxis, v3dNewYAxis);
        //        drawLine(_tgVelocity, new Vector3d(p3dOrigin),
        //                v3dCrossProduct_RotationAxis, new Color3f(Color.WHITE), 0.1f);
        rotate(v3dCrossProduct_RotationAxis, dCosinus);
 
        v3dNewYAxis = null;
        v3dOldYAxis = null;
        v3dCrossProduct_RotationAxis = null;
 
    }
 
    protected double rotate(Vector3d rotationAxis, double angle)
    {
        // float fAngle = (float) Math.toRadians(dRotationX);
 
        //
        // System.out.println(">>>> Rotate Axis (world):  " + rotationAxis
        // + " <<<<<< ");
 
        Transform3D t3dCurrentPositionInWorld = new Transform3D();
        _tgVelocity.getLocalToVworld(t3dCurrentPositionInWorld);
 
        t3dCurrentPositionInWorld.invert();
        t3dCurrentPositionInWorld.transform(rotationAxis);
        // System.out.println(">>>> Rotate Axis (local):  " + rotationAxis
        // + " <<<<<< ");
 
        // //System.out.println("Rotate double:" + this + " : " + dRotationX +
        // "(Rad: " + fAngle + ")");
        // axisAngleX.angle = fAngle;
 
        // if absoute then reset the joint
        //        if (isAbsolute) {
        //            reset();
        //
        //        }
        AxisAngle4d axisAngle = new AxisAngle4d(rotationAxis, angle);
 
        Transform3D t3dNewRotation = new Transform3D();
        t3dNewRotation.setRotation(axisAngle);
 
        Transform3D t3dCurrentMainTransform = new Transform3D();
        _tgVelocity.getTransform(t3dCurrentMainTransform);
 
        t3dCurrentMainTransform.mul(t3dNewRotation);
 
        _tgVelocity.setTransform(t3dCurrentMainTransform);
        // LineDrawer.drawLine(tgMain, rotationAxis, Color.YELLOW);
        //        t3dCurrentMainTransform.
        // update all Listeners
 
        t3dCurrentPositionInWorld = null;
        axisAngle = null;
        return angle;
    }
 
    public void showMotionTrailVelocity(boolean showMotionTrailVelocity)
    {
        if (showMotionTrailVelocity) {
            _velocitySwitch.setWhichChild(Switch.CHILD_ALL);
        } else {
            _velocitySwitch.setWhichChild(0);
        }
    }
}