Skip to content

Commit

Permalink
simplify. drop animus, add oriented txfm/group.
Browse files Browse the repository at this point in the history
  • Loading branch information
Hellblazer committed Sep 13, 2023
1 parent ba9f008 commit d503c3e
Show file tree
Hide file tree
Showing 10 changed files with 324 additions and 340 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,31 @@ Vector3f b() {
}
};

private static final Vector3f POS_X = new Vector3f(1, 0, 0);
private static final Vector3f POS_Y = new Vector3f(0, 1, 0);
private static final Vector3f POS_Z = new Vector3f(0, 0, 1);
private static final float HALF_PI = (float) (Math.PI / 2);
private static final Vector3f POS_X = new Vector3f(1, 0, 0);
private static final Vector3f POS_Y = new Vector3f(0, 1, 0);
private static final Vector3f POS_Z = new Vector3f(0, 0, 1);

public Rotor3f angle(float theta) {
return slerp(theta / 90);
}

/**
* Spherical Linear Interpolation from axis A to axis B.
* Spherical Linear Interpolation around the axis by the supplied radians
*
* @param t - the parameterization value
* @return the Rotor3f corresponding to point (t) in the interpolation from a()
* @param theta - the radians of rotation about the axis
* @return the Rotor3f corresponding to rotation in the interpolation from a()
* to b()
*/
public Rotor3f radians(float theta) {
return slerp(theta / HALF_PI);
}

/**
* Spherical Linear Interpolation around the axis by the supplied angle
*
* @param theta - the angle of rotation about the axis
* @return the Rotor3f corresponding to rotation in the interpolation from a()
* to b()
*/
public Rotor3f slerp(float t) {
Expand Down Expand Up @@ -356,6 +372,11 @@ public Matrix4f toMatrix() {
return result;
}

@Override
public String toString() {
return String.format("Rotor3f [a=%s, xy=%s, yz=%s, zx=%s]", a, xy, yz, zx);
}

/**
* Transform the vector using the receiver
*
Expand Down
120 changes: 0 additions & 120 deletions portal/src/main/java/com/hellblazer/luciferase/portal/Animus.java

This file was deleted.

120 changes: 67 additions & 53 deletions portal/src/main/java/com/hellblazer/luciferase/portal/MagicMirror.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,72 +20,104 @@
import static com.hellblazer.luciferase.lucien.animus.Rotor3f.PrincipalAxis.Y;
import static com.hellblazer.luciferase.lucien.animus.Rotor3f.PrincipalAxis.Z;

import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;

import com.hellblazer.luciferase.lucien.animus.Rotor3f;
import com.hellblazer.luciferase.portal.CubicGrid.Neighborhood;
import com.hellblazer.luciferase.portal.mesh.explorer.Xform;
import com.hellblazer.luciferase.portal.mesh.polyhedra.plato.Cube;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Point3D;
import javafx.scene.Camera;
import javafx.scene.DepthTest;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.paint.Color;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;

/**
* @author hal.hildebrand
*/
public abstract class MagicMirror extends Application {

public static class MouseHandler {
protected double mouseDeltaX;
protected double mouseDeltaY;
protected double mouseOldX;
protected double mouseOldY;
protected double mousePosX;
protected double mousePosY;
protected float rx;
protected float ry;
}

public static final float CUBE_EDGE_LENGTH = (float) (Math.sqrt(2) / 2);
public static final float TET_EDGE_LENGTH = 1;
protected static final double AXIS_LENGTH = 250.0;
protected static final double CONTROL_MULTIPLIER = 0.1;
protected static final double MOUSE_SPEED = 0.1;
protected static final double ROTATION_SPEED = 2.0;
protected static final double SHIFT_MULTIPLIER = 10.0;
protected static final double TRACK_SPEED = 0.3;
public static final float CUBE_EDGE_LENGTH = (float) (Math.sqrt(2) / 2);

public static final float TET_EDGE_LENGTH = 1;
protected static final float AXIS_LENGTH = 250.0f;
protected static final float CAMERA_FAR_CLIP = 10000.0f;
protected static final float CAMERA_INITIAL_DISTANCE = -450f;
protected static final float CAMERA_INITIAL_X_ANGLE = 70.0f;
protected static final float CAMERA_INITIAL_Y_ANGLE = 320.0f;
protected static final float CAMERA_NEAR_CLIP = 0.1f;
protected static final float CONTROL_MULTIPLIER = 0.1f;
protected static final float MOUSE_SPEED = 0.1f;
protected static final float ROTATION_SPEED = 2.0f;
protected static final float SHIFT_MULTIPLIER = 10.0f;
protected static final float TRACK_SPEED = 0.3f;

public static void lookAt(Point3D cameraPosition, Point3D lookAtPos, Camera cam) {
// Create direction vector
Point3D camDirection = lookAtPos.subtract(cameraPosition.getX(), cameraPosition.getY(), cameraPosition.getZ());
camDirection = camDirection.normalize();
double xRotation = Math.toDegrees(Math.asin(-camDirection.getY()));
double yRotation = Math.toDegrees(Math.atan2(camDirection.getX(), camDirection.getZ()));
Rotate rx = new Rotate(xRotation, cameraPosition.getX(), cameraPosition.getY(), cameraPosition.getZ(),
Rotate.X_AXIS);
Rotate ry = new Rotate(yRotation, cameraPosition.getX(), cameraPosition.getY(), cameraPosition.getZ(),
Rotate.Y_AXIS);
cam.getTransforms()
.addAll(ry, rx, new Translate(cameraPosition.getX(), cameraPosition.getY(), cameraPosition.getZ()));
}

public static void main(String[] args) {
launch(args);
}

protected final Group axisGroup = new Group();
protected Portal portal;
protected final Group root = new Group();
protected final Xform transformingGroup = new Xform();
protected final Xform world = new Xform();
protected final Group axisGroup = new Group();
protected final PerspectiveCamera camera;
protected final OrientedGroup cameraTransform;
protected final Group root = new Group();
protected final Xform transformingGroup = new Xform();
protected final Xform world = new Xform();

public MagicMirror() {
super();

var t = new OrientedTxfm();
t.next(new OrientedTxfm()).next(new OrientedTxfm()).setRotate(0, 0, 180.0f);
t.setRotate(CAMERA_INITIAL_X_ANGLE, CAMERA_INITIAL_Y_ANGLE, 0);

cameraTransform = new OrientedGroup(t);
camera = new PerspectiveCamera(true);
cameraTransform.getChildren().add(camera);
}

@Override
public void start(Stage primaryStage) throws Exception {
root.getChildren().add(world);
root.setDepthTest(DepthTest.ENABLE);
portal = portal();

world.getChildren().addAll(portal.getAvatar().getAnimated(), portal.getCamera().getAnimated());
root.getChildren().add(cameraTransform);

camera.setNearClip(CAMERA_NEAR_CLIP);
camera.setFarClip(CAMERA_FAR_CLIP);
camera.setTranslateZ(CAMERA_INITIAL_DISTANCE / 4);
buildAxes();

Scene scene = new Scene(root, 1024, 768, true, SceneAntialiasing.BALANCED);
Expand All @@ -97,8 +129,7 @@ public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(scene);
primaryStage.show();

portal.setCamera(scene);
resetCameraDefault();
scene.setCamera(camera);

// Attach a scroll listener
primaryStage.addEventHandler(ScrollEvent.SCROLL, event -> {
Expand All @@ -110,33 +141,27 @@ public void start(Stage primaryStage) throws Exception {
if (event.isShiftDown()) {
modifier = 100.0f;
}
var position = portal.getCamera().getPosition();

final var p = position.get();
p.z = (float) (p.z + event.getDeltaY() * modifierFactor * modifier);
position.set(p);
double z = camera.getTranslateZ();
double newZ = z + event.getDeltaY() * modifierFactor * modifier;
camera.setTranslateZ(newZ);
});
}

abstract protected Animus<Node> animus();

protected void buildAxes() {
final var cubic = new CubicGrid(Neighborhood.EIGHT, new Cube(CUBE_EDGE_LENGTH), 1);
cubic.addAxes(axisGroup, 0.1, 0.2, 0.008, 20);
axisGroup.setVisible(false);
world.getChildren().addAll(axisGroup);
}

abstract protected Animus<Camera> camera();

protected void handleKeyboard(Scene scene) {
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {

@Override
public void handle(KeyEvent event) {
switch (event.getCode()) {
case Z:
resetCameraDefault();
cameraTransform.getTransform().reset();
break;
case X:
axisGroup.setVisible(!axisGroup.isVisible());
Expand All @@ -153,8 +178,6 @@ public void handle(KeyEvent event) {

protected MouseHandler handleMouse(Scene scene) {
var h = new MouseHandler();
final var position = portal.getCamera().getPosition();
final var orientation = portal.getCamera().getOrientation();

scene.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
Expand Down Expand Up @@ -183,33 +206,24 @@ public void handle(MouseEvent me) {
if (me.isShiftDown()) {
modifier = SHIFT_MULTIPLIER;
}

var t = cameraTransform.getTransform();
if (me.isMiddleButtonDown() || (me.isPrimaryButtonDown() && me.isSecondaryButtonDown())) {
var p = new Vector3f(position.get());
p.add(new Point3f((float) (h.mouseDeltaX * MOUSE_SPEED * modifier * TRACK_SPEED),
(float) (h.mouseDeltaY * MOUSE_SPEED * modifier * TRACK_SPEED), 0f));
position.set(p);
t.t.setX((float) (t.t.getX() + h.mouseDeltaX * MOUSE_SPEED * modifier * TRACK_SPEED));
t.next.t.setY(t.next.t.getY() + h.mouseDeltaY * MOUSE_SPEED * modifier * TRACK_SPEED);
} else if (me.isPrimaryButtonDown()) {
var o = new Rotor3f(orientation.get());
o.combine(X.slerp((float) (-h.mouseDeltaX * MOUSE_SPEED * modifier * ROTATION_SPEED)))
.combine(Y.slerp((float) (h.mouseDeltaY * MOUSE_SPEED * modifier * ROTATION_SPEED)));
orientation.set(o);
h.ry = (float) (h.ry - h.mouseDeltaX * MOUSE_SPEED * modifier * ROTATION_SPEED);
h.rx = (float) (h.rx + h.mouseDeltaY * MOUSE_SPEED * modifier * ROTATION_SPEED);
t.setRotate(h.rx, h.ry, 0);
} else if (me.isSecondaryButtonDown()) {
var p = new Vector3f(position.get());
p.z = (float) (p.z + h.mouseDeltaX * MOUSE_SPEED * modifier);
position.set(p);
double z = camera.getTranslateZ();
double newZ = z + h.mouseDeltaX * MOUSE_SPEED * modifier;
camera.setTranslateZ(newZ);
}
}
});
return h;
}

protected Portal portal() {
return new Portal(animus(), camera());
}

abstract protected void resetCameraDefault();

protected Rotor3f rotation(KeyEvent event, float t) {
return switch (event.getCode()) {
case A -> X.slerp(t);
Expand Down
Loading

0 comments on commit d503c3e

Please sign in to comment.