diff options
author | Sven Gothel <[email protected]> | 2014-03-15 05:47:01 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-03-15 05:47:01 +0100 |
commit | e4641e304fbc64a5d185a39c6ca6357cc678e013 (patch) | |
tree | 002f2597b7462f8a510adc3adcd37bafb8d5c1a2 | |
parent | e2ceb1af352ec73967f2c15341d10fa3069b0a84 (diff) |
Bug 801: Outline/OutlineShape tranform and sort fixes ; Quaternion: Reduce muls in rotateVector
Quaternion:
- rotateVector(..): Reduce multiplication count by 17
Graph:
- Outline
- add: transform
- fix compareTo .. use EPSILON
- OutlineShape
- add transform
- fix compareTo .. use EPSILON
- use Comparator<Outline> in sortOutlines
to avoid reversal of list
- Extract OutlineShapeXForm, pairing { OutlineShape, AffineTransform }
11 files changed, 125 insertions, 61 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java index cb99fbfa4..0d3a61fac 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java +++ b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java @@ -29,12 +29,16 @@ package com.jogamp.graph.curve; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; + +import jogamp.graph.geom.plane.AffineTransform; import com.jogamp.graph.curve.tess.Triangulation; import com.jogamp.graph.curve.tess.Triangulator; import com.jogamp.graph.geom.Outline; import com.jogamp.graph.geom.Triangle; import com.jogamp.graph.geom.Vertex; +import com.jogamp.opengl.math.FloatUtil; import com.jogamp.opengl.math.VectorUtil; import com.jogamp.opengl.math.geom.AABBox; @@ -643,29 +647,51 @@ public class OutlineShape implements Comparable<OutlineShape> { return triangles; } - /** Sort the outlines from large - * to small depending on the AABox + /** + * Return a transformed instance with all {@link Outline}s are copied and transformed. + * <p> + * Note: Triangulated data is lost in returned instance! + * </p> + */ + public OutlineShape transform(AffineTransform t) { + final OutlineShape newOutlineShape = new OutlineShape(vertexFactory); + final int osize = outlines.size(); + for(int i=0; i<osize; i++) { + newOutlineShape.addOutline( outlines.get(i).transform(t) ); + } + return newOutlineShape; + } + + /** + * Sort the outlines from large + * to small depending on the AABox */ private void sortOutlines() { - Collections.sort(outlines); - Collections.reverse(outlines); + Collections.sort(outlines, reversSizeComparator); } + private static Comparator<Outline> reversSizeComparator = new Comparator<Outline>() { + @Override + public int compare(Outline o1, Outline o2) { + return o2.compareTo(o1); // reverse ! + } }; + /** - * Compare two outline shapes with Bounding Box area - * as criteria. + * Compare two outline shape's Bounding Box size. + * @see AABBox#getSize() * @see java.lang.Comparable#compareTo(java.lang.Object) */ @Override public final int compareTo(final OutlineShape other) { final float thisSize = getBounds().getSize(); final float otherSize = other.getBounds().getSize(); - if( thisSize < otherSize ){ + if( FloatUtil.equals(thisSize, otherSize, FloatUtil.EPSILON) ) { + return 0; + } else if( thisSize < otherSize ){ return -1; - } else if( thisSize > otherSize ) { + } else { return 1; } - return 0; // FIXME: No epsilon, i.e. smallest accurate float value ? } private void validateBoundingBox() { diff --git a/src/jogl/classes/com/jogamp/graph/curve/OutlineShapeXForm.java b/src/jogl/classes/com/jogamp/graph/curve/OutlineShapeXForm.java new file mode 100644 index 000000000..b1c99f5ed --- /dev/null +++ b/src/jogl/classes/com/jogamp/graph/curve/OutlineShapeXForm.java @@ -0,0 +1,13 @@ +package com.jogamp.graph.curve; + +import jogamp.graph.geom.plane.AffineTransform; + +public class OutlineShapeXForm { + public final OutlineShape shape; + public final AffineTransform t; + + public OutlineShapeXForm(final OutlineShape shape, final AffineTransform t) { + this.shape = shape; + this.t = t; + } +}
\ No newline at end of file diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java index bff7c905f..741121343 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java @@ -74,7 +74,7 @@ public abstract class RegionRenderer { gl.glEnable(GL.GL_BLEND); gl.glBlendEquation(GL.GL_FUNC_ADD); // default gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); - renderer.rs.setHintBits(RenderState.BITHINT_BLENDING_ENABLED); + renderer.rs.setHintMask(RenderState.BITHINT_BLENDING_ENABLED); } }; @@ -90,7 +90,7 @@ public abstract class RegionRenderer { public static final GLCallback defaultBlendDisable = new GLCallback() { @Override public void run(final GL gl, final RegionRenderer renderer) { - renderer.rs.clearHintBits(RenderState.BITHINT_BLENDING_ENABLED); + renderer.rs.clearHintMask(RenderState.BITHINT_BLENDING_ENABLED); gl.glDisable(GL.GL_BLEND); } }; diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java index d6eac19de..490af140a 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java @@ -44,10 +44,10 @@ public abstract class RenderState { private static final String thisKey = "jogamp.graph.curve.RenderState" ; /** - * Bitfield hint, {@link #isHintBitSet(int) if set} + * Bitfield hint, {@link #isHintMaskSet(int) if set} * stating <i>enabled</i> {@link GL#GL_BLEND}, otherwise <i>disabled</i>. * <p> - * Shall be set via {@link #setHintBits(int)} and cleared via {@link #clearHintBits(int)}. + * Shall be set via {@link #setHintMask(int)} and cleared via {@link #clearHintMask(int)}. * </p> * <p> * Due to alpha blending and multipass rendering, e.g. {@link Region#VBAA_RENDERING_BIT}, @@ -94,13 +94,13 @@ public abstract class RenderState { public final PMVMatrix pmvMatrix() { return pmvMatrix; } public final GLUniformData getPMVMatrix() { return gcu_PMVMatrix; } - public final boolean isHintBitSet(int mask) { + public final boolean isHintMaskSet(int mask) { return mask == ( hintBitfield & mask ); } - public final void setHintBits(int mask) { + public final void setHintMask(int mask) { hintBitfield |= mask; } - public final void clearHintBits(int mask) { + public final void clearHintMask(int mask) { hintBitfield &= ~mask; } diff --git a/src/jogl/classes/com/jogamp/graph/geom/Outline.java b/src/jogl/classes/com/jogamp/graph/geom/Outline.java index 2d9d74966..b299524c0 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/Outline.java +++ b/src/jogl/classes/com/jogamp/graph/geom/Outline.java @@ -29,7 +29,10 @@ package com.jogamp.graph.geom; import java.util.ArrayList; +import jogamp.graph.geom.plane.AffineTransform; + import com.jogamp.graph.geom.Vertex; +import com.jogamp.opengl.math.FloatUtil; import com.jogamp.opengl.math.VectorUtil; import com.jogamp.opengl.math.geom.AABBox; @@ -181,21 +184,18 @@ public class Outline implements Cloneable, Comparable<Outline> { return false; } - /** Compare two outlines with Bounding Box area - * as criteria. - * @see java.lang.Comparable#compareTo(java.lang.Object) + /** + * Return a transformed instance with all vertices are copied and transformed. */ - @Override - public final int compareTo(Outline outline) { - float size = getBounds().getSize(); - float newSize = outline.getBounds().getSize(); - if(size < newSize){ - return -1; - } - else if(size > newSize){ - return 1; + public final Outline transform(AffineTransform t) { + final Outline newOutline = new Outline(); + final int vsize = vertices.size(); + for(int i=0; i<vsize; i++) { + final Vertex v = vertices.get(i); + newOutline.addVertex(t.transform(v, null)); } - return 0; + newOutline.closed = this.closed; + return newOutline; } private final void validateBoundingBox() { @@ -214,6 +214,24 @@ public class Outline implements Cloneable, Comparable<Outline> { } /** + * Compare two outline's Bounding Box size. + * @see AABBox#getSize() + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + @Override + public final int compareTo(final Outline other) { + final float thisSize = getBounds().getSize(); + final float otherSize = other.getBounds().getSize(); + if( FloatUtil.equals(thisSize, otherSize, FloatUtil.EPSILON) ) { + return 0; + } else if(thisSize < otherSize){ + return -1; + } else { + return 1; + } + } + + /** * @param obj the Object to compare this Outline with * @return true if {@code obj} is an Outline, not null, equals bounds and equal vertices in the same order */ diff --git a/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java b/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java index ab419e3cd..56d270380 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java +++ b/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java @@ -380,18 +380,31 @@ public class Quaternion { final float vecX = vecIn[0+vecInOffset]; final float vecY = vecIn[1+vecInOffset]; final float vecZ = vecIn[2+vecInOffset]; - vecOut[0+vecOutOffset] = w * w * vecX + 2f * y * w * vecZ - - 2f * z * w * vecY + x * x * vecX - + 2f * y * x * vecY + 2f * z * x * vecZ - - z * z * vecX - y * y * vecX; - vecOut[1+vecOutOffset] = 2f * x * y * vecX + y * y * vecY - + 2f * z * y * vecZ + 2f * w * z * vecX - - z * z * vecY + w * w * vecY - - 2f * x * w * vecZ - x * x * vecY; - vecOut[2+vecOutOffset] = 2f * x * z * vecX + 2f * y * z * vecY - + z * z * vecZ - 2f * w * y * vecX - - y * y * vecZ + 2f * w * x * vecY - - x * x * vecZ + w * w * vecZ; + final float x_x = x*x; + final float y_y = y*y; + final float z_z = z*z; + final float w_w = w*w; + + vecOut[0+vecOutOffset] = w_w * vecX + + x_x * vecX + - z_z * vecX + - y_y * vecX + + 2f * ( y*w*vecZ - z*w*vecY + y*x*vecY + z*x*vecZ ); + ; + + vecOut[1+vecOutOffset] = y_y * vecY + - z_z * vecY + + w_w * vecY + - x_x * vecY + + 2f * ( x*y*vecX + z*y*vecZ + w*z*vecX - x*w*vecZ ); + ; + + vecOut[2+vecOutOffset] = z_z * vecZ + - y_y * vecZ + - x_x * vecZ + + w_w * vecZ + + 2f * ( x*z*vecX + y*z*vecY - w*y*vecX + w*x*vecY ); + ; } return vecOut; } diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java index 4fceb4f2b..7fcb9a848 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java @@ -215,7 +215,7 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB final PMVMatrix pmv = renderer.getMatrix(); renderer.resetModelview(null); renderer.setColorStatic(gl, 0.0f, 0.0f, 0.0f); - if( renderer.getRenderState().isHintBitSet(RenderState.BITHINT_BLENDING_ENABLED) ) { + if( renderer.getRenderState().isHintMaskSet(RenderState.BITHINT_BLENDING_ENABLED) ) { gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); } final float pixelSizeFName = font.getPixelSize(fontSizeFName, dpiH); @@ -238,7 +238,7 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB final String modeS = Region.getRenderModeString(renderer.getRenderModes()); final String text = String.format("%03.1f/%03.1f fps, v-sync %d, fontSize [head %.1f, bottom %.1f], %s-samples [%d, this %d], td %4.1f, blend %b, alpha-bits %d", lfps, tfps, gl.getSwapInterval(), fontSizeHead, fontSizeBottom, modeS, getSampleCount()[0], sampleCountFPS[0], td, - renderer.getRenderState().isHintBitSet(RenderState.BITHINT_BLENDING_ENABLED), + renderer.getRenderState().isHintMaskSet(RenderState.BITHINT_BLENDING_ENABLED), drawable.getChosenGLCapabilities().getAlphaBits()); // bottom, half line up @@ -279,7 +279,7 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB renderer.translate(null, getXTran(), getYTran(), getZTran()); renderer.rotate(gl, getAngle(), 0, 1, 0); renderer.setColorStatic(gl, 1.0f, 0.0f, 0.0f); - if( renderer.getRenderState().isHintBitSet(RenderState.BITHINT_BLENDING_ENABLED) ) { + if( renderer.getRenderState().isHintMaskSet(RenderState.BITHINT_BLENDING_ENABLED) ) { gl.glClearColor(1.0f, 0.0f, 0.0f, 0.0f); } diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneGLListener0A.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneGLListener0A.java index 6804fdab1..c377bb71c 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneGLListener0A.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneGLListener0A.java @@ -328,7 +328,7 @@ public class GPUUISceneGLListener0A implements GLEventListener { final String modeS = Region.getRenderModeString(renderer.getRenderModes()); final String text = String.format("%03.1f/%03.1f fps, v-sync %d, fontSize %.1f, %s-samples %d, td %4.1f, blend %b, alpha-bits %d", lfps, tfps, gl.getSwapInterval(), fontSizeFixed, modeS, sampleCount[0], td, - renderer.getRenderState().isHintBitSet(RenderState.BITHINT_BLENDING_ENABLED), + renderer.getRenderState().isHintMaskSet(RenderState.BITHINT_BLENDING_ENABLED), drawable.getChosenGLCapabilities().getAlphaBits()); if(null != fpsLabel) { fpsLabel.clear(gl, renderer); diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java index 243be4e68..4d79e5ad7 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java @@ -32,6 +32,7 @@ import javax.media.opengl.GL2ES2; import jogamp.graph.geom.plane.AffineTransform; import com.jogamp.graph.curve.OutlineShape; +import com.jogamp.graph.curve.OutlineShapeXForm; import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.graph.curve.opengl.TextRegionUtil; import com.jogamp.graph.font.Font; @@ -94,7 +95,7 @@ public class Label extends UIShape { final float[] tmp = new float[3]; @Override public void visit(OutlineShape shape, AffineTransform t) { - shapes.add(new TransformedShape(shape, new AffineTransform(t))); + shapes.add(new OutlineShapeXForm(shape, new AffineTransform(t))); final AABBox sbox = shape.getBounds(); t.transform(sbox.getLow(), tmp); box.resize(tmp, 0); diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/RIButton.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/RIButton.java index 0e49d1bee..c1f984519 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/RIButton.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/RIButton.java @@ -30,6 +30,7 @@ package com.jogamp.opengl.test.junit.graph.demos.ui; import javax.media.opengl.GL2ES2; import com.jogamp.graph.curve.OutlineShape; +import com.jogamp.graph.curve.OutlineShapeXForm; import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.graph.font.Font; import com.jogamp.graph.geom.Vertex; @@ -135,7 +136,7 @@ public abstract class RIButton extends UIShape { label.locTranslate( ( box.getWidth() - lbox1.getWidth() ) / 1f, -1f * ( box.getHeight() - lbox1.getHeight() ) / 1f ); - shapes.add(new TransformedShape(shape, null)); + shapes.add(new OutlineShapeXForm(shape, null)); System.err.println("XXX.UIShape.RIButton: Added Shape: "+shape+", "+box); } private void createSharpOutline(OutlineShape shape, AABBox lbox) { diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShape.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShape.java index 4db7da3ac..768c95765 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShape.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShape.java @@ -35,6 +35,7 @@ import jogamp.graph.geom.plane.AffineTransform; import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.curve.Region; +import com.jogamp.graph.curve.OutlineShapeXForm; import com.jogamp.graph.curve.opengl.GLRegion; import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.graph.curve.opengl.RenderState; @@ -45,16 +46,7 @@ import com.jogamp.opengl.math.geom.AABBox; public abstract class UIShape { private final Factory<? extends Vertex> vertexFactory; - public class TransformedShape { - public final OutlineShape shape; - public final AffineTransform t; - - public TransformedShape(final OutlineShape shape, final AffineTransform t) { - this.shape = shape; - this.t = t; - } - } - protected final ArrayList<TransformedShape> shapes; + protected final ArrayList<OutlineShapeXForm> shapes; protected static final int DIRTY_SHAPE = 1 << 0 ; protected static final int DIRTY_POSITION = 1 << 1 ; @@ -76,7 +68,7 @@ public abstract class UIShape { public UIShape(Factory<? extends Vertex> factory) { this.vertexFactory = factory; - this.shapes = new ArrayList<TransformedShape>(); + this.shapes = new ArrayList<OutlineShapeXForm>(); this.box = new AABBox(); } @@ -151,7 +143,7 @@ public abstract class UIShape { return 0 != ( dirty & DIRTY_REGION ) ; } - public ArrayList<TransformedShape> getShapes() { return shapes; } + public ArrayList<OutlineShapeXForm> getShapes() { return shapes; } public final AABBox getBounds() { return box; } @@ -186,7 +178,7 @@ public abstract class UIShape { _color = selectedColor; } if(!select){ - if( renderer.getRenderState().isHintBitSet(RenderState.BITHINT_BLENDING_ENABLED) ) { + if( renderer.getRenderState().isHintMaskSet(RenderState.BITHINT_BLENDING_ENABLED) ) { gl.glClearColor(_color[0], _color[1], _color[2], 0.0f); } renderer.setColorStatic(gl, _color[0], _color[1], _color[2]); @@ -249,7 +241,7 @@ public abstract class UIShape { } final int shapeCount = shapes.size(); for(int i=0; i<shapeCount; i++) { - final TransformedShape tshape = shapes.get(i); + final OutlineShapeXForm tshape = shapes.get(i); final AffineTransform t2; if( null != tshape.t ) { if( null != t ) { |