From 7df0dc24dfc64cda43b18547d8d41e25fc404f53 Mon Sep 17 00:00:00 2001
From: Dan Royer
Date: Sun, 7 Jan 2024 08:48:00 -0800
Subject: [PATCH 1/6] more adjustable camera movement speed.
---
.../viewporttools/move/MoveCameraTool.java | 195 ------------------
.../render/viewporttools/move/ScaleTool.java | 111 ----------
2 files changed, 306 deletions(-)
delete mode 100644 src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/MoveCameraTool.java
delete mode 100644 src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/ScaleTool.java
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/MoveCameraTool.java b/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/MoveCameraTool.java
deleted file mode 100644
index 871323ff3..000000000
--- a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/MoveCameraTool.java
+++ /dev/null
@@ -1,195 +0,0 @@
-package com.marginallyclever.ro3.apps.render.viewporttools.move;
-
-import com.jogamp.opengl.GL3;
-import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.viewporttools.ViewportTool;
-import com.marginallyclever.ro3.node.Node;
-import com.marginallyclever.ro3.node.nodes.Camera;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
-import com.marginallyclever.ro3.apps.render.Viewport;
-
-import javax.swing.*;
-import javax.vecmath.Point3d;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseWheelEvent;
-import java.util.List;
-
-/**
- * Moves the active camera around the scene based on mouse and keyboard input.
- * Hold the middle mouse button to move the camera.
- * Hold the SHIFT key to move the camera in the XY plane (strafe aka truck/pedestal relative to camera).
- * Hold the CTRL key to move the camera in the Z direction (dolly).
- * @author Dan Royer
- * @since 2.5.0
- */
-@Deprecated
-public class MoveCameraTool implements ViewportTool {
- private Viewport viewport;
-
- /**
- * Must be greater than or equal to zero.
- */
- private final double snapDeadZone = 100;
-
- /**
- * Must be greater than or equal to zero.
- */
- private final double snapDegrees = 45;
-
- /**
- * Must be greater than one.
- */
- private final double wheelScale = 1.25;
-
- private boolean isMoving=false;
- private boolean isControlDown =false;
- private boolean isShiftDown =false;
- private double previousX, previousY;
-
-
- @Override
- public void activate(List list) {}
-
- @Override
- public void deactivate() {}
-
- @Override
- public void handleMouseEvent(MouseEvent event) {
- if (event.getID() == MouseEvent.MOUSE_PRESSED) {
- mousePressed(event);
- } else if(event.getID() == MouseEvent.MOUSE_RELEASED) {
- mouseReleased(event);
- } else if(event.getID() == MouseEvent.MOUSE_DRAGGED) {
- mouseDragged(event);
- } else if(event.getID() == MouseEvent.MOUSE_WHEEL) {
- mouseWheelMoved((MouseWheelEvent)event);
- }
- }
-
- private void updatePrevious(MouseEvent event) {
- previousX = event.getX();
- previousY = event.getY();
- }
-
- @Override
- public void mouseMoved(MouseEvent event) {}
-
- @Override
- public void mousePressed(MouseEvent event) {
- if (SwingUtilities.isMiddleMouseButton(event)) {
- isMoving = true;
- updatePrevious(event);
- }
- }
- @Override
- public void mouseDragged(MouseEvent event) {
- if(!SwingUtilities.isMiddleMouseButton(event)) return;
-
- Camera cameraComponent = Registry.getActiveCamera();
- if(cameraComponent==null) return;
- if(!isMoving) return;
-
- double dx = event.getX() - previousX;
- double dy = event.getY() - previousY;
- if(dx==0 && dy==0) return;
-
- updatePrevious(event);
-
- if(isShiftDown) {
- cameraComponent.pedestal(dy);
- cameraComponent.truck(dx);
- } else if(isControlDown) {
- cameraComponent.dolly(dy);
- } else {
- cameraComponent.orbit(dx,dy);
- }
- }
-
- @Override
- public void mouseReleased(MouseEvent event) {
- if(SwingUtilities.isMiddleMouseButton(event)) {
- isMoving=false;
- }
- }
-
- public void mouseWheelMoved(MouseWheelEvent e) {
- Camera camera = Registry.getActiveCamera();
- if(camera==null) return;
-
- if(e.getWheelRotation()>0) {
- camera.setOrbitRadius(camera.getOrbitRadius() / wheelScale);
- } else {
- camera.setOrbitRadius(camera.getOrbitRadius() * wheelScale);
- }
- }
-
- @Override
- public void update(double deltaTime) {}
-
- /**
- * Renders any tool-specific visuals to the 3D scene.
- *
- * @param gl
- */
- @Override
- public void render(GL3 gl, ShaderProgram shaderProgram) {}
-
- @Override
- public void handleKeyEvent(KeyEvent event) {
- if(event.getID() == KeyEvent.KEY_PRESSED) {
- // remember if SHIFT is down
- if (event.getKeyCode() == KeyEvent.VK_SHIFT) {
- isShiftDown = true;
- }
- // remember if CTRL is down
- if (event.getKeyCode() == KeyEvent.VK_CONTROL) {
- isControlDown = true;
- }
- } else if(event.getID() == KeyEvent.KEY_RELEASED) {
- // remember if SHIFT is down
- if (event.getKeyCode() == KeyEvent.VK_SHIFT) {
- isShiftDown = false;
- }
- // remember if CTRL is down
- if (event.getKeyCode() == KeyEvent.VK_CONTROL) {
- isControlDown = false;
- }
- }
- }
-
- @Override
- public void setViewport(Viewport viewport) {
- this.viewport = viewport;
- }
-
- @Override
- public boolean isInUse() {
- return isMoving;
- }
-
- @Override
- public void cancelUse() {
- isMoving=false;
- }
-
- @Override
- public Point3d getStartPoint() {
- return null;
- }
-
- /**
- * Sets the frame of reference for the tool.
- *
- * @param index 0 for world, 1 for local, 2 for camera.
- */
- @Override
- public void setFrameOfReference(int index) {
-
- }
- @Override
- public void init(GL3 gl3) {}
-
- @Override
- public void dispose(GL3 gl3) {}
-}
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/ScaleTool.java b/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/ScaleTool.java
deleted file mode 100644
index b661f6ed9..000000000
--- a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/ScaleTool.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package com.marginallyclever.ro3.apps.render.viewporttools.move;
-
-import com.jogamp.opengl.GL3;
-import com.marginallyclever.ro3.apps.render.viewporttools.ViewportTool;
-import com.marginallyclever.ro3.node.Node;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
-import com.marginallyclever.ro3.apps.render.Viewport;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.vecmath.Point3d;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseEvent;
-import java.util.List;
-
-/**
- * A tool to scale {@link com.marginallyclever.ro3.node.nodes.Pose} nodes in the Viewport.
- *
- * @author Dan Royer
- * @since 2.5.0
- */
-@Deprecated
-public class ScaleTool implements ViewportTool {
- private static final Logger logger = LoggerFactory.getLogger(ScaleTool.class);
-
- /**
- * This method is called when the tool is activated. It receives the SelectedItems object containing the selected
- * entities and their initial world poses.
- *
- * @param list The selected items to be manipulated by the tool.
- */
- @Override
- public void activate(List list) {}
-
- /**
- * This method is called when the tool is deactivated. It allows the tool to perform any necessary cleanup
- * actions before another tool takes over.
- */
- @Override
- public void deactivate() {}
-
- @Override
- public void handleMouseEvent(MouseEvent event) {}
-
- @Override
- public void handleKeyEvent(KeyEvent event) {}
-
- /**
- * Updates the tool's internal state, if necessary.
- *
- * @param deltaTime Time elapsed since the last update.
- */
- @Override
- public void update(double deltaTime) {}
-
- /**
- * Renders any tool-specific visuals to the 3D scene.
- *
- * @param gl
- */
- @Override
- public void render(GL3 gl, ShaderProgram shaderProgram) {}
-
- @Override
- public void setViewport(Viewport viewport) {}
-
- @Override
- public boolean isInUse() {
- return false;
- }
-
- @Override
- public void cancelUse() {}
-
- @Override
- public Point3d getStartPoint() {
- return null;
- }
-
- @Override
- public void mouseMoved(MouseEvent event) {}
-
- @Override
- public void mousePressed(MouseEvent event) {}
-
- @Override
- public void mouseDragged(MouseEvent event) {}
-
- @Override
- public void mouseReleased(MouseEvent event) {}
-
- /**
- * Sets the frame of reference for the tool.
- *
- * @param index 0 for world, 1 for local, 2 for camera.
- */
- @Override
- public void setFrameOfReference(int index) {}
-
- @Override
- public void init(GL3 gl3) {
- // TODO
- logger.error("Not finished.");
- }
-
- @Override
- public void dispose(GL3 gl3) {
- // TODO
- logger.error("Not finished.");
- }
-}
From 6657859e319439d5745e5d846d08e1b121907154 Mon Sep 17 00:00:00 2001
From: Dan Royer
Date: Sun, 7 Jan 2024 08:49:23 -0800
Subject: [PATCH 2/6] :truck: apps/render -> apss/viewport
---
.../convenience/helpers/MatrixHelper.java | 4 +--
.../marginallyclever/ro3/apps/RO3Frame.java | 4 +--
.../{render => viewport}/OpenGLPanel.java | 3 +-
.../apps/{render => viewport}/RenderPass.java | 4 +--
.../{render => viewport}/ShaderProgram.java | 4 +--
.../apps/{render => viewport}/Viewport.java | 29 +++++++++---------
.../renderpasses/AbstractRenderPass.java | 6 ++--
.../renderpasses/DrawBackground.java | 10 +++---
.../renderpasses/DrawBoundingBoxes.java | 11 +++----
.../renderpasses/DrawCameras.java | 10 +++---
.../renderpasses/DrawDHParameters.java | 10 +++---
.../renderpasses/DrawGroundPlane.java | 10 +++---
.../renderpasses/DrawHingeJoints.java | 11 +++----
.../renderpasses/DrawMeshes.java | 10 +++---
.../renderpasses/DrawPoses.java | 11 +++----
.../viewporttools/Compass3D.java | 8 ++---
.../viewporttools/SelectedItems.java | 4 +--
.../viewporttools/SelectionTool.java | 7 ++---
.../viewporttools/ViewportTool.java | 6 ++--
.../viewporttools/move/MoveUtils.java | 8 ++---
.../viewporttools/move/RotateToolMulti.java | 10 +++---
.../viewporttools/move/RotateToolOneAxis.java | 10 +++---
.../move/TranslateToolMulti.java | 10 +++---
.../move/TranslateToolOneAxis.java | 10 +++---
.../move/TranslateToolTwoAxis.java | 10 +++---
.../com/marginallyclever/ro3/mesh/Mesh.java | 4 +--
.../ro3/node/nodes/Camera.java | 7 ++---
.../ro3/texture/TextureWithMetadata.java | 6 ++--
.../components/LinearPatternComponent.java | 2 +-
.../renderpanel/MatrixMaterialRender.java | 2 +-
.../renderpanel/OpenGLRenderPanel.java | 16 +++++-----
.../systems/render/ShaderProgram.java | 2 +-
.../systems/render/mesh/Mesh.java | 4 +--
.../apps/{render => viewport}/default.frag | 0
.../apps/{render => viewport}/default.vert | 0
.../{render => viewport}/icons8-add-16.png | Bin
.../{render => viewport}/icons8-move-16.png | Bin
.../{render => viewport}/icons8-rotate-16.png | Bin
.../{render => viewport}/icons8-select-16.png | Bin
.../renderpasses/center-of-mass.png | Bin
.../renderpasses/mesh.frag | 0
.../renderpasses/mesh.vert | 0
.../renderpasses/shadow.frag | 0
.../renderpasses/shadow.vert | 0
.../unused/debugTexture_330.vert | 0
.../unused/default_330.frag | 0
.../unused/default_330.vert | 0
.../unused/givenColor_330.frag | 0
.../{render => viewport}/unused/jfa_330.frag | 0
.../{render => viewport}/unused/jfa_330.vert | 0
.../unused/notransform_330.vert | 0
.../unused/outline2_330.frag | 0
.../unused/outline2_330.vert | 0
.../unused/outline_330.frag | 0
.../unused/outline_330.vert | 0
.../{render => viewport}/unused/red_330.frag | 0
.../unused/testTextureDepth1_330.frag | 0
.../unused/testTextureDepth2_330.frag | 0
.../unused/testTextureUV_330.frag | 0
.../viewporttools/axisLetters.png | Bin
.../{render => viewport}/OpenGLPanelTest.java | 2 +-
.../{render => viewport}/ViewportTest.java | 2 +-
.../renderpanel/OpenGLTestStencil.java | 2 +-
63 files changed, 131 insertions(+), 138 deletions(-)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/OpenGLPanel.java (98%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/RenderPass.java (91%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/ShaderProgram.java (98%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/Viewport.java (95%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/renderpasses/AbstractRenderPass.java (89%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/renderpasses/DrawBackground.java (95%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/renderpasses/DrawBoundingBoxes.java (94%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/renderpasses/DrawCameras.java (95%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/renderpasses/DrawDHParameters.java (94%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/renderpasses/DrawGroundPlane.java (91%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/renderpasses/DrawHingeJoints.java (94%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/renderpasses/DrawMeshes.java (97%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/renderpasses/DrawPoses.java (92%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/viewporttools/Compass3D.java (97%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/viewporttools/SelectedItems.java (95%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/viewporttools/SelectionTool.java (97%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/viewporttools/ViewportTool.java (94%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/viewporttools/move/MoveUtils.java (93%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/viewporttools/move/RotateToolMulti.java (96%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/viewporttools/move/RotateToolOneAxis.java (98%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/viewporttools/move/TranslateToolMulti.java (96%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/viewporttools/move/TranslateToolOneAxis.java (96%)
rename src/main/java/com/marginallyclever/ro3/apps/{render => viewport}/viewporttools/move/TranslateToolTwoAxis.java (96%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/default.frag (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/default.vert (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/icons8-add-16.png (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/icons8-move-16.png (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/icons8-rotate-16.png (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/icons8-select-16.png (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/renderpasses/center-of-mass.png (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/renderpasses/mesh.frag (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/renderpasses/mesh.vert (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/renderpasses/shadow.frag (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/renderpasses/shadow.vert (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/unused/debugTexture_330.vert (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/unused/default_330.frag (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/unused/default_330.vert (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/unused/givenColor_330.frag (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/unused/jfa_330.frag (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/unused/jfa_330.vert (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/unused/notransform_330.vert (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/unused/outline2_330.frag (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/unused/outline2_330.vert (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/unused/outline_330.frag (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/unused/outline_330.vert (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/unused/red_330.frag (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/unused/testTextureDepth1_330.frag (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/unused/testTextureDepth2_330.frag (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/unused/testTextureUV_330.frag (100%)
rename src/main/resources/com/marginallyclever/ro3/apps/{render => viewport}/viewporttools/axisLetters.png (100%)
rename src/test/java/com/marginallyclever/ro3/apps/{render => viewport}/OpenGLPanelTest.java (91%)
rename src/test/java/com/marginallyclever/ro3/apps/{render => viewport}/ViewportTest.java (93%)
diff --git a/src/main/java/com/marginallyclever/convenience/helpers/MatrixHelper.java b/src/main/java/com/marginallyclever/convenience/helpers/MatrixHelper.java
index 6318f0ccd..98d3d4200 100644
--- a/src/main/java/com/marginallyclever/convenience/helpers/MatrixHelper.java
+++ b/src/main/java/com/marginallyclever/convenience/helpers/MatrixHelper.java
@@ -88,7 +88,7 @@ static public void createMesh(GL3 gl, Vector3d p, Vector3d u, Vector3d v, Vector
/**
* Draw the three vectors of a matrix at a point
- * @param gl render context
+ * @param gl viewport context
* @param p position at which to draw
* @param u in yellow (1,1,0)
* @param v in teal (0,1,1)
@@ -915,7 +915,7 @@ public static FloatBuffer matrixToFloatBuffer(Matrix4d m) {
/**
*
- * @param gl render context
+ * @param gl viewport context
* @param type either GL3.GL_MODELVIEW_MATRIX or GL3.GL_PROJECTION_MATRIX
* @return
*/
diff --git a/src/main/java/com/marginallyclever/ro3/apps/RO3Frame.java b/src/main/java/com/marginallyclever/ro3/apps/RO3Frame.java
index 637571b9b..8ac56cd21 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/RO3Frame.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/RO3Frame.java
@@ -20,8 +20,8 @@
import com.marginallyclever.ro3.apps.nodetreeview.NodeTreeView;
import com.marginallyclever.ro3.apps.shared.PersistentJFileChooser;
import com.marginallyclever.ro3.apps.webcampanel.WebCamPanel;
-import com.marginallyclever.ro3.apps.render.OpenGLPanel;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.OpenGLPanel;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/OpenGLPanel.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/OpenGLPanel.java
similarity index 98%
rename from src/main/java/com/marginallyclever/ro3/apps/render/OpenGLPanel.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/OpenGLPanel.java
index 9bbb3bda0..6327cb593 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/OpenGLPanel.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/OpenGLPanel.java
@@ -1,10 +1,9 @@
-package com.marginallyclever.ro3.apps.render;
+package com.marginallyclever.ro3.apps.viewport;
import com.jogamp.opengl.*;
import com.jogamp.opengl.awt.GLJPanel;
import com.jogamp.opengl.util.FPSAnimator;
import com.marginallyclever.ro3.apps.App;
-import com.marginallyclever.ro3.apps.DockingPanel;
import com.marginallyclever.ro3.Registry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/RenderPass.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/RenderPass.java
similarity index 91%
rename from src/main/java/com/marginallyclever/ro3/apps/render/RenderPass.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/RenderPass.java
index 0653c28e0..a5cf7d43e 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/RenderPass.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/RenderPass.java
@@ -1,4 +1,4 @@
-package com.marginallyclever.ro3.apps.render;
+package com.marginallyclever.ro3.apps.viewport;
import com.jogamp.opengl.GLEventListener;
import com.marginallyclever.ro3.Registry;
@@ -30,7 +30,7 @@ public interface RenderPass extends GLEventListener {
String getName();
/**
- * Draw this render pass.
+ * Draw this viewport pass.
* @param viewport the viewport to draw into
*/
void draw(Viewport viewport);
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/ShaderProgram.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/ShaderProgram.java
similarity index 98%
rename from src/main/java/com/marginallyclever/ro3/apps/render/ShaderProgram.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/ShaderProgram.java
index 79b0f3144..42d294d54 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/ShaderProgram.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/ShaderProgram.java
@@ -1,4 +1,4 @@
-package com.marginallyclever.ro3.apps.render;
+package com.marginallyclever.ro3.apps.viewport;
import com.jogamp.opengl.GL3;
import com.marginallyclever.convenience.helpers.MatrixHelper;
@@ -127,7 +127,7 @@ public void setVector3d(GL3 gl, String name, Vector3d value) {
/**
* Set a matrix in the shader. OpenGL uses column-major order, where Java and DirectX use row-major order.
* Don't forget to transpose!
- * @param gl the render context
+ * @param gl the viewport context
* @param name the name of the uniform variable
* @param value the matrix to set
*/
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/Viewport.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/Viewport.java
similarity index 95%
rename from src/main/java/com/marginallyclever/ro3/apps/render/Viewport.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/Viewport.java
index 143213aaa..e7c565267 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/Viewport.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/Viewport.java
@@ -1,4 +1,4 @@
-package com.marginallyclever.ro3.apps.render;
+package com.marginallyclever.ro3.apps.viewport;
import com.jogamp.opengl.GL3;
import com.jogamp.opengl.GLAutoDrawable;
@@ -8,12 +8,12 @@
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.convenience.helpers.ResourceHelper;
import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.renderpasses.*;
-import com.marginallyclever.ro3.apps.render.viewporttools.Compass3D;
-import com.marginallyclever.ro3.apps.render.viewporttools.SelectionTool;
-import com.marginallyclever.ro3.apps.render.viewporttools.ViewportTool;
-import com.marginallyclever.ro3.apps.render.viewporttools.move.RotateToolMulti;
-import com.marginallyclever.ro3.apps.render.viewporttools.move.TranslateToolMulti;
+import com.marginallyclever.ro3.apps.viewport.renderpasses.*;
+import com.marginallyclever.ro3.apps.viewport.viewporttools.Compass3D;
+import com.marginallyclever.ro3.apps.viewport.viewporttools.SelectionTool;
+import com.marginallyclever.ro3.apps.viewport.viewporttools.ViewportTool;
+import com.marginallyclever.ro3.apps.viewport.viewporttools.move.RotateToolMulti;
+import com.marginallyclever.ro3.apps.viewport.viewporttools.move.TranslateToolMulti;
import com.marginallyclever.ro3.listwithevents.ListWithEvents;
import com.marginallyclever.ro3.node.nodes.Camera;
import org.slf4j.Logger;
@@ -51,6 +51,7 @@ public class Viewport extends OpenGLPanel implements GLEventListener {
private final List viewportTools = new ArrayList<>();
private int activeToolIndex = -1;
private ShaderProgram toolShader;
+ private final double userMovementScale = 1.0;
public Viewport() {
@@ -138,7 +139,7 @@ private void addRenderPasses() {
}
/**
- * Load the render pass state from the {@link java.util.prefs.Preferences}.
+ * Load the viewport pass state from the {@link java.util.prefs.Preferences}.
*/
private void loadRenderPassState() {
Preferences pref = Preferences.userNodeForPackage(this.getClass());
@@ -151,7 +152,7 @@ private void loadRenderPassState() {
}
/**
- * Save the render pass state to the {@link java.util.prefs.Preferences}.
+ * Save the viewport pass state to the {@link java.util.prefs.Preferences}.
*/
public void saveRenderPassState() {
Preferences pref = Preferences.userNodeForPackage(this.getClass());
@@ -196,7 +197,7 @@ private void addRenderPassSelection() {
toolBar.add(button);
// Add an ActionListener to the JButton to show the JPopupMenu when clicked
button.addActionListener(e -> renderPassMenu.show(button, button.getWidth()/2, button.getHeight()/2));
- button.setToolTipText("Select the render passes to use.");
+ button.setToolTipText("Select the viewport passes to use.");
updateRenderPassMenu();
}
@@ -237,7 +238,7 @@ private void removeRenderPass(Object source,RenderPass renderPass) {
}
/**
- * Refreshes the entire contents of the render pass menu.
+ * Refreshes the entire contents of the viewport pass menu.
*/
private void updateRenderPassMenu() {
renderPassMenu.removeAll();
@@ -319,8 +320,8 @@ public void init(GLAutoDrawable glAutoDrawable) {
GL3 gl3 = glAutoDrawable.getGL().getGL3();
try {
toolShader = new ShaderProgram(gl3,
- ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/render/default.vert"),
- ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/render/default.frag"));
+ ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/viewport/default.vert"),
+ ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/viewport/default.frag"));
} catch(Exception e) {
logger.error("Failed to load shader", e);
}
@@ -432,7 +433,7 @@ public void mouseDragged(MouseEvent e) {
assert camera != null;
// scale based on orbit distance - smaller orbits need smaller movements
- double scale = camera.getOrbitRadius() / 50d;
+ double scale = camera.getOrbitRadius() * userMovementScale / 50d;
dx *= scale;
dy *= scale;
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/AbstractRenderPass.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/AbstractRenderPass.java
similarity index 89%
rename from src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/AbstractRenderPass.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/AbstractRenderPass.java
index 813bf7021..d6c8642b4 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/AbstractRenderPass.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/AbstractRenderPass.java
@@ -1,8 +1,8 @@
-package com.marginallyclever.ro3.apps.render.renderpasses;
+package com.marginallyclever.ro3.apps.viewport.renderpasses;
import com.jogamp.opengl.GLAutoDrawable;
-import com.marginallyclever.ro3.apps.render.RenderPass;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.RenderPass;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
/**
* {@link AbstractRenderPass} handles common methods for all {@link RenderPass}.
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawBackground.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawBackground.java
similarity index 95%
rename from src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawBackground.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawBackground.java
index b327ee398..193d06c18 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawBackground.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawBackground.java
@@ -1,4 +1,4 @@
-package com.marginallyclever.ro3.apps.render.renderpasses;
+package com.marginallyclever.ro3.apps.viewport.renderpasses;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL3;
@@ -8,10 +8,10 @@
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.convenience.helpers.ResourceHelper;
import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import com.marginallyclever.ro3.node.nodes.Camera;
import com.marginallyclever.ro3.texture.TextureWithMetadata;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
+import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
import com.marginallyclever.ro3.mesh.Mesh;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -95,8 +95,8 @@ public void init(GLAutoDrawable glAutoDrawable) {
GL3 gl3 = glAutoDrawable.getGL().getGL3();
try {
shader = new ShaderProgram(gl3,
- ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/render/default.vert"),
- ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/render/default.frag"));
+ ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/viewport/default.vert"),
+ ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/viewport/default.frag"));
} catch(Exception e) {
logger.error("Failed to load shader", e);
}
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawBoundingBoxes.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawBoundingBoxes.java
similarity index 94%
rename from src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawBoundingBoxes.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawBoundingBoxes.java
index 6eb7448d7..da4c2f10e 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawBoundingBoxes.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawBoundingBoxes.java
@@ -1,4 +1,4 @@
-package com.marginallyclever.ro3.apps.render.renderpasses;
+package com.marginallyclever.ro3.apps.viewport.renderpasses;
import com.jogamp.opengl.GL3;
import com.jogamp.opengl.GLAutoDrawable;
@@ -7,11 +7,11 @@
import com.marginallyclever.convenience.helpers.OpenGLHelper;
import com.marginallyclever.convenience.helpers.ResourceHelper;
import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import com.marginallyclever.ro3.node.Node;
import com.marginallyclever.ro3.node.nodes.Camera;
import com.marginallyclever.ro3.node.nodes.MeshInstance;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
+import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
import com.marginallyclever.ro3.mesh.Mesh;
import com.marginallyclever.ro3.mesh.AABB;
import org.slf4j.Logger;
@@ -22,7 +22,6 @@
import javax.vecmath.Vector3d;
import java.awt.*;
import java.util.ArrayList;
-import java.util.List;
/**
* Draw the bounding box of each {@link MeshInstance} in the scene.
@@ -67,8 +66,8 @@ public void init(GLAutoDrawable glAutoDrawable) {
GL3 gl3 = glAutoDrawable.getGL().getGL3();
try {
shader = new ShaderProgram(gl3,
- ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/render/default.vert"),
- ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/render/default.frag"));
+ ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/viewport/default.vert"),
+ ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/viewport/default.frag"));
} catch(Exception e) {
logger.error("Failed to load shader", e);
}
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawCameras.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawCameras.java
similarity index 95%
rename from src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawCameras.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawCameras.java
index 1b322d2d4..2108877f1 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawCameras.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawCameras.java
@@ -1,4 +1,4 @@
-package com.marginallyclever.ro3.apps.render.renderpasses;
+package com.marginallyclever.ro3.apps.viewport.renderpasses;
import com.jogamp.opengl.GL3;
import com.jogamp.opengl.GLAutoDrawable;
@@ -7,9 +7,9 @@
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.convenience.helpers.ResourceHelper;
import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import com.marginallyclever.ro3.node.nodes.Camera;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
+import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
import com.marginallyclever.ro3.mesh.Mesh;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -79,8 +79,8 @@ public void init(GLAutoDrawable glAutoDrawable) {
GL3 gl3 = glAutoDrawable.getGL().getGL3();
try {
shader = new ShaderProgram(gl3,
- ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/render/default.vert"),
- ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/render/default.frag"));
+ ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/viewport/default.vert"),
+ ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/viewport/default.frag"));
} catch(Exception e) {
logger.error("Failed to load shader", e);
}
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawDHParameters.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawDHParameters.java
similarity index 94%
rename from src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawDHParameters.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawDHParameters.java
index aae6b1bb3..677dbfb2b 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawDHParameters.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawDHParameters.java
@@ -1,4 +1,4 @@
-package com.marginallyclever.ro3.apps.render.renderpasses;
+package com.marginallyclever.ro3.apps.viewport.renderpasses;
import com.jogamp.opengl.GL3;
import com.jogamp.opengl.GLAutoDrawable;
@@ -7,12 +7,12 @@
import com.marginallyclever.convenience.helpers.OpenGLHelper;
import com.marginallyclever.convenience.helpers.ResourceHelper;
import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import com.marginallyclever.ro3.node.Node;
import com.marginallyclever.ro3.node.nodes.Camera;
import com.marginallyclever.ro3.node.nodes.DHParameter;
import com.marginallyclever.ro3.node.nodes.Pose;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
+import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
import com.marginallyclever.ro3.mesh.Mesh;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -50,8 +50,8 @@ public void init(GLAutoDrawable glAutoDrawable) {
GL3 gl3 = glAutoDrawable.getGL().getGL3();
try {
shader = new ShaderProgram(gl3,
- ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/render/default.vert"),
- ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/render/default.frag"));
+ ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/viewport/default.vert"),
+ ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/viewport/default.frag"));
} catch(IOException e) {
logger.error("Failed to create default shader.",e);
}
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawGroundPlane.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawGroundPlane.java
similarity index 91%
rename from src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawGroundPlane.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawGroundPlane.java
index 20c2de99b..4c014c496 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawGroundPlane.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawGroundPlane.java
@@ -1,4 +1,4 @@
-package com.marginallyclever.ro3.apps.render.renderpasses;
+package com.marginallyclever.ro3.apps.viewport.renderpasses;
import com.jogamp.opengl.GL3;
import com.jogamp.opengl.GLAutoDrawable;
@@ -6,9 +6,9 @@
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.convenience.helpers.ResourceHelper;
import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import com.marginallyclever.ro3.node.nodes.Camera;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
+import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
import com.marginallyclever.ro3.mesh.Mesh;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,8 +45,8 @@ public void init(GLAutoDrawable glAutoDrawable) {
GL3 gl3 = glAutoDrawable.getGL().getGL3();
try {
shader = new ShaderProgram(gl3,
- ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/render/default.vert"),
- ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/render/default.frag"));
+ ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/viewport/default.vert"),
+ ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/viewport/default.frag"));
} catch(Exception e) {
logger.error("Failed to load shader", e);
}
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawHingeJoints.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawHingeJoints.java
similarity index 94%
rename from src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawHingeJoints.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawHingeJoints.java
index 1cee372df..5eea8275d 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawHingeJoints.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawHingeJoints.java
@@ -1,4 +1,4 @@
-package com.marginallyclever.ro3.apps.render.renderpasses;
+package com.marginallyclever.ro3.apps.viewport.renderpasses;
import com.jogamp.opengl.GL3;
import com.jogamp.opengl.GLAutoDrawable;
@@ -6,13 +6,13 @@
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.convenience.helpers.ResourceHelper;
import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import com.marginallyclever.ro3.mesh.shapes.CircleXY;
import com.marginallyclever.ro3.node.Node;
import com.marginallyclever.ro3.node.nodes.Camera;
import com.marginallyclever.ro3.node.nodes.HingeJoint;
import com.marginallyclever.ro3.node.nodes.Pose;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
+import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
import com.marginallyclever.ro3.mesh.Mesh;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -21,7 +21,6 @@
import javax.vecmath.Vector3d;
import java.awt.*;
import java.util.ArrayList;
-import java.util.List;
/**
* Draw a ring around each hinge joint to show the range of motion.
@@ -47,8 +46,8 @@ public void init(GLAutoDrawable glAutoDrawable) {
GL3 gl3 = glAutoDrawable.getGL().getGL3();
try {
shader = new ShaderProgram(gl3,
- ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/render/default.vert"),
- ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/render/default.frag"));
+ ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/viewport/default.vert"),
+ ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/viewport/default.frag"));
} catch(Exception e) {
logger.error("Failed to load shader", e);
}
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawMeshes.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawMeshes.java
similarity index 97%
rename from src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawMeshes.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawMeshes.java
index 876523f33..39bc616d3 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawMeshes.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawMeshes.java
@@ -1,4 +1,4 @@
-package com.marginallyclever.ro3.apps.render.renderpasses;
+package com.marginallyclever.ro3.apps.viewport.renderpasses;
import com.jogamp.opengl.GL3;
import com.jogamp.opengl.GLAutoDrawable;
@@ -7,13 +7,13 @@
import com.marginallyclever.convenience.helpers.OpenGLHelper;
import com.marginallyclever.convenience.helpers.ResourceHelper;
import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import com.marginallyclever.ro3.node.Node;
import com.marginallyclever.ro3.node.nodes.Camera;
import com.marginallyclever.ro3.node.nodes.Material;
import com.marginallyclever.ro3.node.nodes.MeshInstance;
import com.marginallyclever.ro3.texture.TextureWithMetadata;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
+import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
import com.marginallyclever.ro3.mesh.Mesh;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -105,7 +105,7 @@ private void generateDepthMap(GL3 gl3, List meshes) {
// before, set up the shadow FBO
gl3.glViewport(0,0,SHADOW_WIDTH,SHADOW_HEIGHT);
gl3.glBindFramebuffer(GL3.GL_FRAMEBUFFER, shadowFBO[0]);
- // setup shader and render to depth map
+ // setup shader and viewport to depth map
gl3.glClear(GL3.GL_DEPTH_BUFFER_BIT);
gl3.glEnable(GL3.GL_DEPTH_TEST);
gl3.glCullFace(GL3.GL_FRONT);
@@ -119,7 +119,7 @@ private void generateDepthMap(GL3 gl3, List meshes) {
shadowShader.setMatrix4d(gl3,"modelMatrix",w);
meshInstance.getMesh().render(gl3);
}
- // render scene as normal with shadow mapping (using depth map)
+ // viewport scene as normal with shadow mapping (using depth map)
gl3.glCullFace(GL3.GL_BACK);
gl3.glBindFramebuffer(GL3.GL_FRAMEBUFFER,0);
gl3.glViewport(0,0,canvasWidth,canvasHeight);
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawPoses.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawPoses.java
similarity index 92%
rename from src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawPoses.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawPoses.java
index 8772c55d7..d75ff0a30 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/renderpasses/DrawPoses.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawPoses.java
@@ -1,4 +1,4 @@
-package com.marginallyclever.ro3.apps.render.renderpasses;
+package com.marginallyclever.ro3.apps.viewport.renderpasses;
import com.jogamp.opengl.GL3;
import com.jogamp.opengl.GLAutoDrawable;
@@ -6,11 +6,11 @@
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.convenience.helpers.ResourceHelper;
import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import com.marginallyclever.ro3.node.Node;
import com.marginallyclever.ro3.node.nodes.Camera;
import com.marginallyclever.ro3.node.nodes.Pose;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
+import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
import com.marginallyclever.ro3.mesh.Mesh;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -19,7 +19,6 @@
import javax.vecmath.Vector3d;
import java.awt.*;
import java.util.ArrayList;
-import java.util.List;
/**
* Draw each {@link Pose} as RGB lines from the origin to the X,Y,Z axes.
@@ -38,8 +37,8 @@ public void init(GLAutoDrawable glAutoDrawable) {
GL3 gl3 = glAutoDrawable.getGL().getGL3();
try {
shader = new ShaderProgram(gl3,
- ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/render/default.vert"),
- ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/render/default.frag"));
+ ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/viewport/default.vert"),
+ ResourceHelper.readResource(this.getClass(), "/com/marginallyclever/ro3/apps/viewport/default.frag"));
} catch(Exception e) {
logger.error("Failed to load shader", e);
}
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/Compass3D.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/Compass3D.java
similarity index 97%
rename from src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/Compass3D.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/Compass3D.java
index 3b6209a6c..9455dab25 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/Compass3D.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/Compass3D.java
@@ -1,12 +1,12 @@
-package com.marginallyclever.ro3.apps.render.viewporttools;
+package com.marginallyclever.ro3.apps.viewport.viewporttools;
import com.jogamp.opengl.GL3;
import com.marginallyclever.convenience.Ray;
import com.marginallyclever.convenience.helpers.IntersectionHelper;
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import com.marginallyclever.ro3.mesh.Mesh;
import com.marginallyclever.ro3.mesh.shapes.CircleXY;
import com.marginallyclever.ro3.node.Node;
@@ -50,7 +50,7 @@ public class Compass3D implements ViewportTool {
public Compass3D() {
super();
- texture = Registry.textureFactory.load("/com/marginallyclever/ro3/apps/render/viewporttools/axisLetters.png");
+ texture = Registry.textureFactory.load("/com/marginallyclever/ro3/apps/viewport/viewporttools/axisLetters.png");
createQuadMesh();
}
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/SelectedItems.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/SelectedItems.java
similarity index 95%
rename from src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/SelectedItems.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/SelectedItems.java
index ef3b55c41..83817c475 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/SelectedItems.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/SelectedItems.java
@@ -1,4 +1,4 @@
-package com.marginallyclever.ro3.apps.render.viewporttools;
+package com.marginallyclever.ro3.apps.viewport.viewporttools;
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.ro3.node.nodes.Pose;
@@ -11,7 +11,7 @@
import java.util.Map;
/**
- * A list of {@link Node}s selected in the {@link com.marginallyclever.ro3.apps.render.Viewport}.
+ * A list of {@link Node}s selected in the {@link com.marginallyclever.ro3.apps.viewport.Viewport}.
*
* @author Dan Royer
* @since 2.5.0
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/SelectionTool.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/SelectionTool.java
similarity index 97%
rename from src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/SelectionTool.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/SelectionTool.java
index dae335b31..a1b0321d9 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/SelectionTool.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/SelectionTool.java
@@ -1,4 +1,4 @@
-package com.marginallyclever.ro3.apps.render.viewporttools;
+package com.marginallyclever.ro3.apps.viewport.viewporttools;
import com.jogamp.opengl.GL3;
import com.marginallyclever.convenience.Ray;
@@ -9,13 +9,12 @@
import com.marginallyclever.ro3.node.nodes.Pose;
import com.marginallyclever.ro3.raypicking.RayHit;
import com.marginallyclever.ro3.raypicking.RayPickSystem;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.vecmath.*;
-import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/ViewportTool.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/ViewportTool.java
similarity index 94%
rename from src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/ViewportTool.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/ViewportTool.java
index 9e13cac52..7466152b0 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/ViewportTool.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/ViewportTool.java
@@ -1,9 +1,9 @@
-package com.marginallyclever.ro3.apps.render.viewporttools;
+package com.marginallyclever.ro3.apps.viewport.viewporttools;
import com.jogamp.opengl.GL3;
import com.marginallyclever.ro3.node.Node;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import javax.vecmath.Point3d;
import java.awt.event.KeyEvent;
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/MoveUtils.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/MoveUtils.java
similarity index 93%
rename from src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/MoveUtils.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/MoveUtils.java
index dcb2df914..231d1589e 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/MoveUtils.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/MoveUtils.java
@@ -1,16 +1,16 @@
-package com.marginallyclever.ro3.apps.render.viewporttools.move;
+package com.marginallyclever.ro3.apps.viewport.viewporttools.move;
import com.marginallyclever.convenience.Plane;
import com.marginallyclever.convenience.Ray;
import com.marginallyclever.convenience.helpers.IntersectionHelper;
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.viewporttools.SelectedItems;
-import com.marginallyclever.ro3.apps.render.viewporttools.ViewportTool;
+import com.marginallyclever.ro3.apps.viewport.viewporttools.SelectedItems;
+import com.marginallyclever.ro3.apps.viewport.viewporttools.ViewportTool;
import com.marginallyclever.ro3.node.Node;
import com.marginallyclever.ro3.node.nodes.Camera;
import com.marginallyclever.ro3.node.nodes.Pose;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import javax.vecmath.Matrix4d;
import javax.vecmath.Point3d;
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/RotateToolMulti.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/RotateToolMulti.java
similarity index 96%
rename from src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/RotateToolMulti.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/RotateToolMulti.java
index 4bb8cdd15..c10475005 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/RotateToolMulti.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/RotateToolMulti.java
@@ -1,15 +1,15 @@
-package com.marginallyclever.ro3.apps.render.viewporttools.move;
+package com.marginallyclever.ro3.apps.viewport.viewporttools.move;
import com.jogamp.opengl.GL3;
import com.marginallyclever.convenience.ColorRGB;
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.viewporttools.SelectedItems;
-import com.marginallyclever.ro3.apps.render.viewporttools.ViewportTool;
+import com.marginallyclever.ro3.apps.viewport.viewporttools.SelectedItems;
+import com.marginallyclever.ro3.apps.viewport.viewporttools.ViewportTool;
import com.marginallyclever.ro3.node.Node;
import com.marginallyclever.ro3.node.nodes.Camera;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import javax.vecmath.Matrix4d;
import javax.vecmath.Point3d;
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/RotateToolOneAxis.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/RotateToolOneAxis.java
similarity index 98%
rename from src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/RotateToolOneAxis.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/RotateToolOneAxis.java
index 6a60ddc9a..6554cdf4b 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/RotateToolOneAxis.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/RotateToolOneAxis.java
@@ -1,17 +1,17 @@
-package com.marginallyclever.ro3.apps.render.viewporttools.move;
+package com.marginallyclever.ro3.apps.viewport.viewporttools.move;
import com.jogamp.opengl.GL3;
import com.marginallyclever.convenience.ColorRGB;
import com.marginallyclever.convenience.PrimitiveSolids;
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.viewporttools.SelectedItems;
-import com.marginallyclever.ro3.apps.render.viewporttools.ViewportTool;
+import com.marginallyclever.ro3.apps.viewport.viewporttools.SelectedItems;
+import com.marginallyclever.ro3.apps.viewport.viewporttools.ViewportTool;
import com.marginallyclever.ro3.mesh.Mesh;
import com.marginallyclever.ro3.mesh.shapes.Box;
import com.marginallyclever.ro3.node.Node;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import com.marginallyclever.ro3.node.nodes.Camera;
import com.marginallyclever.ro3.node.nodes.Pose;
import org.slf4j.Logger;
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/TranslateToolMulti.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/TranslateToolMulti.java
similarity index 96%
rename from src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/TranslateToolMulti.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/TranslateToolMulti.java
index a03af04ae..34a85cd26 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/TranslateToolMulti.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/TranslateToolMulti.java
@@ -1,15 +1,15 @@
-package com.marginallyclever.ro3.apps.render.viewporttools.move;
+package com.marginallyclever.ro3.apps.viewport.viewporttools.move;
import com.jogamp.opengl.GL3;
import com.marginallyclever.convenience.ColorRGB;
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.viewporttools.SelectedItems;
-import com.marginallyclever.ro3.apps.render.viewporttools.ViewportTool;
+import com.marginallyclever.ro3.apps.viewport.viewporttools.SelectedItems;
+import com.marginallyclever.ro3.apps.viewport.viewporttools.ViewportTool;
import com.marginallyclever.ro3.node.Node;
import com.marginallyclever.ro3.node.nodes.Camera;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import javax.vecmath.Matrix4d;
import javax.vecmath.Point3d;
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/TranslateToolOneAxis.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/TranslateToolOneAxis.java
similarity index 96%
rename from src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/TranslateToolOneAxis.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/TranslateToolOneAxis.java
index 00e44e257..c793c8acd 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/TranslateToolOneAxis.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/TranslateToolOneAxis.java
@@ -1,18 +1,18 @@
-package com.marginallyclever.ro3.apps.render.viewporttools.move;
+package com.marginallyclever.ro3.apps.viewport.viewporttools.move;
import com.jogamp.opengl.GL3;
import com.marginallyclever.convenience.ColorRGB;
import com.marginallyclever.convenience.Plane;
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.viewporttools.SelectedItems;
-import com.marginallyclever.ro3.apps.render.viewporttools.ViewportTool;
+import com.marginallyclever.ro3.apps.viewport.viewporttools.SelectedItems;
+import com.marginallyclever.ro3.apps.viewport.viewporttools.ViewportTool;
import com.marginallyclever.ro3.node.nodes.Camera;
import com.marginallyclever.ro3.node.nodes.Pose;
import com.marginallyclever.ro3.mesh.shapes.Sphere;
import com.marginallyclever.ro3.node.Node;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import com.marginallyclever.ro3.mesh.Mesh;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/TranslateToolTwoAxis.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/TranslateToolTwoAxis.java
similarity index 96%
rename from src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/TranslateToolTwoAxis.java
rename to src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/TranslateToolTwoAxis.java
index 30730ec0f..2a554409c 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/render/viewporttools/move/TranslateToolTwoAxis.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/viewporttools/move/TranslateToolTwoAxis.java
@@ -1,17 +1,17 @@
-package com.marginallyclever.ro3.apps.render.viewporttools.move;
+package com.marginallyclever.ro3.apps.viewport.viewporttools.move;
import com.jogamp.opengl.GL3;
import com.marginallyclever.convenience.ColorRGB;
import com.marginallyclever.convenience.Plane;
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.viewporttools.SelectedItems;
-import com.marginallyclever.ro3.apps.render.viewporttools.ViewportTool;
+import com.marginallyclever.ro3.apps.viewport.viewporttools.SelectedItems;
+import com.marginallyclever.ro3.apps.viewport.viewporttools.ViewportTool;
import com.marginallyclever.ro3.node.nodes.Camera;
import com.marginallyclever.ro3.node.nodes.Pose;
import com.marginallyclever.ro3.node.Node;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
-import com.marginallyclever.ro3.apps.render.Viewport;
+import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
+import com.marginallyclever.ro3.apps.viewport.Viewport;
import com.marginallyclever.ro3.mesh.Mesh;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/com/marginallyclever/ro3/mesh/Mesh.java b/src/main/java/com/marginallyclever/ro3/mesh/Mesh.java
index 2a2616539..930c52de2 100644
--- a/src/main/java/com/marginallyclever/ro3/mesh/Mesh.java
+++ b/src/main/java/com/marginallyclever/ro3/mesh/Mesh.java
@@ -207,8 +207,8 @@ public void render(GL3 gl) {
/**
* Render a portion of the mesh.
* @param gl the OpenGL context
- * @param startIndex index of the first vertex to render
- * @param count number of vertices to render
+ * @param startIndex index of the first vertex to viewport
+ * @param count number of vertices to viewport
*/
public void render(GL3 gl,int startIndex,int count) {
if(!isLoaded) {
diff --git a/src/main/java/com/marginallyclever/ro3/node/nodes/Camera.java b/src/main/java/com/marginallyclever/ro3/node/nodes/Camera.java
index 5924f7472..e846a4258 100644
--- a/src/main/java/com/marginallyclever/ro3/node/nodes/Camera.java
+++ b/src/main/java/com/marginallyclever/ro3/node/nodes/Camera.java
@@ -3,22 +3,19 @@
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.convenience.swing.NumberFormatHelper;
import com.marginallyclever.ro3.Registry;
-import com.marginallyclever.ro3.apps.render.Viewport;
import javax.swing.*;
-import javax.swing.text.NumberFormatter;
import javax.vecmath.Matrix3d;
import javax.vecmath.Matrix4d;
import javax.vecmath.Vector3d;
import java.awt.*;
import java.security.InvalidParameterException;
-import java.text.NumberFormat;
import java.util.List;
/**
- * The Camera class is a subclass of the Pose class and is used by a Viewport to render the scene in a 3D graphics or game engine. This class provides several functionalities:
+ * The Camera class is a subclass of the Pose class and is used by a Viewport to viewport the scene in a 3D graphics or game engine. This class provides several functionalities:
*
- * - It can be set to render in orthographic projection.
+ * - It can be set to viewport in orthographic projection.
* - It has a vertical field of view, a near and far clipping plane for perspective rendering.
* - It can translate and rotate relative to its current orientation.
* - It can look at a specific point in the scene.
diff --git a/src/main/java/com/marginallyclever/ro3/texture/TextureWithMetadata.java b/src/main/java/com/marginallyclever/ro3/texture/TextureWithMetadata.java
index 8573a5b30..e11616c47 100644
--- a/src/main/java/com/marginallyclever/ro3/texture/TextureWithMetadata.java
+++ b/src/main/java/com/marginallyclever/ro3/texture/TextureWithMetadata.java
@@ -5,7 +5,7 @@
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.util.texture.Texture;
import com.jogamp.opengl.util.texture.awt.AWTTextureIO;
-import com.marginallyclever.ro3.apps.render.ShaderProgram;
+import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
import java.awt.image.BufferedImage;
@@ -38,7 +38,7 @@ public BufferedImage getImage() {
}
/**
- * Must only be called when there is a valid OpenGL render context, likely from within
+ * Must only be called when there is a valid OpenGL viewport context, likely from within
* a {@link com.jogamp.opengl.GLAutoDrawable}.
* @param shader the shader to use.
*/
@@ -66,7 +66,7 @@ public void use(ShaderProgram shader) {
}
/**
- * Must only be called when there is a valid OpenGL render context, likely from within
+ * Must only be called when there is a valid OpenGL viewport context, likely from within
* a {@link com.jogamp.opengl.GLAutoDrawable}.
*/
public void unload() {
diff --git a/src/main/java/com/marginallyclever/robotoverlord/components/LinearPatternComponent.java b/src/main/java/com/marginallyclever/robotoverlord/components/LinearPatternComponent.java
index 4601c16e4..558943b92 100644
--- a/src/main/java/com/marginallyclever/robotoverlord/components/LinearPatternComponent.java
+++ b/src/main/java/com/marginallyclever/robotoverlord/components/LinearPatternComponent.java
@@ -5,7 +5,7 @@
import com.marginallyclever.robotoverlord.parameters.IntParameter;
/**
- * A component that should render a child component in a linear pattern.
+ * A component that should viewport a child component in a linear pattern.
*
* @since 2.6.0
* @author Dan Royer
diff --git a/src/main/java/com/marginallyclever/robotoverlord/renderpanel/MatrixMaterialRender.java b/src/main/java/com/marginallyclever/robotoverlord/renderpanel/MatrixMaterialRender.java
index 486387e66..fb36248a4 100644
--- a/src/main/java/com/marginallyclever/robotoverlord/renderpanel/MatrixMaterialRender.java
+++ b/src/main/java/com/marginallyclever/robotoverlord/renderpanel/MatrixMaterialRender.java
@@ -6,7 +6,7 @@
import javax.vecmath.Matrix4d;
/**
- * A matrix, a material, and a render component.
+ * A matrix, a material, and a viewport component.
*/
public class MatrixMaterialRender {
public Matrix4d matrix = new Matrix4d();
diff --git a/src/main/java/com/marginallyclever/robotoverlord/renderpanel/OpenGLRenderPanel.java b/src/main/java/com/marginallyclever/robotoverlord/renderpanel/OpenGLRenderPanel.java
index 48e63bd96..091488fcd 100644
--- a/src/main/java/com/marginallyclever/robotoverlord/renderpanel/OpenGLRenderPanel.java
+++ b/src/main/java/com/marginallyclever/robotoverlord/renderpanel/OpenGLRenderPanel.java
@@ -306,7 +306,7 @@ public void display( GLAutoDrawable drawable ) {
try {
renderStep(getGL3(drawable));
} catch(Exception e) {
- logger.error("Exception during render",e);
+ logger.error("Exception during viewport",e);
}
}
@@ -383,14 +383,14 @@ public void keyReleased(KeyEvent e) {
private void createShaderPrograms(GL3 gl3) {
shaderDefault = new ShaderProgram(gl3,
- readResource("/com/marginallyclever/ro3/apps/render/unused/default_330.vert"),
- readResource("/com/marginallyclever/ro3/apps/render/unused/default_330.frag"));
+ readResource("/com/marginallyclever/ro3/apps/viewport/unused/default_330.vert"),
+ readResource("/com/marginallyclever/ro3/apps/viewport/unused/default_330.frag"));
shaderOutline = new ShaderProgram(gl3,
- readResource("/com/marginallyclever/ro3/apps/render/unused/outline_330.vert"),
- readResource("/com/marginallyclever/ro3/apps/render/unused/outline_330.frag"));
+ readResource("/com/marginallyclever/ro3/apps/viewport/unused/outline_330.vert"),
+ readResource("/com/marginallyclever/ro3/apps/viewport/unused/outline_330.frag"));
shaderHUD = new ShaderProgram(gl3,
- readResource("/com/marginallyclever/ro3/apps/render/unused/default_330.vert"),
- readResource("/com/marginallyclever/ro3/apps/render/unused/givenColor_330.frag"));
+ readResource("/com/marginallyclever/ro3/apps/viewport/unused/default_330.vert"),
+ readResource("/com/marginallyclever/ro3/apps/viewport/unused/givenColor_330.frag"));
}
private void destroyShaderPrograms(GL3 gl) {
@@ -668,7 +668,7 @@ private void renderAllEntities(GL3 gl3,ShaderProgram shaderProgram) {
/**
* Render all the lists in an {@link MatrixMaterialRenderSet} in the correct order.
* @param gl the OpenGL context
- * @param mmrSet the set to render
+ * @param mmrSet the set to viewport
* @param shaderProgram the shader to use
*/
private void renderMMRSet(GL3 gl, MatrixMaterialRenderSet mmrSet, ShaderProgram shaderProgram) {
diff --git a/src/main/java/com/marginallyclever/robotoverlord/systems/render/ShaderProgram.java b/src/main/java/com/marginallyclever/robotoverlord/systems/render/ShaderProgram.java
index c7871e344..99390c9e1 100644
--- a/src/main/java/com/marginallyclever/robotoverlord/systems/render/ShaderProgram.java
+++ b/src/main/java/com/marginallyclever/robotoverlord/systems/render/ShaderProgram.java
@@ -139,7 +139,7 @@ public void setVector3d(GL3 gl, String name, Vector3d value) {
/**
* Set a matrix in the shader. OpenGL uses column-major order, where Java and DirectX use row-major order.
* Don't forget to transpose!
- * @param gl the render context
+ * @param gl the viewport context
* @param name the name of the uniform variable
* @param value the matrix to set
*/
diff --git a/src/main/java/com/marginallyclever/robotoverlord/systems/render/mesh/Mesh.java b/src/main/java/com/marginallyclever/robotoverlord/systems/render/mesh/Mesh.java
index c50838023..5a6ae4c57 100644
--- a/src/main/java/com/marginallyclever/robotoverlord/systems/render/mesh/Mesh.java
+++ b/src/main/java/com/marginallyclever/robotoverlord/systems/render/mesh/Mesh.java
@@ -199,8 +199,8 @@ public void render(GL3 gl) {
/**
* Render a portion of the mesh.
* @param gl the OpenGL context
- * @param count number of vertices to render
- * @param startIndex index of the first vertex to render
+ * @param count number of vertices to viewport
+ * @param startIndex index of the first vertex to viewport
*/
public void render(GL3 gl,int count,int startIndex) {
if(!isLoaded) {
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/default.frag b/src/main/resources/com/marginallyclever/ro3/apps/viewport/default.frag
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/default.frag
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/default.frag
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/default.vert b/src/main/resources/com/marginallyclever/ro3/apps/viewport/default.vert
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/default.vert
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/default.vert
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/icons8-add-16.png b/src/main/resources/com/marginallyclever/ro3/apps/viewport/icons8-add-16.png
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/icons8-add-16.png
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/icons8-add-16.png
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/icons8-move-16.png b/src/main/resources/com/marginallyclever/ro3/apps/viewport/icons8-move-16.png
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/icons8-move-16.png
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/icons8-move-16.png
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/icons8-rotate-16.png b/src/main/resources/com/marginallyclever/ro3/apps/viewport/icons8-rotate-16.png
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/icons8-rotate-16.png
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/icons8-rotate-16.png
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/icons8-select-16.png b/src/main/resources/com/marginallyclever/ro3/apps/viewport/icons8-select-16.png
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/icons8-select-16.png
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/icons8-select-16.png
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/renderpasses/center-of-mass.png b/src/main/resources/com/marginallyclever/ro3/apps/viewport/renderpasses/center-of-mass.png
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/renderpasses/center-of-mass.png
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/renderpasses/center-of-mass.png
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/renderpasses/mesh.frag b/src/main/resources/com/marginallyclever/ro3/apps/viewport/renderpasses/mesh.frag
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/renderpasses/mesh.frag
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/renderpasses/mesh.frag
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/renderpasses/mesh.vert b/src/main/resources/com/marginallyclever/ro3/apps/viewport/renderpasses/mesh.vert
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/renderpasses/mesh.vert
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/renderpasses/mesh.vert
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/renderpasses/shadow.frag b/src/main/resources/com/marginallyclever/ro3/apps/viewport/renderpasses/shadow.frag
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/renderpasses/shadow.frag
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/renderpasses/shadow.frag
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/renderpasses/shadow.vert b/src/main/resources/com/marginallyclever/ro3/apps/viewport/renderpasses/shadow.vert
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/renderpasses/shadow.vert
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/renderpasses/shadow.vert
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/unused/debugTexture_330.vert b/src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/debugTexture_330.vert
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/unused/debugTexture_330.vert
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/debugTexture_330.vert
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/unused/default_330.frag b/src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/default_330.frag
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/unused/default_330.frag
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/default_330.frag
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/unused/default_330.vert b/src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/default_330.vert
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/unused/default_330.vert
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/default_330.vert
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/unused/givenColor_330.frag b/src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/givenColor_330.frag
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/unused/givenColor_330.frag
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/givenColor_330.frag
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/unused/jfa_330.frag b/src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/jfa_330.frag
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/unused/jfa_330.frag
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/jfa_330.frag
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/unused/jfa_330.vert b/src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/jfa_330.vert
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/unused/jfa_330.vert
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/jfa_330.vert
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/unused/notransform_330.vert b/src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/notransform_330.vert
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/unused/notransform_330.vert
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/notransform_330.vert
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/unused/outline2_330.frag b/src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/outline2_330.frag
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/unused/outline2_330.frag
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/outline2_330.frag
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/unused/outline2_330.vert b/src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/outline2_330.vert
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/unused/outline2_330.vert
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/outline2_330.vert
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/unused/outline_330.frag b/src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/outline_330.frag
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/unused/outline_330.frag
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/outline_330.frag
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/unused/outline_330.vert b/src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/outline_330.vert
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/unused/outline_330.vert
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/outline_330.vert
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/unused/red_330.frag b/src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/red_330.frag
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/unused/red_330.frag
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/red_330.frag
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/unused/testTextureDepth1_330.frag b/src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/testTextureDepth1_330.frag
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/unused/testTextureDepth1_330.frag
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/testTextureDepth1_330.frag
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/unused/testTextureDepth2_330.frag b/src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/testTextureDepth2_330.frag
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/unused/testTextureDepth2_330.frag
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/testTextureDepth2_330.frag
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/unused/testTextureUV_330.frag b/src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/testTextureUV_330.frag
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/unused/testTextureUV_330.frag
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/unused/testTextureUV_330.frag
diff --git a/src/main/resources/com/marginallyclever/ro3/apps/render/viewporttools/axisLetters.png b/src/main/resources/com/marginallyclever/ro3/apps/viewport/viewporttools/axisLetters.png
similarity index 100%
rename from src/main/resources/com/marginallyclever/ro3/apps/render/viewporttools/axisLetters.png
rename to src/main/resources/com/marginallyclever/ro3/apps/viewport/viewporttools/axisLetters.png
diff --git a/src/test/java/com/marginallyclever/ro3/apps/render/OpenGLPanelTest.java b/src/test/java/com/marginallyclever/ro3/apps/viewport/OpenGLPanelTest.java
similarity index 91%
rename from src/test/java/com/marginallyclever/ro3/apps/render/OpenGLPanelTest.java
rename to src/test/java/com/marginallyclever/ro3/apps/viewport/OpenGLPanelTest.java
index 99e8e6c09..2b2284c47 100644
--- a/src/test/java/com/marginallyclever/ro3/apps/render/OpenGLPanelTest.java
+++ b/src/test/java/com/marginallyclever/ro3/apps/viewport/OpenGLPanelTest.java
@@ -1,4 +1,4 @@
-package com.marginallyclever.ro3.apps.render;
+package com.marginallyclever.ro3.apps.viewport;
import com.marginallyclever.ro3.Registry;
diff --git a/src/test/java/com/marginallyclever/ro3/apps/render/ViewportTest.java b/src/test/java/com/marginallyclever/ro3/apps/viewport/ViewportTest.java
similarity index 93%
rename from src/test/java/com/marginallyclever/ro3/apps/render/ViewportTest.java
rename to src/test/java/com/marginallyclever/ro3/apps/viewport/ViewportTest.java
index 2b21f16cc..720f8ead2 100644
--- a/src/test/java/com/marginallyclever/ro3/apps/render/ViewportTest.java
+++ b/src/test/java/com/marginallyclever/ro3/apps/viewport/ViewportTest.java
@@ -1,4 +1,4 @@
-package com.marginallyclever.ro3.apps.render;
+package com.marginallyclever.ro3.apps.viewport;
import com.marginallyclever.ro3.Registry;
diff --git a/src/test/java/com/marginallyclever/robotoverlord/renderpanel/OpenGLTestStencil.java b/src/test/java/com/marginallyclever/robotoverlord/renderpanel/OpenGLTestStencil.java
index bfa0683c2..0da0226d5 100644
--- a/src/test/java/com/marginallyclever/robotoverlord/renderpanel/OpenGLTestStencil.java
+++ b/src/test/java/com/marginallyclever/robotoverlord/renderpanel/OpenGLTestStencil.java
@@ -155,7 +155,7 @@ private void checkFrameBufferStatus(GL3 gl3,String name) {
/**
* Render the given texture to the screen, for debugging purposes.
* @param gl3 The OpenGL state
- * @param textureID The texture to render
+ * @param textureID The texture to viewport
*/
private void debugTexture(GL3 gl3,int textureID, ShaderProgram program) {
// Use the debug texture shader
From de44f4bf752170a6aa856d658f6bae1fb5786130 Mon Sep 17 00:00:00 2001
From: Dan Royer
Date: Sun, 7 Jan 2024 11:44:16 -0800
Subject: [PATCH 3/6] Move MeshInstance and LookAt into node/nodes/Pose
---
.../com/marginallyclever/ro3/apps/RO3FrameDropTarget.java | 2 +-
.../ro3/apps/viewport/renderpasses/DrawBoundingBoxes.java | 2 +-
.../ro3/apps/viewport/renderpasses/DrawMeshes.java | 2 +-
.../java/com/marginallyclever/ro3/node/nodes/DHParameter.java | 3 +--
.../marginallyclever/ro3/node/nodes/{ => pose}/LookAt.java | 4 ++--
.../ro3/node/nodes/{ => pose}/MeshInstance.java | 3 ++-
src/main/java/com/marginallyclever/ro3/raypicking/RayHit.java | 2 +-
.../com/marginallyclever/ro3/raypicking/RayPickSystem.java | 3 +--
8 files changed, 10 insertions(+), 11 deletions(-)
rename src/main/java/com/marginallyclever/ro3/node/nodes/{ => pose}/LookAt.java (96%)
rename src/main/java/com/marginallyclever/ro3/node/nodes/{ => pose}/MeshInstance.java (98%)
diff --git a/src/main/java/com/marginallyclever/ro3/apps/RO3FrameDropTarget.java b/src/main/java/com/marginallyclever/ro3/apps/RO3FrameDropTarget.java
index d965aebe6..6815a66c0 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/RO3FrameDropTarget.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/RO3FrameDropTarget.java
@@ -2,7 +2,7 @@
import com.marginallyclever.ro3.Registry;
import com.marginallyclever.ro3.apps.commands.ImportScene;
-import com.marginallyclever.ro3.node.nodes.MeshInstance;
+import com.marginallyclever.ro3.node.nodes.pose.MeshInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawBoundingBoxes.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawBoundingBoxes.java
index da4c2f10e..4ba6a7d8f 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawBoundingBoxes.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawBoundingBoxes.java
@@ -10,7 +10,7 @@
import com.marginallyclever.ro3.apps.viewport.Viewport;
import com.marginallyclever.ro3.node.Node;
import com.marginallyclever.ro3.node.nodes.Camera;
-import com.marginallyclever.ro3.node.nodes.MeshInstance;
+import com.marginallyclever.ro3.node.nodes.pose.MeshInstance;
import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
import com.marginallyclever.ro3.mesh.Mesh;
import com.marginallyclever.ro3.mesh.AABB;
diff --git a/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawMeshes.java b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawMeshes.java
index 39bc616d3..c693ecac3 100644
--- a/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawMeshes.java
+++ b/src/main/java/com/marginallyclever/ro3/apps/viewport/renderpasses/DrawMeshes.java
@@ -11,7 +11,7 @@
import com.marginallyclever.ro3.node.Node;
import com.marginallyclever.ro3.node.nodes.Camera;
import com.marginallyclever.ro3.node.nodes.Material;
-import com.marginallyclever.ro3.node.nodes.MeshInstance;
+import com.marginallyclever.ro3.node.nodes.pose.MeshInstance;
import com.marginallyclever.ro3.texture.TextureWithMetadata;
import com.marginallyclever.ro3.apps.viewport.ShaderProgram;
import com.marginallyclever.ro3.mesh.Mesh;
diff --git a/src/main/java/com/marginallyclever/ro3/node/nodes/DHParameter.java b/src/main/java/com/marginallyclever/ro3/node/nodes/DHParameter.java
index fff77c120..6270df146 100644
--- a/src/main/java/com/marginallyclever/ro3/node/nodes/DHParameter.java
+++ b/src/main/java/com/marginallyclever/ro3/node/nodes/DHParameter.java
@@ -2,15 +2,14 @@
import com.marginallyclever.convenience.swing.NumberFormatHelper;
import com.marginallyclever.ro3.node.Node;
+import com.marginallyclever.ro3.node.nodes.pose.MeshInstance;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
-import javax.swing.text.NumberFormatter;
import javax.vecmath.Matrix4d;
import java.awt.*;
-import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
diff --git a/src/main/java/com/marginallyclever/ro3/node/nodes/LookAt.java b/src/main/java/com/marginallyclever/ro3/node/nodes/pose/LookAt.java
similarity index 96%
rename from src/main/java/com/marginallyclever/ro3/node/nodes/LookAt.java
rename to src/main/java/com/marginallyclever/ro3/node/nodes/pose/LookAt.java
index d1d0b0d99..0e5c518fd 100644
--- a/src/main/java/com/marginallyclever/ro3/node/nodes/LookAt.java
+++ b/src/main/java/com/marginallyclever/ro3/node/nodes/pose/LookAt.java
@@ -1,10 +1,10 @@
-package com.marginallyclever.ro3.node.nodes;
+package com.marginallyclever.ro3.node.nodes.pose;
import com.marginallyclever.convenience.PathCalculator;
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.ro3.apps.nodeselector.NodeSelector;
-import com.marginallyclever.ro3.node.Node;
import com.marginallyclever.ro3.node.NodePath;
+import com.marginallyclever.ro3.node.nodes.Pose;
import org.json.JSONObject;
import javax.swing.*;
diff --git a/src/main/java/com/marginallyclever/ro3/node/nodes/MeshInstance.java b/src/main/java/com/marginallyclever/ro3/node/nodes/pose/MeshInstance.java
similarity index 98%
rename from src/main/java/com/marginallyclever/ro3/node/nodes/MeshInstance.java
rename to src/main/java/com/marginallyclever/ro3/node/nodes/pose/MeshInstance.java
index 4e3d31ec5..94d23c8c0 100644
--- a/src/main/java/com/marginallyclever/ro3/node/nodes/MeshInstance.java
+++ b/src/main/java/com/marginallyclever/ro3/node/nodes/pose/MeshInstance.java
@@ -1,4 +1,4 @@
-package com.marginallyclever.ro3.node.nodes;
+package com.marginallyclever.ro3.node.nodes.pose;
import com.marginallyclever.convenience.Ray;
import com.marginallyclever.convenience.helpers.MatrixHelper;
@@ -6,6 +6,7 @@
import com.marginallyclever.ro3.apps.dialogs.MeshChooserDialog;
import com.marginallyclever.ro3.mesh.Mesh;
import com.marginallyclever.ro3.mesh.MeshSmoother;
+import com.marginallyclever.ro3.node.nodes.Pose;
import com.marginallyclever.ro3.raypicking.RayHit;
import org.json.JSONObject;
diff --git a/src/main/java/com/marginallyclever/ro3/raypicking/RayHit.java b/src/main/java/com/marginallyclever/ro3/raypicking/RayHit.java
index b200caf2d..f66b61cda 100644
--- a/src/main/java/com/marginallyclever/ro3/raypicking/RayHit.java
+++ b/src/main/java/com/marginallyclever/ro3/raypicking/RayHit.java
@@ -1,6 +1,6 @@
package com.marginallyclever.ro3.raypicking;
-import com.marginallyclever.ro3.node.nodes.MeshInstance;
+import com.marginallyclever.ro3.node.nodes.pose.MeshInstance;
import javax.vecmath.Vector3d;
diff --git a/src/main/java/com/marginallyclever/ro3/raypicking/RayPickSystem.java b/src/main/java/com/marginallyclever/ro3/raypicking/RayPickSystem.java
index 82c2378ba..ba5382064 100644
--- a/src/main/java/com/marginallyclever/ro3/raypicking/RayPickSystem.java
+++ b/src/main/java/com/marginallyclever/ro3/raypicking/RayPickSystem.java
@@ -3,11 +3,10 @@
import com.marginallyclever.convenience.Ray;
import com.marginallyclever.ro3.Registry;
import com.marginallyclever.ro3.node.Node;
-import com.marginallyclever.ro3.node.nodes.MeshInstance;
+import com.marginallyclever.ro3.node.nodes.pose.MeshInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.vecmath.Matrix4d;
import java.util.*;
/**
From b1c585aafb558a34a4cab2fd09bd5804640000a1 Mon Sep 17 00:00:00 2001
From: Dan Royer
Date: Sun, 7 Jan 2024 11:44:45 -0800
Subject: [PATCH 4/6] create Limb and LimbSolver
---
.../com/marginallyclever/ro3/Registry.java | 6 +-
.../com/marginallyclever/ro3/node/Node.java | 7 +
.../ro3/node/nodes/LimbSolver.java | 273 +++++++++++++
.../ro3/node/nodes/Motor.java | 2 +-
.../ApproximateJacobianFiniteDifferences.java | 3 +-
.../ApproximateJacobianScrewTheory.java | 3 +-
.../nodes/marlinrobotarm/MarlinRobotArm.java | 384 +++---------------
.../ro3/node/nodes/pose/Limb.java | 249 ++++++++++++
.../ApproximateJacobianTest.java | 7 +-
9 files changed, 590 insertions(+), 344 deletions(-)
create mode 100644 src/main/java/com/marginallyclever/ro3/node/nodes/LimbSolver.java
create mode 100644 src/main/java/com/marginallyclever/ro3/node/nodes/pose/Limb.java
diff --git a/src/main/java/com/marginallyclever/ro3/Registry.java b/src/main/java/com/marginallyclever/ro3/Registry.java
index 8e04deb14..46d082cfc 100644
--- a/src/main/java/com/marginallyclever/ro3/Registry.java
+++ b/src/main/java/com/marginallyclever/ro3/Registry.java
@@ -5,6 +5,9 @@
import com.marginallyclever.ro3.node.nodes.*;
import com.marginallyclever.ro3.node.Node;
import com.marginallyclever.ro3.node.nodes.marlinrobotarm.MarlinRobotArm;
+import com.marginallyclever.ro3.node.nodes.pose.Limb;
+import com.marginallyclever.ro3.node.nodes.pose.LookAt;
+import com.marginallyclever.ro3.node.nodes.pose.MeshInstance;
import com.marginallyclever.ro3.texture.TextureFactory;
import javax.swing.event.EventListenerList;
@@ -34,6 +37,7 @@ public static void start() {
Factory.Category nodule = nodeFactory.getRoot().add("Node", Node::new);
nodule.add("DHParameter", DHParameter::new);
nodule.add("HingeJoint", HingeJoint::new);
+ nodule.add("LimbSolver", LimbSolver::new);
nodule.add("MarlinRobotArm", MarlinRobotArm::new);
nodule.add("Material", Material::new);
nodule.add("MeshInstance", MeshInstance::new);
@@ -41,7 +45,7 @@ public static void start() {
Factory.Category pose = nodule.add("Pose", Pose::new);
pose.add("Camera", Camera::new);
pose.add("LookAt", LookAt::new);
-
+ pose.add("Limb", Limb::new);
reset();
}
diff --git a/src/main/java/com/marginallyclever/ro3/node/Node.java b/src/main/java/com/marginallyclever/ro3/node/Node.java
index caf727a1d..e672af3cd 100644
--- a/src/main/java/com/marginallyclever/ro3/node/Node.java
+++ b/src/main/java/com/marginallyclever/ro3/node/Node.java
@@ -2,6 +2,7 @@
import com.marginallyclever.convenience.PathCalculator;
import com.marginallyclever.ro3.Registry;
+import com.marginallyclever.ro3.apps.nodeselector.NodeSelector;
import com.marginallyclever.ro3.node.nodes.Pose;
import org.json.JSONArray;
import org.json.JSONObject;
@@ -391,6 +392,12 @@ protected void addLabelAndComponent(JPanel pane, String labelText, JComponent co
pane.add(component);
}
+ protected void addNodeSelector(JPanel pane, String label, NodePath nodePath, Class clazz, GridBagConstraints gbc) {
+ NodeSelector selector = new NodeSelector<>(clazz, nodePath.getSubject());
+ selector.addPropertyChangeListener("subject", (e) -> nodePath.setRelativePath(this, (T) e.getNewValue()));
+ addLabelAndComponent(pane, label, selector, gbc);
+ }
+
/**
* Find the first child of the given type. The type must be an exact match - it will not match subclasses.
* @param type the type of node to find
diff --git a/src/main/java/com/marginallyclever/ro3/node/nodes/LimbSolver.java b/src/main/java/com/marginallyclever/ro3/node/nodes/LimbSolver.java
new file mode 100644
index 000000000..a52e38d4a
--- /dev/null
+++ b/src/main/java/com/marginallyclever/ro3/node/nodes/LimbSolver.java
@@ -0,0 +1,273 @@
+package com.marginallyclever.ro3.node.nodes;
+
+import com.marginallyclever.convenience.helpers.MatrixHelper;
+import com.marginallyclever.ro3.node.Node;
+import com.marginallyclever.ro3.node.NodePath;
+import com.marginallyclever.ro3.node.nodes.marlinrobotarm.ApproximateJacobian;
+import com.marginallyclever.ro3.node.nodes.marlinrobotarm.ApproximateJacobianFiniteDifferences;
+import com.marginallyclever.ro3.node.nodes.pose.Limb;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * {@link LimbSolver} calculates Inverse Kinematics for
+ * a {@link Limb}. Given a target and a linear velocity, {@link LimbSolver} will calculate and apply the
+ * joint velocities required to move the end effector towards the target in a straight line.
+ */
+public class LimbSolver extends Node {
+ private final NodePath limb = new NodePath<>(null,Limb.class);
+ private final NodePath target = new NodePath<>(this,Pose.class);
+ private double linearVelocity = 0;
+
+ public LimbSolver() {
+ this("LimbSolver");
+ }
+
+ public LimbSolver(String name) {
+ super(name);
+ }
+
+ public Pose getTarget() {
+ return target.getSubject();
+ }
+
+ public void setTarget(Pose target) {
+ this.target.setRelativePath(this,target);
+ }
+
+ public void update(double dt) {
+ if(dt==0) return;
+ moveTowardsTarget();
+ }
+
+ public Limb getLimb() {
+ return limb.getSubject();
+ }
+
+ public void setLimb(Limb limb) {
+ this.limb.setRelativePath(this,limb);
+ }
+
+ private Pose getEndEffector() {
+ Limb limb = getLimb();
+ return limb!=null ? limb.getEndEffector() : null;
+ }
+
+ private void moveTowardsTarget() {
+ if(getLimb()==null || getEndEffector()==null || getTarget()==null || linearVelocity<0.0001) {
+ return;
+ }
+ double[] cartesianVelocity = MatrixHelper.getCartesianBetweenTwoMatrices(
+ getEndEffector().getWorld(),
+ getTarget().getWorld());
+ scaleVectorToMagnitude(cartesianVelocity,linearVelocity);
+ moveEndEffectorInCartesianDirection(cartesianVelocity);
+ }
+
+ /**
+ * Attempts to move the robot arm such that the end effector travels in the direction of the cartesian velocity.
+ * @param cartesianVelocity three linear forces (mm) and three angular forces (degrees).
+ * @throws RuntimeException if the robot cannot be moved in the direction of the cartesian force.
+ */
+ public void moveEndEffectorInCartesianDirection(double[] cartesianVelocity) {
+ // is it a tiny move?
+ double sum = sumCartesianVelocityComponents(cartesianVelocity);
+ if(sum<0.0001) return;
+ if(sum <= 1) {
+ setMotorVelocitiesFromCartesianVelocity(cartesianVelocity);
+ return;
+ }
+
+ // set motor velocities.
+ setMotorVelocitiesFromCartesianVelocity(cartesianVelocity);
+ }
+
+ /**
+ * Attempts to move the robot arm such that the end effector travels in the cartesian direction. This is
+ * achieved by setting the velocity of the motors.
+ * @param cartesianVelocity three linear forces (mm) and three angular forces (degrees).
+ * @throws RuntimeException if the robot cannot be moved in the direction of the cartesian force.
+ */
+ private void setMotorVelocitiesFromCartesianVelocity(double[] cartesianVelocity) {
+ ApproximateJacobian aj = getJacobian();
+ try {
+ double[] jointVelocity = aj.getJointFromCartesian(cartesianVelocity); // uses inverse jacobian
+ if(impossibleVelocity(jointVelocity)) return; // TODO: throw exception instead?
+ getLimb().setAllJointVelocities(jointVelocity);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private ApproximateJacobian getJacobian() {
+ // option 1, use finite differences
+ return new ApproximateJacobianFiniteDifferences(getLimb());
+ // option 2, use screw theory
+ //ApproximateJacobian aj = new ApproximateJacobianScrewTheory(getLimb());
+ }
+
+ /**
+ * @param jointVelocity the joint velocity to check
+ * @return true if the given joint velocity is impossible.
+ */
+ private boolean impossibleVelocity(double[] jointVelocity) {
+ double maxV = 100; // RPM*60 TODO: get from robot per joint
+ for(double v : jointVelocity) {
+ if(Double.isNaN(v) || Math.abs(v) > maxV) return true;
+ }
+ return false;
+ }
+
+ @Override
+ public JSONObject toJSON() {
+ JSONObject json = super.toJSON();
+ JSONArray jointArray = new JSONArray();
+ json.put("version",1);
+
+ json.put("motors",jointArray);
+ if(getTarget()!=null) json.put("target",target.getPath());
+ json.put("linearVelocity",linearVelocity);
+ return json;
+ }
+
+ @Override
+ public void fromJSON(JSONObject from) {
+ super.fromJSON(from);
+ int version = from.has("version") ? from.getInt("version") : 0;
+
+ Node root = this.getRootNode();
+
+ if(from.has("target")) {
+ String s = from.getString("target");
+ if(version==1) {
+ target.setPath(s);
+ } else if(version==0) {
+ Pose goal = root.findNodeByID(s,Pose.class);
+ target.setRelativePath(this,goal);
+ }
+ }
+ if(from.has("limb")) {
+ Limb limb = root.findNodeByID(from.getString("limb"),Limb.class);
+ this.limb.setRelativePath(this,limb);
+ }
+ if(from.has("linearVelocity")) {
+ linearVelocity = from.getDouble("linearVelocity");
+ }
+ }
+
+ /**
+ * Make sure the given vector's length does not exceed maxLen. It can be less than the given magnitude.
+ * Store the results in the original array.
+ * @param vector the vector to cap
+ * @param maxLen the max length of the vector.
+ */
+ public static void scaleVectorToMagnitude(double[] vector, double maxLen) {
+ // get the length of the vector
+ double len = 0;
+ for (double v : vector) {
+ len += v * v;
+ }
+
+ len = Math.sqrt(len);
+ if(maxLen>len) maxLen=len;
+
+ // scale the vector
+ double scale = len==0? 0 : maxLen / len; // catch len==0
+ for(int i=0;i linearVelocity = slider.getValue());
+
+ // Make the slider fill the available horizontal space
+ slider.setMaximumSize(new Dimension(Integer.MAX_VALUE, slider.getPreferredSize().height));
+ slider.setMinimumSize(new Dimension(50, slider.getPreferredSize().height));
+
+ container.add(new JLabel("Linear Vel"), BorderLayout.LINE_START);
+ container.add(slider, BorderLayout.CENTER); // Add slider to the center of the container
+
+ return container;
+ }
+
+ private void setTargetToEndEffector() {
+ if(getTarget()!=null && getEndEffector()!=null) {
+ getTarget().setWorld(getEndEffector().getWorld());
+ }
+ }
+
+ private void addMoveTargetToEndEffector(JPanel pane,GridBagConstraints gbc) {
+ // move target to end effector
+ JButton targetToEE = new JButton(new AbstractAction() {
+ {
+ putValue(Action.NAME,"Move");
+ putValue(Action.SHORT_DESCRIPTION,"Move the Target Pose to the End Effector.");
+ putValue(Action.SMALL_ICON,new ImageIcon(Objects.requireNonNull(getClass().getResource(
+ "/com/marginallyclever/ro3/apps/shared/icons8-move-16.png"))));
+ }
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ setTargetToEndEffector();
+ }
+ });
+ addLabelAndComponent(pane, "Target to EE", targetToEE,gbc);
+ }
+
+ @Override
+ public void getComponents(List list) {
+ JPanel pane = new JPanel(new GridBagLayout());
+ list.add(pane);
+ pane.setName(LimbSolver.class.getSimpleName());
+
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = GridBagConstraints.BOTH;
+ gbc.gridx=0;
+ gbc.gridy=0;
+ gbc.gridwidth=2;
+ pane.add(createVelocitySlider(),gbc);
+
+ gbc.gridy++;
+ gbc.gridwidth=1;
+ addMoveTargetToEndEffector(pane,gbc);
+
+ gbc.gridy++;
+ addNodeSelector(pane, "Target", target, Pose.class, gbc);
+
+ super.getComponents(list);
+ }
+
+ public double getLinearVelocity() {
+ return linearVelocity;
+ }
+
+ /**
+ * Set the linear velocity of the end effector in cm/s.
+ * @param linearVelocity must be >= 0
+ */
+ public void setLinearVelocity(double linearVelocity) {
+ if(linearVelocity<0) throw new IllegalArgumentException("linearVelocity must be >= 0");
+ this.linearVelocity = linearVelocity;
+ }
+}
diff --git a/src/main/java/com/marginallyclever/ro3/node/nodes/Motor.java b/src/main/java/com/marginallyclever/ro3/node/nodes/Motor.java
index d70a17453..b74351e19 100644
--- a/src/main/java/com/marginallyclever/ro3/node/nodes/Motor.java
+++ b/src/main/java/com/marginallyclever/ro3/node/nodes/Motor.java
@@ -87,6 +87,6 @@ public void setAxle(HingeJoint hinge) {
}
public boolean hasAxle() {
- return hinge.getSubject()!=null;
+ return getHinge()!=null;
}
}
diff --git a/src/main/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/ApproximateJacobianFiniteDifferences.java b/src/main/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/ApproximateJacobianFiniteDifferences.java
index 8af63ad06..b72374c20 100644
--- a/src/main/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/ApproximateJacobianFiniteDifferences.java
+++ b/src/main/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/ApproximateJacobianFiniteDifferences.java
@@ -1,6 +1,7 @@
package com.marginallyclever.ro3.node.nodes.marlinrobotarm;
import com.marginallyclever.ro3.node.nodes.Pose;
+import com.marginallyclever.ro3.node.nodes.pose.Limb;
import javax.vecmath.Matrix3d;
import javax.vecmath.Matrix4d;
@@ -13,7 +14,7 @@
*/
public class ApproximateJacobianFiniteDifferences extends ApproximateJacobian {
public double ANGLE_STEP_SIZE_DEGREES = 0.1; // degrees
- protected ApproximateJacobianFiniteDifferences(MarlinRobotArm arm) {
+ public ApproximateJacobianFiniteDifferences(Limb arm) {
super(arm.getNumJoints());
Pose endEffector = arm.getEndEffector();
diff --git a/src/main/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/ApproximateJacobianScrewTheory.java b/src/main/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/ApproximateJacobianScrewTheory.java
index 90f18457e..2a2870a7f 100644
--- a/src/main/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/ApproximateJacobianScrewTheory.java
+++ b/src/main/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/ApproximateJacobianScrewTheory.java
@@ -2,6 +2,7 @@
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.ro3.node.nodes.Pose;
+import com.marginallyclever.ro3.node.nodes.pose.Limb;
import javax.vecmath.Matrix4d;
import javax.vecmath.Vector3d;
@@ -19,7 +20,7 @@ public class ApproximateJacobianScrewTheory extends ApproximateJacobian {
* Given the current pose of the robot, find the approximate jacobian.
* @param arm the robot to analyze.
*/
- public ApproximateJacobianScrewTheory(MarlinRobotArm arm) {
+ public ApproximateJacobianScrewTheory(Limb arm) {
super(arm.getNumJoints());
Pose parentPose = arm.findParent(Pose.class);
diff --git a/src/main/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/MarlinRobotArm.java b/src/main/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/MarlinRobotArm.java
index e54022a16..651539928 100644
--- a/src/main/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/MarlinRobotArm.java
+++ b/src/main/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/MarlinRobotArm.java
@@ -2,16 +2,15 @@
import com.marginallyclever.convenience.helpers.MatrixHelper;
import com.marginallyclever.convenience.helpers.StringHelper;
-import com.marginallyclever.convenience.swing.Dial;
import com.marginallyclever.convenience.swing.NumberFormatHelper;
import com.marginallyclever.ro3.apps.nodedetailview.CollapsiblePanel;
import com.marginallyclever.ro3.node.Node;
import com.marginallyclever.ro3.node.NodePath;
import com.marginallyclever.ro3.node.nodes.HingeJoint;
+import com.marginallyclever.ro3.node.nodes.LimbSolver;
import com.marginallyclever.ro3.node.nodes.Motor;
import com.marginallyclever.ro3.node.nodes.Pose;
-import com.marginallyclever.ro3.apps.nodeselector.NodeSelector;
-import org.json.JSONArray;
+import com.marginallyclever.ro3.node.nodes.pose.Limb;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -23,8 +22,6 @@
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.HierarchyEvent;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@@ -32,22 +29,17 @@
* {@link MarlinRobotArm} converts the state of a robot arm into GCode and back.
* In order to work it requires references to:
*
- * - five or six {@link Motor}s, with names matching those in Marlin;
- * - a {@link Pose} end effector to obtain the inverse kinematic pose. The end effector should be at the end of
- * the kinematic chain.
- * - a {@link Pose} target that the end effector will try to match. It will only do so when the linear velocity
- * is greater than zero.
+ * - a {@link Limb} of no more than six {@link Motor}s, whose names match those in Marlin;
+ * - a {@link LimbSolver} to calculate the inverse kinematics;
* - an optional {@link Motor} for the tool on arm.
*
*/
public class MarlinRobotArm extends Node {
private static final Logger logger = LoggerFactory.getLogger(MarlinRobotArm.class);
- public static final int MAX_JOINTS = 6;
- private final List> motors = new ArrayList<>();
+ public final Limb limb = new Limb();
+ public final LimbSolver solver = new LimbSolver();
private final NodePath gripperMotor = new NodePath<>(this,Motor.class);
- private final NodePath endEffector = new NodePath<>(this,Pose.class);
- private final NodePath target = new NodePath<>(this,Pose.class);
- private double linearVelocity=0;
+ private double reportInterval=1.0;
public MarlinRobotArm() {
this("MarlinRobotArm");
@@ -55,25 +47,15 @@ public MarlinRobotArm() {
public MarlinRobotArm(String name) {
super(name);
- for(int i=0;i(this,Motor.class));
- }
}
@Override
public JSONObject toJSON() {
JSONObject json = super.toJSON();
- JSONArray jointArray = new JSONArray();
- json.put("version",1);
-
- for(var motor : motors) {
- jointArray.put(motor == null ? JSONObject.NULL : motor.getPath());
- }
- json.put("motors",jointArray);
- if(endEffector.getSubject()!=null) json.put("endEffector",endEffector.getPath());
- if(target.getSubject()!=null) json.put("target",target.getPath());
+ json.put("version",2);
+ json.put("limb",limb.toJSON());
+ json.put("solver",solver.toJSON());
if(gripperMotor.getSubject()!=null) json.put("gripperMotor",gripperMotor.getPath());
- json.put("linearVelocity",linearVelocity);
return json;
}
@@ -81,53 +63,24 @@ public JSONObject toJSON() {
public void fromJSON(JSONObject from) {
super.fromJSON(from);
int version = from.has("version") ? from.getInt("version") : 0;
-
- if(from.has("motors")) {
- JSONArray motorArray = from.getJSONArray("motors");
- for(int i=0;i list) {
gbc.gridx=0;
gbc.gridy=0;
- gbc.gridwidth=2;
- pane.add(createVelocitySlider(),gbc);
-
- gbc.gridy++;
gbc.gridwidth=1;
- addMoveTargetToEndEffector(pane,gbc);
-
JButton M114 = new JButton("M114");
M114.addActionListener(e-> sendGCode("M114"));
addLabelAndComponent(pane, "Get state", M114,gbc);
gbc.gridwidth=1;
gbc.gridy++;
-
- addNodeSelector(pane, "End Effector", endEffector, Pose.class, gbc);
- addNodeSelector(pane, "Target", target, Pose.class, gbc);
addNodeSelector(pane, "Gripper motor", gripperMotor, Motor.class, gbc);
gbc.gridx=0;
@@ -169,34 +113,13 @@ public void getComponents(List list) {
pane.add(getSender(),gbc);
gbc.gridy++;
pane.add(createReportInterval(),gbc);
- gbc.gridy++;
- pane.add(createEasyFK(),gbc);
- gbc.gridy++;
- gbc.gridwidth=2;
- pane.add(addMotorPanel(),gbc);
+ solver.getComponents(list);
+ limb.getComponents(list);
super.getComponents(list);
}
- private JComponent createVelocitySlider() {
- JPanel container = new JPanel(new BorderLayout());
- // add a slider to control linear velocity
- JSlider slider = new JSlider(0,20,(int)linearVelocity);
- slider.addChangeListener(e-> linearVelocity = slider.getValue());
-
- // Make the slider fill the available horizontal space
- slider.setMaximumSize(new Dimension(Integer.MAX_VALUE, slider.getPreferredSize().height));
- slider.setMinimumSize(new Dimension(50, slider.getPreferredSize().height));
-
- container.add(new JLabel("Linear Vel"), BorderLayout.LINE_START);
- container.add(slider, BorderLayout.CENTER); // Add slider to the center of the container
-
- return container;
- }
-
- private double reportInterval=1.0;
-
private JComponent createReportInterval() {
var containerPanel = new CollapsiblePanel("Report");
var outerPanel = containerPanel.getContentPane();
@@ -277,96 +200,6 @@ private void setReportInterval(double seconds) {
reportInterval = Math.max(0.1,seconds);
}
-
- private void addNodeSelector(JPanel pane, String label, NodePath nodePath, Class clazz, GridBagConstraints gbc) {
- NodeSelector selector = new NodeSelector<>(clazz, nodePath.getSubject());
- selector.addPropertyChangeListener("subject", (e) -> nodePath.setRelativePath(this, (T) e.getNewValue()));
- addLabelAndComponent(pane, label, selector, gbc);
- }
-
- private void addMoveTargetToEndEffector(JPanel pane,GridBagConstraints gbc) {
- // move target to end effector
- JButton targetToEE = new JButton(new AbstractAction() {
- {
- putValue(Action.NAME,"Move");
- putValue(Action.SHORT_DESCRIPTION,"Move the Target Pose to the End Effector.");
- putValue(Action.SMALL_ICON,new ImageIcon(Objects.requireNonNull(getClass().getResource(
- "/com/marginallyclever/ro3/apps/shared/icons8-move-16.png"))));
- }
- @Override
- public void actionPerformed(ActionEvent e) {
- setTargetToEndEffector();
- }
- });
- addLabelAndComponent(pane, "Target to EE", targetToEE,gbc);
- }
-
- private void setTargetToEndEffector() {
- if(target.getSubject()!=null && endEffector.getSubject()!=null) {
- target.getSubject().setWorld(endEffector.getSubject().getWorld());
- }
- }
-
- private JComponent addMotorPanel() {
- var containerPanel = new CollapsiblePanel("Motors");
- var outerPanel = containerPanel.getContentPane();
- outerPanel.setLayout(new GridBagLayout());
-
- GridBagConstraints gbc = new GridBagConstraints();
- gbc.weightx = 1.0;
- gbc.weighty = 1.0;
- gbc.gridx=0;
- gbc.gridy=0;
- gbc.fill = GridBagConstraints.BOTH;
-
- // add a selector for each motor
- var motorSelector = new NodeSelector[MAX_JOINTS];
- for(int i=0;i(Motor.class, motors.get(i).getSubject());
- int j = i;
- motorSelector[i].addPropertyChangeListener("subject",(e)-> {
- motors.get(j).setRelativePath(this,(Motor)e.getNewValue());
- });
- addLabelAndComponent(outerPanel, "Motor "+i, motorSelector[i],gbc);
- }
- return containerPanel;
- }
-
- private JComponent createEasyFK() {
- var containerPanel = new CollapsiblePanel("Forward Kinematics");
- var outerPanel = containerPanel.getContentPane();
- outerPanel.setLayout(new GridLayout(0,3));
-
- int count=0;
- for(int i=0;i {
- motor.getHinge().setAngle(dial.getValue());
- });
- // TODO subscribe to motor.getAxle().getAngle(), then dial.setValue() without triggering an action event.
-
- JLabel label = new JLabel(motor.getName());
- label.setLabelFor(dial);
- label.setHorizontalAlignment(SwingConstants.CENTER);
- innerPanel.add(label,BorderLayout.PAGE_START);
- innerPanel.add(dial,BorderLayout.CENTER);
- dial.setPreferredSize(new Dimension(80,80));
-
- outerPanel.add(innerPanel);
- count++;
- }
- }
- count = 3-(count%3);
- for(int i=0;i paths : this.motors) {
+ for(NodePath paths : limb.getMotors()) {
Motor motor = paths.getSubject();
if(motor!=null && motor.hasAxle()) {
sb.append(" ")
@@ -422,7 +255,7 @@ private String getMotorsAndFeedrateAsString() {
.append(StringHelper.formatDouble(gripperMotor.getHinge().getAngle()));
}
// feedrate
- sb.append(" F").append(StringHelper.formatDouble(linearVelocity));
+ sb.append(" F").append(StringHelper.formatDouble(solver.getLinearVelocity()));
return sb.toString();
}
@@ -444,7 +277,7 @@ public void sendGCode(String gcode) {
} else if(gcode.equals("ik")) {
fireMarlinMessage(getEndEffectorIK());
} else if(gcode.equals("aj")) {
- ApproximateJacobianFiniteDifferences jacobian = new ApproximateJacobianFiniteDifferences(this);
+ ApproximateJacobianFiniteDifferences jacobian = new ApproximateJacobianFiniteDifferences(limb);
fireMarlinMessage( "Ok: "+jacobian );
return;
} else if(gcode.startsWith("G1")) {
@@ -463,7 +296,7 @@ public void sendGCode(String gcode) {
private String parseG0(String gcode) {
String [] parts = gcode.split("\\s+");
try {
- for (NodePath paths : this.motors) {
+ for (NodePath paths : limb.getMotors()) {
Motor motor = paths.getSubject();
if (motor != null && motor.hasAxle()) {
for (String p : parts) {
@@ -499,24 +332,24 @@ private String parseG0(String gcode) {
* G1 Linear move.
* Parse gcode for names and values, then set the new target position. Names are XYZ for linear, UVW for
* angular. Angular values should be in degrees.
- * Movement will occur on {@link #update(double)} provided the {@link #linearVelocity} and the update time are
- * greater than zero.
+ * Movement will occur on {@link #update(double)} provided the {@link LimbSolver} linear velocity and the update
+ * time are greater than zero.
* @param gcode GCode command
* @return response from robot arm
*/
private String parseG1(String gcode) {
- if(target.getSubject()==null) {
+ if(solver.getTarget()==null) {
logger.warn("no target");
return "Error: no target";
}
- if(endEffector.getSubject()==null) {
+ if(limb.getEndEffector()==null) {
logger.warn("no end effector");
return "Error: no end effector";
}
String [] parts = gcode.split("\\s+");
- double [] cartesian = getCartesianFromWorld(endEffector.getSubject().getWorld());
+ double [] cartesian = getCartesianFromWorld(limb.getEndEffector().getWorld());
for(String p : parts) {
- if(p.startsWith("F")) setLinearVelocity(Double.parseDouble(p.substring(1)));
+ if(p.startsWith("F")) solver.setLinearVelocity(Double.parseDouble(p.substring(1)));
if(p.startsWith("X")) cartesian[0] = Double.parseDouble(p.substring(1));
else if(p.startsWith("Y")) cartesian[1] = Double.parseDouble(p.substring(1));
else if(p.startsWith("Z")) cartesian[2] = Double.parseDouble(p.substring(1));
@@ -526,18 +359,18 @@ private String parseG1(String gcode) {
else logger.warn("unknown G1 command: "+p);
}
// set the target position relative to the base of the robot arm
- target.getSubject().setLocal(getReverseCartesianFromWorld(cartesian));
+ solver.getTarget().setLocal(getReverseCartesianFromWorld(cartesian));
return "Ok";
}
private String getEndEffectorIK() {
- if(endEffector.getSubject()==null) {
+ if(limb.getEndEffector()==null) {
return ( "Error: no end effector" );
}
- double [] cartesian = getCartesianFromWorld(endEffector.getSubject().getWorld());
+ double [] cartesian = getCartesianFromWorld(limb.getEndEffector().getWorld());
int i=0;
String response = "G1"
- +" F"+StringHelper.formatDouble(linearVelocity)
+ +" F"+StringHelper.formatDouble(solver.getLinearVelocity())
+" X"+StringHelper.formatDouble(cartesian[i++])
+" Y"+StringHelper.formatDouble(cartesian[i++])
+" Z"+StringHelper.formatDouble(cartesian[i++])
@@ -578,20 +411,16 @@ private double[] getCartesianFromWorld(Matrix4d world) {
public int getNumJoints() {
// count the number of motors such that motors.get(i).getSubject()!=null
int count=0;
- for(NodePath paths : motors) {
+ for(NodePath paths : limb.getMotors()) {
if(paths.getSubject()!=null) count++;
}
return count;
}
- public Motor getJoint(int i) {
- return motors.get(i).getSubject();
- }
-
public double[] getAllJointAngles() {
double[] result = new double[getNumJoints()];
int i=0;
- for(NodePath paths : motors) {
+ for(NodePath paths : limb.getMotors()) {
Motor motor = paths.getSubject();
if(motor!=null) {
result[i++] = motor.getHinge().getAngle();
@@ -606,7 +435,7 @@ public void setAllJointAngles(double[] values) {
return;
}
int i=0;
- for(NodePath paths : motors) {
+ for(NodePath paths : limb.getMotors()) {
Motor motor = paths.getSubject();
if(motor!=null) {
HingeJoint axle = motor.getHinge();
@@ -624,7 +453,7 @@ public void setAllJointVelocities(double[] values) {
return;
}
int i=0;
- for(NodePath paths : motors) {
+ for(NodePath paths : limb.getMotors()) {
Motor motor = paths.getSubject();
if(motor!=null) {
HingeJoint axle = motor.getHinge();
@@ -639,124 +468,14 @@ public void setAllJointVelocities(double[] values) {
* @return the end effector pose or null if not set.
*/
public Pose getEndEffector() {
- return endEffector.getSubject() == null ? null : endEffector.getSubject();
+ return limb.getEndEffector();
}
/**
* @return the target pose or null if not set.
*/
public Pose getTarget() {
- return target.getSubject() == null ? null : target.getSubject();
- }
-
- public void setTarget(Pose target) {
- this.target.setRelativePath(this,target);
- }
-
- @Override
- public void update(double dt) {
- super.update(dt);
- if(dt==0) return;
- moveTowardsTarget(dt);
- }
-
- private void moveTowardsTarget(double dt) {
- if(endEffector.getSubject()==null || target.getSubject()==null || linearVelocity<0.0001) {
- double[] jointAnglesOriginal = getAllJointAngles();
- Arrays.fill(jointAnglesOriginal, 0);
- setAllJointVelocities(jointAnglesOriginal);
- return;
- }
- double[] cartesianVelocity = MatrixHelper.getCartesianBetweenTwoMatrices(
- endEffector.getSubject().getWorld(),
- target.getSubject().getWorld());
- scaleVectorToMagnitude(cartesianVelocity,linearVelocity);
- moveEndEffectorInCartesianDirection(cartesianVelocity);
- }
-
- /**
- * Make sure the given vector's length does not exceed maxLen. It can be less than the given magnitude.
- * Store the results in the original array.
- * @param vector the vector to cap
- * @param maxLen the max length of the vector.
- */
- public static void scaleVectorToMagnitude(double[] vector, double maxLen) {
- // get the length of the vector
- double len = 0;
- for (double v : vector) {
- len += v * v;
- }
-
- len = Math.sqrt(len);
- if(maxLen>len) maxLen=len;
-
- // scale the vector
- double scale = len==0? 0 : maxLen / len; // catch len==0
- for(int i=0;iAttempts to move the robot arm such that the end effector travels in the cartesian direction. This is
- * achieved by setting the velocity of the motors.
- * @param cartesianVelocity three linear forces (mm) and three angular forces (degrees).
- * @throws RuntimeException if the robot cannot be moved in the direction of the cartesian force.
- */
- private void setMotorVelocitiesFromCartesianVelocity(double[] cartesianVelocity) {
- ApproximateJacobian aj = getJacobian();
- try {
- double[] jointVelocity = aj.getJointFromCartesian(cartesianVelocity); // uses inverse jacobian
- if(impossibleVelocity(jointVelocity)) return; // TODO: throw exception instead?
- setAllJointVelocities(jointVelocity);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- private ApproximateJacobian getJacobian() {
- // option 1, use finite differences
- return new ApproximateJacobianFiniteDifferences(this);
- // option 2, use screw theory
- //ApproximateJacobian aj = new ApproximateJacobianScrewTheory(robotComponent);
- }
-
- /**
- * @param jointVelocity the joint velocity to check
- * @return true if the given joint velocity is impossible.
- */
- private boolean impossibleVelocity(double[] jointVelocity) {
- double maxV = 100; // RPM*60 TODO: get from robot per joint
- for(double v : jointVelocity) {
- if(Double.isNaN(v) || Math.abs(v) > maxV) return true;
- }
- return false;
- }
-
- private double sumCartesianVelocityComponents(double [] cartesianVelocity) {
- double sum = 0;
- for (double v : cartesianVelocity) {
- sum += Math.abs(v);
- }
- return sum;
+ return solver.getTarget();
}
public void addMarlinListener(MarlinListener editorPanel) {
@@ -774,13 +493,4 @@ private void fireMarlinMessage(String message) {
listener.messageFromMarlin(message);
}
}
-
- public double getLinearVelocity() {
- return linearVelocity;
- }
-
- public void setLinearVelocity(double linearVelocity) {
- if(linearVelocity<0) throw new IllegalArgumentException("linearVelocity must be >= 0");
- this.linearVelocity = linearVelocity;
- }
}
diff --git a/src/main/java/com/marginallyclever/ro3/node/nodes/pose/Limb.java b/src/main/java/com/marginallyclever/ro3/node/nodes/pose/Limb.java
new file mode 100644
index 000000000..6f2e5662a
--- /dev/null
+++ b/src/main/java/com/marginallyclever/ro3/node/nodes/pose/Limb.java
@@ -0,0 +1,249 @@
+package com.marginallyclever.ro3.node.nodes.pose;
+
+import com.marginallyclever.convenience.swing.Dial;
+import com.marginallyclever.ro3.apps.nodedetailview.CollapsiblePanel;
+import com.marginallyclever.ro3.apps.nodeselector.NodeSelector;
+import com.marginallyclever.ro3.node.Node;
+import com.marginallyclever.ro3.node.NodePath;
+import com.marginallyclever.ro3.node.nodes.HingeJoint;
+import com.marginallyclever.ro3.node.nodes.Motor;
+import com.marginallyclever.ro3.node.nodes.Pose;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * {@link Limb} represents a linear chain of bones and muscles. Bones are represented by {@link Pose}s. Muscles are
+ * represented by {@link Motor}s. The end of the chain is represented by an {@link Pose} called the end effector.
+ * Limbs only perform Forward Kinematics - given the
+ * angle of each joint, they calculate the world space position of the end effector. For more sophisticated behavior,
+ * use a {@link com.marginallyclever.ro3.node.nodes.LimbSolver}.
+ */
+public class Limb extends Pose {
+ private static final Logger logger = LoggerFactory.getLogger(Limb.class);
+ public static final int MAX_JOINTS = 6;
+ private final List> motors = new ArrayList<>();
+ private final NodePath endEffector = new NodePath<>(this,Pose.class);
+
+ public Limb() {
+ this("Limb");
+ }
+
+ public Limb(String name) {
+ super(name);
+
+ for(int i=0;i(this,Motor.class));
+ }
+ }
+
+ /**
+ * @return the end effector pose or null if not set.
+ */
+ public Pose getEndEffector() {
+ return endEffector.getSubject() == null ? null : endEffector.getSubject();
+ }
+
+ public List> getMotors() {
+ return motors;
+ }
+
+ public int getNumJoints() {
+ int count=0;
+ for(NodePath paths : motors) {
+ if(paths.getSubject()!=null) count++;
+ }
+ return count;
+ }
+
+ public Motor getJoint(int i) {
+ return motors.get(i).getSubject();
+ }
+
+ public double[] getAllJointAngles() {
+ double[] result = new double[getNumJoints()];
+ int i=0;
+ for(NodePath paths : motors) {
+ Motor motor = paths.getSubject();
+ if(motor!=null) {
+ result[i++] = motor.getHinge().getAngle();
+ }
+ }
+ return result;
+ }
+
+ public void setAllJointAngles(double[] values) {
+ if(values.length != getNumJoints()) {
+ throw new IllegalArgumentException("setAllJointValues: one value for every motor");
+ }
+ int i=0;
+ for(NodePath paths : motors) {
+ Motor motor = paths.getSubject();
+ if(motor!=null) {
+ HingeJoint axle = motor.getHinge();
+ if(axle!=null) {
+ axle.setAngle(values[i++]);
+ axle.update(0);
+ }
+ }
+ }
+ }
+
+ public void setAllJointVelocities(double[] values) {
+ if(values.length!=getNumJoints()) {
+ throw new IllegalArgumentException("setAllJointValues: one value for every motor");
+ }
+ int i=0;
+ for(NodePath paths : motors) {
+ Motor motor = paths.getSubject();
+ if(motor!=null) {
+ HingeJoint axle = motor.getHinge();
+ if(axle!=null) {
+ axle.setVelocity(values[i++]);
+ }
+ }
+ }
+ }
+
+ @Override
+ public JSONObject toJSON() {
+ JSONObject json = super.toJSON();
+ JSONArray jointArray = new JSONArray();
+ json.put("version",1);
+
+ for(var motor : motors) {
+ jointArray.put(motor == null ? JSONObject.NULL : motor.getPath());
+ }
+ json.put("motors",jointArray);
+ if(endEffector.getSubject()!=null) json.put("endEffector",endEffector.getPath());
+ return json;
+ }
+
+ @Override
+ public void fromJSON(JSONObject from) {
+ super.fromJSON(from);
+ int version = from.has("version") ? from.getInt("version") : 0;
+
+ if(from.has("motors")) {
+ JSONArray motorArray = from.getJSONArray("motors");
+ for(int i=0;i list) {
+ JPanel pane = new JPanel(new GridBagLayout());
+ list.add(pane);
+ pane.setName(Limb.class.getSimpleName());
+
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.fill = GridBagConstraints.BOTH;
+ gbc.gridx=0;
+ gbc.gridy=0;
+ gbc.gridwidth=1;
+ addNodeSelector(pane, "End Effector", endEffector, Pose.class, gbc);
+
+ gbc.gridx=0;
+ gbc.gridwidth=2;
+ gbc.gridy++;
+ pane.add(createEasyFK(),gbc);
+
+ gbc.gridy++;
+ pane.add(addMotorPanel(),gbc);
+
+ super.getComponents(list);
+ }
+
+ private JComponent createEasyFK() {
+ var containerPanel = new CollapsiblePanel("Forward Kinematics");
+ var outerPanel = containerPanel.getContentPane();
+ outerPanel.setLayout(new GridLayout(0,3));
+
+ int count=0;
+ for(int i=0;i {
+ if(motor.hasAxle()) {
+ motor.getHinge().setAngle(dial.getValue());
+ }
+ });
+ // TODO subscribe to motor.getAxle().getAngle(), then dial.setValue() without triggering an action event.
+
+ JLabel label = new JLabel(motor.getName());
+ label.setLabelFor(dial);
+ label.setHorizontalAlignment(SwingConstants.CENTER);
+ panel.add(label,BorderLayout.PAGE_START);
+ panel.add(dial,BorderLayout.CENTER);
+ dial.setPreferredSize(new Dimension(80,80));
+ return panel;
+ }
+
+ private JComponent addMotorPanel() {
+ var containerPanel = new CollapsiblePanel("Motors");
+ var outerPanel = containerPanel.getContentPane();
+ outerPanel.setLayout(new GridBagLayout());
+
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridx=0;
+ gbc.gridy=0;
+ gbc.fill = GridBagConstraints.BOTH;
+
+ // add a selector for each motor
+ var motorSelector = new NodeSelector[MAX_JOINTS];
+ for(int i=0;i(Motor.class, motors.get(i).getSubject());
+ int j = i;
+ motorSelector[i].addPropertyChangeListener("subject",(e)-> {
+ motors.get(j).setRelativePath(this,(Motor)e.getNewValue());
+ });
+ addLabelAndComponent(outerPanel, "Motor "+i, motorSelector[i],gbc);
+ }
+ return containerPanel;
+ }
+}
diff --git a/src/test/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/ApproximateJacobianTest.java b/src/test/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/ApproximateJacobianTest.java
index f9a630471..19cfec6a4 100644
--- a/src/test/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/ApproximateJacobianTest.java
+++ b/src/test/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/ApproximateJacobianTest.java
@@ -2,6 +2,7 @@
import com.marginallyclever.ro3.Registry;
import com.marginallyclever.ro3.apps.actions.LoadScene;
+import com.marginallyclever.ro3.node.nodes.pose.Limb;
import org.junit.jupiter.api.*;
import java.io.File;
@@ -19,13 +20,13 @@ public void setup() {
Registry.start();
}
- private MarlinRobotArm build6AxisArm() throws Exception {
+ private Limb build6AxisArm() throws Exception {
// TODO load a robot from a file.
var load = new LoadScene(null,null);
// find file {project root}/src/test/resources/com/marginallyclever/ro3/apps/node/nodes/marlinrobotarm/Sixi3-5.RO
File file = new File("src/test/resources/com/marginallyclever/ro3/apps/node/nodes/marlinrobotarm/Sixi3-5.RO");
load.commitLoad(file);
- return (MarlinRobotArm) Registry.getScene().get("./Sixi3/MarlinRobotArm");
+ return (Limb) Registry.getScene().get("./Sixi3/MarlinRobotArm");
}
/**
@@ -35,7 +36,7 @@ private MarlinRobotArm build6AxisArm() throws Exception {
@Test
@Disabled
public void compare() throws Exception {
- MarlinRobotArm robot = build6AxisArm();
+ Limb robot = build6AxisArm();
ApproximateJacobian finite = new ApproximateJacobianFiniteDifferences(robot);
ApproximateJacobian screw = new ApproximateJacobianScrewTheory(robot);
From 79c1fd4b301945a3d40eac7a0b63915f77241aac Mon Sep 17 00:00:00 2001
From: Dan Royer
Date: Sun, 7 Jan 2024 12:12:57 -0800
Subject: [PATCH 5/6] setting up NodePaths
---
.../ro3/node/nodes/LimbSolver.java | 2 +-
.../nodes/marlinrobotarm/MarlinRobotArm.java | 157 +++++++-----------
2 files changed, 65 insertions(+), 94 deletions(-)
diff --git a/src/main/java/com/marginallyclever/ro3/node/nodes/LimbSolver.java b/src/main/java/com/marginallyclever/ro3/node/nodes/LimbSolver.java
index a52e38d4a..9596f46dc 100644
--- a/src/main/java/com/marginallyclever/ro3/node/nodes/LimbSolver.java
+++ b/src/main/java/com/marginallyclever/ro3/node/nodes/LimbSolver.java
@@ -23,7 +23,7 @@
* joint velocities required to move the end effector towards the target in a straight line.
*/
public class LimbSolver extends Node {
- private final NodePath limb = new NodePath<>(null,Limb.class);
+ private final NodePath limb = new NodePath<>(this,Limb.class);
private final NodePath target = new NodePath<>(this,Pose.class);
private double linearVelocity = 0;
diff --git a/src/main/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/MarlinRobotArm.java b/src/main/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/MarlinRobotArm.java
index 651539928..8b5bbaa70 100644
--- a/src/main/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/MarlinRobotArm.java
+++ b/src/main/java/com/marginallyclever/ro3/node/nodes/marlinrobotarm/MarlinRobotArm.java
@@ -36,8 +36,8 @@
*/
public class MarlinRobotArm extends Node {
private static final Logger logger = LoggerFactory.getLogger(MarlinRobotArm.class);
- public final Limb limb = new Limb();
- public final LimbSolver solver = new LimbSolver();
+ public final NodePath limb = new NodePath<>(this,Limb.class);
+ public final NodePath solver = new NodePath<>(this,LimbSolver.class);
private final NodePath gripperMotor = new NodePath<>(this,Motor.class);
private double reportInterval=1.0;
@@ -53,8 +53,6 @@ public MarlinRobotArm(String name) {
public JSONObject toJSON() {
JSONObject json = super.toJSON();
json.put("version",2);
- json.put("limb",limb.toJSON());
- json.put("solver",solver.toJSON());
if(gripperMotor.getSubject()!=null) json.put("gripperMotor",gripperMotor.getPath());
return json;
}
@@ -63,13 +61,11 @@ public JSONObject toJSON() {
public void fromJSON(JSONObject from) {
super.fromJSON(from);
int version = from.has("version") ? from.getInt("version") : 0;
- if(version==2) {
- limb.fromJSON(from.getJSONObject("limb"));
- solver.fromJSON(from.getJSONObject("solver"));
- return;
- } else {
- limb.fromJSON(from);
- solver.fromJSON(from);
+ if(version<2) {
+ Limb limb1 = new Limb();
+ LimbSolver solver1 = new LimbSolver();
+ limb1.fromJSON(from);
+ solver1.fromJSON(from);
Node root = this.getRootNode();
if (from.has("gripperMotor")) {
String s = from.getString("gripperMotor");
@@ -80,6 +76,16 @@ public void fromJSON(JSONObject from) {
gripperMotor.setRelativePath(this, goal);
}
}
+
+ limb1.setName("Limb");
+ getParent().addChild(limb1);
+ limb.setRelativePath(this,limb1);
+
+ solver1.setName("LimbSolver");
+ getParent().addChild(solver1);
+ solver.setRelativePath(this,solver1);
+
+ solver1.setLimb(limb1);
}
}
@@ -114,9 +120,6 @@ public void getComponents(List list) {
gbc.gridy++;
pane.add(createReportInterval(),gbc);
- solver.getComponents(list);
- limb.getComponents(list);
-
super.getComponents(list);
}
@@ -237,9 +240,18 @@ private String getM114() {
return "M114"+getMotorsAndFeedrateAsString();
}
+ private Limb getLimb() {
+ return limb.getSubject();
+ }
+
+ private LimbSolver getSolver() {
+ return solver.getSubject();
+ }
+
private String getMotorsAndFeedrateAsString() {
+ if(getLimb()==null || getSolver()==null) return "";
StringBuilder sb = new StringBuilder();
- for(NodePath paths : limb.getMotors()) {
+ for(NodePath paths : getLimb().getMotors()) {
Motor motor = paths.getSubject();
if(motor!=null && motor.hasAxle()) {
sb.append(" ")
@@ -255,7 +267,7 @@ private String getMotorsAndFeedrateAsString() {
.append(StringHelper.formatDouble(gripperMotor.getHinge().getAngle()));
}
// feedrate
- sb.append(" F").append(StringHelper.formatDouble(solver.getLinearVelocity()));
+ sb.append(" F").append(StringHelper.formatDouble(getSolver().getLinearVelocity()));
return sb.toString();
}
@@ -277,7 +289,7 @@ public void sendGCode(String gcode) {
} else if(gcode.equals("ik")) {
fireMarlinMessage(getEndEffectorIK());
} else if(gcode.equals("aj")) {
- ApproximateJacobianFiniteDifferences jacobian = new ApproximateJacobianFiniteDifferences(limb);
+ ApproximateJacobianFiniteDifferences jacobian = new ApproximateJacobianFiniteDifferences(getLimb());
fireMarlinMessage( "Ok: "+jacobian );
return;
} else if(gcode.startsWith("G1")) {
@@ -294,9 +306,13 @@ public void sendGCode(String gcode) {
* @return response from robot arm
*/
private String parseG0(String gcode) {
+ if(getLimb()==null) {
+ logger.warn("no limb");
+ return "Error: no limb";
+ }
String [] parts = gcode.split("\\s+");
try {
- for (NodePath paths : limb.getMotors()) {
+ for (NodePath paths : getLimb().getMotors()) {
Motor motor = paths.getSubject();
if (motor != null && motor.hasAxle()) {
for (String p : parts) {
@@ -338,18 +354,28 @@ private String parseG0(String gcode) {
* @return response from robot arm
*/
private String parseG1(String gcode) {
- if(solver.getTarget()==null) {
+ Limb myLimb = getLimb();
+ if(myLimb==null) {
+ logger.warn("no limb");
+ return "Error: no limb";
+ }
+ LimbSolver mySolver = getSolver();
+ if(mySolver==null) {
+ logger.warn("no solver");
+ return "Error: no solver";
+ }
+ if(mySolver.getTarget()==null) {
logger.warn("no target");
return "Error: no target";
}
- if(limb.getEndEffector()==null) {
+ if(myLimb.getEndEffector()==null) {
logger.warn("no end effector");
return "Error: no end effector";
}
String [] parts = gcode.split("\\s+");
- double [] cartesian = getCartesianFromWorld(limb.getEndEffector().getWorld());
+ double [] cartesian = getCartesianFromWorld(myLimb.getEndEffector().getWorld());
for(String p : parts) {
- if(p.startsWith("F")) solver.setLinearVelocity(Double.parseDouble(p.substring(1)));
+ if(p.startsWith("F")) mySolver.setLinearVelocity(Double.parseDouble(p.substring(1)));
if(p.startsWith("X")) cartesian[0] = Double.parseDouble(p.substring(1));
else if(p.startsWith("Y")) cartesian[1] = Double.parseDouble(p.substring(1));
else if(p.startsWith("Z")) cartesian[2] = Double.parseDouble(p.substring(1));
@@ -359,18 +385,28 @@ private String parseG1(String gcode) {
else logger.warn("unknown G1 command: "+p);
}
// set the target position relative to the base of the robot arm
- solver.getTarget().setLocal(getReverseCartesianFromWorld(cartesian));
+ mySolver.getTarget().setLocal(getReverseCartesianFromWorld(cartesian));
return "Ok";
}
private String getEndEffectorIK() {
- if(limb.getEndEffector()==null) {
+ Limb myLimb = getLimb();
+ if(myLimb==null) {
+ logger.warn("no limb");
+ return "Error: no limb";
+ }
+ LimbSolver mySolver = getSolver();
+ if(mySolver==null) {
+ logger.warn("no solver");
+ return "Error: no solver";
+ }
+ if(myLimb.getEndEffector()==null) {
return ( "Error: no end effector" );
}
- double [] cartesian = getCartesianFromWorld(limb.getEndEffector().getWorld());
+ double [] cartesian = getCartesianFromWorld(myLimb.getEndEffector().getWorld());
int i=0;
String response = "G1"
- +" F"+StringHelper.formatDouble(solver.getLinearVelocity())
+ +" F"+StringHelper.formatDouble(mySolver.getLinearVelocity())
+" X"+StringHelper.formatDouble(cartesian[i++])
+" Y"+StringHelper.formatDouble(cartesian[i++])
+" Z"+StringHelper.formatDouble(cartesian[i++])
@@ -405,77 +441,12 @@ private double[] getCartesianFromWorld(Matrix4d world) {
return new double[] {translate.x,translate.y,translate.z,rotate.x,rotate.y,rotate.z};
}
- /**
- * @return the number of non-null motors.
- */
- public int getNumJoints() {
- // count the number of motors such that motors.get(i).getSubject()!=null
- int count=0;
- for(NodePath paths : limb.getMotors()) {
- if(paths.getSubject()!=null) count++;
- }
- return count;
- }
-
- public double[] getAllJointAngles() {
- double[] result = new double[getNumJoints()];
- int i=0;
- for(NodePath paths : limb.getMotors()) {
- Motor motor = paths.getSubject();
- if(motor!=null) {
- result[i++] = motor.getHinge().getAngle();
- }
- }
- return result;
- }
-
- public void setAllJointAngles(double[] values) {
- if(values.length != getNumJoints()) {
- logger.error("setAllJointValues: one value for every motor");
- return;
- }
- int i=0;
- for(NodePath paths : limb.getMotors()) {
- Motor motor = paths.getSubject();
- if(motor!=null) {
- HingeJoint axle = motor.getHinge();
- if(axle!=null) {
- axle.setAngle(values[i++]);
- axle.update(0);
- }
- }
- }
- }
-
- public void setAllJointVelocities(double[] values) {
- if(values.length!=getNumJoints()) {
- logger.error("setAllJointValues: one value for every motor");
- return;
- }
- int i=0;
- for(NodePath paths : limb.getMotors()) {
- Motor motor = paths.getSubject();
- if(motor!=null) {
- HingeJoint axle = motor.getHinge();
- if(axle!=null) {
- axle.setVelocity(values[i++]);
- }
- }
- }
- }
-
- /**
- * @return the end effector pose or null if not set.
- */
- public Pose getEndEffector() {
- return limb.getEndEffector();
- }
-
/**
* @return the target pose or null if not set.
*/
public Pose getTarget() {
- return solver.getTarget();
+ LimbSolver solver = getSolver();
+ return solver == null ? null : solver.getTarget();
}
public void addMarlinListener(MarlinListener editorPanel) {
From a4cb7e6b9e91f5d9f7d14983883f78bcbb4e88eb Mon Sep 17 00:00:00 2001
From: Dan Royer
Date: Sun, 7 Jan 2024 12:29:27 -0800
Subject: [PATCH 6/6] prevent drift when linear velocity=0
---
.../java/com/marginallyclever/ro3/node/nodes/LimbSolver.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/main/java/com/marginallyclever/ro3/node/nodes/LimbSolver.java b/src/main/java/com/marginallyclever/ro3/node/nodes/LimbSolver.java
index 9596f46dc..9ad7965b1 100644
--- a/src/main/java/com/marginallyclever/ro3/node/nodes/LimbSolver.java
+++ b/src/main/java/com/marginallyclever/ro3/node/nodes/LimbSolver.java
@@ -63,6 +63,8 @@ private Pose getEndEffector() {
private void moveTowardsTarget() {
if(getLimb()==null || getEndEffector()==null || getTarget()==null || linearVelocity<0.0001) {
+ // no limb, no end effector, no target, or no velocity. Do nothing.
+ getLimb().setAllJointVelocities(new double[getLimb().getNumJoints()]);
return;
}
double[] cartesianVelocity = MatrixHelper.getCartesianBetweenTwoMatrices(