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);
|
}
|
}
|
}
|