package plane;
import bomb.Bomb;
import javafx.scene.media.AudioClip;
import mainPac.PhysicalObject;
import javax.vecmath.AxisAngle4d;
import javax.vecmath.Quat4d;
import javax.vecmath.Vector3d;
import mainPac.SimulationEntity;
import physics.QuatUtil;
import physics.VectorUtils;
public class PlanePhysicalObject extends PhysicalObject{
private boolean pressingUp;
private boolean pressingDown;
private boolean pressingRight;
private boolean pressingLeft;
private boolean pressingRudderRight;
private boolean pressingRudderLeft;
private static final Vector3d FORWARD = new Vector3d(0, 0, 1);
private static final Vector3d LEFT = new Vector3d(-1, 0, 0);
private static final Vector3d UP = new Vector3d(0, -1, 0);
private static final Vector3d GRAVITY = new Vector3d(0, 0.2, 0);
private Vector3d orientationForward;
private Vector3d orientationUp;
private Vector3d orientationLeft;
private double attackAngle;
private double slidingAngle;
private double speedSquared;
public PlanePhysicalObject() {
Quat4d initialQuat = new Quat4d();
initialQuat.set(new AxisAngle4d(0, 1, 0, Math.toRadians(90)));
setOrientation(initialQuat);
setPlace(new Vector3d(0, 200, 1000));
setSpeed(new Vector3d(10, -2, 0));
}
public void airborneSimulationStep(){
calculateValues();
thrust();
gravity();
airDrag();
angularDrag();
alignLeftRight();
dihedral();
alignUpDown();
lift();
bounce();
applyUserForces();
}
public void fallingSimulationStep(){
calculateValues();
gravity();
airDrag();
angularDrag();
dihedral();
alignUpDown();
}
public void groundedSimulationStep(){
calculateValues();
Vector3d newSpeed= new Vector3d(speed.x, 0, speed.z);
double length= newSpeed.length();
newSpeed.normalize();
newSpeed.scale(length-0.1);
Vector3d newPlace= new Vector3d(place.x, 700, place.z);
setSpeed(newSpeed);
setPlace(newPlace);
angularDrag();
dihedral();
alignUpDown();
}
private void calculateValues() {
orientationForward = QuatUtil.rotateVector(FORWARD, orientation);
orientationUp = QuatUtil.rotateVector(UP, orientation);
orientationLeft = QuatUtil.rotateVector(LEFT, orientation);
attackAngle = orientationUp.angle(speed) - Math.PI / 2.0;
slidingAngle = orientationLeft.angle(speed) - Math.PI / 2.0;
speedSquared = speed.length()*speed.length();
}
private void airDrag() {
Vector3d drag = new Vector3d(speed);
drag.normalize();
drag.scale(Math.abs(attackAngle)+0.1);
drag.scale(speedSquared);
drag.scale(-0.0005);
speed.add(drag);
}
private void angularDrag() {
Quat4d zero = new Quat4d(0, 0, 0, 1);
zero.interpolate(rotationSpeed, -0.1);
rotationSpeed.mul(zero);
}
private void thrust(){
if(speed.length()>10){
return;
}
Vector3d thrust = new Vector3d(speed);
thrust.normalize();
thrust.scale(0.1);
speed.add(thrust);
}
private void gravity(){
speed.add(GRAVITY);
}
private void lift() {
if (getPlace().y < -100) {
return;
}
Vector3d lift = VectorUtils.getProjection(speed, orientationUp);
lift.normalize();
double factor;
if(Math.abs(attackAngle)<0.25){
factor= attackAngle;
}
else{
factor= 0;
}
lift.scale(factor);
lift.scale(Math.cos(slidingAngle));
lift.scale(speedSquared);
lift.scale(0.02);
double speedLegthBefore= speed.length();
speed.add(lift);
speed.normalize();
speed.scale(speedLegthBefore);
}
private void alignLeftRight() {
Quat4d quat = new Quat4d();
quat.set(new AxisAngle4d(0, -1, 0, slidingAngle * -0.0001 * speedSquared));
rotationSpeed.mul(quat);
}
private void dihedral() {
Quat4d quat = new Quat4d();
quat.set(new AxisAngle4d(0, 0, 1, slidingAngle * -0.0001 * speedSquared));
rotationSpeed.mul(quat);
}
private void alignUpDown() {
if (Math.abs(attackAngle) < 0.25) {
return;
}
Quat4d quat = new Quat4d();
quat.set(new AxisAngle4d(1, 0, 0, attackAngle * -0.001 * speedSquared));
rotationSpeed.mul(quat);
}
private void bounce(){
if(getPlace().y>700){
Vector3d newSpeed= new Vector3d(speed.x, -Math.abs(speed.y), speed.z);
setSpeed(newSpeed);
}
}
private void applyUserForces() {
if (pressingUp) {
Quat4d q = new Quat4d();
q.set(new AxisAngle4d(1, 0, 0, -0.0002 * speed.length()));
rotationSpeed.mul(q);
}
if (pressingDown) {
Quat4d q = new Quat4d();
q.set(new AxisAngle4d(1, 0, 0, 0.0003 * speed.length()));
rotationSpeed.mul(q);
}
if (pressingRight) {
Quat4d q = new Quat4d();
q.set(new AxisAngle4d(0, 0, 1, 0.0007 * speed.length()));
rotationSpeed.mul(q);
}
if (pressingLeft) {
Quat4d q = new Quat4d();
q.set(new AxisAngle4d(0, 0, 1, -0.0007 * speed.length()));
rotationSpeed.mul(q);
}
if (pressingRudderRight) {
Quat4d q = new Quat4d();
q.set(new AxisAngle4d(0, 1, 0, 0.0003 * speed.length()));
rotationSpeed.mul(q);
}
if (pressingRudderLeft) {
Quat4d q = new Quat4d();
q.set(new AxisAngle4d(0, 1, 0, -0.0003 * speed.length()));
rotationSpeed.mul(q);
}
}
public void setPressingUp(boolean b) {
pressingUp = b;
}
public void setPressingDown(boolean b) {
pressingDown = b;
}
public void setPressingRight(boolean b) {
pressingRight = b;
}
public void setPressingLeft(boolean b) {
pressingLeft = b;
}
public void setPressingRudderRight(boolean b) {
this.pressingRudderRight = b;
}
public void setPressingRudderLeft(boolean b) {
this.pressingRudderLeft = b;
}
}