diff options
author | Sven Gothel <[email protected]> | 2023-04-18 05:15:16 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2023-04-18 05:15:16 +0200 |
commit | c65c750e032118f229050ff8e834961264ed0591 (patch) | |
tree | 8500286ca6086eb21a9b275ccd586185090b1500 /src/jogl/classes/com | |
parent | cd845589eea6c7773007e013bd5f2f37242cbe1a (diff) |
Graph + GraphUI: Consolidate Vertex: Drop SVertex and factory, use Vec[234]f instead of float[] and remove unused VectorUtil methods
After Matrix4f consolidation and proving same or better performance on non array types,
this enhances code readability, simplifies API, reduces bugs and may improve performance.
GraphUI:
- Have RoundButton as a functional class to make a round or rectangular backdrop,
i.e. impl. addShapeToRegion() via reused addRoundShapeToRegion()
Diffstat (limited to 'src/jogl/classes/com')
15 files changed, 438 insertions, 956 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java index 9b71865f6..30987ec7e 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java +++ b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java @@ -34,14 +34,15 @@ import java.util.Comparator; 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.SVertex; import com.jogamp.graph.geom.Triangle; import com.jogamp.graph.geom.Vertex; import com.jogamp.graph.geom.plane.AffineTransform; import com.jogamp.graph.geom.plane.Path2F; import com.jogamp.graph.geom.plane.Winding; import com.jogamp.opengl.math.FloatUtil; +import com.jogamp.opengl.math.Vec3f; import com.jogamp.opengl.math.VectorUtil; +import com.jogamp.opengl.math.Vert2fImmutable; import com.jogamp.opengl.math.geom.AABBox; /** @@ -142,8 +143,6 @@ public final class OutlineShape implements Comparable<OutlineShape> { */ public static final int DIRTY_TRIANGLES = 1 << 2; - private final Vertex.Factory<? extends Vertex> vertexFactory; - /** The list of {@link Outline}s that are part of this * outline shape. */ @@ -161,25 +160,14 @@ public final class OutlineShape implements Comparable<OutlineShape> { private float sharpness; - private final float[] tmpV1 = new float[3]; - private final float[] tmpV2 = new float[3]; - private final float[] tmpV3 = new float[3]; - - /** Returns the default Vertex.Factory. */ - public static Vertex.Factory<? extends Vertex> getDefaultVertexFactory() { return SVertex.factory(); } - - /** - * Create a new Outline based Shape using {@link #getDefaultVertexFactory()} - */ - public OutlineShape() { - this(getDefaultVertexFactory()); - } + private final Vec3f tmpV1 = new Vec3f(); + private final Vec3f tmpV2 = new Vec3f(); + private final Vec3f tmpV3 = new Vec3f(); /** * Create a new Outline based Shape */ - public OutlineShape(final Vertex.Factory<? extends Vertex> factory) { - this.vertexFactory = factory; + public OutlineShape() { this.outlines = new ArrayList<Outline>(3); this.outlines.add(new Outline()); this.outlineState = VerticesState.UNDEFINED; @@ -230,12 +218,6 @@ public final class OutlineShape implements Comparable<OutlineShape> { dirtyBits |= DIRTY_TRIANGLES | DIRTY_VERTICES; } - /** - * Returns the associated vertex factory of this outline shape - * @return Vertex.Factory object - */ - public final Vertex.Factory<? extends Vertex> vertexFactory() { return vertexFactory; } - /** Returns the number of {@link Outline}s. */ public final int getOutlineCount() { return outlines.size(); @@ -437,7 +419,7 @@ public final class OutlineShape implements Comparable<OutlineShape> { * @see <a href="#windingrules">see winding rules</a> */ public final void addVertex(final float x, final float y, final boolean onCurve) { - addVertex(vertexFactory.create(x, y, 0f, onCurve)); + addVertex(new Vertex(x, y, 0f, onCurve)); } /** @@ -451,7 +433,7 @@ public final class OutlineShape implements Comparable<OutlineShape> { * @see <a href="#windingrules">see winding rules</a> */ public final void addVertex(final int position, final float x, final float y, final boolean onCurve) { - addVertex(position, vertexFactory.create(x, y, 0f, onCurve)); + addVertex(position, new Vertex(x, y, 0f, onCurve)); } /** @@ -464,7 +446,7 @@ public final class OutlineShape implements Comparable<OutlineShape> { * @see <a href="#windingrules">see winding rules</a> */ public final void addVertex(final float x, final float y, final float z, final boolean onCurve) { - addVertex(vertexFactory.create(x, y, z, onCurve)); + addVertex(new Vertex(x, y, z, onCurve)); } /** @@ -478,7 +460,7 @@ public final class OutlineShape implements Comparable<OutlineShape> { * @see <a href="#windingrules">see winding rules</a> */ public final void addVertex(final int position, final float x, final float y, final float z, final boolean onCurve) { - addVertex(position, vertexFactory.create(x, y, z, onCurve)); + addVertex(position, new Vertex(x, y, z, onCurve)); } /** @@ -495,7 +477,7 @@ public final class OutlineShape implements Comparable<OutlineShape> { * @see <a href="#windingrules">see winding rules</a> */ public final void addVertex(final float[] coordsBuffer, final int offset, final int length, final boolean onCurve) { - addVertex(vertexFactory.create(coordsBuffer, offset, length, onCurve)); + addVertex(new Vertex(coordsBuffer, offset, length, onCurve)); } /** @@ -513,7 +495,7 @@ public final class OutlineShape implements Comparable<OutlineShape> { * @see <a href="#windingrules">see winding rules</a> */ public final void addVertex(final int position, final float[] coordsBuffer, final int offset, final int length, final boolean onCurve) { - addVertex(position, vertexFactory.create(coordsBuffer, offset, length, onCurve)); + addVertex(position, new Vertex(coordsBuffer, offset, length, onCurve)); } /** @@ -578,9 +560,9 @@ public final class OutlineShape implements Comparable<OutlineShape> { } { // Skip if last vertex in last outline matching this point -> already connected. - final float[] llc = lo.getVertex(lo_sz-1).getCoord(); - if( llc[0] == points[idx+0] && - llc[1] == points[idx+1] ) { + final Vert2fImmutable llc = lo.getVertex(lo_sz-1); + if( llc.x() == points[idx+0] && + llc.y() == points[idx+1] ) { break; } } @@ -652,9 +634,9 @@ public final class OutlineShape implements Comparable<OutlineShape> { } { // Skip if last vertex in last outline matching this point -> already connected. - final float[] llc = lo.getVertex(0).getCoord(); - if( llc[0] == points[idx+0] && - llc[1] == points[idx+1] ) { + final Vert2fImmutable llc = lo.getVertex(0); + if( llc.x() == points[idx+0] && + llc.y() == points[idx+1] ) { break; } } @@ -790,11 +772,11 @@ public final class OutlineShape implements Comparable<OutlineShape> { VectorUtil.midVec3(tmpV2, tmpV1, tmpV3); //drop off-curve vertex to image on the curve - b.setCoord(tmpV2, 0, 3); + b.setCoord(tmpV2); b.setOnCurve(true); - outline.addVertex(index, vertexFactory.create(tmpV1, 0, 3, false)); - outline.addVertex(index+2, vertexFactory.create(tmpV3, 0, 3, false)); + outline.addVertex(index, new Vertex(tmpV1, false)); + outline.addVertex(index+2, new Vertex(tmpV3, false)); addedVerticeCount += 2; } @@ -934,7 +916,7 @@ public final class OutlineShape implements Comparable<OutlineShape> { if ( !currentVertex.isOnCurve() && !nextVertex.isOnCurve() ) { VectorUtil.midVec3(tmpV1, currentVertex.getCoord(), nextVertex.getCoord()); System.err.println("XXX: Cubic: "+i+": "+currentVertex+", "+j+": "+nextVertex); - final Vertex v = vertexFactory.create(tmpV1, 0, 3, true); + final Vertex v = new Vertex(tmpV1, true); i++; vertexCount++; addedVerticeCount++; @@ -946,8 +928,8 @@ public final class OutlineShape implements Comparable<OutlineShape> { outlines.remove(outline); cc--; count--; - } else if( 0 < vertexCount && - VectorUtil.isVec3Equal( outline.getVertex(0).getCoord(), 0, outline.getLastVertex().getCoord(), 0, FloatUtil.EPSILON )) { + } else if( 0 < vertexCount && + outline.getVertex(0).getCoord().isEqual( outline.getLastVertex().getCoord() ) ) { outline.removeVertex(vertexCount-1); } } @@ -1047,10 +1029,10 @@ public final class OutlineShape implements Comparable<OutlineShape> { * </p> */ public final OutlineShape transform(final AffineTransform t) { - final OutlineShape newOutlineShape = new OutlineShape(vertexFactory); + final OutlineShape newOutlineShape = new OutlineShape(); final int osize = outlines.size(); for(int i=0; i<osize; i++) { - newOutlineShape.addOutline( outlines.get(i).transform(t, vertexFactory) ); + newOutlineShape.addOutline( outlines.get(i).transform(t) ); } return newOutlineShape; } diff --git a/src/jogl/classes/com/jogamp/graph/curve/Region.java b/src/jogl/classes/com/jogamp/graph/curve/Region.java index b3cee629c..799b8b7bd 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/Region.java +++ b/src/jogl/classes/com/jogamp/graph/curve/Region.java @@ -47,6 +47,8 @@ import com.jogamp.common.util.PerfCounterCtrl; import com.jogamp.graph.curve.opengl.GLRegion; import com.jogamp.opengl.GLCapabilitiesImmutable; import com.jogamp.opengl.GLProfile; +import com.jogamp.opengl.math.Vec3f; +import com.jogamp.opengl.math.Vec4f; import com.jogamp.opengl.math.geom.AABBox; import com.jogamp.opengl.math.geom.Frustum; import com.jogamp.opengl.util.texture.TextureSequence; @@ -256,9 +258,9 @@ public abstract class Region { */ public abstract void setBufferCapacity(int verticesCount, int indicesCount); - protected abstract void pushVertex(final float[] coords, final float[] texParams, float[] rgba); - protected abstract void pushVertices(final float[] coords1, final float[] coords2, final float[] coords3, - final float[] texParams1, final float[] texParams2, final float[] texParams3, float[] rgba); + protected abstract void pushVertex(final Vec3f coords, final Vec3f texParams, Vec4f rgba); + protected abstract void pushVertices(final Vec3f coords1, final Vec3f coords2, final Vec3f coords3, + final Vec3f texParams1, final Vec3f texParams2, final Vec3f texParams3, Vec4f rgba); protected abstract void pushIndex(int idx); protected abstract void pushIndices(int idx1, int idx2, int idx3); @@ -336,12 +338,9 @@ public abstract class Region { this.frustum = frustum; } - private void pushNewVertexImpl(final Vertex vertIn, final AffineTransform transform, final float[] rgba) { + private void pushNewVertexImpl(final Vertex vertIn, final AffineTransform transform, final Vec4f rgba) { if( null != transform ) { - final float[] coordsEx1 = new float[3]; - final float[] coordsIn = vertIn.getCoord(); - transform.transform(coordsIn, coordsEx1); - coordsEx1[2] = coordsIn[2]; + final Vec3f coordsEx1 = transform.transform(vertIn.getCoord(), new Vec3f()); box.resize(coordsEx1); pushVertex(coordsEx1, vertIn.getTexCoord(), rgba); } else { @@ -351,20 +350,11 @@ public abstract class Region { numVertices++; } - private void pushNewVerticesImpl(final Vertex vertIn1, final Vertex vertIn2, final Vertex vertIn3, final AffineTransform transform, final float[] rgba) { + private void pushNewVerticesImpl(final Vertex vertIn1, final Vertex vertIn2, final Vertex vertIn3, final AffineTransform transform, final Vec4f rgba) { if( null != transform ) { - final float[] coordsEx1 = new float[3]; - final float[] coordsEx2 = new float[3]; - final float[] coordsEx3 = new float[3]; - final float[] coordsIn1 = vertIn1.getCoord(); - final float[] coordsIn2 = vertIn2.getCoord(); - final float[] coordsIn3 = vertIn3.getCoord(); - transform.transform(coordsIn1, coordsEx1); - transform.transform(coordsIn2, coordsEx2); - transform.transform(coordsIn3, coordsEx3); - coordsEx1[2] = coordsIn1[2]; - coordsEx2[2] = coordsIn2[2]; - coordsEx3[2] = coordsIn3[2]; + final Vec3f coordsEx1 = transform.transform(vertIn1.getCoord(), new Vec3f()); + final Vec3f coordsEx2 = transform.transform(vertIn2.getCoord(), new Vec3f()); + final Vec3f coordsEx3 = transform.transform(vertIn3.getCoord(), new Vec3f()); box.resize(coordsEx1); box.resize(coordsEx2); box.resize(coordsEx3); @@ -381,11 +371,11 @@ public abstract class Region { } @SuppressWarnings("unused") - private void pushNewVertexIdxImpl(final Vertex vertIn, final AffineTransform transform, final float[] rgba) { + private void pushNewVertexIdxImpl(final Vertex vertIn, final AffineTransform transform, final Vec4f rgba) { pushIndex(numVertices); pushNewVertexImpl(vertIn, transform, rgba); } - private void pushNewVerticesIdxImpl(final Vertex vertIn1, final Vertex vertIn2, final Vertex vertIn3, final AffineTransform transform, final float[] rgba) { + private void pushNewVerticesIdxImpl(final Vertex vertIn1, final Vertex vertIn2, final Vertex vertIn3, final AffineTransform transform, final Vec4f rgba) { pushIndices(numVertices, numVertices+1, numVertices+2); pushNewVerticesImpl(vertIn1, vertIn2, vertIn3, transform, rgba); } @@ -396,12 +386,15 @@ public abstract class Region { protected static void put3s(final ShortBuffer b, final short v1, final short v2, final short v3) { b.put(v1); b.put(v2); b.put(v3); } - protected static void put3f(final FloatBuffer b, final float v1, final float v2, final float v3) { - b.put(v1); b.put(v2); b.put(v3); + protected static void put3f(final FloatBuffer b, final Vec3f v) { + b.put(v.x()); b.put(v.y()); b.put(v.z()); } protected static void put4f(final FloatBuffer b, final float v1, final float v2, final float v3, final float v4) { b.put(v1); b.put(v2); b.put(v3); b.put(v4); } + protected static void put4f(final FloatBuffer b, final Vec4f v) { + b.put(v.x()); b.put(v.y()); b.put(v.z()); b.put(v.w()); + } private final AABBox tmpBox = new AABBox(); @@ -529,7 +522,7 @@ public abstract class Region { * @param t the optional {@link AffineTransform} to be applied on each vertex * @param rgbaColor if {@link #hasColorChannel()} RGBA color must be passed, otherwise value is ignored. */ - public final void addOutlineShape(final OutlineShape shape, final AffineTransform t, final float[] rgbaColor) { + public final void addOutlineShape(final OutlineShape shape, final AffineTransform t, final Vec4f rgbaColor) { if( null != frustum ) { final AABBox shapeBox = shape.getBounds(); final AABBox shapeBoxT; @@ -550,7 +543,7 @@ public abstract class Region { } markShapeDirty(); } - private final void addOutlineShape0(final OutlineShape shape, final AffineTransform t, final float[] rgbaColor) { + private final void addOutlineShape0(final OutlineShape shape, final AffineTransform t, final Vec4f rgbaColor) { final List<Triangle> trisIn = shape.getTriangles(OutlineShape.VerticesState.QUADRATIC_NURBS); final ArrayList<Vertex> vertsIn = shape.getVertices(); { @@ -587,7 +580,7 @@ public abstract class Region { } } } - private final void addOutlineShape1(final OutlineShape shape, final AffineTransform t, final float[] rgbaColor) { + private final void addOutlineShape1(final OutlineShape shape, final AffineTransform t, final Vec4f rgbaColor) { ++perf.count; final long t0 = Clock.currentNanos(); final List<Triangle> trisIn = shape.getTriangles(OutlineShape.VerticesState.QUADRATIC_NURBS); @@ -682,7 +675,7 @@ public abstract class Region { * @param t the optional {@link AffineTransform} to be applied on each vertex * @param rgbaColor if {@link #hasColorChannel()} RGBA color must be passed, otherwise value is ignored. */ - public final void addOutlineShapes(final List<OutlineShape> shapes, final AffineTransform transform, final float[] rgbaColor) { + public final void addOutlineShapes(final List<OutlineShape> shapes, final AffineTransform transform, final Vec4f rgbaColor) { for (int i = 0; i < shapes.size(); i++) { addOutlineShape(shapes.get(i), transform, rgbaColor); } 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 2f518d1cc..89a48e0c8 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java @@ -33,6 +33,7 @@ import com.jogamp.opengl.GL; import com.jogamp.opengl.GL2ES2; import com.jogamp.opengl.GLException; import com.jogamp.opengl.GLUniformData; +import com.jogamp.opengl.math.Vec4f; import jogamp.common.os.PlatformPropsImpl; import jogamp.graph.curve.opengl.shader.UniformNames; @@ -241,13 +242,14 @@ public class RenderState { weight[0] = v; } - - public final float[] getColorStatic(final float[] rgbaColor) { - System.arraycopy(colorStatic, 0, rgbaColor, 0, 4); - return rgbaColor; + public final Vec4f getColorStatic(final Vec4f rgbaColor) { + return rgbaColor.set(colorStatic); } - public final void setColorStatic(final float[] rgbaColor){ - System.arraycopy(rgbaColor, 0, colorStatic, 0, 4); + public final void setColorStatic(final Vec4f rgbaColor){ + colorStatic[0] = rgbaColor.x(); + colorStatic[1] = rgbaColor.y(); + colorStatic[2] = rgbaColor.z(); + colorStatic[3] = rgbaColor.w(); } public final void setColorStatic(final float r, final float g, final float b, final float a){ colorStatic[0] = r; diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java index 237d93184..6beb11be1 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java @@ -33,6 +33,7 @@ import java.util.Iterator; import com.jogamp.opengl.GL2ES2; import com.jogamp.opengl.GLException; +import com.jogamp.opengl.math.Vec4f; import com.jogamp.opengl.math.geom.AABBox; import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.curve.Region; @@ -82,7 +83,7 @@ public class TextRegionUtil { * @return the bounding box of the given string by taking each glyph's font em-sized [0..1] OutlineShape into account. */ public static AABBox addStringToRegion(final Region region, final Font font, final AffineTransform transform, - final CharSequence str, final float[] rgbaColor) { + final CharSequence str, final Vec4f rgbaColor) { return addStringToRegion(region, font, transform, str, rgbaColor, new AffineTransform(), new AffineTransform()); } @@ -105,7 +106,7 @@ public class TextRegionUtil { * @return the bounding box of the given string by taking each glyph's font em-sized [0..1] OutlineShape into account. */ public static AABBox addStringToRegion(final Region region, final Font font, final AffineTransform transform, - final CharSequence str, final float[] rgbaColor, + final CharSequence str, final Vec4f rgbaColor, final AffineTransform temp1, final AffineTransform temp2) { final Font.GlyphVisitor visitor = new Font.GlyphVisitor() { @Override @@ -113,7 +114,7 @@ public class TextRegionUtil { if( glyph.isWhiteSpace() ) { return; } - region.addOutlineShape(glyph.getShape(), t, region.hasColorChannel() ? rgbaColor : null); + region.addOutlineShape(glyph.getShape(), t, rgbaColor); } }; return font.processString(visitor, transform, str, temp1, temp2); @@ -167,7 +168,7 @@ public class TextRegionUtil { */ public AABBox drawString3D(final GL2ES2 gl, final RegionRenderer renderer, final Font font, final CharSequence str, - final float[] rgbaColor, final int[/*1*/] sampleCount) { + final Vec4f rgbaColor, final int[/*1*/] sampleCount) { if( !renderer.isInitialized() ) { throw new GLException("TextRendererImpl01: not initialized!"); } @@ -193,7 +194,7 @@ public class TextRegionUtil { */ public static AABBox drawString3D(final GL2ES2 gl, final int renderModes, final RegionRenderer renderer, final Font font, final CharSequence str, - final float[] rgbaColor, final int[/*1*/] sampleCount) { + final Vec4f rgbaColor, final int[/*1*/] sampleCount) { return drawString3D(gl, renderModes, renderer, font, str, rgbaColor, sampleCount, new AffineTransform(), new AffineTransform()); } @@ -228,7 +229,7 @@ public class TextRegionUtil { */ public static AABBox drawString3D(final GL2ES2 gl, final int renderModes, final RegionRenderer renderer, final Font font, final CharSequence str, - final float[] rgbaColor, final int[/*1*/] sampleCount, final AffineTransform tmp1, final AffineTransform tmp2) { + final Vec4f rgbaColor, final int[/*1*/] sampleCount, final AffineTransform tmp1, final AffineTransform tmp2) { if(!renderer.isInitialized()){ throw new GLException("TextRendererImpl01: not initialized!"); } @@ -246,7 +247,7 @@ public class TextRegionUtil { * </p> */ public static AABBox drawString3D(final GL2ES2 gl, final GLRegion region, final RegionRenderer renderer, - final Font font, final CharSequence str, final float[] rgbaColor, final int[/*1*/] sampleCount) { + final Font font, final CharSequence str, final Vec4f rgbaColor, final int[/*1*/] sampleCount) { return drawString3D(gl, region, renderer, font, str, rgbaColor, sampleCount, new AffineTransform(), new AffineTransform()); } @@ -278,7 +279,7 @@ public class TextRegionUtil { * @throws Exception if TextRenderer not initialized */ public static AABBox drawString3D(final GL2ES2 gl, final GLRegion region, final RegionRenderer renderer, - final Font font, final CharSequence str, final float[] rgbaColor, + final Font font, final CharSequence str, final Vec4f rgbaColor, final int[/*1*/] sampleCount, final AffineTransform tmp1, final AffineTransform tmp2) { if(!renderer.isInitialized()){ throw new GLException("TextRendererImpl01: not initialized!"); diff --git a/src/jogl/classes/com/jogamp/graph/geom/Outline.java b/src/jogl/classes/com/jogamp/graph/geom/Outline.java index bd25aeccc..a0999baa1 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/Outline.java +++ b/src/jogl/classes/com/jogamp/graph/geom/Outline.java @@ -1,5 +1,5 @@ /** - * Copyright 2010 JogAmp Community. All rights reserved. + * Copyright 2010-2023 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -268,7 +268,7 @@ public class Outline implements Comparable<Outline> { if( !isEmpty() ) { final Vertex first = vertices.get(0); final Vertex last = getLastVertex(); - if( !VectorUtil.isVec3Equal( first.getCoord(), 0, last.getCoord(), 0, FloatUtil.EPSILON ) ) { + if( !first.getCoord().isEqual( last.getCoord() ) ) { if( closeTail ) { vertices.add(first.clone()); } else { @@ -283,12 +283,12 @@ public class Outline implements Comparable<Outline> { /** * Return a transformed instance with all vertices are copied and transformed. */ - public final Outline transform(final AffineTransform t, final Vertex.Factory<? extends Vertex> vertexFactory) { + public final Outline transform(final 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, vertexFactory.create())); + newOutline.addVertex(t.transform(v, new Vertex())); } newOutline.closed = this.closed; return newOutline; diff --git a/src/jogl/classes/com/jogamp/graph/geom/SVertex.java b/src/jogl/classes/com/jogamp/graph/geom/SVertex.java deleted file mode 100644 index dc6982025..000000000 --- a/src/jogl/classes/com/jogamp/graph/geom/SVertex.java +++ /dev/null @@ -1,224 +0,0 @@ -/** - * Copyright 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ -package com.jogamp.graph.geom; - -import com.jogamp.opengl.math.FloatUtil; -import com.jogamp.opengl.math.VectorUtil; - -/** A Simple Vertex Implementation. Where the coordinates, and other attributes are - * float based, and the coordinates and texture coordinates are saved in two float arrays. - * - */ -public class SVertex implements Vertex { - private int id; - protected boolean onCurve; - protected final float[] coord = new float[3]; - private final float[] texCoord = new float[3]; - - static final Factory factory = new Factory(); - - public static Factory factory() { return factory; } - - public static class Factory implements Vertex.Factory<SVertex> { - @Override - public SVertex create() { - return new SVertex(); - } - - public SVertex create(final Vertex src) { - return new SVertex(src); - } - - @Override - public SVertex create(final int id, final boolean onCurve, final float[] texCoordsBuffer) { - return new SVertex(id, onCurve, texCoordsBuffer); - } - - @Override - public SVertex create(final float x, final float y, final float z, final boolean onCurve) { - return new SVertex(x, y, z, onCurve); - } - - @Override - public SVertex create(final float[] coordsBuffer, final int offset, final int length, final boolean onCurve) { - return new SVertex(coordsBuffer, offset, length, onCurve); - } - } - - public SVertex() { - this.id = Integer.MAX_VALUE; - } - - public SVertex(final Vertex src) { - this.id = Integer.MAX_VALUE; - System.arraycopy(src.getCoord(), 0, coord, 0, 3); - System.arraycopy(src.getTexCoord(), 0, texCoord, 0, 3); - setOnCurve(src.isOnCurve()); - } - - public SVertex(final int id, final boolean onCurve, final float[] texCoordsBuffer) { - this.id = id; - this.onCurve = onCurve; - System.arraycopy(texCoordsBuffer, 0, texCoord, 0, 3); - } - - public SVertex(final float x, final float y, final float z, final boolean onCurve) { - this.id = Integer.MAX_VALUE; - setCoord(x, y, z); - setOnCurve(onCurve); - } - - public SVertex(final float[] coordsBuffer, final int offset, final int length, final boolean onCurve) { - this.id = Integer.MAX_VALUE; - setCoord(coordsBuffer, offset, length); - setOnCurve(onCurve); - } - - @Override - public final void setCoord(final float x, final float y, final float z) { - coord[0] = x; - coord[1] = y; - coord[2] = z; - } - - @Override - public final void setCoord(final float[] coordsBuffer, final int offset, final int length) { - System.arraycopy(coordsBuffer, offset, coord, 0, length); - } - - @Override - public int getCoordCount() { - return 3; - } - - @Override - public final float[] getCoord() { - return coord; - } - - @Override - public final void setX(final float x) { - this.coord[0] = x; - } - - @Override - public final void setY(final float y) { - this.coord[1] = y; - } - - @Override - public final void setZ(final float z) { - this.coord[2] = z; - } - - @Override - public final float getX() { - return this.coord[0]; - } - - @Override - public final float getY() { - return this.coord[1]; - } - - @Override - public final float getZ() { - return this.coord[2]; - } - - @Override - public final boolean isOnCurve() { - return onCurve; - } - - @Override - public final void setOnCurve(final boolean onCurve) { - this.onCurve = onCurve; - } - - @Override - public final int getId(){ - return id; - } - - @Override - public final void setId(final int id){ - this.id = id; - } - - @Override - public boolean equals(final Object obj) { - if( obj == this) { - return true; - } - if( null == obj || !(obj instanceof Vertex) ) { - return false; - } - final Vertex v = (Vertex) obj; - return this == v || - isOnCurve() == v.isOnCurve() && - VectorUtil.isVec3Equal(getTexCoord(), 0, v.getTexCoord(), 0, FloatUtil.EPSILON) && - VectorUtil.isVec3Equal(getCoord(), 0, v.getCoord(), 0, FloatUtil.EPSILON) ; - } - @Override - public final int hashCode() { - throw new InternalError("hashCode not designed"); - } - - @Override - public final float[] getTexCoord() { - return texCoord; - } - - @Override - public final void setTexCoord(final float s, final float t, final float p) { - texCoord[0] = s; - texCoord[1] = t; - texCoord[2] = p; - } - - @Override - public final void setTexCoord(final float[] texCoordsBuffer, final int offset, final int length) { - System.arraycopy(texCoordsBuffer, offset, texCoord, 0, length); - } - - /** - * @return deep clone of this Vertex elements - */ - @Override - public SVertex clone(){ - return new SVertex(this); // OK to not call super.clone(), using own copy-ctor - } - - @Override - public String toString() { - return "[ID: " + id + ", onCurve: " + onCurve + - ": p " + coord[0] + ", " + coord[1] + ", " + coord[2] + - ", t " + texCoord[0] + ", " + texCoord[1] + ", " + texCoord[2] + "]"; - } -} diff --git a/src/jogl/classes/com/jogamp/graph/geom/Triangle.java b/src/jogl/classes/com/jogamp/graph/geom/Triangle.java index 1c63c4005..6b07501a6 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/Triangle.java +++ b/src/jogl/classes/com/jogamp/graph/geom/Triangle.java @@ -64,11 +64,11 @@ public class Triangle { /** * Returns a transformed a clone of this instance using the given AffineTransform. */ - public Triangle transform(final AffineTransform t, final Vertex.Factory<? extends Vertex> vertexFactory) { + public Triangle transform(final AffineTransform t) { final Triangle tri = new Triangle(id, boundaryEdges, boundaryVertices); - tri.vertices[0] = t.transform(vertices[0], vertexFactory.create()); - tri.vertices[1] = t.transform(vertices[1], vertexFactory.create()); - tri.vertices[2] = t.transform(vertices[2], vertexFactory.create()); + tri.vertices[0] = t.transform(vertices[0], new Vertex()); + tri.vertices[1] = t.transform(vertices[1], new Vertex()); + tri.vertices[2] = t.transform(vertices[2], new Vertex()); return tri; } @@ -83,9 +83,9 @@ public class Triangle { * Returns true if all vertices are lines, i.e. zero tex-coord, otherwise false. */ public final boolean isLine() { - return VectorUtil.isVec2Zero(vertices[0].getTexCoord(), 0) && - VectorUtil.isVec2Zero(vertices[1].getTexCoord(), 0) && - VectorUtil.isVec2Zero(vertices[2].getTexCoord(), 0) ; + return VectorUtil.isVec2Zero(vertices[0].getTexCoord()) && + VectorUtil.isVec2Zero(vertices[1].getTexCoord()) && + VectorUtil.isVec2Zero(vertices[2].getTexCoord()) ; } public int getId() { diff --git a/src/jogl/classes/com/jogamp/graph/geom/Vertex.java b/src/jogl/classes/com/jogamp/graph/geom/Vertex.java index e9c8dd193..e5fe76c28 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/Vertex.java +++ b/src/jogl/classes/com/jogamp/graph/geom/Vertex.java @@ -1,5 +1,5 @@ /** - * Copyright 2011 JogAmp Community. All rights reserved. + * Copyright 2011-2023 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -27,64 +27,185 @@ */ package com.jogamp.graph.geom; +import com.jogamp.opengl.math.Vec2f; +import com.jogamp.opengl.math.Vec3f; import com.jogamp.opengl.math.Vert3fImmutable; /** - * A Vertex with custom memory layout using custom factory. + * A Vertex exposing Vec3f vertex- and texture-coordinates. */ -public interface Vertex extends Vert3fImmutable, Cloneable { +public final class Vertex implements Vert3fImmutable, Cloneable { + private int id; + private boolean onCurve; + private final Vec3f coord = new Vec3f(); + private final Vec3f texCoord = new Vec3f(); + + public Vertex() { + this.id = Integer.MAX_VALUE; + } - public static interface Factory <T extends Vertex> { - T create(); + public Vertex(final Vertex src) { + this.id = Integer.MAX_VALUE; + coord.set(src.getCoord()); + texCoord.set(src.getTexCoord()); + setOnCurve(src.isOnCurve()); + } - T create(Vertex src); + public Vertex(final int id, final boolean onCurve, final Vec3f texCoord) { + this.id = id; + this.onCurve = onCurve; + this.texCoord.set(texCoord); + } - T create(int id, boolean onCurve, float[] texCoordsBuffer); + public Vertex(final int id, final boolean onCurve, final float texCoordX, final float texCoordY, final float texCoordZ) { + this.id = id; + this.onCurve = onCurve; + this.texCoord.set(texCoordX, texCoordY, texCoordZ); + } - T create(float x, float y, float z, boolean onCurve); + public Vertex(final Vec3f coord, final boolean onCurve) { + this.id = Integer.MAX_VALUE; + this.coord.set(coord); + setOnCurve(onCurve); + } - T create(float[] coordsBuffer, int offset, int length, boolean onCurve); + public Vertex(final Vec2f coord, final boolean onCurve) { + this.id = Integer.MAX_VALUE; + this.coord.set(coord, 0f); + setOnCurve(onCurve); } - void setCoord(float x, float y, float z); + public Vertex(final float x, final float y, final boolean onCurve) { + this(x, y, 0, onCurve); + } - /** - * @see System#arraycopy(Object, int, Object, int, int) for thrown IndexOutOfBoundsException - */ - void setCoord(float[] coordsBuffer, int offset, int length); + public Vertex(final float[] coordsBuffer, final int offset, final int length, final boolean onCurve) { + this(coordsBuffer[offset+0], coordsBuffer[offset+1], 2 < length ? coordsBuffer[offset+2] : 0f, onCurve); + } - void setX(float x); + public Vertex(final float x, final float y, final float z, final boolean onCurve) { + this.id = Integer.MAX_VALUE; + coord.set(x, y, z); + setOnCurve(onCurve); + } - void setY(float y); + public final void setCoord(final Vec3f coord) { + this.coord.set(coord); + } - void setZ(float z); + public void setCoord(final Vec2f coord) { + this.coord.set(coord, 0f); + } + + public final void setCoord(final float x, final float y, final float z) { + coord.set(x, y, z); + } - boolean isOnCurve(); + public final void setCoord(final float x, final float y) { + coord.set(x, y, 0f); + } - void setOnCurve(boolean onCurve); + @Override + public int getCoordCount() { + return 3; + } - int getId(); + @Override + public final Vec3f getCoord() { + return coord; + } - void setId(int id); + public final void setX(final float x) { + coord.setX(x); + } - float[] getTexCoord(); + public final void setY(final float y) { + coord.setY(y); + } - void setTexCoord(float s, float t, float p); + public final void setZ(final float z) { + coord.setZ(z); + } - /** - * @see System#arraycopy(Object, int, Object, int, int) for thrown IndexOutOfBoundsException - */ - void setTexCoord(float[] texCoordsBuffer, int offset, int length); + @Override + public final float x() { + return coord.x(); + } + + @Override + public final float y() { + return coord.y(); + } + + @Override + public final float z() { + return coord.z(); + } + + public final boolean isOnCurve() { + return onCurve; + } + + public final void setOnCurve(final boolean onCurve) { + this.onCurve = onCurve; + } + + public final int getId(){ + return id; + } + + public final void setId(final int id){ + this.id = id; + } /** * @param obj the Object to compare this Vertex with * @return true if {@code obj} is a Vertex and not null, on-curve flag is equal and has same vertex- and tex-coords. */ @Override - boolean equals(Object obj); + public boolean equals(final Object obj) { + if( obj == this) { + return true; + } + if( null == obj || !(obj instanceof Vertex) ) { + return false; + } + final Vertex v = (Vertex) obj; + return this == v || + isOnCurve() == v.isOnCurve() && + getTexCoord().isEqual( v.getTexCoord() ) && + getCoord().isEqual( v.getCoord() ); + } + + @Override + public final int hashCode() { + throw new InternalError("hashCode not designed"); + } + + public final Vec3f getTexCoord() { + return texCoord; + } + + public final void setTexCoord(final Vec3f v) { + texCoord.set(v); + } + + public final void setTexCoord(final float s, final float t, final float p) { + texCoord.set(s, t, p); + } /** - * @return deep clone of this Vertex + * @return deep clone of this Vertex elements */ - Vertex clone(); + @Override + public Vertex clone(){ + return new Vertex(this); // OK to not call super.clone(), using own copy-ctor + } + + @Override + public String toString() { + return "[ID: " + id + ", onCurve: " + onCurve + + ": p " + coord + + ", t " + texCoord + "]"; + } } diff --git a/src/jogl/classes/com/jogamp/graph/geom/plane/AffineTransform.java b/src/jogl/classes/com/jogamp/graph/geom/plane/AffineTransform.java index 74036f97d..434746240 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/plane/AffineTransform.java +++ b/src/jogl/classes/com/jogamp/graph/geom/plane/AffineTransform.java @@ -420,9 +420,9 @@ public class AffineTransform implements Cloneable { * @return dst for chaining */ public final Vertex transform(final Vertex src, final Vertex dst) { - final float x = src.getX(); - final float y = src.getY(); - dst.setCoord(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12, src.getZ()); + final float x = src.x(); + final float y = src.y(); + dst.setCoord(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12, src.z()); return dst; } @@ -433,9 +433,9 @@ public class AffineTransform implements Cloneable { if (dstPoint == null) { throw new IllegalArgumentException("dst["+dstOff+"] is null"); } - final float x = srcPoint.getX(); - final float y = srcPoint.getY(); - dstPoint.setCoord(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12, srcPoint.getZ()); + final float x = srcPoint.x(); + final float y = srcPoint.y(); + dstPoint.setCoord(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12, srcPoint.z()); dst[dstOff++] = dstPoint; } } @@ -511,9 +511,9 @@ public class AffineTransform implements Cloneable { * @return return dst for chaining */ public final Vertex deltaTransform(final Vertex src, final Vertex dst) { - final float x = src.getX(); - final float y = src.getY(); - dst.setCoord(x * m00 + y * m01, x * m10 + y * m11, src.getZ()); + final float x = src.x(); + final float y = src.y(); + dst.setCoord(x * m00 + y * m01, x * m10 + y * m11, src.z()); return dst; } @@ -538,9 +538,9 @@ public class AffineTransform implements Cloneable { if (FloatUtil.abs(det) < ZERO) { throw new NoninvertibleTransformException(determinantIsZero); } - final float x = src.getX() - m02; - final float y = src.getY() - m12; - dst.setCoord((x * m11 - y * m01) / det, (y * m00 - x * m10) / det, src.getZ()); + final float x = src.x() - m02; + final float y = src.y() - m12; + dst.setCoord((x * m11 - y * m01) / det, (y * m00 - x * m10) / det, src.z()); return dst; } diff --git a/src/jogl/classes/com/jogamp/opengl/math/Vec2f.java b/src/jogl/classes/com/jogamp/opengl/math/Vec2f.java index 616ba0f60..20628d949 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Vec2f.java +++ b/src/jogl/classes/com/jogamp/opengl/math/Vec2f.java @@ -126,6 +126,13 @@ public final class Vec2f { return new Vec2f(this).scale(val); } + /** this = a * b, returns this. */ + public Vec2f mul(final Vec2f a, final Vec2f b) { + x = a.x * b.x; + y = a.y * b.y; + return this; + } + /** this = this * s, returns this. */ public Vec2f scale(final float s) { x *= s; @@ -145,6 +152,13 @@ public final class Vec2f { return new Vec2f(this).add(arg); } + /** this = a + b, returns this. */ + public Vec2f plus(final Vec2f a, final Vec2f b) { + x = a.x + b.x; + y = a.y + b.y; + return this; + } + /** this = this + { dx, dy }, returns this. */ public Vec2f add(final float dx, final float dy) { x += dx; @@ -159,23 +173,18 @@ public final class Vec2f { return this; } - /** Returns this + s * arg; creates new vector */ - public Vec2f plusScaled(final float s, final Vec2f arg) { - return new Vec2f(this).addScaled(s, arg); - } - - /** this = this + s * b, returns this. */ - public Vec2f addScaled(final float s, final Vec2f b) { - x += s * b.x; - y += s * b.y; - return this; - } - /** Returns this - arg; creates new vector */ public Vec2f minus(final Vec2f arg) { return new Vec2f(this).sub(arg); } + /** this = a - b, returns this. */ + public Vec2f minus(final Vec2f a, final Vec2f b) { + x = a.x - b.x; + y = a.y - b.y; + return this; + } + /** this = this - b, returns this. */ public Vec2f sub(final Vec2f b) { x -= b.x; diff --git a/src/jogl/classes/com/jogamp/opengl/math/Vec3f.java b/src/jogl/classes/com/jogamp/opengl/math/Vec3f.java index 9ef985b36..fbcd1e9a5 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Vec3f.java +++ b/src/jogl/classes/com/jogamp/opengl/math/Vec3f.java @@ -35,11 +35,11 @@ package com.jogamp.opengl.math; * and its data layout from JOAL's Vec3f. */ public final class Vec3f { - public static final Vec3f ONE = new Vec3f(VectorUtil.VEC3_ONE); - public static final Vec3f UNIT_Y = new Vec3f(VectorUtil.VEC3_UNIT_Y); - public static final Vec3f UNIT_Y_NEG = new Vec3f(VectorUtil.VEC3_UNIT_Y_NEG); - public static final Vec3f UNIT_Z = new Vec3f(VectorUtil.VEC3_UNIT_Z); - public static final Vec3f UNIT_Z_NEG = new Vec3f(VectorUtil.VEC3_UNIT_Z_NEG); + public static final Vec3f ONE = new Vec3f(1f, 1f, 1f); + public static final Vec3f UNIT_Y = new Vec3f(0f, 1f, 0f); + public static final Vec3f UNIT_Y_NEG = new Vec3f(0f, -1f, 0f); + public static final Vec3f UNIT_Z = new Vec3f(0f, 0f, 1f); + public static final Vec3f UNIT_Z_NEG = new Vec3f(0f, 0f, -1f); private float x; private float y; @@ -154,6 +154,14 @@ public final class Vec3f { return new Vec3f(this).scale(val); } + /** this = a * b, returns this. */ + public Vec3f mul(final Vec3f a, final Vec3f b) { + x = a.x * b.x; + y = a.y * b.y; + z = a.z * b.z; + return this; + } + /** this = this * s, returns this. */ public Vec3f scale(final float s) { x *= s; @@ -175,6 +183,14 @@ public final class Vec3f { return new Vec3f(this).add(arg); } + /** this = a + b, returns this. */ + public Vec3f plus(final Vec3f a, final Vec3f b) { + x = a.x + b.x; + y = a.y + b.y; + z = a.z + b.z; + return this; + } + /** this = this + { dx, dy, dz }, returns this. */ public Vec3f add(final float dx, final float dy, final float dz) { x += dx; @@ -191,24 +207,19 @@ public final class Vec3f { return this; } - /** Returns this + s * arg; creates new vector */ - public Vec3f plusScaled(final float s, final Vec3f arg) { - return new Vec3f(this).addScaled(s, arg); - } - - /** this = this + s * b, returns this. */ - public Vec3f addScaled(final float s, final Vec3f b) { - x += s * b.x; - y += s * b.y; - z += s * b.z; - return this; - } - /** Returns this - arg; creates new vector */ public Vec3f minus(final Vec3f arg) { return new Vec3f(this).sub(arg); } + /** this = a - b, returns this. */ + public Vec3f minus(final Vec3f a, final Vec3f b) { + x = a.x - b.x; + y = a.y - b.y; + z = a.z - b.z; + return this; + } + /** this = this - b, returns this. */ public Vec3f sub(final Vec3f b) { x -= b.x; diff --git a/src/jogl/classes/com/jogamp/opengl/math/Vec4f.java b/src/jogl/classes/com/jogamp/opengl/math/Vec4f.java index 570b7b2b3..254566ae0 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Vec4f.java +++ b/src/jogl/classes/com/jogamp/opengl/math/Vec4f.java @@ -145,6 +145,15 @@ public final class Vec4f { return new Vec4f(this).scale(val); } + /** this = a * b, returns this. */ + public Vec4f mul(final Vec4f a, final Vec4f b) { + x = a.x * b.x; + y = a.y * b.y; + z = a.z * b.z; + w = a.w * b.w; + return this; + } + /** this = this * s, returns this. */ public Vec4f scale(final float s) { x *= s; @@ -168,6 +177,15 @@ public final class Vec4f { return new Vec4f(this).add(arg); } + /** this = a + b, returns this. */ + public Vec4f plus(final Vec4f a, final Vec4f b) { + x = a.x + b.x; + y = a.y + b.y; + z = a.z + b.z; + w = a.w + b.w; + return this; + } + /** this = this + { dx, dy, dz, dw }, returns this. */ public Vec4f add(final float dx, final float dy, final float dz, final float dw) { x += dx; @@ -191,6 +209,15 @@ public final class Vec4f { return new Vec4f(this).sub(arg); } + /** this = a - b, returns this. */ + public Vec4f minus(final Vec4f a, final Vec4f b) { + x = a.x - b.x; + y = a.y - b.y; + z = a.z - b.z; + w = a.w - b.w; + return this; + } + /** this = this - b, returns this. */ public Vec4f sub(final Vec4f b) { x -= b.x; diff --git a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java index 8edbd0cd7..2bf468435 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java @@ -32,144 +32,11 @@ import java.util.ArrayList; import com.jogamp.graph.geom.plane.Winding; public final class VectorUtil { - - public static final float[] VEC3_ONE = { 1f, 1f, 1f }; - public static final float[] VEC3_UNIT_Y = { 0f, 1f, 0f }; - public static final float[] VEC3_UNIT_Y_NEG = { 0f, -1f, 0f }; - public static final float[] VEC3_UNIT_Z = { 0f, 0f, 1f }; - public static final float[] VEC3_UNIT_Z_NEG = { 0f, 0f, -1f }; - - /** - * Copies a vector of length 2 - * @param dst output vector - * @param dstOffset offset of dst in array - * @param src input vector - * @param srcOffset offset of src in array - * @return copied output vector for chaining - */ - public static float[] copyVec2(final float[] dst, final int dstOffset, final float[] src, final int srcOffset) - { - System.arraycopy(src, srcOffset, dst, dstOffset, 2); - return dst; - } - - /** - * Copies a vector of length 3 - * @param dst output vector - * @param dstOffset offset of dst in array - * @param src input vector - * @param srcOffset offset of src in array - * @return copied output vector for chaining - */ - public static float[] copyVec3(final float[] dst, final int dstOffset, final float[] src, final int srcOffset) - { - System.arraycopy(src, srcOffset, dst, dstOffset, 3); - return dst; - } - - /** - * Copies a vector of length 4 - * @param dst output vector - * @param dstOffset offset of dst in array - * @param src input vector - * @param srcOffset offset of src in array - * @return copied output vector for chaining - */ - public static float[] copyVec4(final float[] dst, final int dstOffset, final float[] src, final int srcOffset) - { - System.arraycopy(src, srcOffset, dst, dstOffset, 4); - return dst; - } - /** - * Return true if both vectors are equal w/o regarding an epsilon. - * <p> - * Implementation uses {@link FloatUtil#isEqual(float, float)}, see API doc for details. - * </p> + * Return true if 2D vector components are zero, no {@link FloatUtil#EPSILON} is taken into consideration. */ - public static boolean isVec2Equal(final float[] vec1, final int vec1Offset, final float[] vec2, final int vec2Offset) { - return FloatUtil.isEqual(vec1[0+vec1Offset], vec2[0+vec2Offset]) && - FloatUtil.isEqual(vec1[1+vec1Offset], vec2[1+vec2Offset]) ; - } - - /** - * Return true if both vectors are equal w/o regarding an epsilon. - * <p> - * Implementation uses {@link FloatUtil#isEqual(float, float)}, see API doc for details. - * </p> - */ - public static boolean isVec3Equal(final float[] vec1, final int vec1Offset, final float[] vec2, final int vec2Offset) { - return FloatUtil.isEqual(vec1[0+vec1Offset], vec2[0+vec2Offset]) && - FloatUtil.isEqual(vec1[1+vec1Offset], vec2[1+vec2Offset]) && - FloatUtil.isEqual(vec1[2+vec1Offset], vec2[2+vec2Offset]) ; - } - - /** - * Return true if both vectors are equal, i.e. their absolute delta < <code>epsilon</code>. - * <p> - * Implementation uses {@link FloatUtil#isEqual(float, float, float)}, see API doc for details. - * </p> - */ - public static boolean isVec2Equal(final float[] vec1, final int vec1Offset, final float[] vec2, final int vec2Offset, final float epsilon) { - return FloatUtil.isEqual(vec1[0+vec1Offset], vec2[0+vec2Offset], epsilon) && - FloatUtil.isEqual(vec1[1+vec1Offset], vec2[1+vec2Offset], epsilon) ; - } - - /** - * Return true if both vectors are equal, i.e. their absolute delta < <code>epsilon</code>. - * <p> - * Implementation uses {@link FloatUtil#isEqual(float, float, float)}, see API doc for details. - * </p> - */ - public static boolean isVec3Equal(final float[] vec1, final int vec1Offset, final float[] vec2, final int vec2Offset, final float epsilon) { - return FloatUtil.isEqual(vec1[0+vec1Offset], vec2[0+vec2Offset], epsilon) && - FloatUtil.isEqual(vec1[1+vec1Offset], vec2[1+vec2Offset], epsilon) && - FloatUtil.isEqual(vec1[2+vec1Offset], vec2[2+vec2Offset], epsilon) ; - } - - /** - * Return true if vector is zero, no {@link FloatUtil#EPSILON} is taken into consideration. - */ - public static boolean isVec2Zero(final float[] vec, final int vecOffset) { - return 0f == vec[0+vecOffset] && 0f == vec[1+vecOffset]; - } - - /** - * Return true if vector is zero, no {@link FloatUtil#EPSILON} is taken into consideration. - */ - public static boolean isVec3Zero(final float[] vec, final int vecOffset) { - return 0f == vec[0+vecOffset] && 0f == vec[1+vecOffset] && 0f == vec[2+vecOffset]; - } - - /** - * Return true if vector is zero, i.e. it's absolute components < <code>epsilon</code>. - * <p> - * Implementation uses {@link FloatUtil#isZero(float, float)}, see API doc for details. - * </p> - */ - public static boolean isVec2Zero(final float[] vec, final int vecOffset, final float epsilon) { - return isZero(vec[0+vecOffset], vec[1+vecOffset], epsilon); - } - - /** - * Return true if vector is zero, i.e. it's absolute components < <code>epsilon</code>. - * <p> - * Implementation uses {@link FloatUtil#isZero(float, float)}, see API doc for details. - * </p> - */ - public static boolean isVec3Zero(final float[] vec, final int vecOffset, final float epsilon) { - return isZero(vec[0+vecOffset], vec[1+vecOffset], vec[2+vecOffset], epsilon); - } - - /** - * Return true if all two vector components are zero, i.e. it's their absolute value < <code>epsilon</code>. - * <p> - * Implementation uses {@link FloatUtil#isZero(float, float)}, see API doc for details. - * </p> - */ - public static boolean isZero(final float x, final float y, final float epsilon) { - return FloatUtil.isZero(x, epsilon) && - FloatUtil.isZero(y, epsilon) ; + public static boolean isVec2Zero(final Vec3f vec) { + return 0f == vec.x() && 0f == vec.y(); } /** @@ -206,34 +73,6 @@ public final class VectorUtil { } /** - * Return the dot product of two points - * @param vec1 vector 1 - * @param vec2 vector 2 - * @return the dot product as float - */ - public static float dotVec3(final float[] vec1, final float[] vec2) { - return vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2]; - } - - /** - * Return the cosines of the angle between to vectors - * @param vec1 vector 1 - * @param vec2 vector 2 - */ - public static float cosAngleVec3(final float[] vec1, final float[] vec2) { - return dotVec3(vec1, vec2) / ( normVec3(vec1) * normVec3(vec2) ) ; - } - - /** - * Return the angle between to vectors in radians - * @param vec1 vector 1 - * @param vec2 vector 2 - */ - public static float angleVec3(final float[] vec1, final float[] vec2) { - return FloatUtil.acos(cosAngleVec3(vec1, vec2)); - } - - /** * Return the squared length of a vector, a.k.a the squared <i>norm</i> or squared <i>magnitude</i> */ public static float normSquareVec2(final float[] vec) { @@ -243,16 +82,6 @@ public final class VectorUtil { /** * Return the squared length of a vector, a.k.a the squared <i>norm</i> or squared <i>magnitude</i> */ - public static float normSquareVec2(final float[] vec, final int offset) { - float v = vec[0+offset]; - final float r = v*v; - v = vec[1+offset]; - return r + v*v; - } - - /** - * Return the squared length of a vector, a.k.a the squared <i>norm</i> or squared <i>magnitude</i> - */ public static float normSquareVec3(final float[] vec) { return vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]; } @@ -277,73 +106,6 @@ public final class VectorUtil { } /** - * Return the length of a vector, a.k.a the <i>norm</i> or <i>magnitude</i> - */ - public static float normVec3(final float[] vec) { - return FloatUtil.sqrt(normSquareVec3(vec)); - } - - /** - * Normalize a vector - * @param result output vector, may be vector (in-place) - * @param vector input vector - * @return normalized output vector - * @return result vector for chaining - */ - public static float[] normalizeVec2(final float[] result, final float[] vector) { - final float lengthSq = normSquareVec2(vector); - if ( FloatUtil.isZero(lengthSq, FloatUtil.EPSILON) ) { - result[0] = 0f; - result[1] = 0f; - } else { - final float invSqr = 1f / FloatUtil.sqrt(lengthSq); - result[0] = vector[0] * invSqr; - result[1] = vector[1] * invSqr; - } - return result; - } - - /** - * Normalize a vector in place - * @param vector input vector - * @return normalized output vector - */ - public static float[] normalizeVec2(final float[] vector) { - final float lengthSq = normSquareVec2(vector); - if ( FloatUtil.isZero(lengthSq, FloatUtil.EPSILON) ) { - vector[0] = 0f; - vector[1] = 0f; - } else { - final float invSqr = 1f / FloatUtil.sqrt(lengthSq); - vector[0] *= invSqr; - vector[1] *= invSqr; - } - return vector; - } - - /** - * Normalize a vector - * @param result output vector, may be vector (in-place) - * @param vector input vector - * @return normalized output vector - * @return result vector for chaining - */ - public static float[] normalizeVec3(final float[] result, final float[] vector) { - final float lengthSq = normSquareVec3(vector); - if ( FloatUtil.isZero(lengthSq, FloatUtil.EPSILON) ) { - result[0] = 0f; - result[1] = 0f; - result[2] = 0f; - } else { - final float invSqr = 1f / FloatUtil.sqrt(lengthSq); - result[0] = vector[0] * invSqr; - result[1] = vector[1] * invSqr; - result[2] = vector[2] * invSqr; - } - return result; - } - - /** * Normalize a vector in place * @param vector input vector * @return normalized output vector @@ -400,35 +162,6 @@ public final class VectorUtil { * Scales a vector by param using given result float[], result = vector * scale * @param result vector for the result, may be vector (in-place) * @param vector input vector - * @param scale single scale constant for all vector components - * @return result vector for chaining - */ - public static float[] scaleVec3(final float[] result, final float[] vector, final float scale) { - result[0] = vector[0] * scale; - result[1] = vector[1] * scale; - result[2] = vector[2] * scale; - return result; - } - - /** - * Scales a vector by param using given result float[], result = vector * scale - * @param result vector for the result, may be vector (in-place) - * @param vector input vector - * @param scale 3 component scale constant for each vector component - * @return result vector for chaining - */ - public static float[] scaleVec3(final float[] result, final float[] vector, final float[] scale) - { - result[0] = vector[0] * scale[0]; - result[1] = vector[1] * scale[1]; - result[2] = vector[2] * scale[2]; - return result; - } - - /** - * Scales a vector by param using given result float[], result = vector * scale - * @param result vector for the result, may be vector (in-place) - * @param vector input vector * @param scale 2 component scale constant for each vector component * @return result vector for chaining */ @@ -456,35 +189,6 @@ public final class VectorUtil { * Divides a vector by param using given result float[], result = vector / scale * @param result vector for the result, may be vector (in-place) * @param vector input vector - * @param scale single scale constant for all vector components - * @return result vector for chaining - */ - public static float[] divVec3(final float[] result, final float[] vector, final float scale) { - result[0] = vector[0] / scale; - result[1] = vector[1] / scale; - result[2] = vector[2] / scale; - return result; - } - - /** - * Divides a vector by param using given result float[], result = vector / scale - * @param result vector for the result, may be vector (in-place) - * @param vector input vector - * @param scale 3 component scale constant for each vector component - * @return result vector for chaining - */ - public static float[] divVec3(final float[] result, final float[] vector, final float[] scale) - { - result[0] = vector[0] / scale[0]; - result[1] = vector[1] / scale[1]; - result[2] = vector[2] / scale[2]; - return result; - } - - /** - * Divides a vector by param using given result float[], result = vector / scale - * @param result vector for the result, may be vector (in-place) - * @param vector input vector * @param scale 2 component scale constant for each vector component * @return result vector for chaining */ @@ -509,20 +213,6 @@ public final class VectorUtil { } /** - * Adds two vectors, result = v1 + v2 - * @param result float[3] result vector, may be either v1 or v2 (in-place) - * @param v1 vector 1 - * @param v2 vector 2 - * @return result vector for chaining - */ - public static float[] addVec3(final float[] result, final float[] v1, final float[] v2) { - result[0] = v1[0] + v2[0]; - result[1] = v1[1] + v2[1]; - result[2] = v1[2] + v2[2]; - return result; - } - - /** * Subtracts two vectors, result = v1 - v2 * @param result float[2] result vector, may be either v1 or v2 (in-place) * @param v1 vector 1 @@ -536,34 +226,6 @@ public final class VectorUtil { } /** - * Subtracts two vectors, result = v1 - v2 - * @param result float[3] result vector, may be either v1 or v2 (in-place) - * @param v1 vector 1 - * @param v2 vector 2 - * @return result vector for chaining - */ - public static float[] subVec3(final float[] result, final float[] v1, final float[] v2) { - result[0] = v1[0] - v2[0]; - result[1] = v1[1] - v2[1]; - result[2] = v1[2] - v2[2]; - return result; - } - - /** - * cross product vec1 x vec2 - * @param v1 vector 1 - * @param v2 vector 2 - * @return the resulting vector - */ - public static float[] crossVec3(final float[] result, final float[] v1, final float[] v2) - { - result[0] = v1[1] * v2[2] - v1[2] * v2[1]; - result[1] = v1[2] * v2[0] - v1[0] * v2[2]; - result[2] = v1[0] * v2[1] - v1[1] * v2[0]; - return result; - } - - /** * cross product vec1 x vec2 * @param v1 vector 1 * @param v2 vector 2 @@ -578,55 +240,15 @@ public final class VectorUtil { } /** - * Multiplication of column-major 4x4 matrix with vector - * @param colMatrix column matrix (4x4) - * @param vec vector(x,y,z) - * @return result - */ - public static float[] mulColMat4Vec3(final float[] result, final float[] colMatrix, final float[] vec) - { - result[0] = vec[0]*colMatrix[0] + vec[1]*colMatrix[4] + vec[2]*colMatrix[8] + colMatrix[12]; - result[1] = vec[0]*colMatrix[1] + vec[1]*colMatrix[5] + vec[2]*colMatrix[9] + colMatrix[13]; - result[2] = vec[0]*colMatrix[2] + vec[1]*colMatrix[6] + vec[2]*colMatrix[10] + colMatrix[14]; - - return result; - } - - /** - * Matrix Vector multiplication - * @param rawMatrix column matrix (4x4) - * @param vec vector(x,y,z) - * @return result - */ - public static float[] mulRowMat4Vec3(final float[] result, final float[] rawMatrix, final float[] vec) - { - result[0] = vec[0]*rawMatrix[0] + vec[1]*rawMatrix[1] + vec[2]*rawMatrix[2] + rawMatrix[3]; - result[1] = vec[0]*rawMatrix[4] + vec[1]*rawMatrix[5] + vec[2]*rawMatrix[6] + rawMatrix[7]; - result[2] = vec[0]*rawMatrix[8] + vec[1]*rawMatrix[9] + vec[2]*rawMatrix[10] + rawMatrix[11]; - - return result; - } - - /** - * Calculate the midpoint of two values - * @param p1 first value - * @param p2 second vale - * @return midpoint - */ - public static float mid(final float p1, final float p2) { - return (p1+p2)*0.5f; - } - - /** * Calculate the midpoint of two points * @param p1 first point vector * @param p2 second point vector * @return midpoint */ - public static float[] midVec3(final float[] result, final float[] p1, final float[] p2) { - result[0] = (p1[0] + p2[0])*0.5f; - result[1] = (p1[1] + p2[1])*0.5f; - result[2] = (p1[2] + p2[2])*0.5f; + public static Vec3f midVec3(final Vec3f result, final Vec3f p1, final Vec3f p2) { + result.set( (p1.x() + p2.x())*0.5f, + (p1.y() + p2.y())*0.5f, + (p1.z() + p2.z())*0.5f ); return result; } @@ -637,8 +259,8 @@ public final class VectorUtil { * @param c vector 3 * @return the determinant value */ - public static float determinantVec3(final float[] a, final float[] b, final float[] c) { - return a[0]*b[1]*c[2] + a[1]*b[2]*c[0] + a[2]*b[0]*c[1] - a[0]*b[2]*c[1] - a[1]*b[0]*c[2] - a[2]*b[1]*c[0]; + public static float determinantVec3(final Vec3f a, final Vec3f b, final Vec3f c) { + return a.x()*b.y()*c.z() + a.y()*b.z()*c.x() + a.z()*b.x()*c.y() - a.x()*b.z()*c.y() - a.y()*b.x()*c.z() - a.z()*b.y()*c.x(); } /** @@ -648,7 +270,7 @@ public final class VectorUtil { * @param v3 vertex 3 * @return true if collinear, false otherwise */ - public static boolean isCollinearVec3(final float[] v1, final float[] v2, final float[] v3) { + public static boolean isCollinearVec3(final Vec3f v1, final Vec3f v2, final Vec3f v3) { return FloatUtil.isZero( determinantVec3(v1, v2, v3), FloatUtil.EPSILON ); } @@ -662,14 +284,10 @@ public final class VectorUtil { * vertices a, b, c. from paper by Guibas and Stolfi (1985). */ public static boolean isInCircleVec2(final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c, final Vert2fImmutable d) { - final float[] A = a.getCoord(); - final float[] B = b.getCoord(); - final float[] C = c.getCoord(); - final float[] D = d.getCoord(); - return (A[0] * A[0] + A[1] * A[1]) * triAreaVec2(B, C, D) - - (B[0] * B[0] + B[1] * B[1]) * triAreaVec2(A, C, D) + - (C[0] * C[0] + C[1] * C[1]) * triAreaVec2(A, B, D) - - (D[0] * D[0] + D[1] * D[1]) * triAreaVec2(A, B, C) > 0; + return (a.x() * a.x() + a.y() * a.y()) * triAreaVec2(b, c, d) - + (b.x() * b.x() + b.y() * b.y()) * triAreaVec2(a, c, d) + + (c.x() * c.x() + c.y() * c.y()) * triAreaVec2(a, b, d) - + (d.x() * d.x() + d.y() * d.y()) * triAreaVec2(a, b, c) > 0; } /** @@ -681,47 +299,34 @@ public final class VectorUtil { * is positive if the triangle is oriented counterclockwise. */ public static float triAreaVec2(final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c){ - final float[] A = a.getCoord(); - final float[] B = b.getCoord(); - final float[] C = c.getCoord(); - return (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1]) * (C[0] - A[0]); - } - - /** - * Computes oriented area of a triangle - * @param A first vertex - * @param B second vertex - * @param C third vertex - * @return compute twice the area of the oriented triangle (a,b,c), the area - * is positive if the triangle is oriented counterclockwise. - */ - public static float triAreaVec2(final float[] A, final float[] B, final float[] C){ - return (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1])*(C[0] - A[0]); + return (b.x() - a.x()) * (c.y() - a.y()) - (b.y() - a.y()) * (c.x() - a.x()); } /** - * Check if a vertex is in triangle using - * barycentric coordinates computation. + * Check if a vertex is in triangle using barycentric coordinates computation. * @param a first triangle vertex * @param b second triangle vertex * @param c third triangle vertex * @param p the vertex in question + * @param ac temporary storage + * @param ab temporary storage + * @param ap temporary storage * @return true if p is in triangle (a, b, c), false otherwise. */ - public static boolean isInTriangleVec3(final float[] a, final float[] b, final float[] c, - final float[] p, - final float[] ac, final float[] ab, final float[] ap){ + public static boolean isInTriangleVec3(final Vec3f a, final Vec3f b, final Vec3f c, + final Vec3f p, + final Vec3f ac, final Vec3f ab, final Vec3f ap){ // Compute vectors - subVec3(ac, c, a); //v0 - subVec3(ab, b, a); //v1 - subVec3(ap, p, a); //v2 + ac.minus( c, a); // v0 + ab.minus( b, a); // v1 + ap.minus( p, a); // v2 // Compute dot products - final float dotAC_AC = dotVec3(ac, ac); - final float dotAC_AB = dotVec3(ac, ab); - final float dotAB_AB = dotVec3(ab, ab); - final float dotAC_AP = dotVec3(ac, ap); - final float dotAB_AP = dotVec3(ab, ap); + final float dotAC_AC = ac.dot(ac); + final float dotAC_AB = ac.dot(ab); + final float dotAB_AB = ab.dot(ab); + final float dotAC_AP = ac.dot(ap); + final float dotAB_AP = ab.dot(ap); // Compute barycentric coordinates final float invDenom = 1 / (dotAC_AC * dotAB_AB - dotAC_AB * dotAC_AB); @@ -733,37 +338,36 @@ public final class VectorUtil { } /** - * Check if one of three vertices are in triangle using - * barycentric coordinates computation. + * Check if one of three vertices are in triangle using barycentric coordinates computation. * @param a first triangle vertex * @param b second triangle vertex * @param c third triangle vertex * @param p1 the vertex in question * @param p2 the vertex in question * @param p3 the vertex in question - * @param tmpAC - * @param tmpAB - * @param tmpAP + * @param ac temporary storage + * @param ab temporary storage + * @param ap temporary storage * @return true if p1 or p2 or p3 is in triangle (a, b, c), false otherwise. */ - public static boolean isVec3InTriangle3(final float[] a, final float[] b, final float[] c, - final float[] p1, final float[] p2, final float[] p3, - final float[] tmpAC, final float[] tmpAB, final float[] tmpAP){ + public static boolean isVec3InTriangle3(final Vec3f a, final Vec3f b, final Vec3f c, + final Vec3f p1, final Vec3f p2, final Vec3f p3, + final Vec3f ac, final Vec3f ab, final Vec3f ap){ // Compute vectors - subVec3(tmpAC, c, a); //v0 - subVec3(tmpAB, b, a); //v1 + ac.minus(c, a); // v0 + ab.minus(b, a); // v1 // Compute dot products - final float dotAC_AC = dotVec3(tmpAC, tmpAC); - final float dotAC_AB = dotVec3(tmpAC, tmpAB); - final float dotAB_AB = dotVec3(tmpAB, tmpAB); + final float dotAC_AC = ac.dot(ac); + final float dotAC_AB = ac.dot(ab); + final float dotAB_AB = ab.dot(ab); // Compute barycentric coordinates final float invDenom = 1 / (dotAC_AC * dotAB_AB - dotAC_AB * dotAC_AB); { - subVec3(tmpAP, p1, a); //v2 - final float dotAC_AP1 = dotVec3(tmpAC, tmpAP); - final float dotAB_AP1 = dotVec3(tmpAB, tmpAP); + ap.minus(p1, a); // v2 + final float dotAC_AP1 = ac.dot(ap); + final float dotAB_AP1 = ab.dot(ap); final float u = (dotAB_AB * dotAC_AP1 - dotAC_AB * dotAB_AP1) * invDenom; final float v = (dotAC_AC * dotAB_AP1 - dotAC_AB * dotAC_AP1) * invDenom; @@ -773,10 +377,11 @@ public final class VectorUtil { } } - { - subVec3(tmpAP, p1, a); //v2 - final float dotAC_AP2 = dotVec3(tmpAC, tmpAP); - final float dotAB_AP2 = dotVec3(tmpAB, tmpAP); + { // FIXME: p2? + ap.minus(p1, a); // v3 + // ap.minus(p2, a); // v2 + final float dotAC_AP2 = ac.dot(ap); + final float dotAB_AP2 = ab.dot(ap); final float u = (dotAB_AB * dotAC_AP2 - dotAC_AB * dotAB_AP2) * invDenom; final float v = (dotAC_AC * dotAB_AP2 - dotAC_AB * dotAC_AP2) * invDenom; @@ -786,10 +391,11 @@ public final class VectorUtil { } } - { - subVec3(tmpAP, p2, a); //v2 - final float dotAC_AP3 = dotVec3(tmpAC, tmpAP); - final float dotAB_AP3 = dotVec3(tmpAB, tmpAP); + { // FIXME: p3? + ap.minus(p2, a); // v4 + // ap.minus(p3, a); // v3 + final float dotAC_AP3 = ac.dot(ap); + final float dotAB_AP3 = ab.dot(ap); final float u = (dotAB_AB * dotAC_AP3 - dotAC_AB * dotAB_AP3) * invDenom; final float v = (dotAC_AC * dotAB_AP3 - dotAC_AB * dotAC_AP3) * invDenom; @@ -814,25 +420,25 @@ public final class VectorUtil { * @param tmpAP * @return true if p1 or p2 or p3 is in triangle (a, b, c), false otherwise. */ - public static boolean isVec3InTriangle3(final float[] a, final float[] b, final float[] c, - final float[] p1, final float[] p2, final float[] p3, - final float[] tmpAC, final float[] tmpAB, final float[] tmpAP, - final float epsilon){ + public static boolean isVec3InTriangle3(final Vec3f a, final Vec3f b, final Vec3f c, + final Vec3f p1, final Vec3f p2, final Vec3f p3, + final Vec3f ac, final Vec3f ab, final Vec3f ap, + final float epsilon) { // Compute vectors - subVec3(tmpAC, c, a); //v0 - subVec3(tmpAB, b, a); //v1 + ac.minus(c, a); // v0 + ab.minus(b, a); // v1 // Compute dot products - final float dotAC_AC = dotVec3(tmpAC, tmpAC); - final float dotAC_AB = dotVec3(tmpAC, tmpAB); - final float dotAB_AB = dotVec3(tmpAB, tmpAB); + final float dotAC_AC = ac.dot(ac); + final float dotAC_AB = ac.dot(ab); + final float dotAB_AB = ab.dot(ab); // Compute barycentric coordinates final float invDenom = 1 / (dotAC_AC * dotAB_AB - dotAC_AB * dotAC_AB); { - subVec3(tmpAP, p1, a); //v2 - final float dotAC_AP1 = dotVec3(tmpAC, tmpAP); - final float dotAB_AP1 = dotVec3(tmpAB, tmpAP); + ap.minus(p1, a); // v2 + final float dotAC_AP1 = ac.dot(ap); + final float dotAB_AP1 = ab.dot(ap); final float u = (dotAB_AB * dotAC_AP1 - dotAC_AB * dotAB_AP1) * invDenom; final float v = (dotAC_AC * dotAB_AP1 - dotAC_AB * dotAC_AP1) * invDenom; @@ -844,10 +450,11 @@ public final class VectorUtil { } } - { - subVec3(tmpAP, p1, a); //v2 - final float dotAC_AP2 = dotVec3(tmpAC, tmpAP); - final float dotAB_AP2 = dotVec3(tmpAB, tmpAP); + { // FIXME: p2? + ap.minus(p1, a); // v2 + // ap.minus(p2, a); // v3 + final float dotAC_AP2 = ac.dot(ap); + final float dotAB_AP2 = ab.dot(ap); final float u = (dotAB_AB * dotAC_AP2 - dotAC_AB * dotAB_AP2) * invDenom; final float v = (dotAC_AC * dotAB_AP2 - dotAC_AB * dotAC_AP2) * invDenom; @@ -859,10 +466,11 @@ public final class VectorUtil { } } - { - subVec3(tmpAP, p2, a); //v2 - final float dotAC_AP3 = dotVec3(tmpAC, tmpAP); - final float dotAB_AP3 = dotVec3(tmpAB, tmpAP); + { // FIXME: p3? + ap.minus(p2, a); // v2 + // ap.minus(p3, a); // v4 + final float dotAC_AP3 = ac.dot(ap); + final float dotAB_AP3 = ab.dot(ap); final float u = (dotAB_AB * dotAC_AP3 - dotAC_AB * dotAB_AP3) * invDenom; final float v = (dotAC_AC * dotAB_AP3 - dotAC_AB * dotAC_AP3) * invDenom; @@ -873,7 +481,6 @@ public final class VectorUtil { return true; } } - return false; } @@ -917,9 +524,9 @@ public final class VectorUtil { final int n = vertices.size(); float area = 0.0f; for (int p = n - 1, q = 0; q < n; p = q++) { - final float[] pCoord = vertices.get(p).getCoord(); - final float[] qCoord = vertices.get(q).getCoord(); - area += pCoord[0] * qCoord[1] - qCoord[0] * pCoord[1]; + final Vert2fImmutable pCoord = vertices.get(p); + final Vert2fImmutable qCoord = vertices.get(q); + area += pCoord.x() * qCoord.y() - qCoord.x() * pCoord.y(); } return area; } @@ -939,36 +546,6 @@ public final class VectorUtil { } /** - * @param result vec2 result for normal - * @param v1 vec2 - * @param v2 vec2 - * @return result for chaining - */ - public static float[] getNormalVec2(final float[] result, final float[] v1, final float[] v2 ) { - subVec2(result, v2, v1); - final float tmp = result [ 0 ] ; result [ 0 ] = -result [ 1 ] ; result [ 1 ] = tmp ; - return normalizeVec2 ( result ) ; - } - - /** - * Returns the 3d surface normal of a triangle given three vertices. - * - * @param result vec3 result for normal - * @param v1 vec3 - * @param v2 vec3 - * @param v3 vec3 - * @param tmp1Vec3 temp vec3 - * @param tmp2Vec3 temp vec3 - * @return result for chaining - */ - public static float[] getNormalVec3(final float[] result, final float[] v1, final float[] v2, final float[] v3, - final float[] tmp1Vec3, final float[] tmp2Vec3) { - subVec3 ( tmp1Vec3, v2, v1 ); - subVec3 ( tmp2Vec3, v3, v1 ) ; - return normalizeVec3 ( crossVec3(result, tmp1Vec3, tmp2Vec3) ) ; - } - - /** * Finds the plane equation of a plane given its normal and a point on the plane. * * @param resultV4 vec4 plane equation @@ -976,15 +553,14 @@ public final class VectorUtil { * @param pVec3 * @return result for chaining */ - public static float[] getPlaneVec3(final float[/*4*/] resultV4, final float[] normalVec3, final float[] pVec3) { + public static Vec4f getPlaneVec3(final Vec4f resultV4, final Vec3f normalVec3, final Vec3f pVec3) { /** Ax + By + Cz + D == 0 ; D = - ( Ax + By + Cz ) = - ( A*a[0] + B*a[1] + C*a[2] ) = - vec3Dot ( normal, a ) ; */ - System.arraycopy(normalVec3, 0, resultV4, 0, 3); - resultV4 [ 3 ] = -dotVec3(normalVec3, pVec3) ; + resultV4.set(normalVec3, -normalVec3.dot(pVec3)); return resultV4; } @@ -999,16 +575,16 @@ public final class VectorUtil { * @param temp2V3 * @return result for chaining */ - public static float[] getPlaneVec3(final float[/*4*/] resultVec4, final float[] v1, final float[] v2, final float[] v3, - final float[] temp1V3, final float[] temp2V3) { + public static Vec4f getPlaneVec3(final Vec4f resultVec4, final Vec3f v1, final Vec3f v2, final Vec3f v3, + final Vec3f temp1V3, final Vec3f temp2V3, final Vec3f temp3V3) { /** Ax + By + Cz + D == 0 ; D = - ( Ax + By + Cz ) = - ( A*a[0] + B*a[1] + C*a[2] ) = - vec3Dot ( normal, a ) ; */ - getNormalVec3( resultVec4, v1, v2, v3, temp1V3, temp2V3 ) ; - resultVec4 [ 3 ] = -dotVec3 (resultVec4, v1) ; + temp3V3.cross(temp1V3.minus(v2, v1), temp2V3.minus(v3, v1)).normalize(); + resultVec4.set(temp3V3, -temp3V3.dot(v1)); return resultVec4; } @@ -1042,26 +618,23 @@ public final class VectorUtil { * @param d vertex 2 of second segment * @return the intersection coordinates if the segments intersect, otherwise returns null */ - public static float[] seg2SegIntersection(final float[] result, final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c, final Vert2fImmutable d) { - final float determinant = (a.getX()-b.getX())*(c.getY()-d.getY()) - (a.getY()-b.getY())*(c.getX()-d.getX()); + public static Vec3f seg2SegIntersection(final Vec3f result, final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c, final Vert2fImmutable d) { + final float determinant = (a.x()-b.x())*(c.y()-d.y()) - (a.y()-b.y())*(c.x()-d.x()); if (determinant == 0) return null; - final float alpha = (a.getX()*b.getY()-a.getY()*b.getX()); - final float beta = (c.getX()*d.getY()-c.getY()*d.getY()); - final float xi = ((c.getX()-d.getX())*alpha-(a.getX()-b.getX())*beta)/determinant; - final float yi = ((c.getY()-d.getY())*alpha-(a.getY()-b.getY())*beta)/determinant; + final float alpha = (a.x()*b.y()-a.y()*b.x()); + final float beta = (c.x()*d.y()-c.y()*d.y()); + final float xi = ((c.x()-d.x())*alpha-(a.x()-b.x())*beta)/determinant; + final float yi = ((c.y()-d.y())*alpha-(a.y()-b.y())*beta)/determinant; - final float gamma = (xi - a.getX())/(b.getX() - a.getX()); - final float gamma1 = (xi - c.getX())/(d.getX() - c.getX()); + final float gamma = (xi - a.x())/(b.x() - a.x()); + final float gamma1 = (xi - c.x())/(d.x() - c.x()); if(gamma <= 0 || gamma >= 1) return null; if(gamma1 <= 0 || gamma1 >= 1) return null; - result[0] = xi; - result[1] = yi; - result[2] = 0; - return result; + return result.set(xi, yi, 0); } /** @@ -1074,23 +647,18 @@ public final class VectorUtil { */ public static boolean testSeg2SegIntersection(final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c, final Vert2fImmutable d) { - final float[] A = a.getCoord(); - final float[] B = b.getCoord(); - final float[] C = c.getCoord(); - final float[] D = d.getCoord(); - - final float determinant = (A[0]-B[0])*(C[1]-D[1]) - (A[1]-B[1])*(C[0]-D[0]); + final float determinant = (a.x()-b.x())*(c.y()-d.y()) - (a.y()-b.y())*(c.x()-d.x()); if (determinant == 0) { return false; } - final float alpha = (A[0]*B[1]-A[1]*B[0]); - final float beta = (C[0]*D[1]-C[1]*D[1]); - final float xi = ((C[0]-D[0])*alpha-(A[0]-B[0])*beta)/determinant; + final float alpha = (a.x()*b.y()-a.y()*b.x()); + final float beta = (c.x()*d.y()-c.y()*d.y()); + final float xi = ((c.x()-d.x())*alpha-(a.x()-b.x())*beta)/determinant; - final float gamma0 = (xi - A[0])/(B[0] - A[0]); - final float gamma1 = (xi - C[0])/(D[0] - C[0]); + final float gamma0 = (xi - a.x())/(b.x() - a.x()); + final float gamma1 = (xi - c.x())/(d.x() - c.x()); if(gamma0 <= 0 || gamma0 >= 1 || gamma1 <= 0 || gamma1 >= 1) { return false; } @@ -1108,23 +676,19 @@ public final class VectorUtil { public static boolean testSeg2SegIntersection(final Vert2fImmutable a, final Vert2fImmutable b, final Vert2fImmutable c, final Vert2fImmutable d, final float epsilon) { - final float[] A = a.getCoord(); - final float[] B = b.getCoord(); - final float[] C = c.getCoord(); - final float[] D = d.getCoord(); - - final float determinant = (A[0]-B[0])*(C[1]-D[1]) - (A[1]-B[1])*(C[0]-D[0]); + final float determinant = (a.x()-b.x())*(c.y()-d.y()) - (a.y()-b.y())*(c.x()-d.x()); if ( FloatUtil.isZero(determinant, epsilon) ) { return false; } - final float alpha = (A[0]*B[1]-A[1]*B[0]); - final float beta = (C[0]*D[1]-C[1]*D[1]); - final float xi = ((C[0]-D[0])*alpha-(A[0]-B[0])*beta)/determinant; + final float alpha = (a.x()*b.y()-a.y()*b.x()); + final float beta = (c.x()*d.y()-c.y()*d.y()); + final float xi = ((c.x()-d.x())*alpha-(a.x()-b.x())*beta)/determinant; + + final float gamma0 = (xi - a.x())/(b.x() - a.x()); + final float gamma1 = (xi - c.x())/(d.x() - c.x()); - final float gamma0 = (xi - A[0])/(B[0] - A[0]); - final float gamma1 = (xi - C[0])/(D[0] - C[0]); if( FloatUtil.compare(gamma0, 0.0f, epsilon) <= 0 || FloatUtil.compare(gamma0, 1.0f, epsilon) >= 0 || FloatUtil.compare(gamma1, 0.0f, epsilon) <= 0 || @@ -1148,23 +712,20 @@ public final class VectorUtil { * @return the intersection coordinates if the lines intersect, otherwise * returns null */ - public static float[] line2lineIntersection(final float[] result, - final Vert2fImmutable a, final Vert2fImmutable b, - final Vert2fImmutable c, final Vert2fImmutable d) { - final float determinant = (a.getX()-b.getX())*(c.getY()-d.getY()) - (a.getY()-b.getY())*(c.getX()-d.getX()); + public static Vec3f line2lineIntersection(final Vec3f result, + final Vert2fImmutable a, final Vert2fImmutable b, + final Vert2fImmutable c, final Vert2fImmutable d) { + final float determinant = (a.x()-b.x())*(c.y()-d.y()) - (a.y()-b.y())*(c.x()-d.x()); if (determinant == 0) return null; - final float alpha = (a.getX()*b.getY()-a.getY()*b.getX()); - final float beta = (c.getX()*d.getY()-c.getY()*d.getY()); - final float xi = ((c.getX()-d.getX())*alpha-(a.getX()-b.getX())*beta)/determinant; - final float yi = ((c.getY()-d.getY())*alpha-(a.getY()-b.getY())*beta)/determinant; + final float alpha = (a.x()*b.y()-a.y()*b.x()); + final float beta = (c.x()*d.y()-c.y()*d.y()); + final float xi = ((c.x()-d.x())*alpha-(a.x()-b.x())*beta)/determinant; + final float yi = ((c.y()-d.y())*alpha-(a.y()-b.y())*beta)/determinant; - result[0] = xi; - result[1] = yi; - result[2] = 0; - return result; + return result.set(xi, yi, 0); } /** diff --git a/src/jogl/classes/com/jogamp/opengl/math/Vert2fImmutable.java b/src/jogl/classes/com/jogamp/opengl/math/Vert2fImmutable.java index ec90b401f..66bf078f3 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Vert2fImmutable.java +++ b/src/jogl/classes/com/jogamp/opengl/math/Vert2fImmutable.java @@ -28,12 +28,9 @@ package com.jogamp.opengl.math; public interface Vert2fImmutable { - float getX(); + float x(); - float getY(); + float y(); int getCoordCount(); - - float[] getCoord(); - } diff --git a/src/jogl/classes/com/jogamp/opengl/math/Vert3fImmutable.java b/src/jogl/classes/com/jogamp/opengl/math/Vert3fImmutable.java index 76bd02fbc..6f63a746c 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Vert3fImmutable.java +++ b/src/jogl/classes/com/jogamp/opengl/math/Vert3fImmutable.java @@ -28,5 +28,7 @@ package com.jogamp.opengl.math; public interface Vert3fImmutable extends Vert2fImmutable { - float getZ(); + float z(); + + Vec3f getCoord(); } |