/**
|
* JMOCAP
|
*
|
* Developed by Michael Kipp, 2008-2011, DFKI Saarbrücken, Germany
|
* E-Mail: mich.kipp@googlemail.com
|
*
|
* This software has been released under the
|
* GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007
|
*/
|
|
package mocap;
|
|
import java.awt.Color;
|
import java.awt.Dimension;
|
import java.awt.Font;
|
import java.awt.GraphicsConfiguration;
|
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseListener;
|
import java.awt.event.MouseMotionListener;
|
import java.awt.event.MouseWheelEvent;
|
import java.awt.event.MouseWheelListener;
|
import java.io.File;
|
import java.io.IOException;
|
import java.util.Map;
|
|
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.J3DGraphics2D;
|
import javax.media.j3d.Material;
|
import javax.media.j3d.Switch;
|
import javax.media.j3d.Transform3D;
|
import javax.vecmath.Color3f;
|
import javax.vecmath.Point3d;
|
import javax.vecmath.Vector3d;
|
import javax.vecmath.Vector3f;
|
|
import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;
|
import com.sun.j3d.utils.geometry.Sphere;
|
import com.sun.j3d.utils.universe.SimpleUniverse;
|
|
import mocap.figure.AnimData;
|
import mocap.figure.Bone;
|
import mocap.figure.Figure;
|
import mocap.figure.FigureManager;
|
import mocap.figure.MotionTrailPoint;
|
import mocap.gui.CameraChangeListener;
|
import mocap.reader.AMCReader;
|
import mocap.reader.BVHReader;
|
import mocap.scene.CoordCross;
|
import mocap.scene.Floor;
|
import java.util.List;
|
|
/**
|
* Provides a Java3D world for viewing mocap files (ASF/AMC and BVH).
|
*
|
* FLICKER PROBLEM: One solution appears to be switching off "Use unified back/depth buffer" for
|
* NVIDIA cards
|
*
|
* @author Michael Kipp
|
*/
|
public class JMocap
|
implements
|
MouseMotionListener,
|
MouseListener,
|
MouseWheelListener
|
{
|
|
private static final String VERSION = "1.0";
|
private static final boolean HAS_ORBIT_CONTROL = false;
|
private static final int VIEW_ACTIVATION_RADIUS = 250;
|
private static final double BACK_CLIP_DISTANCE = 500;
|
private static final float LIGHT_REACH = 500;
|
private Figure _figure;
|
private FigureManager _figureManager = new FigureManager();
|
private static final int W = 1100;
|
private static final int H = 800;
|
protected BranchGroup _root;
|
protected SimpleUniverse _su;
|
protected JMocapCanvas3D _canvas;
|
private Switch _coordCrossSwitch;
|
private Switch _floorSwitch;
|
private boolean _dirty = false;
|
private BranchGroup _bgMotionTrails;
|
private boolean _bMouseButtonPressed;
|
private int _nBeginMouseCoord_Y;
|
private int _nLastMouseCoord_Y;
|
private int _nLastMouseCoord_X;
|
private int _nBeginMouseCoord_X;
|
private Point3d _p3dCameraPosition = new Point3d(1, 3, 15);
|
public static final int _nCAMERA_YAW_MAX = 180;
|
public static final int _nCAMERA_YAW_MIN = -180;
|
private int _nCameraYaw = 0;
|
private int _nCameraPitch = 0;
|
public static final int _nCAMERA_PITCH_MAX = 90;
|
public static final int _nCAMERA_PITCH_MIN = -90;
|
private int _nCameraRoll;
|
private Point3d _p3dCameraTarget;
|
private boolean _bLookAtPosition = false;
|
private Point3d _p3dCameraPositionInit;
|
private float _fGainer_Y = 0.08f;
|
private float _fGainer_X = 0.08f;
|
private float _fGainer_Z = 0.2f;
|
private double _dScale = 1.0;
|
private int nReverseX = 1;
|
private int nReverseY = 1;
|
private boolean _bClearTrails;
|
private List<MotionTrailPoint> _motionTrailPoints = null;
|
private CameraChangeListener _cameraChangeListener = null;
|
// private Time _timeMotionTrailEnd;
|
// private Time _timeMotionTrailStart;
|
private boolean _bShowMotionTrailVelocity = false;
|
|
public JMocap()
|
{
|
super();
|
_root = createScenegraph();
|
_root.compile();
|
_canvas = new JMocapCanvas3D(SimpleUniverse.getPreferredConfiguration())
|
{
|
|
@Override
|
public void postSwap()
|
{
|
super.postSwap();
|
synchronized (this) {
|
_dirty = false;
|
}
|
}
|
};
|
// _canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
|
// _canvas = new
|
// Canvas3D(GraphicsEnvironment.getLocalGraphicsEnvironment().
|
// getDefaultScreenDevice().getDefaultConfiguration());
|
_canvas.setPreferredSize(new Dimension(W, H));
|
_canvas.setSize(new Dimension(W, H));
|
_su = new SimpleUniverse(_canvas);
|
// _su.getViewingPlatform().getViewPlatform().setCapability(ViewPlatform.ALLOW_BOUNDS_WRITE);
|
|
_su.getViewer().getView().setBackClipDistance(BACK_CLIP_DISTANCE);
|
_su.getViewingPlatform().getViewPlatform().setActivationRadius(
|
VIEW_ACTIVATION_RADIUS);
|
if (HAS_ORBIT_CONTROL) {
|
OrbitBehavior orbit = new OrbitBehavior(_canvas,
|
OrbitBehavior.REVERSE_ALL);
|
orbit.setSchedulingBounds(new BoundingSphere());
|
_su.getViewingPlatform().setViewPlatformBehavior(orbit);
|
} else {
|
// _su.getViewingPlatform().getViewPlatform().setBounds(new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0));
|
}
|
// _su.getViewer().getView().addCanvas3D();
|
_su.addBranchGraph(_root);
|
|
// printInfo();
|
_canvas.addMouseListener(this);
|
_canvas.addMouseMotionListener(this);
|
_canvas.addMouseWheelListener(this);
|
}
|
|
public void initCanvasComponents()
|
{
|
_canvas.initComponents();
|
}
|
|
public synchronized void setDirty()
|
{
|
_dirty = true;
|
}
|
|
public synchronized boolean isDirty()
|
{
|
return _dirty;
|
}
|
|
/**
|
* @return String with infos on current Java and J3D versions, used
|
* pipeline and renderer.
|
*/
|
public String getInfo()
|
{
|
StringBuilder sb = new StringBuilder();
|
Map props = SimpleUniverse.getProperties();
|
sb.append("JMocap version: " + VERSION);
|
sb.append("\nJava version: "
|
+ System.getProperty("java.version"));
|
sb.append("\nJ3D Version: " + props.get("j3d.version"));
|
sb.append("\nJ3D Specification: "
|
+ props.get("j3d.specification.version"));
|
sb.append("\nPipeline: " + props.get("j3d.pipeline"));
|
sb.append("\nRenderer: " + props.get("j3d.renderer"));
|
return sb.toString();
|
}
|
|
private void createFloor(BranchGroup bg)
|
{
|
_floorSwitch = new Switch();
|
_floorSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);
|
_floorSwitch.addChild(new Floor().getBG()); // add the floor
|
bg.addChild(_floorSwitch);
|
_floorSwitch.setWhichChild(0);
|
}
|
|
public FigureManager getFigureManager()
|
{
|
return _figureManager;
|
}
|
|
/**
|
* Removes all figures.
|
*/
|
public void clearAll()
|
{
|
for (Figure f : _figureManager.getFigures()) {
|
_root.removeChild(f.getBG());
|
}
|
_figureManager.getFigures().clear();
|
if (_bgMotionTrails != null) {
|
_bgMotionTrails.removeAllChildren();
|
_bgMotionTrails = null;
|
}
|
|
}
|
|
public void dispose()
|
{
|
_canvas.dispose();
|
}
|
|
/**
|
* @return 3D viewing component.
|
*/
|
public Canvas3D getViewComponent()
|
{
|
return _canvas;
|
}
|
|
public void setCameraView(Point3d pos, Point3d target)
|
{
|
_p3dCameraPosition = pos;
|
_p3dCameraPositionInit = new Point3d(pos);
|
_p3dCameraTarget = target;
|
Transform3D t3d = new Transform3D();
|
t3d.setTranslation(new Vector3d(_p3dCameraPosition));
|
// _su.getViewingPlatform().getViewPlatformTransform().getTransform(t3d);
|
// t3d.lookAt(pos, target, new Vector3d(0, 1, 0));
|
// t3d.invert();
|
_su.getViewingPlatform().getViewPlatformTransform().setTransform(t3d);
|
t3d = null;
|
}
|
|
public void resetCamera()
|
{
|
_p3dCameraPosition = new Point3d(_p3dCameraPositionInit);
|
moveCamera(_p3dCameraPosition.x, _p3dCameraPosition.y,
|
_p3dCameraPosition.z, -_nCameraYaw, _nCameraPitch, 0, false);
|
|
}
|
|
public SimpleUniverse getUniverse()
|
{
|
return _su;
|
}
|
|
public BranchGroup getRootBG()
|
{
|
return _root;
|
}
|
|
/**
|
* @return Most recently loaded figure.
|
*/
|
public Figure getFigure()
|
{
|
return _figure;
|
}
|
|
public void initFigure(Bone skel, String name)
|
{
|
initFigure(skel, name, new Point3d());
|
}
|
|
public void initFigure(Bone skel, String name, Point3d offset)
|
{
|
_figure = _figureManager.addFigure(name, skel, offset);
|
_root.addChild(_figure.getBG());
|
}
|
|
public void initAnim(AnimData data, String name)
|
{
|
_figure.setAnimation(data);
|
_figure.getPlayer().reset();
|
}
|
|
public void loadAMC(File file) throws IOException
|
{
|
AMCReader r = new AMCReader();
|
AnimData d = r.readAMC(file, _figure.getSkeleton());
|
initAnim(d, file.getName());
|
}
|
|
public void loadBVH(File f, float targetHeight, Point3d offset)
|
throws IOException
|
{
|
_figureManager.pauseAll();
|
BVHReader rd = new BVHReader(targetHeight);
|
BVHReader.BVHResult bvh = rd.readFile(f);
|
initFigure(bvh.skeleton, f.getName(), offset);
|
initAnim(bvh.animation, f.getName());
|
|
_dScale = rd.getScale();
|
}
|
|
protected Sphere createSphere(Color c, float radius)
|
{
|
Sphere s = new Sphere(radius);
|
Color3f c3 = new Color3f(c);
|
Appearance app = new Appearance();
|
app.setMaterial(new Material(c3, c3, new Color3f(Color.WHITE), c3,
|
.3f));
|
s.setAppearance(app);
|
return s;
|
}
|
|
protected Switch createCoordCross(BranchGroup r, float diameter, float thick)
|
{
|
Switch s = new Switch();
|
s.setCapability(Switch.ALLOW_SWITCH_WRITE);
|
CoordCross cc = new CoordCross(1.2f);
|
s.addChild(cc.getRoot());
|
s.setWhichChild(Switch.CHILD_ALL);
|
return s;
|
}
|
|
/**
|
* One ambient light. 2 directional lights: 1) from up-right-front 2) from up-left-back
|
*/
|
protected void lightScene(BranchGroup bg)
|
{
|
BoundingSphere bounds = new BoundingSphere(new Point3d(), LIGHT_REACH);
|
Color3f white = new Color3f(Color.YELLOW);
|
AmbientLight ambientLightNode = new AmbientLight(white);
|
ambientLightNode.setInfluencingBounds(bounds);
|
bg.addChild(ambientLightNode);
|
|
// Directional lights:
|
// comes from up-right-front
|
Vector3f light1Direction = new Vector3f(-5f, -5f, -5f); // left, down,
|
// backwards
|
// comes from up-left-back
|
Vector3f light2Direction = new Vector3f(5f, -5f, 5f); // right, down,
|
// forwards
|
|
DirectionalLight light1 = new DirectionalLight(white, light1Direction);
|
light1.setInfluencingBounds(bounds);
|
bg.addChild(light1);
|
|
DirectionalLight light2 = new DirectionalLight(white, light2Direction);
|
light2.setInfluencingBounds(bounds);
|
bg.addChild(light2);
|
}
|
|
public void showCoordCross(boolean val)
|
{
|
_coordCrossSwitch.setWhichChild(val
|
? Switch.CHILD_ALL
|
: Switch.CHILD_NONE);
|
}
|
|
public void showFloor(boolean val)
|
{
|
_floorSwitch.setWhichChild(val ? Switch.CHILD_ALL : Switch.CHILD_NONE);
|
}
|
|
public BranchGroup createScenegraph()
|
{
|
BranchGroup r = new BranchGroup();
|
r.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
|
lightScene(r);
|
r.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
|
_coordCrossSwitch = createCoordCross(r, 15f, .01f);
|
r.addChild(_coordCrossSwitch);
|
r.setBounds(new BoundingSphere(new Point3d(0, 0, 0), 10d));
|
createFloor(r);
|
return r;
|
}
|
|
/**
|
* Shows the path of the special joint.
|
*
|
* @param startFrame
|
* @param endFrame
|
* @param color
|
* @param jointName
|
*/
|
public void addMotionTrail(List<MotionTrailPoint> motionTrailPoints)
|
{
|
_bClearTrails = true;
|
_motionTrailPoints = motionTrailPoints;
|
_canvas.addPositionsToMotionTrail();
|
_canvas.repaint();
|
}
|
|
/**
|
* Add the path of the special joint to the scene
|
*
|
* @param startFrame
|
* @param endFrame
|
* @param color
|
* @param jointName
|
*/
|
private void addPositionsToMotionTrailPoints(
|
List<MotionTrailPoint> motionTrailPoints)
|
{
|
|
if (_figure.getPlayer() != null) {
|
int nCurrentFrame = _figure.getPlayer().getCurrentFrame();
|
for (MotionTrailPoint motionTrailPoint : motionTrailPoints) {
|
Bone bone = _figure.getSkeleton().findBone(
|
motionTrailPoint.getBone());
|
|
if (bone != null) {
|
_figure.getPlayer().gotoTime(
|
motionTrailPoint.getTimePointInSeconds());
|
motionTrailPoint.setScale(_dScale);
|
Point3d p3dPositionInWorld = new Point3d();
|
bone.getWorldPosition(p3dPositionInWorld);
|
|
// NEW: position is relative to root joint
|
// bone.getRelativePosition(_figure.getSkeleton(), p3dPositionInWorld);
|
|
motionTrailPoint.setPosition(p3dPositionInWorld);
|
p3dPositionInWorld = null;
|
|
} else {
|
System.err.println("Bone " + motionTrailPoint.getBone()
|
+ " not found");
|
|
}
|
bone = null;
|
}
|
// go to old position
|
_figure.getPlayer().gotoTime(
|
nCurrentFrame / _figure.getPlayer().getPlaybackFps());
|
} else {
|
System.err.println("No player Mocap-Player found");
|
|
}
|
|
}
|
|
/**
|
* Add the given MotionTrailPoints to scene
|
*
|
* @param motionTrailPoints
|
* Vector of MotionTrailPoints
|
*/
|
private void addMotionTrailsToScene(
|
List<MotionTrailPoint> motionTrailPoints)
|
{
|
// Point3d p = new Point3d();
|
// _figure.getSkeleton().getWorldPosition(p);
|
// System.out.println("Figure position in World: " + p);
|
|
if (_bgMotionTrails == null) {
|
_bgMotionTrails = new BranchGroup();
|
_bgMotionTrails.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
|
_bgMotionTrails.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
|
_bgMotionTrails.setCapability(BranchGroup.ALLOW_DETACH);
|
_root.addChild(_bgMotionTrails);
|
} else if (_bClearTrails) {
|
removeMotionTrails();
|
}
|
|
for (int i = 0; i + 1 < motionTrailPoints.size() - 1; i++) {
|
motionTrailPoints.get(i).showMotionTrailVelocity(
|
_bShowMotionTrailVelocity);
|
_bgMotionTrails.addChild(motionTrailPoints.get(i).getObject());
|
|
Vector3d v3dNextPositionInWorld = new Vector3d();
|
motionTrailPoints.get(i + 1).getPosition(v3dNextPositionInWorld);
|
motionTrailPoints.get(i).angleVelocityVisualisation(
|
new Point3d(v3dNextPositionInWorld));
|
if (i + 1 == motionTrailPoints.size() - 1) {
|
_bgMotionTrails.addChild(motionTrailPoints.get(i + 1).getObject());
|
}
|
|
}
|
|
// write the positions into a file
|
// PathsFileWriter checkpointPoseReader = new PathsFileWriter();
|
// checkpointPoseReader.writeDocument("checkpoints", motionTrailPoints);
|
// System.out.println("Figure Scale: " + _figure.getScale());
|
|
}
|
|
public void showMotionTrailVelocity(boolean showMotionTrailVelocity)
|
{
|
if (showMotionTrailVelocity != _bShowMotionTrailVelocity
|
&& _motionTrailPoints != null) {
|
for (MotionTrailPoint mtPoint : _motionTrailPoints) {
|
mtPoint.showMotionTrailVelocity(showMotionTrailVelocity);
|
}
|
}
|
_bShowMotionTrailVelocity = showMotionTrailVelocity;
|
}
|
|
public void removeMotionTrails()
|
{
|
if (_bgMotionTrails != null) {
|
_bgMotionTrails.removeAllChildren();
|
}
|
}
|
|
public void initCameraToSkeleton(Point3d cameraTarget)
|
{
|
|
// _p3dCameraTarget = cameraTarget;
|
double dSkeletonSize = 1.5d * _figure.getSkeleton().getMaxDistance();
|
// System.out.println("Max Distance: " + dSkeletonSize);
|
|
// get the field of view
|
|
double dFieldOfView = _su.getViewer().getView().getFieldOfView();
|
double dCameraZPos = Math.atan(dFieldOfView / 2d) / dSkeletonSize;
|
// System.out.println("Max Distance:dCameraZPos: " + dCameraZPos);
|
// double dFieldOfViewInRadians = Math
|
// .atan((dSkeletonSize / (2 * _cameraConfiguration.getFocal())))
|
// * factor;
|
// // System.out.println("\n\n\n\nCameraController::" + this +
|
// // "getObjectInFieldOfView::_dFieldOfViewInRadians::" +
|
// // dFieldOfViewInRadians + "\n\n\n\n");
|
// _cameraConfiguration.setFieldOfView(dFieldOfViewInRadians);
|
// return dFieldOfViewInRadians;
|
// update();
|
_p3dCameraPosition.z = dCameraZPos;
|
_p3dCameraPosition.x = cameraTarget.x;
|
_p3dCameraPosition.y = cameraTarget.y;
|
moveCamera(_p3dCameraPosition.x, _p3dCameraPosition.y,
|
_p3dCameraPosition.z, -_nCameraYaw, _nCameraPitch, 0, false);
|
onCameraChanged("z_coord", _p3dCameraPosition.z);
|
onCameraChanged("x_coord", _p3dCameraPosition.x);
|
onCameraChanged("y_coord", _p3dCameraPosition.y);
|
// System.out.println("Max Distance:_p3dCameraPosition: " + _p3dCameraPosition);
|
// System.out.println("Max Distance:_p3dCameraTarget: " + _p3dCameraTarget);
|
// System.out.println("Max Distance:getCameraYaw(): " + getCameraYaw());
|
// System.out.println("Max Distance:getCameraPitch: " + getCameraPitch());
|
|
|
}
|
|
private Transform3D moveCamera(double x, double y, double z, double yaw,
|
double pitch, double roll, boolean holdLookAt)
|
{
|
Transform3D ret = new Transform3D();// return transform
|
Transform3D xrot = new Transform3D();
|
Transform3D yrot = new Transform3D();
|
Transform3D zrot = new Transform3D();
|
Transform3D pos = new Transform3D();
|
|
// roll pitch yaw rotations by Degrees
|
yrot.rotY(yaw / 360 * (2 * Math.PI));
|
xrot.rotX(pitch / 360 * (2 * Math.PI));
|
zrot.rotZ(roll / 360 * (2 * Math.PI));
|
// multiply return values by rotation
|
// (order of multiplication is important dependent on coordinate system
|
// being used)
|
ret.mul(zrot);
|
ret.mul(yrot);
|
ret.mul(xrot);
|
|
// multiply return values by translation
|
pos.setTranslation(new Vector3d(x, y, z));
|
ret.mul(pos);
|
|
if (holdLookAt) {
|
Vector3d v3dPos = new Vector3d();
|
ret.get(v3dPos);
|
Transform3D t3d = new Transform3D();
|
t3d.lookAt(new Point3d(v3dPos), _p3dCameraTarget, new Vector3d(0,
|
1, 0));
|
t3d.invert();
|
|
_su.getViewingPlatform().getViewPlatformTransform().setTransform(
|
t3d);
|
} else {
|
_su.getViewingPlatform().getViewPlatformTransform().setTransform(
|
ret);
|
}
|
return ret;
|
}
|
|
/**
|
* Zooming by changing the field of view
|
*
|
* @param fieldOfView
|
*/
|
private void zoomCamera(double fieldOfView)
|
{
|
double dFieldOfView = _su.getViewingPlatform().getViewers()[0].getView().getFieldOfView();
|
|
_su.getViewingPlatform().getViewers()[0].getView().setFieldOfView(
|
dFieldOfView + fieldOfView * 0.05);
|
}
|
|
@Override
|
public void mouseDragged(MouseEvent e)
|
{
|
// camera rotating
|
if (e.getButton() == MouseEvent.BUTTON1) {
|
|
if (!_bMouseButtonPressed) {
|
|
_nCameraYaw = _nCameraYaw + e.getX() - _nLastMouseCoord_X;
|
|
} else {
|
_nCameraYaw = _nCameraYaw + e.getX() - _nBeginMouseCoord_X;
|
|
}
|
if (_nCameraYaw >= _nCAMERA_YAW_MAX) {
|
_nCameraYaw = _nCAMERA_YAW_MAX;
|
} else if (_nCameraYaw <= _nCAMERA_YAW_MIN) {
|
_nCameraYaw = _nCAMERA_YAW_MIN;
|
}
|
// negate _fYaw to get an intuitive behavior. Move mouse to right,
|
moveCamera(_p3dCameraPosition.x, _p3dCameraPosition.y,
|
_p3dCameraPosition.z, -_nCameraYaw, _nCameraPitch, 0,
|
_bLookAtPosition);
|
onCameraChanged("yaw", _nCameraYaw);
|
_bMouseButtonPressed = false;
|
|
} else if (e.getButton() == MouseEvent.BUTTON3) // camera moving
|
{
|
if (!_bMouseButtonPressed) {
|
|
_p3dCameraPosition.x = _p3dCameraPosition.x
|
+ (nReverseX * ((e.getX() - _nLastMouseCoord_X))
|
* _fGainer_X * _dScale);
|
_p3dCameraPosition.y = _p3dCameraPosition.y
|
+ (nReverseY * ((e.getY() - _nLastMouseCoord_Y))
|
* _fGainer_Y * _dScale);
|
|
} else {
|
_p3dCameraPosition.x = _p3dCameraPosition.x
|
+ (nReverseX * ((e.getX() - _nBeginMouseCoord_X))
|
* _fGainer_X * _dScale);
|
_p3dCameraPosition.y = _p3dCameraPosition.y
|
+ (nReverseY * ((e.getY() - _nBeginMouseCoord_Y))
|
* _fGainer_Y * _dScale);
|
}
|
|
moveCamera(_p3dCameraPosition.x, _p3dCameraPosition.y,
|
_p3dCameraPosition.z, -_nCameraYaw, _nCameraPitch, 0, false);
|
onCameraChanged("x_coord", _p3dCameraPosition.x);
|
onCameraChanged("y_coord", _p3dCameraPosition.y);
|
_bMouseButtonPressed = false;
|
|
} else if (e.getButton() == MouseEvent.BUTTON2) // camera moving
|
{
|
if (!_bMouseButtonPressed) {
|
|
_nCameraPitch = _nCameraPitch + e.getY() - _nLastMouseCoord_Y;
|
|
} else {
|
|
_nCameraPitch = _nCameraPitch + e.getY() - _nBeginMouseCoord_Y;
|
}
|
if (_nCameraPitch >= _nCAMERA_PITCH_MAX) {
|
_nCameraPitch = _nCAMERA_PITCH_MAX;
|
} else if (_nCameraPitch <= _nCAMERA_PITCH_MIN) {
|
_nCameraPitch = _nCAMERA_PITCH_MIN;
|
}
|
// negate _fYaw to get an intuitive behavior. Move mouse to
|
// right,
|
moveCamera(_p3dCameraPosition.x, _p3dCameraPosition.y,
|
_p3dCameraPosition.z, -_nCameraYaw, _nCameraPitch, 0,
|
_bLookAtPosition);
|
onCameraChanged("pitch", _nCameraPitch);
|
_bMouseButtonPressed = false;
|
|
}
|
_nLastMouseCoord_X = e.getX();
|
_nLastMouseCoord_Y = e.getY();
|
}
|
|
private void onCameraChanged(String command, double value)
|
{
|
if (_cameraChangeListener != null) {
|
_cameraChangeListener.onCameraChanged(command, value);// TODO Auto-generated method stub
|
}
|
}
|
|
public Point3d getCameraPosition()
|
{
|
return _p3dCameraPosition;
|
}
|
|
public int getCameraPitch()
|
{
|
return _nCameraPitch;
|
}
|
|
public int getCameraYaw()
|
{
|
return _nCameraYaw;
|
}
|
|
public void reverseXAxis(boolean reverse)
|
{
|
if (reverse) {
|
nReverseX = -1;
|
} else {
|
nReverseX = 1;
|
}
|
}
|
|
public void reverseYAxis(boolean reverse)
|
{
|
if (reverse) {
|
nReverseY = -1;
|
} else {
|
nReverseY = 1;
|
}
|
}
|
|
@Override
|
public void mouseMoved(MouseEvent e)
|
{
|
// TODO Auto-generated method stub
|
}
|
|
@Override
|
public void mouseClicked(MouseEvent e)
|
{
|
// TODO Auto-generated method stub
|
}
|
|
@Override
|
public void mouseEntered(MouseEvent e)
|
{
|
// TODO Auto-generated method stub
|
}
|
|
@Override
|
public void mouseExited(MouseEvent e)
|
{
|
// TODO Auto-generated method stub
|
}
|
|
@Override
|
public void mousePressed(MouseEvent e)
|
{
|
_nBeginMouseCoord_X = e.getX();
|
_nLastMouseCoord_X = e.getX();
|
_nBeginMouseCoord_Y = e.getY();
|
_nLastMouseCoord_Y = e.getY();
|
_bMouseButtonPressed = true;
|
|
}
|
|
@Override
|
public void mouseReleased(MouseEvent e)
|
{
|
// TODO Auto-generated method stub
|
}
|
|
@Override
|
public void mouseWheelMoved(MouseWheelEvent e)
|
{
|
int notches = e.getWheelRotation();
|
_p3dCameraPosition.z = _p3dCameraPosition.z + notches * _fGainer_Z;
|
moveCamera(_p3dCameraPosition.x, _p3dCameraPosition.y,
|
_p3dCameraPosition.z, -_nCameraYaw, _nCameraPitch, 0, false);
|
onCameraChanged("z_coord", _p3dCameraPosition.z);
|
// zoomCamera(notches);
|
|
}
|
|
public void setCameraChangeListener(
|
CameraChangeListener cameraChangeListener)
|
{
|
_cameraChangeListener = cameraChangeListener;
|
|
}
|
|
public void setCamera(double x, double y, double z, int yaw, int pitch,
|
int roll, boolean lookAtPos)
|
{
|
_p3dCameraPosition.x = x;
|
_p3dCameraPosition.y = y;
|
_p3dCameraPosition.z = z;
|
_nCameraYaw = yaw;
|
_nCameraPitch = pitch;
|
_nCameraRoll = roll;
|
_bLookAtPosition = lookAtPos;
|
// System.out.println("Set Camera values (" + x + ", " + y + ", " + z
|
// + ", " + yaw + ", " + pitch + ")");
|
moveCamera(_p3dCameraPosition.x, _p3dCameraPosition.y,
|
_p3dCameraPosition.z, -_nCameraYaw, _nCameraPitch,
|
_nCameraRoll, _bLookAtPosition);
|
|
}
|
|
class JMocapCanvas3D extends Canvas3D
|
{
|
|
private boolean bAddMotionTrail;
|
// private double pathStartTime;
|
// private double pathEndTime;
|
// private float fps;
|
// private Color pathColor;
|
// private String jointName1;
|
// private String jointName2;
|
private J3DGraphics2D graphics2D;
|
|
public JMocapCanvas3D(GraphicsConfiguration gconfig,
|
boolean offscreenflag)
|
{
|
super(gconfig, offscreenflag);
|
initComponents();
|
}
|
|
public JMocapCanvas3D(GraphicsConfiguration preferredConfiguration)
|
{
|
super(preferredConfiguration);
|
initComponents();
|
|
}
|
|
public void initComponents()
|
{
|
graphics2D = this.getGraphics2D();
|
graphics2D.setColor(Color.LIGHT_GRAY);
|
graphics2D.setFont(new Font("Serif", Font.BOLD, 15));
|
}
|
|
@Override
|
public void preRender()
|
{
|
super.preRender();
|
if (bAddMotionTrail) {
|
addPositionsToMotionTrailPoints(_motionTrailPoints);
|
addMotionTrailsToScene(_motionTrailPoints);
|
bAddMotionTrail = false;
|
}
|
}
|
|
@Override
|
public void postRender()
|
{
|
super.postRender();
|
|
showFrameInformation();
|
|
graphics2D.flush(true);
|
}
|
|
public void dispose()
|
{
|
graphics2D.dispose();
|
}
|
|
// public void showPath(double startTime, double endTime, Color color,
|
// String name1, String name2, float fps)
|
// {
|
// bAddMotionTrail = true;
|
// pathStartTime = startTime;
|
// pathEndTime = endTime;
|
// pathColor = color;
|
// jointName1 = name1;
|
// jointName2 = name2;
|
// this.fps = fps;
|
//
|
// }
|
|
public void addPositionsToMotionTrail()
|
{
|
bAddMotionTrail = true;
|
}
|
|
public void showFrameInformation()
|
{
|
if (_figure != null) {
|
graphics2D.drawString("frame: "
|
+ _figure.getPlayer().getCurrentFrame(),
|
getSize().width / 2, getSize().height - 20);
|
}
|
|
}
|
}
|
}
|