diff options
author | Sven Göthel <[email protected]> | 2024-01-22 05:53:34 +0100 |
---|---|---|
committer | Sven Göthel <[email protected]> | 2024-01-22 05:53:34 +0100 |
commit | a883f3e2e1563736df32573141fd5119f0678c92 (patch) | |
tree | 647dd5b5ec8fcd236406a27ed38d68eda0de5c7a | |
parent | ffe4e670c9d35121934c6f3c95067d9c18aee386 (diff) |
Bug 1490 - GraphUI Group: Resolve Performance Issues with Shape Mv Transform -> PMVMatrix4f
Shape.setTransformMv() is called for each renderer frame and for each shape,
involving 6 Matrix4f.mul() and set*() operations.
Since mutation of shape's position, rotation or scale is less frequent
than rendering one frame (for all shapes),
it is more efficient to maintain a local Matrix4f and update it
on such single mutations.
Rendering then only needs to perform one Matrix4f.mul() operation
using this internal matrix.
+++
Also changes name from setTransformMv(PMVMatrix4f) to applyMatToMv(PMVMatrix4f),
as its name might be misleading.
18 files changed, 223 insertions, 116 deletions
diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/FontView01.java b/src/demos/com/jogamp/opengl/demos/graph/ui/FontView01.java index c010c4f07..fa2ae7f3b 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/FontView01.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/FontView01.java @@ -371,7 +371,7 @@ public class FontView01 { final Vec3f rot = new Vec3f(e.getRotation()).scale( FloatUtil.PI / 180.0f ); // swap axis for onscreen rotation matching natural feel final float tmp = rot.x(); rot.setX( rot.y() ); rot.setY( tmp ); - mainView.getRotation().rotateByEuler( rot.scale( 2f ) ); + mainView.setRotation( mainView.getRotation().rotateByEuler( rot.scale( 2f ) ) ); e.setConsumed(true); } } diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UIGraphDemoU01a.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UIGraphDemoU01a.java index 0788ab69e..297827aac 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/UIGraphDemoU01a.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UIGraphDemoU01a.java @@ -307,7 +307,7 @@ public class UIGraphDemoU01a { } if( !textOnly ) { pmv.pushMv(); - shape.setTransformMv(pmv); + shape.applyMatToMv(pmv); shape.draw(gl, renderer); if( onceAtDisplay ) { diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UILayoutBox01.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UILayoutBox01.java index 43f403e8b..daea00d4f 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/UILayoutBox01.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UILayoutBox01.java @@ -137,7 +137,7 @@ public class UILayoutBox01 { final Vec3f rot = new Vec3f(e.getRotation()).scale( FloatUtil.PI / 180.0f ); // swap axis for onscreen rotation matching natural feel final float tmp = rot.x(); rot.setX( rot.y() ); rot.setY( tmp ); - shape.getRotation().rotateByEuler( rot.scale( 2f ) ); + shape.setRotation( shape.getRotation().rotateByEuler( rot.scale( 2f ) ) ); } }; diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UILayoutGrid01.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UILayoutGrid01.java index e1558e7b3..c1b041b42 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/UILayoutGrid01.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UILayoutGrid01.java @@ -136,7 +136,7 @@ public class UILayoutGrid01 { final Vec3f rot = new Vec3f(e.getRotation()).scale( FloatUtil.PI / 180.0f ); // swap axis for onscreen rotation matching natural feel final float tmp = rot.x(); rot.setX( rot.y() ); rot.setY( tmp ); - shape.getRotation().rotateByEuler( rot.scale( 2f ) ); + shape.setRotation( shape.getRotation().rotateByEuler( rot.scale( 2f ) ) ); } }; diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo01b.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo01b.java index a66f5af56..f527226c3 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo01b.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo01b.java @@ -39,6 +39,7 @@ import com.jogamp.graph.ui.Shape; import com.jogamp.graph.ui.shapes.Button; import com.jogamp.graph.ui.shapes.GLButton; import com.jogamp.math.FloatUtil; +import com.jogamp.math.Quaternion; import com.jogamp.math.geom.AABBox; import com.jogamp.math.util.PMVMatrix4f; import com.jogamp.newt.event.MouseEvent; @@ -77,8 +78,12 @@ public class UISceneDemo01b { System.err.println("Font: "+font.getFullFamilyName()); final Shape shape = new Button(options.renderModes, font, "L", 1/8f, 1/8f/2.5f).setPerp(); // normalized: 1 is 100% surface size (width and/or height) - shape.getRotation().rotateByAngleX(FloatUtil.PI); - shape.getRotation().rotateByAngleY(FloatUtil.PI); + { + final Quaternion q = shape.getRotation().copy(); + q.rotateByAngleX(FloatUtil.PI); + q.rotateByAngleY(FloatUtil.PI); + shape.setRotation(q); + } System.err.println("Shape bounds "+shape.getBounds(reqCaps.getGLProfile())); System.err.println("Shape "+shape); @@ -168,9 +173,10 @@ public class UISceneDemo01b { } else { shape.getRotation().rotateByAngleY(rad); } + shape.updateMat(); System.err.println("Shape "+shape); final PMVMatrix4f pmv = new PMVMatrix4f(); - shape.setTransformMv(pmv); + shape.applyMatToMv(pmv); System.err.println("Shape "+pmv); } } diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo03.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo03.java index 10ddf8c78..fdec041d1 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo03.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo03.java @@ -244,7 +244,7 @@ public class UISceneDemo03 { if( showAnimBox ) { animGroup.scale(0.85f, 0.85f, 1f); animGroup.move(-sceneBox.getWidth()/2f*0.075f, 0f, 0f); - animGroup.getRotation().rotateByAngleY(0.1325f); + animGroup.setRotation( animGroup.getRotation().rotateByAngleY(0.1325f) ); } else { animGroup.scale(1.0f, 1.0f, 1f); } @@ -428,7 +428,7 @@ public class UISceneDemo03 { sd.shape.moveTo( sd.startPos ); }; refShape.setColor(1.0f, 0.0f, 0.0f, 0.9f); - refShape.getRotation().rotateByAngleZ(FloatUtil.QUARTER_PI); + refShape.setRotation( refShape.getRotation().rotateByAngleZ(FloatUtil.QUARTER_PI) ); dynAnimSet[2].addShape(animGroup, refShape, shapeSetup); { final Shape s = new Rectangle(options.renderModes, size2, size2*yscale, sceneBox.getWidth() * 0.0025f ).validate(hasGLP); @@ -571,7 +571,8 @@ public class UISceneDemo03 { } else if( euler.y() <= -FloatUtil.HALF_PI ) { dir = 1f; } - animGroup.getRotation().rotateByAngleY( frame_velocity * dir ); + rot.rotateByAngleY( frame_velocity * dir ); + animGroup.setRotation(rot); } final String text = String.format("%s, v %.1f mm/s, r %.3f rad/s", scene.getStatusText(drawable, options.renderModes, dpiV), velocity * 1e3f, ang_velo); @@ -732,7 +733,7 @@ public class UISceneDemo03 { * @param axis 0 for X-, 1 for Y- and 2 for Z-axis */ public static void rotateShape(final Shape shape, float angle, final int axis) { - final Quaternion rot = shape.getRotation(); + final Quaternion rot = shape.getRotation().copy(); final Vec3f euler = rot.toEuler(new Vec3f()); final Vec3f eulerOld = euler.copy(); @@ -756,7 +757,7 @@ public class UISceneDemo03 { case 2: euler.add(0, 0, angle); break; } System.err.println("Rot: angleDelta "+angle+" (eps "+eps+"): "+eulerOld+" -> "+euler); - rot.setFromEuler(euler); + shape.setRotation( rot.setFromEuler(euler) ); } static class MyGLMediaEventListener implements GLMediaEventListener { diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo20.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo20.java index 5551d4701..7292b05f9 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo20.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo20.java @@ -316,7 +316,7 @@ public class UISceneDemo20 implements GLEventListener { sl.addAll(buttonsLeft.getShapes()); sl.addAll(buttonsRight.getShapes()); for(final Shape s : sl) { - s.getRotation().rotateByEuler( angdeg ); + s.setRotation( s.getRotation().rotateByEuler( angdeg ) ); } } @@ -355,7 +355,7 @@ public class UISceneDemo20 implements GLEventListener { for(final Shape s : sl) { if( s instanceof BaseButton ) { final BaseButton b = (BaseButton)s; - b.getRotation().setIdentity(); + b.setRotation( b.getRotation().setIdentity() ); b.setCorner(BaseButton.ROUND_CORNER); if( b instanceof Button ) { ((Button)b).setSpacing(Button.DEFAULT_SPACING_X, Button.DEFAULT_SPACING_Y); @@ -1177,7 +1177,7 @@ public class UISceneDemo20 implements GLEventListener { final Vec3f rot = new Vec3f(e.getRotation()).scale( FloatUtil.PI / 180.0f ); // swap axis for onscreen rotation matching natural feel final float tmp = rot.x(); rot.setX( rot.y() ); rot.setY( tmp ); - shapeEvent.shape.getRotation().rotateByEuler( rot.scale( 2f ) ); + shapeEvent.shape.setRotation( shapeEvent.shape.getRotation().rotateByEuler( rot.scale( 2f ) ) ); } }; } diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UIShapeClippingDemo00.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UIShapeClippingDemo00.java index c0d8babe1..591d57e97 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/UIShapeClippingDemo00.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UIShapeClippingDemo00.java @@ -256,7 +256,7 @@ public class UIShapeClippingDemo00 implements GLEventListener { final Vec3f rot = new Vec3f(e.getRotation()).scale( FloatUtil.PI / 180.0f ); // swap axis for onscreen rotation matching natural feel final float tmp = rot.x(); rot.setX( rot.y() ); rot.setY( tmp ); - clipRect.getRotation().rotateByEuler( rot.scale( 2f ) ); + clipRect.setRotation( clipRect.getRotation().rotateByEuler( rot.scale( 2f ) ) ); } }); } @@ -292,13 +292,13 @@ public class UIShapeClippingDemo00 implements GLEventListener { final PMVMatrix4f pmv = renderer.getMatrix(); pmv.pushMv(); { - clipRect.setTransformMv(pmv); + clipRect.applyMatToMv(pmv); final Frustum clipFrustumMv = new Cube( clipRect.getBounds() ).transform( pmv.getMv() ).updateFrustumPlanes(new Frustum()); renderer.setClipFrustum( clipFrustumMv ); // System.err.println("Clipping "+renderer.getClipBBox()); if( null != shape && shape.isVisible() ) { pmv.pushMv(); - shape.setTransformMv(pmv); + shape.applyMatToMv(pmv); shape.draw(gl, renderer); pmv.popMv(); } diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UIShapeClippingDemo01.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UIShapeClippingDemo01.java index 35de00965..bcf9dfe63 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/UIShapeClippingDemo01.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UIShapeClippingDemo01.java @@ -140,7 +140,7 @@ public class UIShapeClippingDemo01 { final Vec3f rot = new Vec3f(e.getRotation()).scale( FloatUtil.PI / 180.0f ); // swap axis for onscreen rotation matching natural feel final float tmp = rot.x(); rot.setX( rot.y() ); rot.setY( tmp ); - shapeEvent.shape.getRotation().rotateByEuler( rot.scale( 2f ) ); + shapeEvent.shape.setRotation( shapeEvent.shape.getRotation().rotateByEuler( rot.scale( 2f ) ) ); } }); scene.addShape(contentBox); @@ -154,14 +154,14 @@ public class UIShapeClippingDemo01 { final PMVMatrix4f pmv = renderer.getMatrix(); pmv.pushMv(); - contentBox.setTransformMv(pmv); + contentBox.applyMatToMv(pmv); { final AABBox box = contentBox.getBounds(); final Cube cube = tempC00.set(box); final Frustum frustumCbMv = tempC01.set(cube).transform(pmv.getMv()).updateFrustumPlanes(new Frustum()); pmv.pushMv(); - shape.setTransformMv(pmv); + shape.applyMatToMv(pmv); { final AABBox shapeBox = shape.getBounds(); final Cube shapedMv = tempC10.set(shapeBox).transform(pmv.getMv()); diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UIShapeDemo01.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UIShapeDemo01.java index cca86df68..834686bc2 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/UIShapeDemo01.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UIShapeDemo01.java @@ -236,7 +236,7 @@ public class UIShapeDemo01 implements GLEventListener { private void drawShape(final GL2ES2 gl, final RegionRenderer renderer, final Shape shape) { final PMVMatrix4f pmv = renderer.getMatrix(); pmv.pushMv(); - shape.setTransformMv(pmv); + shape.applyMatToMv(pmv); shape.draw(gl, renderer); if( once ) { System.err.println("draw.0: "+shape); @@ -392,7 +392,7 @@ public class UIShapeDemo01 implements GLEventListener { { pmv.pushMv(); - button.setTransformMv(pmv); + button.applyMatToMv(pmv); System.err.println("\n\nButton: "+button); final Vec3f objPos = button.winToShapeCoord(pmv, viewport, glWinX, glWinY, new Vec3f()); @@ -409,7 +409,7 @@ public class UIShapeDemo01 implements GLEventListener { } { pmv.pushMv(); - crossHair.setTransformMv(pmv); + crossHair.applyMatToMv(pmv); final Vec3f objPosC = crossHair.getBounds().getCenter(); System.err.println("\n\nCrossHair: "+crossHair); diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UITypeDemo01.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UITypeDemo01.java index a131c0fd5..bd36b7509 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/UITypeDemo01.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UITypeDemo01.java @@ -261,7 +261,7 @@ public class UITypeDemo01 implements GLEventListener { private void drawShape(final GL2ES2 gl, final PMVMatrix4f pmv, final RegionRenderer renderer, final Shape shape) { pmv.pushMv(); - shape.setTransformMv(pmv); + shape.applyMatToMv(pmv); shape.draw(gl, renderer); pmv.popMv(); } @@ -466,7 +466,7 @@ public class UITypeDemo01 implements GLEventListener { { pmv.pushMv(); - crossHair.setTransformMv(pmv); + crossHair.applyMatToMv(pmv); final Vec3f objPosC = crossHair.getBounds().getCenter(); System.err.println("\n\nCrossHair: "+crossHair); diff --git a/src/graphui/classes/com/jogamp/graph/ui/AnimGroup.java b/src/graphui/classes/com/jogamp/graph/ui/AnimGroup.java index 01e9f0611..450b2cda5 100644 --- a/src/graphui/classes/com/jogamp/graph/ui/AnimGroup.java +++ b/src/graphui/classes/com/jogamp/graph/ui/AnimGroup.java @@ -306,7 +306,7 @@ public class AnimGroup extends Group { * <p> * The given {@link PMVMatrix4f} has to be setup properly for this object, * i.e. its {@link GLMatrixFunc#GL_PROJECTION} and {@link GLMatrixFunc#GL_MODELVIEW} for the surrounding scene - * only, without a shape's {@link #setTransformMv(PMVMatrix4f)}. See {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}. + * only, without a shape's {@link #applyMatToMv(PMVMatrix4f)}. See {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}. * </p> * @param pixPerMM monitor pixel per millimeter for accurate animation * @param glp used {@link GLProfile} @@ -331,7 +331,7 @@ public class AnimGroup extends Group { refShape.validate(glp); pmv.pushMv(); { - refShape.setTransformMv(pmv); + refShape.applyMatToMv(pmv); as = new Set(pixPerMM, refShape.getPixelPerShapeUnit(pmv, viewport, new float[2]), refShape, accel, velocity, ang_accel, ang_velo, new ArrayList<ShapeData>(), new AABBox(), lerp); @@ -347,7 +347,7 @@ public class AnimGroup extends Group { * <p> * The given {@link PMVMatrix4f} has to be setup properly for this object, * i.e. its {@link GLMatrixFunc#GL_PROJECTION} and {@link GLMatrixFunc#GL_MODELVIEW} for the surrounding scene - * only, without a shape's {@link #setTransformMv(PMVMatrix4f)}. See {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}. + * only, without a shape's {@link #applyMatToMv(PMVMatrix4f)}. See {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}. * </p> * @param pixPerMM monitor pixel per millimeter for accurate animation * @param glp used {@link GLProfile} @@ -381,7 +381,7 @@ public class AnimGroup extends Group { refShape.validate(glp); pmv.pushMv(); { - refShape.setTransformMv(pmv); + refShape.applyMatToMv(pmv); as = new Set(pixPerMM, refShape.getPixelPerShapeUnit(pmv, viewport, new float[2]), refShape, accel, velocity, ang_accel, ang_velo, allShapes, sourceBounds, lerp); } @@ -426,7 +426,7 @@ public class AnimGroup extends Group { * <p> * The given {@link PMVMatrix4f} has to be setup properly for this object, * i.e. its {@link GLMatrixFunc#GL_PROJECTION} and {@link GLMatrixFunc#GL_MODELVIEW} for the surrounding scene - * only, without a shape's {@link #setTransformMv(PMVMatrix4f)}. See {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}. + * only, without a shape's {@link #applyMatToMv(PMVMatrix4f)}. See {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}. * </p> * @param pixPerMM monitor pixel per millimeter for accurate animation * @param glp used {@link GLProfile} @@ -475,7 +475,7 @@ public class AnimGroup extends Group { * <p> * The given {@link PMVMatrix4f} has to be setup properly for this object, * i.e. its {@link GLMatrixFunc#GL_PROJECTION} and {@link GLMatrixFunc#GL_MODELVIEW} for the surrounding scene - * only, without a shape's {@link #setTransformMv(PMVMatrix4f)}. See {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}. + * only, without a shape's {@link #applyMatToMv(PMVMatrix4f)}. See {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti)}. * </p> * @param pixPerMM monitor pixel per millimeter for accurate animation * @param glp used {@link GLProfile} @@ -633,9 +633,8 @@ public class AnimGroup extends Group { final Vec3f pos = sd.shape.getPosition().copy(); final Vec3f p_t = sd.targetPos.minus(pos); final float p_t_diff = p_t.length(); - final Quaternion q = sd.shape.getRotation(); - final Vec3f euler = q.toEuler(new Vec3f()); - final float rotAng = euler.length(); + final Quaternion q = sd.shape.getRotation().copy(); + final float rotAng = q.toEuler(new Vec3f()).length(); final float rotAngDiff = Math.min(Math.abs(rotAng), FloatUtil.TWO_PI - Math.abs(rotAng)); final boolean pos_ok = p_t_diff <= AnimGroup.POS_EPS; final boolean pos_near = pos_ok || p_t_diff <= sd.shape.getBounds().getSize() * shapeScale * 2f; @@ -649,6 +648,7 @@ public class AnimGroup extends Group { } sd.shape.moveTo(sd.targetPos); q.setIdentity(); + sd.shape.setRotation(q); sd.shape.setInteractive(false); return false; } @@ -670,6 +670,7 @@ public class AnimGroup extends Group { } else { q.rotateByAngleNormalAxis( rot_step, rotAxis ); } + sd.shape.setRotation(q); } } else { if( DEBUG ) { @@ -682,6 +683,7 @@ public class AnimGroup extends Group { } else { q.rotateByAngleNormalAxis( rot_step * 3f, rotAxis ); } + sd.shape.setRotation(q); } return true; } diff --git a/src/graphui/classes/com/jogamp/graph/ui/Group.java b/src/graphui/classes/com/jogamp/graph/ui/Group.java index 29352fff0..e3431224c 100644 --- a/src/graphui/classes/com/jogamp/graph/ui/Group.java +++ b/src/graphui/classes/com/jogamp/graph/ui/Group.java @@ -341,7 +341,7 @@ public class Group extends Shape implements Container { final Shape shape = (Shape) shapesS[i]; if( shape.isVisible() ) { pmv.pushMv(); - shape.setTransformMv(pmv); + shape.applyMatToMv(pmv); final AABBox shapeBox = shape.getBounds(); final Cube shapeMv = tempC01.set( shapeBox ).transform( pmv.getMv() ); @@ -361,7 +361,7 @@ public class Group extends Shape implements Container { final Shape shape = (Shape) shapesS[i]; if( shape.isVisible() ) { pmv.pushMv(); - shape.setTransformMv(pmv); + shape.applyMatToMv(pmv); if( !doFrustumCulling || !pmv.getFrustum().isOutside( shape.getBounds() ) ) { shape.draw(gl, renderer); } @@ -389,7 +389,7 @@ public class Group extends Shape implements Container { final Shape shape = (Shape) shapesS[i]; if( shape.isVisible() ) { pmv.pushMv(); - shape.setTransformMv(pmv); + shape.applyMatToMv(pmv); if( !doFrustumCulling || !pmv.getFrustum().isOutside( shape.getBounds() ) ) { shape.drawToSelect(gl, renderer); @@ -526,7 +526,7 @@ public class Group extends Shape implements Container { } s.validate(gl, glp); pmv.pushMv(); - s.setTransformMv(pmv); + s.applyMatToMv(pmv); s.getBounds().transform(pmv.getMv(), tsbox); pmv.popMv(); box.resize(tsbox); @@ -608,7 +608,7 @@ public class Group extends Shape implements Container { @Override public AABBox getBounds(final PMVMatrix4f pmv, final Shape shape) { pmv.reset(); - setTransformMv(pmv); + applyMatToMv(pmv); final AABBox res = new AABBox(); if( null == shape ) { return res; diff --git a/src/graphui/classes/com/jogamp/graph/ui/Scene.java b/src/graphui/classes/com/jogamp/graph/ui/Scene.java index 5c9c6859e..8a9952c04 100644 --- a/src/graphui/classes/com/jogamp/graph/ui/Scene.java +++ b/src/graphui/classes/com/jogamp/graph/ui/Scene.java @@ -471,7 +471,7 @@ public final class Scene implements Container, GLEventListener { final Shape shape = (Shape)shapes[i]; if( shape.isVisible() ) { pmv.pushMv(); - shape.setTransformMv(pmv); + shape.applyMatToMv(pmv); if( !doFrustumCulling || !pmv.getFrustum().isOutside( shape.getBounds() ) ) { shape.draw(gl, renderer); @@ -505,7 +505,7 @@ public final class Scene implements Container, GLEventListener { final Shape shape = (Shape)shapes[i]; if( shape.isVisible() ) { pmv.pushMv(); - shape.setTransformMv(pmv); + shape.applyMatToMv(pmv); if( !doFrustumCulling || !pmv.getFrustum().isOutside( shape.getBounds() ) ) { final float color = ( i + 1f ) / ( shapeCount + 2f ); @@ -680,7 +680,7 @@ public final class Scene implements Container, GLEventListener { if( null != s ) { final PMVMatrix4f pmv = renderer.getMatrix(); pmv.pushMv(); - s.setTransformMv(pmv); + s.applyMatToMv(pmv); final boolean ok = null != shape[0].winToShapeCoord(getMatrix(), getViewport(), glWinX, glWinY, objPos); pmv.popMv(); if( ok ) { diff --git a/src/graphui/classes/com/jogamp/graph/ui/Shape.java b/src/graphui/classes/com/jogamp/graph/ui/Shape.java index 36b15d739..1811d2f61 100644 --- a/src/graphui/classes/com/jogamp/graph/ui/Shape.java +++ b/src/graphui/classes/com/jogamp/graph/ui/Shape.java @@ -215,13 +215,16 @@ public abstract class Shape { private static final int DIRTY_STATE = 1 << 1 ; private volatile Group parent = null; - protected final AABBox box; + protected final AABBox box = new AABBox(); private final Vec3f position = new Vec3f(); private float zOffset = 0; private final Quaternion rotation = new Quaternion(); private Vec3f rotPivot = null; private final Vec3f scale = new Vec3f(1f, 1f, 1f); + private final Matrix4f iMat = new Matrix4f(); + private final Matrix4f tmpMat = new Matrix4f(); + private boolean iMatIdent = true; private volatile int dirty = DIRTY_SHAPE | DIRTY_STATE; private final Object dirtySync = new Object(); @@ -281,9 +284,7 @@ public abstract class Shape { /** * Create a generic UI {@link Shape} */ - protected Shape() { - this.box = new AABBox(); - } + protected Shape() { } protected void setParent(final Group c) { parent = c; } @@ -390,6 +391,8 @@ public abstract class Shape { rotation.setIdentity(); rotPivot = null; scale.set(1f, 1f, 1f); + iMat.loadIdentity(); + iMatIdent = true; box.reset(); mouseListeners.clear(); keyListeners.clear(); @@ -486,24 +489,28 @@ public abstract class Shape { /** Move to scaled position. Position ends up in PMVMatrix4f unmodified. No {@link MoveListener} notification will occur. */ public final Shape moveTo(final float tx, final float ty, final float tz) { position.set(tx, ty, tz); + updateMat(); return this; } /** Move to scaled position. Position ends up in PMVMatrix4f unmodified. No {@link MoveListener} notification will occur. */ public final Shape moveTo(final Vec3f t) { position.set(t); + updateMat(); return this; } /** Move about scaled distance. Position ends up in PMVMatrix4f unmodified. No {@link MoveListener} notification will occur. */ public final Shape move(final float dtx, final float dty, final float dtz) { position.add(dtx, dty, dtz); + updateMat(); return this; } /** Move about scaled distance. Position ends up in PMVMatrix4f unmodified. No {@link MoveListener} notification will occur. */ public final Shape move(final Vec3f dt) { position.add(dt); + updateMat(); return this; } @@ -514,25 +521,48 @@ public abstract class Shape { private final void forwardMove(final Vec3f origin, final Vec3f dest) { if( !origin.isEqual(dest) ) { + updateMat(); if( null != onMoveListener ) { onMoveListener.run(this, origin, dest); } } } - /** Returns position, i.e. scaled translation as set via {@link #moveTo(float, float, float) or {@link #move(float, float, float)}}. */ + /** + * Returns position {@link Vec3f} reference, i.e. scaled translation as set via {@link #moveTo(float, float, float) or {@link #move(float, float, float)}}. + * @see #updateMat() + */ public final Vec3f getPosition() { return position; } - /** Returns {@link Quaternion} for rotation. */ + /** + * Returns {@link Quaternion} for rotation. + * @see #updateMat() + */ public final Quaternion getRotation() { return rotation; } - /** Return unscaled rotation origin, aka pivot. Null if not set via {@link #getRotationPivot()}. */ + + /** + * Sets the rotation {@link Quaternion}. + * @return this shape for chaining + */ + public final Shape setRotation(final Quaternion q) { + rotation.set(q); + updateMat(); + return this; + } + + /** + * Return unscaled rotation origin {@link Vec3f} reference, aka pivot. Null if not set via {@link #setRotationPivot(float, float, float)}. + * @see #updateMat() + */ public final Vec3f getRotationPivot() { return rotPivot; } + /** * Set unscaled rotation origin, aka pivot. Usually the {@link #getBounds()} center and should be set while {@link #validateImpl(GL2ES2, GLProfile)}. * @return this shape for chaining */ public final Shape setRotationPivot(final float px, final float py, final float pz) { rotPivot = new Vec3f(px, py, pz); + updateMat(); return this; } /** @@ -542,6 +572,7 @@ public abstract class Shape { */ public final Shape setRotationPivot(final Vec3f pivot) { rotPivot = new Vec3f(pivot); + updateMat(); return this; } @@ -552,6 +583,7 @@ public abstract class Shape { */ public final Shape setScale(final Vec3f s) { scale.set(s); + updateMat(); return this; } /** @@ -561,6 +593,7 @@ public abstract class Shape { */ public final Shape setScale(final float sx, final float sy, final float sz) { scale.set(sx, sy, sz); + updateMat(); return this; } /** @@ -570,6 +603,7 @@ public abstract class Shape { */ public final Shape scale(final Vec3f s) { scale.scale(s); + updateMat(); return this; } /** @@ -579,12 +613,14 @@ public abstract class Shape { */ public final Shape scale(final float sx, final float sy, final float sz) { scale.scale(sx, sy, sz); + updateMat(); return this; } /** - * Returns scale factors. + * Returns scale {@link Vec3f} reference. * @see #setScale(float, float, float) * @see #scale(float, float, float) + * @see #updateMat() */ public final Vec3f getScale() { return scale; } @@ -701,7 +737,7 @@ public abstract class Shape { /** * Renders the shape. * <p> - * {@link #setTransformMv(PMVMatrix4f)} is expected to be completed beforehand. + * {@link #transformMvTo(PMVMatrix4f)} is expected to be completed beforehand. * </p> * @param gl the current GL object * @param renderer {@link RegionRenderer} which might be used for Graph Curve Rendering, also source of {@link RegionRenderer#getMatrix()} and {@link RegionRenderer#getViewport()}. @@ -799,88 +835,148 @@ public abstract class Shape { } /** - * Setup the {@link PMVMatrix4f#getMv() modelview matrix} of the given {@link PMVMatrix4f} for this object. - * - Scale shape from its center position - * - Rotate shape around optional scaled pivot, see {@link #setRotationPivot(float[])}), otherwise rotate around its scaled center (default) + * Applies the internal {@link Matrix4f} to the given {@link PMVMatrix4f#getMv() modelview matrix}, + * i.e. {@code pmv.mulMv( getMat() )}. * <p> - * Shape's origin should be bottom-left @ 0/0 to have build-in drag-zoom work properly. + * In case {@link #isMatIdentity()} is {@code true}, implementation is a no-operation. * </p> * @param pmv the matrix - * @see #setRotationPivot(float[]) + * @see #isMatIdentity() + * @see #updateMat() + * @see #getMat() + * @see PMVMatrix4f#mulMv(Matrix4f) + */ + public final void transformMvTo(final PMVMatrix4f pmv) { + if( !iMatIdent ) { + pmv.mulMv(iMat); + } + } + + /** + * Returns the internal {@link Matrix4f} reference, see {@link #updateMat()}. + * <p> + * Using this method renders {@link #isMatIdentity()} {@code false}, + * since its content is mutable. Use {@link #getMat(Matrix4f) instead if suitable. + * </p> + * @see #getMat(Matrix4f) + * @see #isMatIdentity() + * @see #transformMvTo(PMVMatrix4f) + * @see #updateMat() + */ + public final Matrix4f getMat() { iMatIdent = false; return iMat; } + + /** + * Returns a copy of the internal {@link Matrix4f} to {@code out} see {@link #updateMat()}. + * @see #getMat() + * @see #isMatIdentity() + * @see #transformMvTo(PMVMatrix4f) + * @see #updateMat() + */ + public final Matrix4f getMat(final Matrix4f out) { out.load(iMat); return out; } + + /** + * Returns true if {@link #getMat()} has not been mutated, i.e. contains identity. + * @see #getMat() + * @see #updateMat() + */ + public final boolean isMatIdentity() { return iMatIdent; } + + /** + * Updates the internal {@link Matrix4f} with local position, rotation and scale. + * <ul> + * <li>Scale shape from its center position</li> + * <li>Rotate shape around optional scaled pivot, see {@link #setRotationPivot(float[])}), otherwise rotate around its scaled center (default)</li> + * </ul> + * <p> + * Shape's origin should be bottom-left @ 0/0 to have build-in drag-zoom work properly. + * </p> + * <p> + * Usually only used internally after modifying position, scale or rotation. + * </p> + * <p> + * However, after modifying borrowed values via {@link #getPosition()}, {@link #getScale()}, {@link #getRotation()} or {@link #getRotationPivot()} + * without any other change thereafter, e.g. {@link #move(Vec3f)}, this method must be called! + * </p> + * @see #isMatIdentity() + * @see #getMat() + * @see #getPosition() + * @see #getScale() * @see #getRotation() - * @see #moveTo(float, float, float) - * @see #setScale(float, float, float) + * @see #getRotationPivot() + * @see #transformMvTo(PMVMatrix4f) */ - public void setTransformMv(final PMVMatrix4f pmv) { + public final void updateMat() { final boolean hasScale = !scale.isEqual(Vec3f.ONE); final boolean hasRotate = !rotation.isIdentity(); final boolean hasRotPivot = null != rotPivot; final Vec3f ctr = box.getCenter(); final boolean sameScaleRotatePivot = hasScale && hasRotate && ( !hasRotPivot || rotPivot.isEqual(ctr) ); - pmv.translateMv(position.x(), position.y(), position.z()); // translate, scaled + iMatIdent = false; + + iMat.setToTranslation(position); // identify + translate, scaled if( sameScaleRotatePivot ) { // Scale shape from its center position and rotate around its center - pmv.translateMv(ctr.x()*scale.x(), ctr.y()*scale.y(), ctr.z()*scale.z()); // add-back center, scaled - pmv.rotateMv(rotation); - pmv.scaleMv(scale.x(), scale.y(), scale.z()); - pmv.translateMv(-ctr.x(), -ctr.y(), -ctr.z()); // move to center + iMat.translate(ctr.x()*scale.x(), ctr.y()*scale.y(), ctr.z()*scale.z(), tmpMat); // add-back center, scaled + iMat.rotate(rotation, tmpMat); + iMat.scale(scale.x(), scale.y(), scale.z(), tmpMat); + iMat.translate(-ctr.x(), -ctr.y(), -ctr.z(), tmpMat); // move to center } else if( hasRotate || hasScale ) { if( hasRotate ) { if( hasRotPivot ) { // Rotate shape around its scaled pivot - pmv.translateMv(rotPivot.x()*scale.x(), rotPivot.y()*scale.y(), rotPivot.z()*scale.z()); // pivot back from rot-pivot, scaled - pmv.rotateMv(rotation); - pmv.translateMv(-rotPivot.x()*scale.x(), -rotPivot.y()*scale.y(), -rotPivot.z()*scale.z()); // pivot to rot-pivot, scaled + iMat.translate(rotPivot.x()*scale.x(), rotPivot.y()*scale.y(), rotPivot.z()*scale.z(), tmpMat); // pivot back from rot-pivot, scaled + iMat.rotate(rotation, tmpMat); + iMat.translate(-rotPivot.x()*scale.x(), -rotPivot.y()*scale.y(), -rotPivot.z()*scale.z(), tmpMat); // pivot to rot-pivot, scaled } else { // Rotate shape around its scaled center - pmv.translateMv(ctr.x()*scale.x(), ctr.y()*scale.y(), ctr.z()*scale.z()); // pivot back from center-pivot, scaled - pmv.rotateMv(rotation); - pmv.translateMv(-ctr.x()*scale.x(), -ctr.y()*scale.y(), -ctr.z()*scale.z()); // pivot to center-pivot, scaled + iMat.translate(ctr.x()*scale.x(), ctr.y()*scale.y(), ctr.z()*scale.z(), tmpMat); // pivot back from center-pivot, scaled + iMat.rotate(rotation, tmpMat); + iMat.translate(-ctr.x()*scale.x(), -ctr.y()*scale.y(), -ctr.z()*scale.z(), tmpMat); // pivot to center-pivot, scaled } } if( hasScale ) { // Scale shape from its center position - pmv.translateMv(ctr.x()*scale.x(), ctr.y()*scale.y(), ctr.z()*scale.z()); // add-back center, scaled - pmv.scaleMv(scale.x(), scale.y(), scale.z()); - pmv.translateMv(-ctr.x(), -ctr.y(), -ctr.z()); // move to center + iMat.translate(ctr.x()*scale.x(), ctr.y()*scale.y(), ctr.z()*scale.z(), tmpMat); // add-back center, scaled + iMat.scale(scale.x(), scale.y(), scale.z(), tmpMat); + iMat.translate(-ctr.x(), -ctr.y(), -ctr.z(), tmpMat); // move to center } } } /** * {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) Setup} the given {@link PMVMatrix4f} - * and apply this shape's {@link #setTransformMv(PMVMatrix4f) transformation}. + * and apply this shape's {@link #transformMvTo(PMVMatrix4f) transformation}. * </p> * @param pmvMatrixSetup {@link Scene.PMVMatrixSetup} to {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) setup} given {@link PMVMatrix4f} {@code pmv}. * @param viewport used viewport for {@link PMVMatrix4f#mapObjToWin(Vec3f, Recti, Vec3f)} * @param pmv a new {@link PMVMatrix4f} which will {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) be setup}, - * {@link #setTransformMv(PMVMatrix4f) shape-transformed} and can be reused by the caller. + * {@link #transformMvTo(PMVMatrix4f) shape-transformed} and can be reused by the caller. * @return the given {@link PMVMatrix4f} for chaining * @see Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) - * @see #setTransformMv(PMVMatrix4f) + * @see #transformMvTo(PMVMatrix4f) * @see #setPMVMatrix(Scene, PMVMatrix4f) */ - public PMVMatrix4f setPMVMatrix(final Scene.PMVMatrixSetup pmvMatrixSetup, final Recti viewport, final PMVMatrix4f pmv) { + public final PMVMatrix4f setPMVMatrix(final Scene.PMVMatrixSetup pmvMatrixSetup, final Recti viewport, final PMVMatrix4f pmv) { pmvMatrixSetup.set(pmv, viewport); - setTransformMv(pmv); + transformMvTo(pmv); return pmv; } /** * {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) Setup} the given {@link PMVMatrix4f} - * and apply this shape's {@link #setTransformMv(PMVMatrix4f) transformation}. + * and apply this shape's {@link #transformMvTo(PMVMatrix4f) transformation}. * </p> * @param scene {@link Scene} to retrieve {@link Scene.PMVMatrixSetup} and the viewport. * @param pmv a new {@link PMVMatrix4f} which will {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) be setup}, - * {@link #setTransformMv(PMVMatrix4f) shape-transformed} and can be reused by the caller. + * {@link #transformMvTo(PMVMatrix4f) shape-transformed} and can be reused by the caller. * @return the given {@link PMVMatrix4f} for chaining * @see Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) - * @see #setTransformMv(PMVMatrix4f) + * @see #transformMvTo(PMVMatrix4f) * @see #setPMVMatrix(com.jogamp.graph.ui.Scene.PMVMatrixSetup, Recti, PMVMatrix4f) */ - public PMVMatrix4f setPMVMatrix(final Scene scene, final PMVMatrix4f pmv) { + public final PMVMatrix4f setPMVMatrix(final Scene scene, final PMVMatrix4f pmv) { return setPMVMatrix(scene.getPMVMatrixSetup(), scene.getViewport(), pmv); } @@ -889,14 +985,14 @@ public abstract class Shape { * <p> * The given {@link PMVMatrix4f} has to be setup properly for this object, * i.e. its {@link GLMatrixFunc#GL_PROJECTION} and {@link GLMatrixFunc#GL_MODELVIEW} for the surrounding scene - * including this shape's {@link #setTransformMv(PMVMatrix4f)}. See {@link #setPMVMatrix(Scene, PMVMatrix4f)}. + * including this shape's {@link #transformMvTo(PMVMatrix4f)}. See {@link #setPMVMatrix(Scene, PMVMatrix4f)}. * </p> * @param pmv well formed {@link PMVMatrix4f}, e.g. could have been setup via {@link Shape#setPMVMatrix(Scene, PMVMatrix4f)}. * @param viewport the int[4] viewport * @param surfacePort Recti target surface port * @return given Recti {@code surfacePort} for successful {@link Matrix4f#mapObjToWin(Vec3f, Matrix4f, Recti, Vec3f) gluProject(..)} operation, otherwise {@code null} */ - public Recti getSurfacePort(final PMVMatrix4f pmv, final Recti viewport, final Recti surfacePort) { + public final Recti getSurfacePort(final PMVMatrix4f pmv, final Recti viewport, final Recti surfacePort) { final Vec3f winCoordHigh = new Vec3f(); final Vec3f winCoordLow = new Vec3f(); final Vec3f high = box.getHigh(); @@ -920,7 +1016,7 @@ public abstract class Shape { * <p> * The given {@link PMVMatrix4f} has to be setup properly for this object, * i.e. its {@link GLMatrixFunc#GL_PROJECTION} and {@link GLMatrixFunc#GL_MODELVIEW} for the surrounding scene - * including this shape's {@link #setTransformMv(PMVMatrix4f)}. See {@link #setPMVMatrix(Scene, PMVMatrix4f)}. + * including this shape's {@link #transformMvTo(PMVMatrix4f)}. See {@link #setPMVMatrix(Scene, PMVMatrix4f)}. * </p> * @param pmv well formed {@link PMVMatrix4f}, e.g. could have been setup via {@link Shape#setPMVMatrix(Scene, PMVMatrix4f)}. * @param viewport the int[4] viewport @@ -929,7 +1025,7 @@ public abstract class Shape { * @see #getSurfaceSize(com.jogamp.graph.ui.Scene.PMVMatrixSetup, Recti, PMVMatrix4f, int[]) * @see #getSurfaceSize(Scene, PMVMatrix4f, int[]) */ - public int[/*2*/] getSurfaceSize(final PMVMatrix4f pmv, final Recti viewport, final int[/*2*/] surfaceSize) { + public final int[/*2*/] getSurfaceSize(final PMVMatrix4f pmv, final Recti viewport, final int[/*2*/] surfaceSize) { // System.err.println("Shape::getSurfaceSize.VP "+viewport[0]+"/"+viewport[1]+" "+viewport[2]+"x"+viewport[3]); final Vec3f winCoordHigh = new Vec3f(); final Vec3f winCoordLow = new Vec3f(); @@ -951,18 +1047,18 @@ public abstract class Shape { * Retrieve surface (view) size in pixels of this shape. * <p> * The given {@link PMVMatrix4f} will be {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) setup} properly for this shape - * including this shape's {@link #setTransformMv(PMVMatrix4f)}. + * including this shape's {@link #transformMvTo(PMVMatrix4f)}. * </p> * @param pmvMatrixSetup {@link Scene.PMVMatrixSetup} to {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) setup} given {@link PMVMatrix4f} {@code pmv}. * @param viewport used viewport for {@link Matrix4f#mapObjToWin(Vec3f, Matrix4f, Recti, Vec3f) gluProject(..)} * @param pmv a new {@link PMVMatrix4f} which will {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) be setup}, - * {@link #setTransformMv(PMVMatrix4f) shape-transformed} and can be reused by the caller. + * {@link #transformMvTo(PMVMatrix4f) shape-transformed} and can be reused by the caller. * @param surfaceSize int[2] target surface size * @return given int[2] {@code surfaceSize} in pixels for successful {@link Matrix4f#mapObjToWin(Vec3f, Matrix4f, Recti, Vec3f) gluProject(..)} operation, otherwise {@code null} * @see #getSurfaceSize(PMVMatrix4f, Recti, int[]) * @see #getSurfaceSize(Scene, PMVMatrix4f, int[]) */ - public int[/*2*/] getSurfaceSize(final Scene.PMVMatrixSetup pmvMatrixSetup, final Recti viewport, final PMVMatrix4f pmv, final int[/*2*/] surfaceSize) { + public final int[/*2*/] getSurfaceSize(final Scene.PMVMatrixSetup pmvMatrixSetup, final Recti viewport, final PMVMatrix4f pmv, final int[/*2*/] surfaceSize) { return getSurfaceSize(setPMVMatrix(pmvMatrixSetup, viewport, pmv), viewport, surfaceSize); } @@ -970,17 +1066,17 @@ public abstract class Shape { * Retrieve surface (view) size in pixels of this shape. * <p> * The given {@link PMVMatrix4f} will be {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) setup} properly for this shape - * including this shape's {@link #setTransformMv(PMVMatrix4f)}. + * including this shape's {@link #transformMvTo(PMVMatrix4f)}. * </p> * @param scene {@link Scene} to retrieve {@link Scene.PMVMatrixSetup} and the viewport. * @param pmv a new {@link PMVMatrix4f} which will {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) be setup}, - * {@link #setTransformMv(PMVMatrix4f) shape-transformed} and can be reused by the caller. + * {@link #transformMvTo(PMVMatrix4f) shape-transformed} and can be reused by the caller. * @param surfaceSize int[2] target surface size * @return given int[2] {@code surfaceSize} in pixels for successful {@link Matrix4f#mapObjToWin(Vec3f, Matrix4f, Recti, Vec3f) gluProject(..)} operation, otherwise {@code null} * @see #getSurfaceSize(PMVMatrix4f, Recti, int[]) * @see #getSurfaceSize(com.jogamp.graph.ui.Scene.PMVMatrixSetup, Recti, PMVMatrix4f, int[]) */ - public int[/*2*/] getSurfaceSize(final Scene scene, final PMVMatrix4f pmv, final int[/*2*/] surfaceSize) { + public final int[/*2*/] getSurfaceSize(final Scene scene, final PMVMatrix4f pmv, final int[/*2*/] surfaceSize) { return getSurfaceSize(scene.getPMVMatrixSetup(), scene.getViewport(), pmv, surfaceSize); } @@ -994,7 +1090,7 @@ public abstract class Shape { * @see #getScaledWidth() * @see #getScaledHeight() */ - public float[] getPixelPerShapeUnit(final int[] shapeSizePx, final float[] pixPerShape) { + public final float[] getPixelPerShapeUnit(final int[] shapeSizePx, final float[] pixPerShape) { pixPerShape[0] = shapeSizePx[0] / getScaledWidth(); pixPerShape[0] = shapeSizePx[1] / getScaledHeight(); return pixPerShape; @@ -1005,7 +1101,7 @@ public abstract class Shape { * <p> * The given {@link PMVMatrix4f} has to be setup properly for this object, * i.e. its {@link GLMatrixFunc#GL_PROJECTION} and {@link GLMatrixFunc#GL_MODELVIEW} for the surrounding scene - * including this shape's {@link #setTransformMv(PMVMatrix4f)}. See {@link #setPMVMatrix(Scene, PMVMatrix4f)}. + * including this shape's {@link #transformMvTo(PMVMatrix4f)}. See {@link #setPMVMatrix(Scene, PMVMatrix4f)}. * </p> * @param pmv well formed {@link PMVMatrix4f}, e.g. could have been setup via {@link Shape#setPMVMatrix(Scene, PMVMatrix4f)}. * @param viewport the int[4] viewport @@ -1016,7 +1112,7 @@ public abstract class Shape { * @see #getScaledWidth() * @see #getScaledHeight() */ - public float[] getPixelPerShapeUnit(final PMVMatrix4f pmv, final Recti viewport, final float[] pixPerShape) { + public final float[] getPixelPerShapeUnit(final PMVMatrix4f pmv, final Recti viewport, final float[] pixPerShape) { final int[] shapeSizePx = new int[2]; if( null != getSurfaceSize(pmv, viewport, shapeSizePx) ) { return getPixelPerShapeUnit(shapeSizePx, pixPerShape); @@ -1029,11 +1125,11 @@ public abstract class Shape { * Retrieve pixel per scaled shape-coordinate unit, i.e. [px]/[obj]. * <p> * The given {@link PMVMatrix4f} will be {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) setup} properly for this shape - * including this shape's {@link #setTransformMv(PMVMatrix4f)}. + * including this shape's {@link #transformMvTo(PMVMatrix4f)}. * </p> * @param scene {@link Scene} to retrieve {@link Scene.PMVMatrixSetup} and the viewport. * @param pmv a new {@link PMVMatrix4f} which will {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) be setup}, - * {@link #setTransformMv(PMVMatrix4f) shape-transformed} and can be reused by the caller. + * {@link #transformMvTo(PMVMatrix4f) shape-transformed} and can be reused by the caller. * @param pixPerShape float[2] pixel per scaled shape-coordinate unit result storage * @return given float[2] {@code pixPerShape} for successful {@link Matrix4f#mapObjToWin(Vec3f, Matrix4f, Recti, Vec3f) gluProject(..)} operation, otherwise {@code null} * @see #getPixelPerShapeUnit(int[], float[]) @@ -1041,7 +1137,7 @@ public abstract class Shape { * @see #getScaledWidth() * @see #getScaledHeight() */ - public float[] getPixelPerShapeUnit(final Scene scene, final PMVMatrix4f pmv, final float[] pixPerShape) { + public final float[] getPixelPerShapeUnit(final Scene scene, final PMVMatrix4f pmv, final float[] pixPerShape) { final int[] shapeSizePx = new int[2]; if( null != getSurfaceSize(scene, pmv, shapeSizePx) ) { return getPixelPerShapeUnit(shapeSizePx, pixPerShape); @@ -1055,7 +1151,7 @@ public abstract class Shape { * <p> * The given {@link PMVMatrix4f} has to be setup properly for this object, * i.e. its {@link GLMatrixFunc#GL_PROJECTION} and {@link GLMatrixFunc#GL_MODELVIEW} for the surrounding scene - * including this shape's {@link #setTransformMv(PMVMatrix4f)}. See {@link #setPMVMatrix(Scene, PMVMatrix4f)}. + * including this shape's {@link #transformMvTo(PMVMatrix4f)}. See {@link #setPMVMatrix(Scene, PMVMatrix4f)}. * </p> * @param pmv well formed {@link PMVMatrix4f}, e.g. could have been setup via {@link Shape#setPMVMatrix(Scene, PMVMatrix4f)}. * @param viewport the viewport @@ -1065,7 +1161,7 @@ public abstract class Shape { * @see #shapeToWinCoord(com.jogamp.graph.ui.Scene.PMVMatrixSetup, Recti, float[], PMVMatrix4f, int[]) * @see #shapeToWinCoord(Scene, float[], PMVMatrix4f, int[]) */ - public int[/*2*/] shapeToWinCoord(final PMVMatrix4f pmv, final Recti viewport, final Vec3f objPos, final int[/*2*/] glWinPos) { + public final int[/*2*/] shapeToWinCoord(final PMVMatrix4f pmv, final Recti viewport, final Vec3f objPos, final int[/*2*/] glWinPos) { // System.err.println("Shape::objToWinCoordgetSurfaceSize.VP "+viewport[0]+"/"+viewport[1]+" "+viewport[2]+"x"+viewport[3]); final Vec3f winCoord = new Vec3f(); @@ -1081,19 +1177,19 @@ public abstract class Shape { * Map given object coordinate relative to this shape to window coordinates. * <p> * The given {@link PMVMatrix4f} will be {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) setup} properly for this shape - * including this shape's {@link #setTransformMv(PMVMatrix4f)}. + * including this shape's {@link #transformMvTo(PMVMatrix4f)}. * </p> * @param pmvMatrixSetup {@link Scene.PMVMatrixSetup} to {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) setup} given {@link PMVMatrix4f} {@code pmv}. * @param viewport used viewport for {@link PMVMatrix4f#mapObjToWin(Vec3f, Recti, Vec3f)} * @param objPos object position relative to this shape's center * @param pmv a new {@link PMVMatrix4f} which will {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) be setup}, - * {@link #setTransformMv(PMVMatrix4f) shape-transformed} and can be reused by the caller. + * {@link #transformMvTo(PMVMatrix4f) shape-transformed} and can be reused by the caller. * @param glWinPos int[2] target window position of objPos relative to this shape * @return given int[2] {@code glWinPos} for successful {@link Matrix4f#mapObjToWin(Vec3f, Matrix4f, Recti, Vec3f) gluProject(..)} operation, otherwise {@code null} * @see #shapeToWinCoord(PMVMatrix4f, Recti, float[], int[]) * @see #shapeToWinCoord(Scene, float[], PMVMatrix4f, int[]) */ - public int[/*2*/] shapeToWinCoord(final Scene.PMVMatrixSetup pmvMatrixSetup, final Recti viewport, final Vec3f objPos, final PMVMatrix4f pmv, final int[/*2*/] glWinPos) { + public final int[/*2*/] shapeToWinCoord(final Scene.PMVMatrixSetup pmvMatrixSetup, final Recti viewport, final Vec3f objPos, final PMVMatrix4f pmv, final int[/*2*/] glWinPos) { return this.shapeToWinCoord(setPMVMatrix(pmvMatrixSetup, viewport, pmv), viewport, objPos, glWinPos); } @@ -1101,18 +1197,18 @@ public abstract class Shape { * Map given object coordinate relative to this shape to window coordinates. * <p> * The given {@link PMVMatrix4f} will be {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) setup} properly for this shape - * including this shape's {@link #setTransformMv(PMVMatrix4f)}. + * including this shape's {@link #transformMvTo(PMVMatrix4f)}. * </p> * @param scene {@link Scene} to retrieve {@link Scene.PMVMatrixSetup} and the viewport. * @param objPos object position relative to this shape's center * @param pmv a new {@link PMVMatrix4f} which will {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) be setup}, - * {@link #setTransformMv(PMVMatrix4f) shape-transformed} and can be reused by the caller. + * {@link #transformMvTo(PMVMatrix4f) shape-transformed} and can be reused by the caller. * @param glWinPos int[2] target window position of objPos relative to this shape * @return given int[2] {@code glWinPos} for successful {@link Matrix4f#mapObjToWin(Vec3f, Matrix4f, Recti, Vec3f) gluProject(..)} operation, otherwise {@code null} * @see #shapeToWinCoord(PMVMatrix4f, Recti, float[], int[]) * @see #shapeToWinCoord(com.jogamp.graph.ui.Scene.PMVMatrixSetup, Recti, float[], PMVMatrix4f, int[]) */ - public int[/*2*/] shapeToWinCoord(final Scene scene, final Vec3f objPos, final PMVMatrix4f pmv, final int[/*2*/] glWinPos) { + public final int[/*2*/] shapeToWinCoord(final Scene scene, final Vec3f objPos, final PMVMatrix4f pmv, final int[/*2*/] glWinPos) { return this.shapeToWinCoord(scene.getPMVMatrixSetup(), scene.getViewport(), objPos, pmv, glWinPos); } @@ -1121,7 +1217,7 @@ public abstract class Shape { * <p> * The given {@link PMVMatrix4f} has to be setup properly for this object, * i.e. its {@link GLMatrixFunc#GL_PROJECTION} and {@link GLMatrixFunc#GL_MODELVIEW} for the surrounding scene - * including this shape's {@link #setTransformMv(PMVMatrix4f)}. See {@link #setPMVMatrix(Scene, PMVMatrix4f)}. + * including this shape's {@link #transformMvTo(PMVMatrix4f)}. See {@link #setPMVMatrix(Scene, PMVMatrix4f)}. * </p> * @param pmv well formed {@link PMVMatrix4f}, e.g. could have been setup via {@link Shape#setPMVMatrix(Scene, PMVMatrix4f)}. * @param viewport the Rect4i viewport @@ -1134,7 +1230,7 @@ public abstract class Shape { * @see #winToShapeCoord(com.jogamp.graph.ui.Scene.PMVMatrixSetup, Recti, int, int, PMVMatrix4f, float[]) * @see #winToShapeCoord(Scene, int, int, PMVMatrix4f, float[]) */ - public Vec3f winToShapeCoord(final PMVMatrix4f pmv, final Recti viewport, final int glWinX, final int glWinY, final Vec3f objPos) { + public final Vec3f winToShapeCoord(final PMVMatrix4f pmv, final Recti viewport, final int glWinX, final int glWinY, final Vec3f objPos) { final Vec3f ctr = box.getCenter(); if( Matrix4f.mapObjToWin(ctr, pmv.getPMv(), viewport, objPos) ) { @@ -1150,14 +1246,14 @@ public abstract class Shape { * Map given gl-window-coordinates to object coordinates relative to this shape and its z-coordinate. * <p> * The given {@link PMVMatrix4f} will be {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) setup} properly for this shape - * including this shape's {@link #setTransformMv(PMVMatrix4f)}. + * including this shape's {@link #transformMvTo(PMVMatrix4f)}. * </p> * @param pmvMatrixSetup {@link Scene.PMVMatrixSetup} to {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) setup} given {@link PMVMatrix4f} {@code pmv}. * @param viewport used viewport for {@link PMVMatrix4f#mapWinToObj(float, float, float, Recti, Vec3f)} * @param glWinX in GL window coordinates, origin bottom-left * @param glWinY in GL window coordinates, origin bottom-left * @param pmv a new {@link PMVMatrix4f} which will {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) be setup}, - * {@link #setTransformMv(PMVMatrix4f) shape-transformed} and can be reused by the caller. + * {@link #transformMvTo(PMVMatrix4f) shape-transformed} and can be reused by the caller. * @param objPos target object position of glWinX/glWinY relative to this shape * @return given {@code objPos} for successful {@link Matrix4f#mapObjToWin(Vec3f, Matrix4f, Recti, Vec3f) gluProject(..)} * and {@link Matrix4f#mapWinToObj(float, float, float, float, Matrix4f, Recti, Vec3f, Vec3f) gluUnProject(..)} @@ -1165,7 +1261,7 @@ public abstract class Shape { * @see #winToShapeCoord(PMVMatrix4f, Recti, int, int, float[]) * @see #winToShapeCoord(Scene, int, int, PMVMatrix4f, float[]) */ - public Vec3f winToShapeCoord(final Scene.PMVMatrixSetup pmvMatrixSetup, final Recti viewport, final int glWinX, final int glWinY, final PMVMatrix4f pmv, final Vec3f objPos) { + public final Vec3f winToShapeCoord(final Scene.PMVMatrixSetup pmvMatrixSetup, final Recti viewport, final int glWinX, final int glWinY, final PMVMatrix4f pmv, final Vec3f objPos) { return this.winToShapeCoord(setPMVMatrix(pmvMatrixSetup, viewport, pmv), viewport, glWinX, glWinY, objPos); } @@ -1173,13 +1269,13 @@ public abstract class Shape { * Map given gl-window-coordinates to object coordinates relative to this shape and its z-coordinate. * <p> * The given {@link PMVMatrix4f} will be {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) setup} properly for this shape - * including this shape's {@link #setTransformMv(PMVMatrix4f)}. + * including this shape's {@link #transformMvTo(PMVMatrix4f)}. * </p> * @param scene {@link Scene} to retrieve {@link Scene.PMVMatrixSetup} and the viewport. * @param glWinX in GL window coordinates, origin bottom-left * @param glWinY in GL window coordinates, origin bottom-left * @param pmv a new {@link PMVMatrix4f} which will {@link Scene.PMVMatrixSetup#set(PMVMatrix4f, Recti) be setup}, - * {@link #setTransformMv(PMVMatrix4f) shape-transformed} and can be reused by the caller. + * {@link #transformMvTo(PMVMatrix4f) shape-transformed} and can be reused by the caller. * @param objPos target object position of glWinX/glWinY relative to this shape * @return given {@code objPos} for successful {@link Matrix4f#mapObjToWin(Vec3f, Matrix4f, Recti, Vec3f) gluProject(..)} * and {@link Matrix4f#mapWinToObj(float, float, float, float, Matrix4f, Recti, Vec3f, Vec3f) gluUnProject(..)} diff --git a/src/graphui/classes/com/jogamp/graph/ui/layout/BoxLayout.java b/src/graphui/classes/com/jogamp/graph/ui/layout/BoxLayout.java index bed4b33eb..bd939f37e 100644 --- a/src/graphui/classes/com/jogamp/graph/ui/layout/BoxLayout.java +++ b/src/graphui/classes/com/jogamp/graph/ui/layout/BoxLayout.java @@ -182,7 +182,7 @@ public class BoxLayout implements Group.Layout { // measure size pmv.pushMv(); - s.setTransformMv(pmv); + s.applyMatToMv(pmv); s.getBounds().transform(pmv.getMv(), sbox); pmv.popMv(); diff --git a/src/graphui/classes/com/jogamp/graph/ui/layout/GridLayout.java b/src/graphui/classes/com/jogamp/graph/ui/layout/GridLayout.java index 43358529a..e77f51aad 100644 --- a/src/graphui/classes/com/jogamp/graph/ui/layout/GridLayout.java +++ b/src/graphui/classes/com/jogamp/graph/ui/layout/GridLayout.java @@ -208,7 +208,7 @@ public class GridLayout implements Group.Layout { final Shape s = shapes.get(i); // measure size pmv.pushMv(); - s.setTransformMv(pmv); + s.applyMatToMv(pmv); final AABBox sbox = s.getBounds().transform(pmv.getMv(), new AABBox()); pmv.popMv(); diff --git a/src/jogl/classes/com/jogamp/math/Quaternion.java b/src/jogl/classes/com/jogamp/math/Quaternion.java index 690c1b8dc..683c1fadc 100644 --- a/src/jogl/classes/com/jogamp/math/Quaternion.java +++ b/src/jogl/classes/com/jogamp/math/Quaternion.java @@ -65,6 +65,8 @@ public class Quaternion { set(x, y, z, w); } + public Quaternion copy() { return new Quaternion(this); } + /** * See {@link #magnitude()} for special handling of {@link FloatUtil#EPSILON epsilon}, * which is not applied here. |