Skip to content

Commit cfcf9a3

Browse files
committed
order geometry transforms properly
This fixes shapes changing depending on their rotation; if we rotate before scaling, the shape is rotated along different axes!
1 parent 4e66e54 commit cfcf9a3

2 files changed

Lines changed: 52 additions & 23 deletions

File tree

src/main/java/edu/umich/soar/svsviewer/command/UpdateGeometryCommand.java

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@
1010
import java.util.List;
1111
import java.util.Map;
1212

13-
import javafx.application.Platform;
14-
import javafx.event.Event;
1513
import javafx.geometry.Point3D;
1614
import javafx.scene.Node;
1715
import javafx.scene.paint.Color;
1816
import javafx.scene.paint.PhongMaterial;
1917
import javafx.scene.shape.*;
2018
import javafx.scene.transform.Rotate;
19+
import javafx.scene.transform.Scale;
20+
import javafx.scene.transform.Translate;
2121

2222
public record UpdateGeometryCommand(
2323
NameMatcher sceneMatcher,
@@ -43,30 +43,21 @@ public void interpret(GeometryManager geoManager, SceneController sceneControlle
4343
// part of this list.
4444
for (Geometry geometry : geoManager.findGeometries(sceneMatcher, geometryMatcher)) {
4545
if (position != null) {
46-
geometry.modifyGroups(
47-
node -> {
48-
node.setTranslateX(position.get(0));
49-
node.setTranslateY(position.get(1));
50-
node.setTranslateZ(position.get(2));
51-
});
46+
geometry.setTranslation(new Translate(position.get(0), position.get(1), position.get(2)));
5247
rerenderedScenes.put(geometry.getParent().name(), geometry.getParent());
5348
}
54-
if (rotation != null) {
55-
rotateWithQuaternion(rotation, geometry);
49+
if (scale != null) {
50+
geometry.setScale(new Scale(scale.get(0), scale.get(1), scale.get(2)));
5651
rerenderedScenes.put(geometry.getParent().name(), geometry.getParent());
5752
}
58-
if (scale != null) {
59-
geometry.modifyGroups(
60-
node -> {
61-
node.setScaleX(scale.get(0));
62-
node.setScaleY(scale.get(1));
63-
node.setScaleZ(scale.get(2));
64-
});
53+
if (rotation != null) {
54+
Rotate r = quaternionToRotation(rotation);
55+
geometry.setRotation(r);
6556
rerenderedScenes.put(geometry.getParent().name(), geometry.getParent());
6657
}
6758

6859
if (vertices != null) {
69-
geometry.clearChildren();
60+
geometry.clear();
7061
TriangleMesh mesh = verticesToTriangleMesh(vertices);
7162
MeshView meshView = new MeshView(mesh);
7263
meshView.setCullFace(CullFace.NONE);
@@ -88,7 +79,7 @@ public void interpret(GeometryManager geoManager, SceneController sceneControlle
8879
rerenderedScenes.put(geometry.getParent().name(), geometry.getParent());
8980
}
9081
if (radius != null) {
91-
geometry.clearChildren();
82+
geometry.clear();
9283
Sphere s = new Sphere(radius);
9384
geometry.getGroup().getChildren().add(s);
9485

@@ -99,7 +90,7 @@ public void interpret(GeometryManager geoManager, SceneController sceneControlle
9990
rerenderedScenes.put(geometry.getParent().name(), geometry.getParent());
10091
}
10192
if (text != null) {
102-
geometry.clearChildren();
93+
geometry.clear();
10394
// svs_viewer calls draw_text(g->text, 0, 0), which would draw at the origin no matter where
10495
// the geometry is;
10596
// that seems wrong. I think maybe it was never implemented properly because it's not

src/main/java/edu/umich/soar/svsviewer/scene/Geometry.java

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,14 @@
44

55
import edu.umich.soar.svsviewer.util.DrawingMode;
66
import java.util.function.Consumer;
7+
8+
import javafx.collections.ObservableList;
79
import javafx.scene.Group;
810
import javafx.scene.Node;
11+
import javafx.scene.transform.Rotate;
12+
import javafx.scene.transform.Scale;
13+
import javafx.scene.transform.Transform;
14+
import javafx.scene.transform.Translate;
915

1016
public class Geometry {
1117
private final SVSScene parent;
@@ -20,18 +26,42 @@ public class Geometry {
2026

2127
private final Node label;
2228

29+
private final Scale scale;
30+
private final Rotate rotation;
31+
private final Translate translation;
32+
33+
// The ordering here is significant (transform matrices are not commutative)
34+
private static final int TRANSLATE_TRANSFORM_INDEX = 0;
35+
private static final int ROTATE_TRANSFORM_INDEX = 1;
36+
private static final int SCALE_TRANSFORM_INDEX = 2;
37+
2338
public Geometry(String name, SVSScene parent) {
2439
this.name = name;
2540
this.parent = parent;
2641
group = new Group();
2742
lineGroup = new Group();
2843
label = createLabel(name);
44+
45+
rotation = new Rotate();
46+
translation = new Translate();
47+
scale = new Scale();
48+
modifyGroups(
49+
g -> {
50+
ObservableList<Transform> transforms = g.getTransforms();
51+
transforms.add(TRANSLATE_TRANSFORM_INDEX, translation);
52+
transforms.add(ROTATE_TRANSFORM_INDEX, rotation);
53+
transforms.add(SCALE_TRANSFORM_INDEX, scale);
54+
});
2955
}
3056

3157
public Group getGroup() {
3258
return group;
3359
}
3460

61+
public Group getLineGroup() {
62+
return lineGroup;
63+
}
64+
3565
/**
3666
* If the client doesn't need the underlying main Group or line Group, it's recommended to operate
3767
* on them via this method to ensure that they stay in sync.
@@ -41,12 +71,20 @@ public void modifyGroups(Consumer<Group> modifier) {
4171
modifier.accept(getLineGroup());
4272
}
4373

44-
public void clearChildren() {
74+
public void clear() {
4575
modifyGroups(g -> g.getChildren().clear());
4676
}
4777

48-
public Group getLineGroup() {
49-
return lineGroup;
78+
public void setTranslation(Translate t) {
79+
modifyGroups(g -> g.getTransforms().set(TRANSLATE_TRANSFORM_INDEX, t));
80+
}
81+
82+
public void setRotation(Rotate r) {
83+
modifyGroups(g -> g.getTransforms().set(ROTATE_TRANSFORM_INDEX, r));
84+
}
85+
86+
public void setScale(Scale s) {
87+
modifyGroups(g -> g.getTransforms().set(SCALE_TRANSFORM_INDEX, s));
5088
}
5189

5290
public Node getLabel() {

0 commit comments

Comments
 (0)