package ddddbb.math;
import ddddbb.gen.AChangeListener;
import ddddbb.gen.DoubleModel;
public class Camera3d extends Camera {
public Point3d eye; //dim 3
protected int orientation = 1;
protected double screenEyeDist;
protected double eyesDistHalf;
protected double barEyeFocusDelta;
public Camera3d(
final DoubleModel _screenEyeDist,
final DoubleModel _eyesDistHalf,
final DoubleModel _barEyeFocusDelta
) {
//v[0], v[1] are Projection plane, v[2] viewing direction
v = new Point3d[] { null, null, null};
new AChangeListener() {
public void stateChanged() {
screenEyeDist = _screenEyeDist.getDouble();
changed();
}
}.addTo(_screenEyeDist);
new AChangeListener() {
public void stateChanged() {
eyesDistHalf = _eyesDistHalf.getDouble();
changed();
}
}.addTo(_eyesDistHalf);
new AChangeListener() {
public void stateChanged() {
barEyeFocusDelta = _barEyeFocusDelta.getDouble();
changed();
}
}.addTo(_barEyeFocusDelta);
setToDefault();
}
private Camera3d(boolean dummy) {}
public Camera3d clone() {
Camera3d res = new Camera3d(true);
res.eye = eye.clone();
for (int i=0;i<3;i++) {
res.v[i] = v[i].clone();
}
return res;
}
public void setToDefault() {
notify=false; setOrientation(1); notify=true;
for (int i=0;i<v.length;i++) v[i] = AOP.unitVector3(i);
eye = new Point3d(0,0,-screenEyeDist);
//takes coordinate origin in the center of the screen
changed();
}
public void rotate(double ph, Point a, Point b) {
assert a.isNormal() && b.isNormal();
for (int i=0;i<3;i++) {
v[i].rotate(ph,a,b);
}
eye.rotate(ph,a,b);
changed();
}
public void rotate3d(double ph, Point3d axis,Point3d o) {
assert axis.isNormal() : axis.len();
((Point3d)v[0]).rotate3d(ph,axis);
((Point3d)v[1]).rotate3d(ph,axis);
((Point3d)v[2]).rotate3d(ph,axis);
eye.rotate3d(ph,axis,o);
AOP.orthoNormalize(v); //avoid those tiny drifts
changed();
}
public void rotate(double ph, Point a, Point b, Point o) {
assert a.dim() == 3 && b.dim() == 3 && o.dim() == 3;
assert a.isNormal() && b.isNormal() : a.len() + "!=1," + b.len() + "!=1";
v[0].rotate(ph, a,b);
v[1].rotate(ph, a,b);
v[2].rotate(ph, a,b);
eye.rotate(ph, a, b, o);
AOP.orthoNormalize(v); //avoid those tiny drifts
changed();
}
public void translate(Point a,double dist) {
assert a.dim() == 3;
assert a.isNormal();
eye.addby(a,dist);
changed();
}
public Point3d viewingDirection() {
if (orientation>0) {
return (Point3d)v[2];
}
Point3d vd = (Point3d)v[0].clone();
vd.multiply(orientation);
return vd;
}
public void swapOrientation() {
orientation *= -1;
for (int i=0;i<3; i++ ) {
v[i].x[2] *= -1;
}
eye.x[2] *= -1;
changed();
}
/** +1 is left-handed, -1 is right-handed */
public void setOrientation(int _orientation) {
if (orientation!=_orientation) {
swapOrientation();
}
}
// /** a1>0, a2>0 */
// public void rot(double ph,final int a1, final int a2) {
// assert a1>0 && a2>0;
// rotate(ph,
// viewAbsRel.selectDirec3d(a1-1),
// viewAbsRel.selectDirec3d(a2-1),
// viewAbsRel.selectCenter3d());
// }
//
// /** a1>0, a2>0 */
// public ActionListener rotAction(final int a1, final int a2) {
// assert a1>0 && a2>0;
// return new ActionListener() {
// public void actionPerformed(ActionEvent e) {
// rot(AOP.deg,a1,a2);
// }
// };
// }
//
// /** axis != 0 */
// public void trans(int axis, double by) {
// assert axis!=0;
// if (axis>0) translate(viewAbsRel.selectDirec3d(axis-1),+by);
// if (axis<0) translate(viewAbsRel.selectDirec3d(-axis-1),-by);
// }
//
//
// /** axis != 0 */
// public ActionListener transAction(final int axis) {
// assert axis != 0;
// return new ActionListener() {
// public void actionPerformed(ActionEvent e) {
// trans(axis,0.1);
// }
// };
// }
}