From 9729f4408a1f340acd2a49e8f86b397e7a6b1b6f Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Tue, 15 May 2012 18:04:11 +0200
Subject: Java Source Files: dos -> unix format
---
.../com/jogamp/graph/curve/OutlineShape.java | 1258 ++++++++++----------
.../classes/com/jogamp/graph/math/Quaternion.java | 764 ++++++------
.../classes/com/jogamp/graph/math/VectorUtil.java | 866 +++++++-------
.../jogamp/graph/curve/opengl/RegionFactory.java | 148 +--
.../graph/curve/opengl/RegionRendererImpl01.java | 186 +--
.../graph/font/typecast/TypecastRenderer.java | 444 +++----
src/jogl/classes/jogamp/graph/math/MathFloat.java | 90 +-
.../opengl/test/bugs/Bug427GLJPanelTest1.java | 144 +--
.../test/junit/graph/TestRegionRendererNEWT01.java | 444 +++----
.../test/junit/graph/TestTextRendererNEWT00.java | 472 ++++----
.../test/junit/graph/TestTextRendererNEWT01.java | 490 ++++----
.../test/junit/jogl/demos/es1/OneTriangle.java | 156 +--
.../test/junit/jogl/swt/TestSWTAWT01GLn.java | 390 +++---
.../jogl/swt/TestSWTEclipseGLCanvas01GLn.java | 388 +++---
.../jogl/swt/TestSWTJOGLGLCanvas01GLnAWT.java | 348 +++---
15 files changed, 3294 insertions(+), 3294 deletions(-)
diff --git a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java
index 025a998d8..e60fba02b 100755
--- a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java
@@ -1,629 +1,629 @@
-/**
- * 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.curve;
-
-import java.util.ArrayList;
-import java.util.Collections;
-
-import com.jogamp.graph.curve.tess.Triangulation;
-import com.jogamp.graph.curve.tess.Triangulator;
-import com.jogamp.graph.geom.AABBox;
-import com.jogamp.graph.geom.Outline;
-import com.jogamp.graph.geom.Triangle;
-import com.jogamp.graph.geom.Vertex;
-import com.jogamp.graph.math.VectorUtil;
-
-
-/** A Generic shape objects which is defined by a list of Outlines.
- * This Shape can be transformed to Triangulations.
- * The list of triangles generated are render-able by a Region object.
- * The triangulation produced by this Shape will define the
- * closed region defined by the outlines.
- *
- * One or more OutlineShape Object can be associated to a region
- * this is left as a high-level representation of the Objects. For
- * optimizations, flexibility requirements for future features.
- *
- *
- * Example to creating an Outline Shape:
- *
- addVertex(...)
- addVertex(...)
- addVertex(...)
- addEmptyOutline()
- addVertex(...)
- addVertex(...)
- addVertex(...)
- *
- *
- * The above will create two outlines each with three vertices. By adding these two outlines to
- * the OutlineShape, we are stating that the combination of the two outlines represent the shape.
- *
- *
- * To specify that the shape is curved at a region, the on-curve flag should be set to false
- * for the vertex that is in the middle of the curved region (if the curved region is defined by 3
- * vertices (quadratic curve).
- *
- * In case the curved region is defined by 4 or more vertices the middle vertices should both have
- * the on-curve flag set to false.
- *
- *
Example:
- *
- addVertex(0,0, true);
- addVertex(0,1, false);
- addVertex(1,1, false);
- addVertex(1,0, true);
- *
- *
- * The above snippet defines a cubic nurbs curve where (0,1 and 1,1)
- * do not belong to the final rendered shape.
- *
- * Implementation Notes:
- *
- * - The first vertex of any outline belonging to the shape should be on-curve
- * - Intersections between off-curved parts of the outline is not handled
- *
- *
- * @see Outline
- * @see Region
- */
-public class OutlineShape implements Comparable {
- /**
- * Outline's vertices have undefined state until transformed.
- */
- public enum VerticesState {
- UNDEFINED(0), QUADRATIC_NURBS(1);
-
- public final int state;
-
- VerticesState(int state){
- this.state = state;
- }
- }
-
- public static final int DIRTY_BOUNDS = 1 << 0;
-
- private final Vertex.Factory extends Vertex> vertexFactory;
- private VerticesState outlineState;
-
- /** The list of {@link Outline}s that are part of this
- * outline shape.
- */
- private ArrayList outlines;
- private AABBox bbox;
-
- /** dirty bits DIRTY_BOUNDS */
- private int dirtyBits;
-
- /** Create a new Outline based Shape
- */
- public OutlineShape(Vertex.Factory extends Vertex> factory) {
- this.vertexFactory = factory;
- this.outlines = new ArrayList(3);
- this.outlines.add(new Outline());
- this.outlineState = VerticesState.UNDEFINED;
- this.bbox = new AABBox();
- this.dirtyBits = 0;
- }
-
- /** Clears all data and reset all states as if this instance was newly created */
- public void clear() {
- outlines.clear();
- outlines.add(new Outline());
- outlineState = VerticesState.UNDEFINED;
- bbox.reset();
- dirtyBits = 0;
- }
-
- /** Returns the associated vertex factory of this outline shape
- * @return Vertex.Factory object
- */
- public final Vertex.Factory extends Vertex> vertexFactory() { return vertexFactory; }
-
- public int getOutlineNumber() {
- return outlines.size();
- }
-
- /** Add a new empty {@link Outline}
- * to the end of this shape's outline list.
- * If the {@link #getLastOutline()} is empty already, no new one will be added.
- *
- * After a call to this function all new vertices added
- * will belong to the new outline
- */
- public void addEmptyOutline() {
- if( !getLastOutline().isEmpty() ) {
- outlines.add(new Outline());
- }
- }
-
- /** Appends the {@link Outline} element to the end,
- * ensuring a clean tail.
- *
- * A clean tail is ensured, no double empty Outlines are produced
- * and a pre-existing empty outline will be replaced with the given one.
- *
- * @param outline Outline object to be added
- * @throws NullPointerException if the {@link Outline} element is null
- */
- public void addOutline(Outline outline) throws NullPointerException {
- addOutline(outlines.size(), outline);
- }
-
- /** Insert the {@link Outline} element at the given {@code position}.
- *
- * If the {@code position} indicates the end of this list,
- * a clean tail is ensured, no double empty Outlines are produced
- * and a pre-existing empty outline will be replaced with the given one.
- *
- * @param position of the added Outline
- * @param outline Outline object to be added
- * @throws NullPointerException if the {@link Outline} element is null
- * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position > getOutlineNumber())
- */
- public void addOutline(int position, Outline outline) throws NullPointerException, IndexOutOfBoundsException {
- if (null == outline) {
- throw new NullPointerException("outline is null");
- }
- if( outlines.size() == position ) {
- final Outline lastOutline = getLastOutline();
- if( outline.isEmpty() && lastOutline.isEmpty() ) {
- return;
- }
- if( lastOutline.isEmpty() ) {
- outlines.set(position-1, outline);
- if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
- bbox.resize(outline.getBounds());
- }
- return;
- }
- }
- outlines.add(position, outline);
- if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
- bbox.resize(outline.getBounds());
- }
- }
-
- /** Insert the {@link OutlineShape} elements of type {@link Outline}, .. at the end of this shape,
- * using {@link #addOutline(Outline)} for each element.
- * Closes the current last outline via {@link #closeLastOutline()} before adding the new ones.
- * @param outlineShape OutlineShape elements to be added.
- * @throws NullPointerException if the {@link OutlineShape} is null
- * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position > getOutlineNumber())
- */
- public void addOutlineShape(OutlineShape outlineShape) throws NullPointerException {
- if (null == outlineShape) {
- throw new NullPointerException("OutlineShape is null");
- }
- closeLastOutline();
- for(int i=0; iSets the bounding box dirty, hence a next call to {@link #getBounds()} will validate it.
- *
- * @param position of the replaced Outline
- * @param outline replacement Outline object
- * @throws NullPointerException if the {@link Outline} element is null
- * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber())
- */
- public void setOutline(int position, Outline outline) throws NullPointerException, IndexOutOfBoundsException {
- if (null == outline) {
- throw new NullPointerException("outline is null");
- }
- outlines.set(position, outline);
- dirtyBits |= DIRTY_BOUNDS;
- }
-
- /** Removes the {@link Outline} element at the given {@code position}.
- * Sets the bounding box dirty, hence a next call to {@link #getBounds()} will validate it.
- *
- * @param position of the to be removed Outline
- * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber())
- */
- public final Outline removeOutline(int position) throws IndexOutOfBoundsException {
- dirtyBits |= DIRTY_BOUNDS;
- return outlines.remove(position);
- }
-
- /** Get the last added outline to the list
- * of outlines that define the shape
- * @return the last outline
- */
- public final Outline getLastOutline() {
- return outlines.get(outlines.size()-1);
- }
-
- /** @return the {@code Outline} at {@code position}
- * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber())
- */
- public Outline getOutline(int position) throws IndexOutOfBoundsException {
- return outlines.get(position);
- }
-
- /** Adds a vertex to the last open outline in the
- * shape.
- * @param v the vertex to be added to the OutlineShape
- */
- public final void addVertex(Vertex v) {
- final Outline lo = getLastOutline();
- lo.addVertex(v);
- if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
- bbox.resize(lo.getBounds());
- }
- }
-
- /** Adds a vertex to the last open outline in the shape.
- * at {@code position}
- * @param position indx at which the vertex will be added
- * @param v the vertex to be added to the OutlineShape
- */
- public final void addVertex(int position, Vertex v) {
- final Outline lo = getLastOutline();
- lo.addVertex(position, v);
- if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
- bbox.resize(lo.getBounds());
- }
- }
-
- /** Add a 2D {@link Vertex} to the last outline by defining the coordniate attribute
- * of the vertex. The 2D vertex will be represented as Z=0.
- *
- * @param x the x coordinate
- * @param y the y coordniate
- * @param onCurve flag if this vertex is on the final curve or defines a curved region
- * of the shape around this vertex.
- */
- public final void addVertex(float x, float y, boolean onCurve) {
- addVertex(vertexFactory.create(x, y, 0f, onCurve));
- }
-
- /** Add a 3D {@link Vertex} to the last outline by defining the coordniate attribute
- * of the vertex.
- * @param x the x coordinate
- * @param y the y coordinate
- * @param z the z coordinate
- * @param onCurve flag if this vertex is on the final curve or defines a curved region
- * of the shape around this vertex.
- */
- public final void addVertex(float x, float y, float z, boolean onCurve) {
- addVertex(vertexFactory.create(x, y, z, onCurve));
- }
-
- /** Add a vertex to the last outline by passing a float array and specifying the
- * offset and length in which. The attributes of the vertex are located.
- * The attributes should be continuous (stride = 0).
- * Attributes which value are not set (when length less than 3)
- * are set implicitly to zero.
- * @param coordsBuffer the coordinate array where the vertex attributes are to be picked from
- * @param offset the offset in the buffer to the x coordinate
- * @param length the number of attributes to pick from the buffer (maximum 3)
- * @param onCurve flag if this vertex is on the final curve or defines a curved region
- * of the shape around this vertex.
- */
- public final void addVertex(float[] coordsBuffer, int offset, int length, boolean onCurve) {
- addVertex(vertexFactory.create(coordsBuffer, offset, length, onCurve));
- }
-
- /** Closes the last outline in the shape.
- * If last vertex is not equal to first vertex.
- * A new temp vertex is added at the end which
- * is equal to the first.
- */
- public void closeLastOutline() {
- getLastOutline().setClosed(true);
- }
-
- /**
- * @return the outline's vertices state, {@link OutlineShape.VerticesState}
- */
- public final VerticesState getOutlineState() {
- return outlineState;
- }
-
- /** Ensure the outlines represent
- * the specified destinationType.
- * and removes all overlaps in boundary triangles
- * @param destinationType the target outline's vertices state. Currently only
- * {@link OutlineShape.VerticesState#QUADRATIC_NURBS} are supported.
- */
- public void transformOutlines(VerticesState destinationType) {
- if(outlineState != destinationType){
- if(destinationType == VerticesState.QUADRATIC_NURBS){
- transformOutlines2Quadratic();
- checkOverlaps();
- } else {
- throw new IllegalStateException("destinationType "+destinationType.name()+" not supported (currently "+outlineState.name()+")");
- }
- }
- }
-
- private void subdivideTriangle(final Outline outline, Vertex a, Vertex b, Vertex c, int index){
- float[] v1 = VectorUtil.mid(a.getCoord(), b.getCoord());
- float[] v3 = VectorUtil.mid(b.getCoord(), c.getCoord());
- float[] v2 = VectorUtil.mid(v1, v3);
-
- //drop off-curve vertex to image on the curve
- b.setCoord(v2, 0, 3);
- b.setOnCurve(true);
-
- outline.addVertex(index, vertexFactory.create(v1, 0, 3, false));
- outline.addVertex(index+2, vertexFactory.create(v3, 0, 3, false));
- }
-
- /** Check overlaps between curved triangles
- * first check if any vertex in triangle a is in triangle b
- * second check if edges of triangle a intersect segments of triangle b
- * if any of the two tests is true we divide current triangle
- * and add the other to the list of overlaps
- *
- * Loop until overlap array is empty. (check only in first pass)
- */
- private void checkOverlaps() {
- ArrayList overlaps = new ArrayList(3);
- int count = getOutlineNumber();
- boolean firstpass = true;
- do {
- for (int cc = 0; cc < count; cc++) {
- final Outline outline = getOutline(cc);
- int vertexCount = outline.getVertexCount();
- for(int i=0; i < outline.getVertexCount(); i++) {
- final Vertex currentVertex = outline.getVertex(i);
- if ( !currentVertex.isOnCurve()) {
- final Vertex nextV = outline.getVertex((i+1)%vertexCount);
- final Vertex prevV = outline.getVertex((i+vertexCount-1)%vertexCount);
- Vertex overlap =null;
-
- //check for overlap even if already set for subdivision
- //ensuring both trianglur overlaps get divided
- //for pref. only check in first pass
- //second pass to clear the overlaps arrray(reduces precision errors)
- if(firstpass) {
- overlap = checkTriOverlaps(prevV, currentVertex, nextV);
- }
- if(overlaps.contains(currentVertex) || overlap != null) {
- overlaps.remove(currentVertex);
-
- subdivideTriangle(outline, prevV, currentVertex, nextV, i);
- i+=3;
- vertexCount+=2;
-
- if(overlap != null && !overlap.isOnCurve()) {
- if(!overlaps.contains(overlap))
- overlaps.add(overlap);
- }
- }
- }
- }
- }
- firstpass = false;
- }while(!overlaps.isEmpty());
- }
-
- private Vertex checkTriOverlaps(Vertex a, Vertex b, Vertex c) {
- int count = getOutlineNumber();
- for (int cc = 0; cc < count; cc++) {
- final Outline outline = getOutline(cc);
- int vertexCount = outline.getVertexCount();
- for(int i=0; i < vertexCount; i++) {
- final Vertex current = outline.getVertex(i);
- if(current.isOnCurve() || current == a || current == b || current == c) {
- continue;
- }
- final Vertex nextV = outline.getVertex((i+1)%vertexCount);
- final Vertex prevV = outline.getVertex((i+vertexCount-1)%vertexCount);
-
- //skip neighboring triangles
- if(prevV == c || nextV == a) {
- continue;
- }
-
- if(VectorUtil.vertexInTriangle(a.getCoord(), b.getCoord(), c.getCoord(), current.getCoord())
- || VectorUtil.vertexInTriangle(a.getCoord(), b.getCoord(), c.getCoord(), nextV.getCoord())
- || VectorUtil.vertexInTriangle(a.getCoord(), b.getCoord(), c.getCoord(), prevV.getCoord())) {
-
- return current;
- }
- if(VectorUtil.tri2SegIntersection(a, b, c, prevV, current)
- || VectorUtil.tri2SegIntersection(a, b, c, current, nextV)
- || VectorUtil.tri2SegIntersection(a, b, c, prevV, nextV)) {
- return current;
- }
- }
- }
- return null;
- }
-
- private void transformOutlines2Quadratic() {
- int count = getOutlineNumber();
- for (int cc = 0; cc < count; cc++) {
- final Outline outline = getOutline(cc);
- int vertexCount = outline.getVertexCount();
-
- for(int i=0; i < vertexCount; i++) {
- final Vertex currentVertex = outline.getVertex(i);
- final Vertex nextVertex = outline.getVertex((i+1)%vertexCount);
- if ( !currentVertex.isOnCurve() && !nextVertex.isOnCurve() ) {
- final float[] newCoords = VectorUtil.mid(currentVertex.getCoord(),
- nextVertex.getCoord());
- final Vertex v = vertexFactory.create(newCoords, 0, 3, true);
- i++;
- vertexCount++;
- outline.addVertex(i, v);
- }
- }
- if(vertexCount <= 0) {
- outlines.remove(outline);
- cc--;
- count--;
- continue;
- }
-
- if( vertexCount > 0 ) {
- if(VectorUtil.checkEquality(outline.getVertex(0).getCoord(),
- outline.getLastVertex().getCoord())) {
- outline.removeVertex(vertexCount-1);
- }
- }
- }
- outlineState = VerticesState.QUADRATIC_NURBS;
- }
-
- private void generateVertexIds() {
- int maxVertexId = 0;
- for(int i=0; i vertices = outlines.get(i).getVertices();
- for(int pos=0; pos getVertices() {
- ArrayList vertices = new ArrayList();
- for(int i=0; i triangulate() {
- if(outlines.size() == 0){
- return null;
- }
- sortOutlines();
- generateVertexIds();
-
- Triangulator triangulator2d = Triangulation.create();
- for(int index = 0; index triangles = triangulator2d.generate();
- triangulator2d.reset();
-
- return triangles;
- }
-
- /** Sort the outlines from large
- * to small depending on the AABox
- */
- private void sortOutlines() {
- Collections.sort(outlines);
- Collections.reverse(outlines);
- }
-
- /** Compare two outline shapes with Bounding Box area
- * as criteria.
- * @see java.lang.Comparable#compareTo(java.lang.Object)
- */
- public final int compareTo(OutlineShape outline) {
- float size = getBounds().getSize();
- float newSize = outline.getBounds().getSize();
- if(size < newSize){
- return -1;
- }
- else if(size > newSize){
- return 1;
- }
- return 0;
- }
-
- private final void validateBoundingBox() {
- dirtyBits &= ~DIRTY_BOUNDS;
- bbox.reset();
- for (int i=0; i=0; i--) {
- if( ! getOutline(i).equals( o.getOutline(i) ) ) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * @return deep clone of this OutlineShape w/o Region
- */
- public OutlineShape clone() {
- OutlineShape o;
- try {
- o = (OutlineShape) super.clone();
- } catch (CloneNotSupportedException e) { throw new InternalError(); }
- o.bbox = bbox.clone();
- o.outlines = new ArrayList(outlines.size());
- for(int i=0; i
+ * Example to creating an Outline Shape:
+ *
+ addVertex(...)
+ addVertex(...)
+ addVertex(...)
+ addEmptyOutline()
+ addVertex(...)
+ addVertex(...)
+ addVertex(...)
+ *
+ *
+ * The above will create two outlines each with three vertices. By adding these two outlines to
+ * the OutlineShape, we are stating that the combination of the two outlines represent the shape.
+ *
+ *
+ * To specify that the shape is curved at a region, the on-curve flag should be set to false
+ * for the vertex that is in the middle of the curved region (if the curved region is defined by 3
+ * vertices (quadratic curve).
+ *
+ * In case the curved region is defined by 4 or more vertices the middle vertices should both have
+ * the on-curve flag set to false.
+ *
+ *
Example:
+ *
+ addVertex(0,0, true);
+ addVertex(0,1, false);
+ addVertex(1,1, false);
+ addVertex(1,0, true);
+ *
+ *
+ * The above snippet defines a cubic nurbs curve where (0,1 and 1,1)
+ * do not belong to the final rendered shape.
+ *
+ * Implementation Notes:
+ *
+ * - The first vertex of any outline belonging to the shape should be on-curve
+ * - Intersections between off-curved parts of the outline is not handled
+ *
+ *
+ * @see Outline
+ * @see Region
+ */
+public class OutlineShape implements Comparable {
+ /**
+ * Outline's vertices have undefined state until transformed.
+ */
+ public enum VerticesState {
+ UNDEFINED(0), QUADRATIC_NURBS(1);
+
+ public final int state;
+
+ VerticesState(int state){
+ this.state = state;
+ }
+ }
+
+ public static final int DIRTY_BOUNDS = 1 << 0;
+
+ private final Vertex.Factory extends Vertex> vertexFactory;
+ private VerticesState outlineState;
+
+ /** The list of {@link Outline}s that are part of this
+ * outline shape.
+ */
+ private ArrayList outlines;
+ private AABBox bbox;
+
+ /** dirty bits DIRTY_BOUNDS */
+ private int dirtyBits;
+
+ /** Create a new Outline based Shape
+ */
+ public OutlineShape(Vertex.Factory extends Vertex> factory) {
+ this.vertexFactory = factory;
+ this.outlines = new ArrayList(3);
+ this.outlines.add(new Outline());
+ this.outlineState = VerticesState.UNDEFINED;
+ this.bbox = new AABBox();
+ this.dirtyBits = 0;
+ }
+
+ /** Clears all data and reset all states as if this instance was newly created */
+ public void clear() {
+ outlines.clear();
+ outlines.add(new Outline());
+ outlineState = VerticesState.UNDEFINED;
+ bbox.reset();
+ dirtyBits = 0;
+ }
+
+ /** Returns the associated vertex factory of this outline shape
+ * @return Vertex.Factory object
+ */
+ public final Vertex.Factory extends Vertex> vertexFactory() { return vertexFactory; }
+
+ public int getOutlineNumber() {
+ return outlines.size();
+ }
+
+ /** Add a new empty {@link Outline}
+ * to the end of this shape's outline list.
+ * If the {@link #getLastOutline()} is empty already, no new one will be added.
+ *
+ * After a call to this function all new vertices added
+ * will belong to the new outline
+ */
+ public void addEmptyOutline() {
+ if( !getLastOutline().isEmpty() ) {
+ outlines.add(new Outline());
+ }
+ }
+
+ /** Appends the {@link Outline} element to the end,
+ * ensuring a clean tail.
+ *
+ * A clean tail is ensured, no double empty Outlines are produced
+ * and a pre-existing empty outline will be replaced with the given one.
+ *
+ * @param outline Outline object to be added
+ * @throws NullPointerException if the {@link Outline} element is null
+ */
+ public void addOutline(Outline outline) throws NullPointerException {
+ addOutline(outlines.size(), outline);
+ }
+
+ /** Insert the {@link Outline} element at the given {@code position}.
+ *
+ * If the {@code position} indicates the end of this list,
+ * a clean tail is ensured, no double empty Outlines are produced
+ * and a pre-existing empty outline will be replaced with the given one.
+ *
+ * @param position of the added Outline
+ * @param outline Outline object to be added
+ * @throws NullPointerException if the {@link Outline} element is null
+ * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position > getOutlineNumber())
+ */
+ public void addOutline(int position, Outline outline) throws NullPointerException, IndexOutOfBoundsException {
+ if (null == outline) {
+ throw new NullPointerException("outline is null");
+ }
+ if( outlines.size() == position ) {
+ final Outline lastOutline = getLastOutline();
+ if( outline.isEmpty() && lastOutline.isEmpty() ) {
+ return;
+ }
+ if( lastOutline.isEmpty() ) {
+ outlines.set(position-1, outline);
+ if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
+ bbox.resize(outline.getBounds());
+ }
+ return;
+ }
+ }
+ outlines.add(position, outline);
+ if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
+ bbox.resize(outline.getBounds());
+ }
+ }
+
+ /** Insert the {@link OutlineShape} elements of type {@link Outline}, .. at the end of this shape,
+ * using {@link #addOutline(Outline)} for each element.
+ * Closes the current last outline via {@link #closeLastOutline()} before adding the new ones.
+ * @param outlineShape OutlineShape elements to be added.
+ * @throws NullPointerException if the {@link OutlineShape} is null
+ * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position > getOutlineNumber())
+ */
+ public void addOutlineShape(OutlineShape outlineShape) throws NullPointerException {
+ if (null == outlineShape) {
+ throw new NullPointerException("OutlineShape is null");
+ }
+ closeLastOutline();
+ for(int i=0; iSets the bounding box dirty, hence a next call to {@link #getBounds()} will validate it.
+ *
+ * @param position of the replaced Outline
+ * @param outline replacement Outline object
+ * @throws NullPointerException if the {@link Outline} element is null
+ * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber())
+ */
+ public void setOutline(int position, Outline outline) throws NullPointerException, IndexOutOfBoundsException {
+ if (null == outline) {
+ throw new NullPointerException("outline is null");
+ }
+ outlines.set(position, outline);
+ dirtyBits |= DIRTY_BOUNDS;
+ }
+
+ /** Removes the {@link Outline} element at the given {@code position}.
+ * Sets the bounding box dirty, hence a next call to {@link #getBounds()} will validate it.
+ *
+ * @param position of the to be removed Outline
+ * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber())
+ */
+ public final Outline removeOutline(int position) throws IndexOutOfBoundsException {
+ dirtyBits |= DIRTY_BOUNDS;
+ return outlines.remove(position);
+ }
+
+ /** Get the last added outline to the list
+ * of outlines that define the shape
+ * @return the last outline
+ */
+ public final Outline getLastOutline() {
+ return outlines.get(outlines.size()-1);
+ }
+
+ /** @return the {@code Outline} at {@code position}
+ * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber())
+ */
+ public Outline getOutline(int position) throws IndexOutOfBoundsException {
+ return outlines.get(position);
+ }
+
+ /** Adds a vertex to the last open outline in the
+ * shape.
+ * @param v the vertex to be added to the OutlineShape
+ */
+ public final void addVertex(Vertex v) {
+ final Outline lo = getLastOutline();
+ lo.addVertex(v);
+ if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
+ bbox.resize(lo.getBounds());
+ }
+ }
+
+ /** Adds a vertex to the last open outline in the shape.
+ * at {@code position}
+ * @param position indx at which the vertex will be added
+ * @param v the vertex to be added to the OutlineShape
+ */
+ public final void addVertex(int position, Vertex v) {
+ final Outline lo = getLastOutline();
+ lo.addVertex(position, v);
+ if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
+ bbox.resize(lo.getBounds());
+ }
+ }
+
+ /** Add a 2D {@link Vertex} to the last outline by defining the coordniate attribute
+ * of the vertex. The 2D vertex will be represented as Z=0.
+ *
+ * @param x the x coordinate
+ * @param y the y coordniate
+ * @param onCurve flag if this vertex is on the final curve or defines a curved region
+ * of the shape around this vertex.
+ */
+ public final void addVertex(float x, float y, boolean onCurve) {
+ addVertex(vertexFactory.create(x, y, 0f, onCurve));
+ }
+
+ /** Add a 3D {@link Vertex} to the last outline by defining the coordniate attribute
+ * of the vertex.
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param z the z coordinate
+ * @param onCurve flag if this vertex is on the final curve or defines a curved region
+ * of the shape around this vertex.
+ */
+ public final void addVertex(float x, float y, float z, boolean onCurve) {
+ addVertex(vertexFactory.create(x, y, z, onCurve));
+ }
+
+ /** Add a vertex to the last outline by passing a float array and specifying the
+ * offset and length in which. The attributes of the vertex are located.
+ * The attributes should be continuous (stride = 0).
+ * Attributes which value are not set (when length less than 3)
+ * are set implicitly to zero.
+ * @param coordsBuffer the coordinate array where the vertex attributes are to be picked from
+ * @param offset the offset in the buffer to the x coordinate
+ * @param length the number of attributes to pick from the buffer (maximum 3)
+ * @param onCurve flag if this vertex is on the final curve or defines a curved region
+ * of the shape around this vertex.
+ */
+ public final void addVertex(float[] coordsBuffer, int offset, int length, boolean onCurve) {
+ addVertex(vertexFactory.create(coordsBuffer, offset, length, onCurve));
+ }
+
+ /** Closes the last outline in the shape.
+ * If last vertex is not equal to first vertex.
+ * A new temp vertex is added at the end which
+ * is equal to the first.
+ */
+ public void closeLastOutline() {
+ getLastOutline().setClosed(true);
+ }
+
+ /**
+ * @return the outline's vertices state, {@link OutlineShape.VerticesState}
+ */
+ public final VerticesState getOutlineState() {
+ return outlineState;
+ }
+
+ /** Ensure the outlines represent
+ * the specified destinationType.
+ * and removes all overlaps in boundary triangles
+ * @param destinationType the target outline's vertices state. Currently only
+ * {@link OutlineShape.VerticesState#QUADRATIC_NURBS} are supported.
+ */
+ public void transformOutlines(VerticesState destinationType) {
+ if(outlineState != destinationType){
+ if(destinationType == VerticesState.QUADRATIC_NURBS){
+ transformOutlines2Quadratic();
+ checkOverlaps();
+ } else {
+ throw new IllegalStateException("destinationType "+destinationType.name()+" not supported (currently "+outlineState.name()+")");
+ }
+ }
+ }
+
+ private void subdivideTriangle(final Outline outline, Vertex a, Vertex b, Vertex c, int index){
+ float[] v1 = VectorUtil.mid(a.getCoord(), b.getCoord());
+ float[] v3 = VectorUtil.mid(b.getCoord(), c.getCoord());
+ float[] v2 = VectorUtil.mid(v1, v3);
+
+ //drop off-curve vertex to image on the curve
+ b.setCoord(v2, 0, 3);
+ b.setOnCurve(true);
+
+ outline.addVertex(index, vertexFactory.create(v1, 0, 3, false));
+ outline.addVertex(index+2, vertexFactory.create(v3, 0, 3, false));
+ }
+
+ /** Check overlaps between curved triangles
+ * first check if any vertex in triangle a is in triangle b
+ * second check if edges of triangle a intersect segments of triangle b
+ * if any of the two tests is true we divide current triangle
+ * and add the other to the list of overlaps
+ *
+ * Loop until overlap array is empty. (check only in first pass)
+ */
+ private void checkOverlaps() {
+ ArrayList overlaps = new ArrayList(3);
+ int count = getOutlineNumber();
+ boolean firstpass = true;
+ do {
+ for (int cc = 0; cc < count; cc++) {
+ final Outline outline = getOutline(cc);
+ int vertexCount = outline.getVertexCount();
+ for(int i=0; i < outline.getVertexCount(); i++) {
+ final Vertex currentVertex = outline.getVertex(i);
+ if ( !currentVertex.isOnCurve()) {
+ final Vertex nextV = outline.getVertex((i+1)%vertexCount);
+ final Vertex prevV = outline.getVertex((i+vertexCount-1)%vertexCount);
+ Vertex overlap =null;
+
+ //check for overlap even if already set for subdivision
+ //ensuring both trianglur overlaps get divided
+ //for pref. only check in first pass
+ //second pass to clear the overlaps arrray(reduces precision errors)
+ if(firstpass) {
+ overlap = checkTriOverlaps(prevV, currentVertex, nextV);
+ }
+ if(overlaps.contains(currentVertex) || overlap != null) {
+ overlaps.remove(currentVertex);
+
+ subdivideTriangle(outline, prevV, currentVertex, nextV, i);
+ i+=3;
+ vertexCount+=2;
+
+ if(overlap != null && !overlap.isOnCurve()) {
+ if(!overlaps.contains(overlap))
+ overlaps.add(overlap);
+ }
+ }
+ }
+ }
+ }
+ firstpass = false;
+ }while(!overlaps.isEmpty());
+ }
+
+ private Vertex checkTriOverlaps(Vertex a, Vertex b, Vertex c) {
+ int count = getOutlineNumber();
+ for (int cc = 0; cc < count; cc++) {
+ final Outline outline = getOutline(cc);
+ int vertexCount = outline.getVertexCount();
+ for(int i=0; i < vertexCount; i++) {
+ final Vertex current = outline.getVertex(i);
+ if(current.isOnCurve() || current == a || current == b || current == c) {
+ continue;
+ }
+ final Vertex nextV = outline.getVertex((i+1)%vertexCount);
+ final Vertex prevV = outline.getVertex((i+vertexCount-1)%vertexCount);
+
+ //skip neighboring triangles
+ if(prevV == c || nextV == a) {
+ continue;
+ }
+
+ if(VectorUtil.vertexInTriangle(a.getCoord(), b.getCoord(), c.getCoord(), current.getCoord())
+ || VectorUtil.vertexInTriangle(a.getCoord(), b.getCoord(), c.getCoord(), nextV.getCoord())
+ || VectorUtil.vertexInTriangle(a.getCoord(), b.getCoord(), c.getCoord(), prevV.getCoord())) {
+
+ return current;
+ }
+ if(VectorUtil.tri2SegIntersection(a, b, c, prevV, current)
+ || VectorUtil.tri2SegIntersection(a, b, c, current, nextV)
+ || VectorUtil.tri2SegIntersection(a, b, c, prevV, nextV)) {
+ return current;
+ }
+ }
+ }
+ return null;
+ }
+
+ private void transformOutlines2Quadratic() {
+ int count = getOutlineNumber();
+ for (int cc = 0; cc < count; cc++) {
+ final Outline outline = getOutline(cc);
+ int vertexCount = outline.getVertexCount();
+
+ for(int i=0; i < vertexCount; i++) {
+ final Vertex currentVertex = outline.getVertex(i);
+ final Vertex nextVertex = outline.getVertex((i+1)%vertexCount);
+ if ( !currentVertex.isOnCurve() && !nextVertex.isOnCurve() ) {
+ final float[] newCoords = VectorUtil.mid(currentVertex.getCoord(),
+ nextVertex.getCoord());
+ final Vertex v = vertexFactory.create(newCoords, 0, 3, true);
+ i++;
+ vertexCount++;
+ outline.addVertex(i, v);
+ }
+ }
+ if(vertexCount <= 0) {
+ outlines.remove(outline);
+ cc--;
+ count--;
+ continue;
+ }
+
+ if( vertexCount > 0 ) {
+ if(VectorUtil.checkEquality(outline.getVertex(0).getCoord(),
+ outline.getLastVertex().getCoord())) {
+ outline.removeVertex(vertexCount-1);
+ }
+ }
+ }
+ outlineState = VerticesState.QUADRATIC_NURBS;
+ }
+
+ private void generateVertexIds() {
+ int maxVertexId = 0;
+ for(int i=0; i vertices = outlines.get(i).getVertices();
+ for(int pos=0; pos getVertices() {
+ ArrayList vertices = new ArrayList();
+ for(int i=0; i triangulate() {
+ if(outlines.size() == 0){
+ return null;
+ }
+ sortOutlines();
+ generateVertexIds();
+
+ Triangulator triangulator2d = Triangulation.create();
+ for(int index = 0; index triangles = triangulator2d.generate();
+ triangulator2d.reset();
+
+ return triangles;
+ }
+
+ /** Sort the outlines from large
+ * to small depending on the AABox
+ */
+ private void sortOutlines() {
+ Collections.sort(outlines);
+ Collections.reverse(outlines);
+ }
+
+ /** Compare two outline shapes with Bounding Box area
+ * as criteria.
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public final int compareTo(OutlineShape outline) {
+ float size = getBounds().getSize();
+ float newSize = outline.getBounds().getSize();
+ if(size < newSize){
+ return -1;
+ }
+ else if(size > newSize){
+ return 1;
+ }
+ return 0;
+ }
+
+ private final void validateBoundingBox() {
+ dirtyBits &= ~DIRTY_BOUNDS;
+ bbox.reset();
+ for (int i=0; i=0; i--) {
+ if( ! getOutline(i).equals( o.getOutline(i) ) ) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @return deep clone of this OutlineShape w/o Region
+ */
+ public OutlineShape clone() {
+ OutlineShape o;
+ try {
+ o = (OutlineShape) super.clone();
+ } catch (CloneNotSupportedException e) { throw new InternalError(); }
+ o.bbox = bbox.clone();
+ o.outlines = new ArrayList(outlines.size());
+ for(int i=0; i 0.0f)
- {
- newVector[0] = vector[0]/d;
- newVector[1] = vector[1]/d;
- newVector[2] = vector[2]/d;
- }
- return newVector;
- }
- /** compute the dot product of two points
- * @param vec1 vector 1
- * @param vec2 vector 2
- * @return the dot product as float
- */
- private float dot(float[] vec1, float[] vec2)
- {
- return (vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2]);
- }
- /** cross product vec1 x vec2
- * @param vec1 vector 1
- * @param vec2 vecttor 2
- * @return the resulting vector
- */
- private float[] cross(float[] vec1, float[] vec2)
- {
- float[] out = new float[3];
-
- out[0] = vec2[2]*vec1[1] - vec2[1]*vec1[2];
- out[1] = vec2[0]*vec1[2] - vec2[2]*vec1[0];
- out[2] = vec2[1]*vec1[0] - vec2[0]*vec1[1];
-
- return out;
- }
- public float getW() {
- return w;
- }
- public void setW(float w) {
- this.w = w;
- }
- public float getX() {
- return x;
- }
- public void setX(float x) {
- this.x = x;
- }
- public float getY() {
- return y;
- }
- public void setY(float y) {
- this.y = y;
- }
- public float getZ() {
- return z;
- }
- public void setZ(float z) {
- this.z = z;
- }
-
- /** Add a quaternion
- * @param q quaternion
- */
- public void add(Quaternion q)
- {
- x+=q.x;
- y+=q.y;
- z+=q.z;
- }
-
- /** Subtract a quaternion
- * @param q quaternion
- */
- public void subtract(Quaternion q)
- {
- x-=q.x;
- y-=q.y;
- z-=q.z;
- }
-
- /** Divide a quaternion by a constant
- * @param n a float to divide by
- */
- public void divide(float n)
- {
- x/=n;
- y/=n;
- z/=n;
- }
-
- /** Multiply this quaternion by
- * the param quaternion
- * @param q a quaternion to multiply with
- */
- public void mult(Quaternion q)
- {
- float w1 = w*q.w - (x*q.x + y*q.y + z*q.z);
-
- float x1 = w*q.z + q.w*z + y*q.z - z*q.y;
- float y1 = w*q.x + q.w*x + z*q.x - x*q.z;
- float z1 = w*q.y + q.w*y + x*q.y - y*q.x;
-
- w = w1;
- x = x1;
- y = y1;
- z = z1;
- }
-
- /** Multiply a quaternion by a constant
- * @param n a float constant
- */
- public void mult(float n)
- {
- x*=n;
- y*=n;
- z*=n;
- }
-
- /** Normalize a quaternion required if
- * to be used as a rotational quaternion
- */
- public void normalize()
- {
- float norme = (float)MathFloat.sqrt(w*w + x*x + y*y + z*z);
- if (norme == 0.0f)
- {
- w = 1.0f;
- x = y = z = 0.0f;
- }
- else
- {
- float recip = 1.0f/norme;
-
- w *= recip;
- x *= recip;
- y *= recip;
- z *= recip;
- }
- }
-
- /** Invert the quaternion If rotational,
- * will produce a the inverse rotation
- */
- public void inverse()
- {
- float norm = w*w + x*x + y*y + z*z;
-
- float recip = 1.0f/norm;
-
- w *= recip;
- x = -1*x*recip;
- y = -1*y*recip;
- z = -1*z*recip;
- }
-
- /** Transform this quaternion to a
- * 4x4 column matrix representing the rotation
- * @return new float[16] column matrix 4x4
- */
- public float[] toMatrix()
- {
- float[] matrix = new float[16];
- matrix[0] = 1.0f - 2*y*y - 2*z*z;
- matrix[1] = 2*x*y + 2*w*z;
- matrix[2] = 2*x*z - 2*w*y;
- matrix[3] = 0;
-
- matrix[4] = 2*x*y - 2*w*z;
- matrix[5] = 1.0f - 2*x*x - 2*z*z;
- matrix[6] = 2*y*z + 2*w*x;
- matrix[7] = 0;
-
- matrix[8] = 2*x*z + 2*w*y;
- matrix[9] = 2*y*z - 2*w*x;
- matrix[10] = 1.0f - 2*x*x - 2*y*y;
- matrix[11] = 0;
-
- matrix[12] = 0;
- matrix[13] = 0;
- matrix[14] = 0;
- matrix[15] = 1;
- return matrix;
- }
-
- /** Set this quaternion from a Sphereical interpolation
- * of two param quaternion, used mostly for rotational animation
- * @param a initial quaternion
- * @param b target quaternion
- * @param t float between 0 and 1 representing interp.
- */
- public void slerp(Quaternion a,Quaternion b, float t)
- {
- float omega, cosom, sinom, sclp, sclq;
- cosom = a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w;
- if ((1.0f+cosom) > MathFloat.E) {
- if ((1.0f-cosom) > MathFloat.E) {
- omega = (float)MathFloat.acos(cosom);
- sinom = (float)MathFloat.sin(omega);
- sclp = (float)MathFloat.sin((1.0f-t)*omega) / sinom;
- sclq = (float)MathFloat.sin(t*omega) / sinom;
- }
- else {
- sclp = 1.0f - t;
- sclq = t;
- }
- x = sclp*a.x + sclq*b.x;
- y = sclp*a.y + sclq*b.y;
- z = sclp*a.z + sclq*b.z;
- w = sclp*a.w + sclq*b.w;
- }
- else {
- x =-a.y;
- y = a.x;
- z =-a.w;
- w = a.z;
- sclp = MathFloat.sin((1.0f-t) * MathFloat.PI * 0.5f);
- sclq = MathFloat.sin(t * MathFloat.PI * 0.5f);
- x = sclp*a.x + sclq*b.x;
- y = sclp*a.y + sclq*b.y;
- z = sclp*a.z + sclq*b.z;
- }
- }
-
- /** Check if this quaternion is empty, ie (0,0,0,1)
- * @return true if empty, false otherwise
- */
- public boolean isEmpty()
- {
- if (w==1 && x==0 && y==0 && z==0)
- return true;
- return false;
- }
-
- /** Check if this quaternion represents an identity
- * matrix, for rotation.
- * @return true if it is an identity rep., false otherwise
- */
- public boolean isIdentity()
- {
- if (w==0 && x==0 && y==0 && z==0)
- return true;
- return false;
- }
-
- /** compute the quaternion from a 3x3 column matrix
- * @param m 3x3 column matrix
- */
- public void setFromMatrix(float[] m) {
- float T= m[0] + m[4] + m[8] + 1;
- if (T>0){
- float S = 0.5f / (float)MathFloat.sqrt(T);
- w = 0.25f / S;
- x = ( m[5] - m[7]) * S;
- y = ( m[6] - m[2]) * S;
- z = ( m[1] - m[3] ) * S;
- }
- else{
- if ((m[0] > m[4])&(m[0] > m[8])) {
- float S = MathFloat.sqrt( 1.0f + m[0] - m[4] - m[8] ) * 2f; // S=4*qx
- w = (m[7] - m[5]) / S;
- x = 0.25f * S;
- y = (m[3] + m[1]) / S;
- z = (m[6] + m[2]) / S;
- }
- else if (m[4] > m[8]) {
- float S = MathFloat.sqrt( 1.0f + m[4] - m[0] - m[8] ) * 2f; // S=4*qy
- w = (m[6] - m[2]) / S;
- x = (m[3] + m[1]) / S;
- y = 0.25f * S;
- z = (m[7] + m[5]) / S;
- }
- else {
- float S = MathFloat.sqrt( 1.0f + m[8] - m[0] - m[4] ) * 2f; // S=4*qz
- w = (m[3] - m[1]) / S;
- x = (m[6] + m[2]) / S;
- y = (m[7] + m[5]) / S;
- z = 0.25f * S;
- }
- }
- }
-
- /** Check if the the 3x3 matrix (param) is in fact
- * an affine rotational matrix
- * @param m 3x3 column matrix
- * @return true if representing a rotational matrix, false otherwise
- */
- public boolean isRotationMatrix(float[] m) {
- double epsilon = 0.01; // margin to allow for rounding errors
- if (MathFloat.abs(m[0]*m[3] + m[3]*m[4] + m[6]*m[7]) > epsilon) return false;
- if (MathFloat.abs(m[0]*m[2] + m[3]*m[5] + m[6]*m[8]) > epsilon) return false;
- if (MathFloat.abs(m[1]*m[2] + m[4]*m[5] + m[7]*m[8]) > epsilon) return false;
- if (MathFloat.abs(m[0]*m[0] + m[3]*m[3] + m[6]*m[6] - 1) > epsilon) return false;
- if (MathFloat.abs(m[1]*m[1] + m[4]*m[4] + m[7]*m[7] - 1) > epsilon) return false;
- if (MathFloat.abs(m[2]*m[2] + m[5]*m[5] + m[8]*m[8] - 1) > epsilon) return false;
- return (MathFloat.abs(determinant(m)-1) < epsilon);
- }
- private float determinant(float[] m) {
- return m[0]*m[4]*m[8] + m[3]*m[7]*m[2] + m[6]*m[1]*m[5] - m[0]*m[7]*m[5] - m[3]*m[1]*m[8] - m[6]*m[4]*m[2];
- }
-}
+/**
+ * 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.math;
+
+import jogamp.graph.math.MathFloat;
+
+public class Quaternion {
+ protected float x,y,z,w;
+
+ public Quaternion(){
+
+ }
+
+ public Quaternion(float x, float y, float z, float w) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.w = w;
+ }
+
+ /** Constructor to create a rotation based quaternion from two vectors
+ * @param vector1
+ * @param vector2
+ */
+ public Quaternion(float[] vector1, float[] vector2)
+ {
+ float theta = (float)MathFloat.acos(dot(vector1, vector2));
+ float[] cross = cross(vector1,vector2);
+ cross = normalizeVec(cross);
+
+ this.x = (float)MathFloat.sin(theta/2)*cross[0];
+ this.y = (float)MathFloat.sin(theta/2)*cross[1];
+ this.z = (float)MathFloat.sin(theta/2)*cross[2];
+ this.w = (float)MathFloat.cos(theta/2);
+ this.normalize();
+ }
+
+ /** Transform the rotational quaternion to axis based rotation angles
+ * @return new float[4] with ,theta,Rx,Ry,Rz
+ */
+ public float[] toAxis()
+ {
+ float[] vec = new float[4];
+ float scale = (float)MathFloat.sqrt(x * x + y * y + z * z);
+ vec[0] =(float) MathFloat.acos(w) * 2.0f;
+ vec[1] = x / scale;
+ vec[2] = y / scale;
+ vec[3] = z / scale;
+ return vec;
+ }
+
+ /** Normalize a vector
+ * @param vector input vector
+ * @return normalized vector
+ */
+ private float[] normalizeVec(float[] vector)
+ {
+ float[] newVector = new float[3];
+
+ float d = MathFloat.sqrt(vector[0]*vector[0] + vector[1]*vector[1] + vector[2]*vector[2]);
+ if(d> 0.0f)
+ {
+ newVector[0] = vector[0]/d;
+ newVector[1] = vector[1]/d;
+ newVector[2] = vector[2]/d;
+ }
+ return newVector;
+ }
+ /** compute the dot product of two points
+ * @param vec1 vector 1
+ * @param vec2 vector 2
+ * @return the dot product as float
+ */
+ private float dot(float[] vec1, float[] vec2)
+ {
+ return (vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2]);
+ }
+ /** cross product vec1 x vec2
+ * @param vec1 vector 1
+ * @param vec2 vecttor 2
+ * @return the resulting vector
+ */
+ private float[] cross(float[] vec1, float[] vec2)
+ {
+ float[] out = new float[3];
+
+ out[0] = vec2[2]*vec1[1] - vec2[1]*vec1[2];
+ out[1] = vec2[0]*vec1[2] - vec2[2]*vec1[0];
+ out[2] = vec2[1]*vec1[0] - vec2[0]*vec1[1];
+
+ return out;
+ }
+ public float getW() {
+ return w;
+ }
+ public void setW(float w) {
+ this.w = w;
+ }
+ public float getX() {
+ return x;
+ }
+ public void setX(float x) {
+ this.x = x;
+ }
+ public float getY() {
+ return y;
+ }
+ public void setY(float y) {
+ this.y = y;
+ }
+ public float getZ() {
+ return z;
+ }
+ public void setZ(float z) {
+ this.z = z;
+ }
+
+ /** Add a quaternion
+ * @param q quaternion
+ */
+ public void add(Quaternion q)
+ {
+ x+=q.x;
+ y+=q.y;
+ z+=q.z;
+ }
+
+ /** Subtract a quaternion
+ * @param q quaternion
+ */
+ public void subtract(Quaternion q)
+ {
+ x-=q.x;
+ y-=q.y;
+ z-=q.z;
+ }
+
+ /** Divide a quaternion by a constant
+ * @param n a float to divide by
+ */
+ public void divide(float n)
+ {
+ x/=n;
+ y/=n;
+ z/=n;
+ }
+
+ /** Multiply this quaternion by
+ * the param quaternion
+ * @param q a quaternion to multiply with
+ */
+ public void mult(Quaternion q)
+ {
+ float w1 = w*q.w - (x*q.x + y*q.y + z*q.z);
+
+ float x1 = w*q.z + q.w*z + y*q.z - z*q.y;
+ float y1 = w*q.x + q.w*x + z*q.x - x*q.z;
+ float z1 = w*q.y + q.w*y + x*q.y - y*q.x;
+
+ w = w1;
+ x = x1;
+ y = y1;
+ z = z1;
+ }
+
+ /** Multiply a quaternion by a constant
+ * @param n a float constant
+ */
+ public void mult(float n)
+ {
+ x*=n;
+ y*=n;
+ z*=n;
+ }
+
+ /** Normalize a quaternion required if
+ * to be used as a rotational quaternion
+ */
+ public void normalize()
+ {
+ float norme = (float)MathFloat.sqrt(w*w + x*x + y*y + z*z);
+ if (norme == 0.0f)
+ {
+ w = 1.0f;
+ x = y = z = 0.0f;
+ }
+ else
+ {
+ float recip = 1.0f/norme;
+
+ w *= recip;
+ x *= recip;
+ y *= recip;
+ z *= recip;
+ }
+ }
+
+ /** Invert the quaternion If rotational,
+ * will produce a the inverse rotation
+ */
+ public void inverse()
+ {
+ float norm = w*w + x*x + y*y + z*z;
+
+ float recip = 1.0f/norm;
+
+ w *= recip;
+ x = -1*x*recip;
+ y = -1*y*recip;
+ z = -1*z*recip;
+ }
+
+ /** Transform this quaternion to a
+ * 4x4 column matrix representing the rotation
+ * @return new float[16] column matrix 4x4
+ */
+ public float[] toMatrix()
+ {
+ float[] matrix = new float[16];
+ matrix[0] = 1.0f - 2*y*y - 2*z*z;
+ matrix[1] = 2*x*y + 2*w*z;
+ matrix[2] = 2*x*z - 2*w*y;
+ matrix[3] = 0;
+
+ matrix[4] = 2*x*y - 2*w*z;
+ matrix[5] = 1.0f - 2*x*x - 2*z*z;
+ matrix[6] = 2*y*z + 2*w*x;
+ matrix[7] = 0;
+
+ matrix[8] = 2*x*z + 2*w*y;
+ matrix[9] = 2*y*z - 2*w*x;
+ matrix[10] = 1.0f - 2*x*x - 2*y*y;
+ matrix[11] = 0;
+
+ matrix[12] = 0;
+ matrix[13] = 0;
+ matrix[14] = 0;
+ matrix[15] = 1;
+ return matrix;
+ }
+
+ /** Set this quaternion from a Sphereical interpolation
+ * of two param quaternion, used mostly for rotational animation
+ * @param a initial quaternion
+ * @param b target quaternion
+ * @param t float between 0 and 1 representing interp.
+ */
+ public void slerp(Quaternion a,Quaternion b, float t)
+ {
+ float omega, cosom, sinom, sclp, sclq;
+ cosom = a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w;
+ if ((1.0f+cosom) > MathFloat.E) {
+ if ((1.0f-cosom) > MathFloat.E) {
+ omega = (float)MathFloat.acos(cosom);
+ sinom = (float)MathFloat.sin(omega);
+ sclp = (float)MathFloat.sin((1.0f-t)*omega) / sinom;
+ sclq = (float)MathFloat.sin(t*omega) / sinom;
+ }
+ else {
+ sclp = 1.0f - t;
+ sclq = t;
+ }
+ x = sclp*a.x + sclq*b.x;
+ y = sclp*a.y + sclq*b.y;
+ z = sclp*a.z + sclq*b.z;
+ w = sclp*a.w + sclq*b.w;
+ }
+ else {
+ x =-a.y;
+ y = a.x;
+ z =-a.w;
+ w = a.z;
+ sclp = MathFloat.sin((1.0f-t) * MathFloat.PI * 0.5f);
+ sclq = MathFloat.sin(t * MathFloat.PI * 0.5f);
+ x = sclp*a.x + sclq*b.x;
+ y = sclp*a.y + sclq*b.y;
+ z = sclp*a.z + sclq*b.z;
+ }
+ }
+
+ /** Check if this quaternion is empty, ie (0,0,0,1)
+ * @return true if empty, false otherwise
+ */
+ public boolean isEmpty()
+ {
+ if (w==1 && x==0 && y==0 && z==0)
+ return true;
+ return false;
+ }
+
+ /** Check if this quaternion represents an identity
+ * matrix, for rotation.
+ * @return true if it is an identity rep., false otherwise
+ */
+ public boolean isIdentity()
+ {
+ if (w==0 && x==0 && y==0 && z==0)
+ return true;
+ return false;
+ }
+
+ /** compute the quaternion from a 3x3 column matrix
+ * @param m 3x3 column matrix
+ */
+ public void setFromMatrix(float[] m) {
+ float T= m[0] + m[4] + m[8] + 1;
+ if (T>0){
+ float S = 0.5f / (float)MathFloat.sqrt(T);
+ w = 0.25f / S;
+ x = ( m[5] - m[7]) * S;
+ y = ( m[6] - m[2]) * S;
+ z = ( m[1] - m[3] ) * S;
+ }
+ else{
+ if ((m[0] > m[4])&(m[0] > m[8])) {
+ float S = MathFloat.sqrt( 1.0f + m[0] - m[4] - m[8] ) * 2f; // S=4*qx
+ w = (m[7] - m[5]) / S;
+ x = 0.25f * S;
+ y = (m[3] + m[1]) / S;
+ z = (m[6] + m[2]) / S;
+ }
+ else if (m[4] > m[8]) {
+ float S = MathFloat.sqrt( 1.0f + m[4] - m[0] - m[8] ) * 2f; // S=4*qy
+ w = (m[6] - m[2]) / S;
+ x = (m[3] + m[1]) / S;
+ y = 0.25f * S;
+ z = (m[7] + m[5]) / S;
+ }
+ else {
+ float S = MathFloat.sqrt( 1.0f + m[8] - m[0] - m[4] ) * 2f; // S=4*qz
+ w = (m[3] - m[1]) / S;
+ x = (m[6] + m[2]) / S;
+ y = (m[7] + m[5]) / S;
+ z = 0.25f * S;
+ }
+ }
+ }
+
+ /** Check if the the 3x3 matrix (param) is in fact
+ * an affine rotational matrix
+ * @param m 3x3 column matrix
+ * @return true if representing a rotational matrix, false otherwise
+ */
+ public boolean isRotationMatrix(float[] m) {
+ double epsilon = 0.01; // margin to allow for rounding errors
+ if (MathFloat.abs(m[0]*m[3] + m[3]*m[4] + m[6]*m[7]) > epsilon) return false;
+ if (MathFloat.abs(m[0]*m[2] + m[3]*m[5] + m[6]*m[8]) > epsilon) return false;
+ if (MathFloat.abs(m[1]*m[2] + m[4]*m[5] + m[7]*m[8]) > epsilon) return false;
+ if (MathFloat.abs(m[0]*m[0] + m[3]*m[3] + m[6]*m[6] - 1) > epsilon) return false;
+ if (MathFloat.abs(m[1]*m[1] + m[4]*m[4] + m[7]*m[7] - 1) > epsilon) return false;
+ if (MathFloat.abs(m[2]*m[2] + m[5]*m[5] + m[8]*m[8] - 1) > epsilon) return false;
+ return (MathFloat.abs(determinant(m)-1) < epsilon);
+ }
+ private float determinant(float[] m) {
+ return m[0]*m[4]*m[8] + m[3]*m[7]*m[2] + m[6]*m[1]*m[5] - m[0]*m[7]*m[5] - m[3]*m[1]*m[8] - m[6]*m[4]*m[2];
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/graph/math/VectorUtil.java b/src/jogl/classes/com/jogamp/graph/math/VectorUtil.java
index b1f2023f3..d51afcbab 100755
--- a/src/jogl/classes/com/jogamp/graph/math/VectorUtil.java
+++ b/src/jogl/classes/com/jogamp/graph/math/VectorUtil.java
@@ -1,433 +1,433 @@
-/**
- * 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.math;
-
-import java.util.ArrayList;
-
-import jogamp.graph.math.MathFloat;
-
-import com.jogamp.graph.geom.Vertex;
-
-public class VectorUtil {
-
- public enum Winding {
- CW(-1), CCW(1);
-
- public final int dir;
-
- Winding(int dir) {
- this.dir = dir;
- }
- }
-
- public static final int COLLINEAR = 0;
-
- /** compute the dot product of two points
- * @param vec1 vector 1
- * @param vec2 vector 2
- * @return the dot product as float
- */
- public static float dot(float[] vec1, float[] vec2)
- {
- return (vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2]);
- }
- /** Normalize a vector
- * @param vector input vector
- * @return normalized vector
- */
- public static float[] normalize(float[] vector)
- {
- float[] newVector = new float[3];
-
- float d = MathFloat.sqrt(vector[0]*vector[0] + vector[1]*vector[1] + vector[2]*vector[2]);
- if(d> 0.0f)
- {
- newVector[0] = vector[0]/d;
- newVector[1] = vector[1]/d;
- newVector[2] = vector[2]/d;
- }
- return newVector;
- }
-
- /** Scales a vector by param
- * @param vector input vector
- * @param scale constant to scale by
- * @return scaled vector
- */
- public static float[] scale(float[] vector, float scale)
- {
- float[] newVector = new float[3];
-
- newVector[0] = vector[0]*scale;
- newVector[1] = vector[1]*scale;
- newVector[2] = vector[2]*scale;
- return newVector;
- }
-
- /** Adds to vectors
- * @param v1 vector 1
- * @param v2 vector 2
- * @return v1 + v2
- */
- public static float[] vectorAdd(float[] v1, float[] v2)
- {
- float[] newVector = new float[3];
-
- newVector[0] = v1[0] + v2[0];
- newVector[1] = v1[1] + v2[1];
- newVector[2] = v1[2] + v2[2];
- return newVector;
- }
-
- /** cross product vec1 x vec2
- * @param vec1 vector 1
- * @param vec2 vecttor 2
- * @return the resulting vector
- */
- public static float[] cross(float[] vec1, float[] vec2)
- {
- float[] out = new float[3];
-
- out[0] = vec2[2]*vec1[1] - vec2[1]*vec1[2];
- out[1] = vec2[0]*vec1[2] - vec2[2]*vec1[0];
- out[2] = vec2[1]*vec1[0] - vec2[0]*vec1[1];
-
- return out;
- }
-
- /** Column Matrix Vector multiplication
- * @param colMatrix column matrix (4x4)
- * @param vec vector(x,y,z)
- * @return result new float[3]
- */
- public static float[] colMatrixVectorMult(float[] colMatrix, float[] vec)
- {
- float[] out = new float[3];
-
- out[0] = vec[0]*colMatrix[0] + vec[1]*colMatrix[4] + vec[2]*colMatrix[8] + colMatrix[12];
- out[1] = vec[0]*colMatrix[1] + vec[1]*colMatrix[5] + vec[2]*colMatrix[9] + colMatrix[13];
- out[2] = vec[0]*colMatrix[2] + vec[1]*colMatrix[6] + vec[2]*colMatrix[10] + colMatrix[14];
-
- return out;
- }
-
- /** Matrix Vector multiplication
- * @param rawMatrix column matrix (4x4)
- * @param vec vector(x,y,z)
- * @return result new float[3]
- */
- public static float[] rowMatrixVectorMult(float[] rawMatrix, float[] vec)
- {
- float[] out = new float[3];
-
- out[0] = vec[0]*rawMatrix[0] + vec[1]*rawMatrix[1] + vec[2]*rawMatrix[2] + rawMatrix[3];
- out[1] = vec[0]*rawMatrix[4] + vec[1]*rawMatrix[5] + vec[2]*rawMatrix[6] + rawMatrix[7];
- out[2] = vec[0]*rawMatrix[8] + vec[1]*rawMatrix[9] + vec[2]*rawMatrix[10] + rawMatrix[11];
-
- return out;
- }
-
- /** Calculate the midpoint of two values
- * @param p1 first value
- * @param p2 second vale
- * @return midpoint
- */
- public static float mid(float p1, float p2)
- {
- return (p1+p2)/2.0f;
- }
- /** Calculate the midpoint of two points
- * @param p1 first point
- * @param p2 second point
- * @return midpoint
- */
- public static float[] mid(float[] p1, float[] p2)
- {
- float[] midPoint = new float[3];
- midPoint[0] = (p1[0] + p2[0])*0.5f;
- midPoint[1] = (p1[1] + p2[1])*0.5f;
- midPoint[2] = (p1[2] + p2[2])*0.5f;
-
- return midPoint;
- }
- /** Compute the norm of a vector
- * @param vec vector
- * @return vorm
- */
- public static float norm(float[] vec)
- {
- return MathFloat.sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
- }
- /** Compute distance between 2 points
- * @param p0 a ref point on the line
- * @param vec vector representing the direction of the line
- * @param point the point to compute the relative distance of
- * @return distance float
- */
- public static float computeLength(float[] p0, float[] point)
- {
- float[] w = new float[]{point[0]-p0[0],point[1]-p0[1],point[2]-p0[2]};
-
- float distance = MathFloat.sqrt(w[0]*w[0] + w[1]*w[1] + w[2]*w[2]);
-
- return distance;
- }
-
- /**Check equality of 2 vec3 vectors
- * @param v1 vertex 1
- * @param v2 vertex 2
- * @return
- */
- public static boolean checkEquality(float[] v1, float[] v2)
- {
- if(Float.compare(v1[0], v2[0]) == 0 &&
- Float.compare(v1[1], v2[1]) == 0 &&
- Float.compare(v1[2], v2[2]) == 0 )
- return true;
- return false;
- }
-
- /**Check equality of 2 vec2 vectors
- * @param v1 vertex 1
- * @param v2 vertex 2
- * @return
- */
- public static boolean checkEqualityVec2(float[] v1, float[] v2)
- {
- if(Float.compare(v1[0], v2[0]) == 0 &&
- Float.compare(v1[1], v2[1]) == 0)
- return true;
- return false;
- }
-
- /** Compute the determinant of 3 vectors
- * @param a vector 1
- * @param b vector 2
- * @param c vector 3
- * @return the determinant value
- */
- public static float computeDeterminant(float[] a, float[] b, float[] c)
- {
- float area = 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];
- return area;
- }
-
- /** Check if three vertices are colliniear
- * @param v1 vertex 1
- * @param v2 vertex 2
- * @param v3 vertex 3
- * @return true if collinear, false otherwise
- */
- public static boolean checkCollinear(float[] v1, float[] v2, float[] v3)
- {
- return (computeDeterminant(v1, v2, v3) == VectorUtil.COLLINEAR);
- }
-
- /** Compute Vector
- * @param v1 vertex 1
- * @param v2 vertex2 2
- * @return Vector V1V2
- */
- public static float[] computeVector(float[] v1, float[] v2)
- {
- float[] vector = new float[3];
- vector[0] = v2[0] - v1[0];
- vector[1] = v2[1] - v1[1];
- vector[2] = v2[2] - v1[2];
- return vector;
- }
-
- /** Check if vertices in triangle circumcircle
- * @param a triangle vertex 1
- * @param b triangle vertex 2
- * @param c triangle vertex 3
- * @param d vertex in question
- * @return true if the vertex d is inside the circle defined by the
- * vertices a, b, c. from paper by Guibas and Stolfi (1985).
- */
- public static boolean inCircle(Vertex a, Vertex b, Vertex c, Vertex d){
- return (a.getX() * a.getX() + a.getY() * a.getY()) * triArea(b, c, d) -
- (b.getX() * b.getX() + b.getY() * b.getY()) * triArea(a, c, d) +
- (c.getX() * c.getX() + c.getY() * c.getY()) * triArea(a, b, d) -
- (d.getX() * d.getX() + d.getY() * d.getY()) * triArea(a, b, c) > 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 triArea(Vertex a, Vertex b, Vertex c){
- return (b.getX() - a.getX()) * (c.getY() - a.getY()) - (b.getY() - a.getY())*(c.getX() - a.getX());
- }
-
- /** 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
- * @return true if p is in triangle (a, b, c), false otherwise.
- */
- public static boolean vertexInTriangle(float[] a, float[] b, float[] c, float[] p){
- // Compute vectors
- float[] ac = computeVector(a, c); //v0
- float[] ab = computeVector(a, b); //v1
- float[] ap = computeVector(a, p); //v2
-
- // Compute dot products
- float dot00 = dot(ac, ac);
- float dot01 = dot(ac, ab);
- float dot02 = dot(ac, ap);
- float dot11 = dot(ab, ab);
- float dot12 = dot(ab, ap);
-
- // Compute barycentric coordinates
- float invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
- float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
- float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
-
- // Check if point is in triangle
- return (u >= 0) && (v >= 0) && (u + v < 1);
- }
-
- /** Check if points are in ccw order
- * @param a first vertex
- * @param b second vertex
- * @param c third vertex
- * @return true if the points a,b,c are in a ccw order
- */
- public static boolean ccw(Vertex a, Vertex b, Vertex c){
- return triArea(a,b,c) > 0;
- }
-
- /** Compute the winding of given points
- * @param a first vertex
- * @param b second vertex
- * @param c third vertex
- * @return Winding
- */
- public static Winding getWinding(Vertex a, Vertex b, Vertex c) {
- return triArea(a,b,c) > 0 ? Winding.CCW : Winding.CW ;
- }
-
- /** Computes the area of a list of vertices to check if ccw
- * @param vertices
- * @return positive area if ccw else negative area value
- */
- public static float area(ArrayList vertices) {
- int n = vertices.size();
- float area = 0.0f;
- for (int p = n - 1, q = 0; q < n; p = q++)
- {
- float[] pCoord = vertices.get(p).getCoord();
- float[] qCoord = vertices.get(q).getCoord();
- area += pCoord[0] * qCoord[1] - qCoord[0] * pCoord[1];
- }
- return area;
- }
-
- /** Compute the general winding of the vertices
- * @param vertices array of Vertices
- * @return CCW or CW {@link Winding}
- */
- public static Winding getWinding(ArrayList vertices) {
- return area(vertices) >= 0 ? Winding.CCW : Winding.CW ;
- }
-
-
- /** Compute intersection between two segments
- * @param a vertex 1 of first segment
- * @param b vertex 2 of first segment
- * @param c vertex 1 of second segment
- * @param d vertex 2 of second segment
- * @return the intersection coordinates if the segments intersect, otherwise
- * returns null
- */
- public static float[] seg2SegIntersection(Vertex a, Vertex b, Vertex c, Vertex d) {
- float determinant = (a.getX()-b.getX())*(c.getY()-d.getY()) - (a.getY()-b.getY())*(c.getX()-d.getX());
-
- if (determinant == 0)
- return null;
-
- float alpha = (a.getX()*b.getY()-a.getY()*b.getX());
- float beta = (c.getX()*d.getY()-c.getY()*d.getY());
- float xi = ((c.getX()-d.getX())*alpha-(a.getX()-b.getX())*beta)/determinant;
- float yi = ((c.getY()-d.getY())*alpha-(a.getY()-b.getY())*beta)/determinant;
-
- float gamma = (xi - a.getX())/(b.getX() - a.getX());
- float gamma1 = (xi - c.getX())/(d.getX() - c.getX());
- if(gamma <= 0 || gamma >= 1) return null;
- if(gamma1 <= 0 || gamma1 >= 1) return null;
-
- return new float[]{xi,yi,0};
- }
-
- /** Compute intersection between two lines
- * @param a vertex 1 of first line
- * @param b vertex 2 of first line
- * @param c vertex 1 of second line
- * @param d vertex 2 of second line
- * @return the intersection coordinates if the lines intersect, otherwise
- * returns null
- */
- public static float[] line2lineIntersection(Vertex a, Vertex b, Vertex c, Vertex d) {
- float determinant = (a.getX()-b.getX())*(c.getY()-d.getY()) - (a.getY()-b.getY())*(c.getX()-d.getX());
-
- if (determinant == 0)
- return null;
-
- float alpha = (a.getX()*b.getY()-a.getY()*b.getX());
- float beta = (c.getX()*d.getY()-c.getY()*d.getY());
- float xi = ((c.getX()-d.getX())*alpha-(a.getX()-b.getX())*beta)/determinant;
- float yi = ((c.getY()-d.getY())*alpha-(a.getY()-b.getY())*beta)/determinant;
-
- return new float[]{xi,yi,0};
- }
-
- /** Check if a segment intersects with a triangle
- * @param a vertex 1 of the triangle
- * @param b vertex 2 of the triangle
- * @param c vertex 3 of the triangle
- * @param d vertex 1 of first segment
- * @param e vertex 2 of first segment
- * @return true if the segment intersects at least one segment of the triangle, false otherwise
- */
- public static boolean tri2SegIntersection(Vertex a, Vertex b, Vertex c, Vertex d, Vertex e){
- if(seg2SegIntersection(a, b, d, e) != null)
- return true;
- if(seg2SegIntersection(b, c, d, e) != null)
- return true;
- if(seg2SegIntersection(a, c, d, e) != null)
- return true;
-
- return false;
- }
-}
+/**
+ * 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.math;
+
+import java.util.ArrayList;
+
+import jogamp.graph.math.MathFloat;
+
+import com.jogamp.graph.geom.Vertex;
+
+public class VectorUtil {
+
+ public enum Winding {
+ CW(-1), CCW(1);
+
+ public final int dir;
+
+ Winding(int dir) {
+ this.dir = dir;
+ }
+ }
+
+ public static final int COLLINEAR = 0;
+
+ /** compute the dot product of two points
+ * @param vec1 vector 1
+ * @param vec2 vector 2
+ * @return the dot product as float
+ */
+ public static float dot(float[] vec1, float[] vec2)
+ {
+ return (vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2]);
+ }
+ /** Normalize a vector
+ * @param vector input vector
+ * @return normalized vector
+ */
+ public static float[] normalize(float[] vector)
+ {
+ float[] newVector = new float[3];
+
+ float d = MathFloat.sqrt(vector[0]*vector[0] + vector[1]*vector[1] + vector[2]*vector[2]);
+ if(d> 0.0f)
+ {
+ newVector[0] = vector[0]/d;
+ newVector[1] = vector[1]/d;
+ newVector[2] = vector[2]/d;
+ }
+ return newVector;
+ }
+
+ /** Scales a vector by param
+ * @param vector input vector
+ * @param scale constant to scale by
+ * @return scaled vector
+ */
+ public static float[] scale(float[] vector, float scale)
+ {
+ float[] newVector = new float[3];
+
+ newVector[0] = vector[0]*scale;
+ newVector[1] = vector[1]*scale;
+ newVector[2] = vector[2]*scale;
+ return newVector;
+ }
+
+ /** Adds to vectors
+ * @param v1 vector 1
+ * @param v2 vector 2
+ * @return v1 + v2
+ */
+ public static float[] vectorAdd(float[] v1, float[] v2)
+ {
+ float[] newVector = new float[3];
+
+ newVector[0] = v1[0] + v2[0];
+ newVector[1] = v1[1] + v2[1];
+ newVector[2] = v1[2] + v2[2];
+ return newVector;
+ }
+
+ /** cross product vec1 x vec2
+ * @param vec1 vector 1
+ * @param vec2 vecttor 2
+ * @return the resulting vector
+ */
+ public static float[] cross(float[] vec1, float[] vec2)
+ {
+ float[] out = new float[3];
+
+ out[0] = vec2[2]*vec1[1] - vec2[1]*vec1[2];
+ out[1] = vec2[0]*vec1[2] - vec2[2]*vec1[0];
+ out[2] = vec2[1]*vec1[0] - vec2[0]*vec1[1];
+
+ return out;
+ }
+
+ /** Column Matrix Vector multiplication
+ * @param colMatrix column matrix (4x4)
+ * @param vec vector(x,y,z)
+ * @return result new float[3]
+ */
+ public static float[] colMatrixVectorMult(float[] colMatrix, float[] vec)
+ {
+ float[] out = new float[3];
+
+ out[0] = vec[0]*colMatrix[0] + vec[1]*colMatrix[4] + vec[2]*colMatrix[8] + colMatrix[12];
+ out[1] = vec[0]*colMatrix[1] + vec[1]*colMatrix[5] + vec[2]*colMatrix[9] + colMatrix[13];
+ out[2] = vec[0]*colMatrix[2] + vec[1]*colMatrix[6] + vec[2]*colMatrix[10] + colMatrix[14];
+
+ return out;
+ }
+
+ /** Matrix Vector multiplication
+ * @param rawMatrix column matrix (4x4)
+ * @param vec vector(x,y,z)
+ * @return result new float[3]
+ */
+ public static float[] rowMatrixVectorMult(float[] rawMatrix, float[] vec)
+ {
+ float[] out = new float[3];
+
+ out[0] = vec[0]*rawMatrix[0] + vec[1]*rawMatrix[1] + vec[2]*rawMatrix[2] + rawMatrix[3];
+ out[1] = vec[0]*rawMatrix[4] + vec[1]*rawMatrix[5] + vec[2]*rawMatrix[6] + rawMatrix[7];
+ out[2] = vec[0]*rawMatrix[8] + vec[1]*rawMatrix[9] + vec[2]*rawMatrix[10] + rawMatrix[11];
+
+ return out;
+ }
+
+ /** Calculate the midpoint of two values
+ * @param p1 first value
+ * @param p2 second vale
+ * @return midpoint
+ */
+ public static float mid(float p1, float p2)
+ {
+ return (p1+p2)/2.0f;
+ }
+ /** Calculate the midpoint of two points
+ * @param p1 first point
+ * @param p2 second point
+ * @return midpoint
+ */
+ public static float[] mid(float[] p1, float[] p2)
+ {
+ float[] midPoint = new float[3];
+ midPoint[0] = (p1[0] + p2[0])*0.5f;
+ midPoint[1] = (p1[1] + p2[1])*0.5f;
+ midPoint[2] = (p1[2] + p2[2])*0.5f;
+
+ return midPoint;
+ }
+ /** Compute the norm of a vector
+ * @param vec vector
+ * @return vorm
+ */
+ public static float norm(float[] vec)
+ {
+ return MathFloat.sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
+ }
+ /** Compute distance between 2 points
+ * @param p0 a ref point on the line
+ * @param vec vector representing the direction of the line
+ * @param point the point to compute the relative distance of
+ * @return distance float
+ */
+ public static float computeLength(float[] p0, float[] point)
+ {
+ float[] w = new float[]{point[0]-p0[0],point[1]-p0[1],point[2]-p0[2]};
+
+ float distance = MathFloat.sqrt(w[0]*w[0] + w[1]*w[1] + w[2]*w[2]);
+
+ return distance;
+ }
+
+ /**Check equality of 2 vec3 vectors
+ * @param v1 vertex 1
+ * @param v2 vertex 2
+ * @return
+ */
+ public static boolean checkEquality(float[] v1, float[] v2)
+ {
+ if(Float.compare(v1[0], v2[0]) == 0 &&
+ Float.compare(v1[1], v2[1]) == 0 &&
+ Float.compare(v1[2], v2[2]) == 0 )
+ return true;
+ return false;
+ }
+
+ /**Check equality of 2 vec2 vectors
+ * @param v1 vertex 1
+ * @param v2 vertex 2
+ * @return
+ */
+ public static boolean checkEqualityVec2(float[] v1, float[] v2)
+ {
+ if(Float.compare(v1[0], v2[0]) == 0 &&
+ Float.compare(v1[1], v2[1]) == 0)
+ return true;
+ return false;
+ }
+
+ /** Compute the determinant of 3 vectors
+ * @param a vector 1
+ * @param b vector 2
+ * @param c vector 3
+ * @return the determinant value
+ */
+ public static float computeDeterminant(float[] a, float[] b, float[] c)
+ {
+ float area = 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];
+ return area;
+ }
+
+ /** Check if three vertices are colliniear
+ * @param v1 vertex 1
+ * @param v2 vertex 2
+ * @param v3 vertex 3
+ * @return true if collinear, false otherwise
+ */
+ public static boolean checkCollinear(float[] v1, float[] v2, float[] v3)
+ {
+ return (computeDeterminant(v1, v2, v3) == VectorUtil.COLLINEAR);
+ }
+
+ /** Compute Vector
+ * @param v1 vertex 1
+ * @param v2 vertex2 2
+ * @return Vector V1V2
+ */
+ public static float[] computeVector(float[] v1, float[] v2)
+ {
+ float[] vector = new float[3];
+ vector[0] = v2[0] - v1[0];
+ vector[1] = v2[1] - v1[1];
+ vector[2] = v2[2] - v1[2];
+ return vector;
+ }
+
+ /** Check if vertices in triangle circumcircle
+ * @param a triangle vertex 1
+ * @param b triangle vertex 2
+ * @param c triangle vertex 3
+ * @param d vertex in question
+ * @return true if the vertex d is inside the circle defined by the
+ * vertices a, b, c. from paper by Guibas and Stolfi (1985).
+ */
+ public static boolean inCircle(Vertex a, Vertex b, Vertex c, Vertex d){
+ return (a.getX() * a.getX() + a.getY() * a.getY()) * triArea(b, c, d) -
+ (b.getX() * b.getX() + b.getY() * b.getY()) * triArea(a, c, d) +
+ (c.getX() * c.getX() + c.getY() * c.getY()) * triArea(a, b, d) -
+ (d.getX() * d.getX() + d.getY() * d.getY()) * triArea(a, b, c) > 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 triArea(Vertex a, Vertex b, Vertex c){
+ return (b.getX() - a.getX()) * (c.getY() - a.getY()) - (b.getY() - a.getY())*(c.getX() - a.getX());
+ }
+
+ /** 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
+ * @return true if p is in triangle (a, b, c), false otherwise.
+ */
+ public static boolean vertexInTriangle(float[] a, float[] b, float[] c, float[] p){
+ // Compute vectors
+ float[] ac = computeVector(a, c); //v0
+ float[] ab = computeVector(a, b); //v1
+ float[] ap = computeVector(a, p); //v2
+
+ // Compute dot products
+ float dot00 = dot(ac, ac);
+ float dot01 = dot(ac, ab);
+ float dot02 = dot(ac, ap);
+ float dot11 = dot(ab, ab);
+ float dot12 = dot(ab, ap);
+
+ // Compute barycentric coordinates
+ float invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
+ float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+ float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
+
+ // Check if point is in triangle
+ return (u >= 0) && (v >= 0) && (u + v < 1);
+ }
+
+ /** Check if points are in ccw order
+ * @param a first vertex
+ * @param b second vertex
+ * @param c third vertex
+ * @return true if the points a,b,c are in a ccw order
+ */
+ public static boolean ccw(Vertex a, Vertex b, Vertex c){
+ return triArea(a,b,c) > 0;
+ }
+
+ /** Compute the winding of given points
+ * @param a first vertex
+ * @param b second vertex
+ * @param c third vertex
+ * @return Winding
+ */
+ public static Winding getWinding(Vertex a, Vertex b, Vertex c) {
+ return triArea(a,b,c) > 0 ? Winding.CCW : Winding.CW ;
+ }
+
+ /** Computes the area of a list of vertices to check if ccw
+ * @param vertices
+ * @return positive area if ccw else negative area value
+ */
+ public static float area(ArrayList vertices) {
+ int n = vertices.size();
+ float area = 0.0f;
+ for (int p = n - 1, q = 0; q < n; p = q++)
+ {
+ float[] pCoord = vertices.get(p).getCoord();
+ float[] qCoord = vertices.get(q).getCoord();
+ area += pCoord[0] * qCoord[1] - qCoord[0] * pCoord[1];
+ }
+ return area;
+ }
+
+ /** Compute the general winding of the vertices
+ * @param vertices array of Vertices
+ * @return CCW or CW {@link Winding}
+ */
+ public static Winding getWinding(ArrayList vertices) {
+ return area(vertices) >= 0 ? Winding.CCW : Winding.CW ;
+ }
+
+
+ /** Compute intersection between two segments
+ * @param a vertex 1 of first segment
+ * @param b vertex 2 of first segment
+ * @param c vertex 1 of second segment
+ * @param d vertex 2 of second segment
+ * @return the intersection coordinates if the segments intersect, otherwise
+ * returns null
+ */
+ public static float[] seg2SegIntersection(Vertex a, Vertex b, Vertex c, Vertex d) {
+ float determinant = (a.getX()-b.getX())*(c.getY()-d.getY()) - (a.getY()-b.getY())*(c.getX()-d.getX());
+
+ if (determinant == 0)
+ return null;
+
+ float alpha = (a.getX()*b.getY()-a.getY()*b.getX());
+ float beta = (c.getX()*d.getY()-c.getY()*d.getY());
+ float xi = ((c.getX()-d.getX())*alpha-(a.getX()-b.getX())*beta)/determinant;
+ float yi = ((c.getY()-d.getY())*alpha-(a.getY()-b.getY())*beta)/determinant;
+
+ float gamma = (xi - a.getX())/(b.getX() - a.getX());
+ float gamma1 = (xi - c.getX())/(d.getX() - c.getX());
+ if(gamma <= 0 || gamma >= 1) return null;
+ if(gamma1 <= 0 || gamma1 >= 1) return null;
+
+ return new float[]{xi,yi,0};
+ }
+
+ /** Compute intersection between two lines
+ * @param a vertex 1 of first line
+ * @param b vertex 2 of first line
+ * @param c vertex 1 of second line
+ * @param d vertex 2 of second line
+ * @return the intersection coordinates if the lines intersect, otherwise
+ * returns null
+ */
+ public static float[] line2lineIntersection(Vertex a, Vertex b, Vertex c, Vertex d) {
+ float determinant = (a.getX()-b.getX())*(c.getY()-d.getY()) - (a.getY()-b.getY())*(c.getX()-d.getX());
+
+ if (determinant == 0)
+ return null;
+
+ float alpha = (a.getX()*b.getY()-a.getY()*b.getX());
+ float beta = (c.getX()*d.getY()-c.getY()*d.getY());
+ float xi = ((c.getX()-d.getX())*alpha-(a.getX()-b.getX())*beta)/determinant;
+ float yi = ((c.getY()-d.getY())*alpha-(a.getY()-b.getY())*beta)/determinant;
+
+ return new float[]{xi,yi,0};
+ }
+
+ /** Check if a segment intersects with a triangle
+ * @param a vertex 1 of the triangle
+ * @param b vertex 2 of the triangle
+ * @param c vertex 3 of the triangle
+ * @param d vertex 1 of first segment
+ * @param e vertex 2 of first segment
+ * @return true if the segment intersects at least one segment of the triangle, false otherwise
+ */
+ public static boolean tri2SegIntersection(Vertex a, Vertex b, Vertex c, Vertex d, Vertex e){
+ if(seg2SegIntersection(a, b, d, e) != null)
+ return true;
+ if(seg2SegIntersection(b, c, d, e) != null)
+ return true;
+ if(seg2SegIntersection(a, c, d, e) != null)
+ return true;
+
+ return false;
+ }
+}
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java b/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java
index e73b0cb85..1f59b5805 100755
--- a/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java
@@ -1,74 +1,74 @@
-/**
- * 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 jogamp.graph.curve.opengl;
-
-import com.jogamp.graph.curve.Region;
-import com.jogamp.graph.curve.opengl.GLRegion;
-
-/** RegionFactory to create a Context specific Region implementation.
- *
- * @see GLRegion
- */
-public class RegionFactory {
-
- /**
- * Create a Region using the passed render mode
- *
- * In case {@link Region#VBAA_RENDERING_BIT} is being requested the default texture unit
- * {@link Region#TWO_PASS_DEFAULT_TEXTURE_UNIT} is being used.
- *
- * @param rs the RenderState to be used
- * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#VBAA_RENDERING_BIT}
- */
- public static GLRegion create(int renderModes) {
- if( 0 != ( Region.VBAA_RENDERING_BIT & renderModes ) ){
- return new VBORegion2PES2(renderModes, Region.TWO_PASS_DEFAULT_TEXTURE_UNIT);
- }
- else{
- return new VBORegionSPES2(renderModes);
- }
- }
-
- /** Create a Single Pass Region using the passed render mode
- * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT},
- * {@link Region#VBAA_RENDERING_BIT}
- * @return
- */
- public static GLRegion createSinglePass(int renderModes) {
- return new VBORegionSPES2(renderModes);
- }
-
- /** Create a Two Pass (VBAA) Region using the passed render mode
- * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT},
- * {@link Region#VBAA_RENDERING_BIT}
- * @return
- */
- public static GLRegion createTwoPass(int renderModes, int textureUnit) {
- return new VBORegion2PES2(renderModes, textureUnit);
- }
-}
+/**
+ * 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 jogamp.graph.curve.opengl;
+
+import com.jogamp.graph.curve.Region;
+import com.jogamp.graph.curve.opengl.GLRegion;
+
+/** RegionFactory to create a Context specific Region implementation.
+ *
+ * @see GLRegion
+ */
+public class RegionFactory {
+
+ /**
+ * Create a Region using the passed render mode
+ *
+ * In case {@link Region#VBAA_RENDERING_BIT} is being requested the default texture unit
+ * {@link Region#TWO_PASS_DEFAULT_TEXTURE_UNIT} is being used.
+ *
+ * @param rs the RenderState to be used
+ * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#VBAA_RENDERING_BIT}
+ */
+ public static GLRegion create(int renderModes) {
+ if( 0 != ( Region.VBAA_RENDERING_BIT & renderModes ) ){
+ return new VBORegion2PES2(renderModes, Region.TWO_PASS_DEFAULT_TEXTURE_UNIT);
+ }
+ else{
+ return new VBORegionSPES2(renderModes);
+ }
+ }
+
+ /** Create a Single Pass Region using the passed render mode
+ * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT},
+ * {@link Region#VBAA_RENDERING_BIT}
+ * @return
+ */
+ public static GLRegion createSinglePass(int renderModes) {
+ return new VBORegionSPES2(renderModes);
+ }
+
+ /** Create a Two Pass (VBAA) Region using the passed render mode
+ * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT},
+ * {@link Region#VBAA_RENDERING_BIT}
+ * @return
+ */
+ public static GLRegion createTwoPass(int renderModes, int textureUnit) {
+ return new VBORegion2PES2(renderModes, textureUnit);
+ }
+}
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java b/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java
index 117faafb8..c34d1cbeb 100755
--- a/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java
@@ -1,93 +1,93 @@
-/**
- * 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 jogamp.graph.curve.opengl;
-
-import javax.media.opengl.GL2ES2;
-import javax.media.opengl.GLException;
-
-import jogamp.graph.curve.opengl.shader.AttributeNames;
-
-import com.jogamp.graph.curve.Region;
-import com.jogamp.graph.curve.opengl.GLRegion;
-import com.jogamp.graph.curve.opengl.RegionRenderer;
-import com.jogamp.graph.curve.opengl.RenderState;
-import com.jogamp.opengl.util.glsl.ShaderCode;
-import com.jogamp.opengl.util.glsl.ShaderProgram;
-import com.jogamp.opengl.util.glsl.ShaderState;
-
-public class RegionRendererImpl01 extends RegionRenderer {
- public RegionRendererImpl01(RenderState rs, int renderModes) {
- super(rs, renderModes);
-
- }
-
- @Override
- protected String getFragmentShaderName(GL2ES2 gl) {
- final String type = Region.isNonUniformWeight(renderModes) ? "02" : "01" ;
- final String pass = Region.isVBAA(renderModes) ? "b" : "a" ;
- return "curverenderer" + type + pass + getShaderGLVersionSuffix(gl);
- }
-
- protected boolean initShaderProgram(GL2ES2 gl) {
- final ShaderState st = rs.getShaderState();
-
- ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RegionRendererImpl01.class, "shader",
- "shader/bin", getVertexShaderName(gl), false);
- ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RegionRendererImpl01.class, "shader",
- "shader/bin", getFragmentShaderName(gl), false);
-
- ShaderProgram sp = new ShaderProgram();
- sp.add(rsVp);
- sp.add(rsFp);
-
- sp.init(gl);
- st.attachShaderProgram(gl, sp, false);
- st.bindAttribLocation(gl, AttributeNames.VERTEX_ATTR_IDX, AttributeNames.VERTEX_ATTR_NAME);
- st.bindAttribLocation(gl, AttributeNames.TEXCOORD_ATTR_IDX, AttributeNames.TEXCOORD_ATTR_NAME);
-
- if(!sp.link(gl, System.err)) {
- throw new GLException("RegionRenderer: Couldn't link program: "+sp);
- }
- st.useProgram(gl, true);
-
- if(DEBUG) {
- System.err.println("RegionRendererImpl01 initialized: " + Thread.currentThread()+" "+st);
- }
- return true;
- }
-
- @Override
- protected void destroyImpl(GL2ES2 gl) {
- super.destroyImpl(gl);
- }
-
- @Override
- protected void drawImpl(GL2ES2 gl, Region region, float[] position, int[] texSize) {
- ((GLRegion)region).draw(gl, rs, vp_width, vp_height, texSize);
- }
-}
+/**
+ * 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 jogamp.graph.curve.opengl;
+
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLException;
+
+import jogamp.graph.curve.opengl.shader.AttributeNames;
+
+import com.jogamp.graph.curve.Region;
+import com.jogamp.graph.curve.opengl.GLRegion;
+import com.jogamp.graph.curve.opengl.RegionRenderer;
+import com.jogamp.graph.curve.opengl.RenderState;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+import com.jogamp.opengl.util.glsl.ShaderState;
+
+public class RegionRendererImpl01 extends RegionRenderer {
+ public RegionRendererImpl01(RenderState rs, int renderModes) {
+ super(rs, renderModes);
+
+ }
+
+ @Override
+ protected String getFragmentShaderName(GL2ES2 gl) {
+ final String type = Region.isNonUniformWeight(renderModes) ? "02" : "01" ;
+ final String pass = Region.isVBAA(renderModes) ? "b" : "a" ;
+ return "curverenderer" + type + pass + getShaderGLVersionSuffix(gl);
+ }
+
+ protected boolean initShaderProgram(GL2ES2 gl) {
+ final ShaderState st = rs.getShaderState();
+
+ ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RegionRendererImpl01.class, "shader",
+ "shader/bin", getVertexShaderName(gl), false);
+ ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RegionRendererImpl01.class, "shader",
+ "shader/bin", getFragmentShaderName(gl), false);
+
+ ShaderProgram sp = new ShaderProgram();
+ sp.add(rsVp);
+ sp.add(rsFp);
+
+ sp.init(gl);
+ st.attachShaderProgram(gl, sp, false);
+ st.bindAttribLocation(gl, AttributeNames.VERTEX_ATTR_IDX, AttributeNames.VERTEX_ATTR_NAME);
+ st.bindAttribLocation(gl, AttributeNames.TEXCOORD_ATTR_IDX, AttributeNames.TEXCOORD_ATTR_NAME);
+
+ if(!sp.link(gl, System.err)) {
+ throw new GLException("RegionRenderer: Couldn't link program: "+sp);
+ }
+ st.useProgram(gl, true);
+
+ if(DEBUG) {
+ System.err.println("RegionRendererImpl01 initialized: " + Thread.currentThread()+" "+st);
+ }
+ return true;
+ }
+
+ @Override
+ protected void destroyImpl(GL2ES2 gl) {
+ super.destroyImpl(gl);
+ }
+
+ @Override
+ protected void drawImpl(GL2ES2 gl, Region region, float[] position, int[] texSize) {
+ ((GLRegion)region).draw(gl, rs, vp_width, vp_height, texSize);
+ }
+}
diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java
index 916c7b4d8..f155345aa 100644
--- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java
+++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java
@@ -1,222 +1,222 @@
-/**
- * Copyright 2011 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 jogamp.graph.font.typecast;
-
-import java.util.ArrayList;
-
-import jogamp.graph.font.FontInt.GlyphInt;
-import jogamp.graph.font.typecast.ot.OTGlyph;
-import jogamp.graph.font.typecast.ot.Point;
-import jogamp.graph.geom.plane.AffineTransform;
-import jogamp.graph.geom.plane.Path2D;
-import jogamp.graph.geom.plane.PathIterator;
-
-import com.jogamp.graph.curve.OutlineShape;
-import com.jogamp.graph.font.Font;
-import com.jogamp.graph.font.Font.Glyph;
-import com.jogamp.graph.geom.Vertex;
-import com.jogamp.graph.geom.Vertex.Factory;
-
-/**
- * Factory to build a {@link com.jogamp.graph.geom.Path2D Path2D} from
- * {@link jogamp.graph.font.typecast.ot.OTGlyph Glyph}s.
- */
-public class TypecastRenderer {
-
- private static void getPaths(TypecastFont font,
- CharSequence string, float pixelSize, AffineTransform transform, Path2D[] p)
- {
- if (string == null) {
- return;
- }
- Font.Metrics metrics = font.getMetrics();
- float advanceTotal = 0;
- float lineGap = metrics.getLineGap(pixelSize) ;
- float ascent = metrics.getAscent(pixelSize) ;
- float descent = metrics.getDescent(pixelSize) ;
- if (transform == null) {
- transform = new AffineTransform();
- }
- AffineTransform t = new AffineTransform();
-
- float advanceY = lineGap - descent + ascent;
- float y = 0;
- for (int i=0; i getOutlineShapes(TypecastFont font, CharSequence string, float pixelSize, AffineTransform transform, Factory extends Vertex> vertexFactory) {
- Path2D[] paths = new Path2D[string.length()];
- getPaths(font, string, pixelSize, transform, paths);
-
- ArrayList shapes = new ArrayList();
- final int numGlyps = paths.length;
- for (int index=0;index vertexFactory, float[] coords, int segmentType){
- switch(segmentType) {
- case PathIterator.SEG_MOVETO:
- shape.closeLastOutline();
- shape.addEmptyOutline();
- shape.addVertex(0, vertexFactory.create(coords, 0, 2, true));
- break;
- case PathIterator.SEG_LINETO:
- shape.addVertex(0, vertexFactory.create(coords, 0, 2, true));
- break;
- case PathIterator.SEG_QUADTO:
- shape.addVertex(0, vertexFactory.create(coords, 0, 2, false));
- shape.addVertex(0, vertexFactory.create(coords, 2, 2, true));
- break;
- case PathIterator.SEG_CUBICTO:
- shape.addVertex(0, vertexFactory.create(coords, 0, 2, false));
- shape.addVertex(0, vertexFactory.create(coords, 2, 2, false));
- shape.addVertex(0, vertexFactory.create(coords, 4, 2, true));
- break;
- case PathIterator.SEG_CLOSE:
- shape.closeLastOutline();
- break;
- default:
- throw new IllegalArgumentException("Unhandled Segment Type: "+segmentType);
- }
- }
-
- /**
- * Build a {@link com.jogamp.graph.geom.Path2D Path2D} from a
- * {@link jogamp.graph.font.typecast.ot.OTGlyph Glyph}. This glyph path can then
- * be transformed and rendered.
- */
- public static Path2D buildPath(OTGlyph glyph) {
-
- if (glyph == null) {
- return null;
- }
-
- Path2D glyphPath = new Path2D();
-
- // Iterate through all of the points in the glyph. Each time we find a
- // contour end point, add the point range to the path.
- int firstIndex = 0;
- int count = 0;
- for (int i = 0; i < glyph.getPointCount(); i++) {
- count++;
- if (glyph.getPoint(i).endOfContour) {
- addContourToPath(glyphPath, glyph, firstIndex, count);
- firstIndex = i + 1;
- count = 0;
- }
- }
- return glyphPath;
- }
-
- private static void addContourToPath(Path2D gp, OTGlyph glyph, int startIndex, int count) {
- int offset = 0;
- while (offset < count) {
- Point point = glyph.getPoint(startIndex + offset%count);
- Point point_plus1 = glyph.getPoint(startIndex + (offset+1)%count);
- Point point_plus2 = glyph.getPoint(startIndex + (offset+2)%count);
- if(offset == 0)
- {
- gp.moveTo(point.x, point.y);
- }
-
- if (point.onCurve) {
- if (point_plus1.onCurve) {
- // s = new Line2D.Float(point.x, point.y, point_plus1.x, point_plus1.y);
- gp.lineTo( point_plus1.x, point_plus1.y );
- offset++;
- } else {
- if (point_plus2.onCurve) {
- // s = new QuadCurve2D.Float( point.x, point.y, point_plus1.x, point_plus1.y, point_plus2.x, point_plus2.y);
- gp.quadTo(point_plus1.x, point_plus1.y, point_plus2.x, point_plus2.y);
- offset+=2;
- } else {
- // s = new QuadCurve2D.Float(point.x,point.y,point_plus1.x,point_plus1.y,
- // midValue(point_plus1.x, point_plus2.x), midValue(point_plus1.y, point_plus2.y));
- gp.quadTo(point_plus1.x, point_plus1.y, midValue(point_plus1.x, point_plus2.x), midValue(point_plus1.y, point_plus2.y));
- offset+=2;
- }
- }
- } else {
- if (point_plus1.onCurve) {
- // s = new QuadCurve2D.Float(midValue(point_minus1.x, point.x), midValue(point_minus1.y, point.y),
- // point.x, point.y, point_plus1.x, point_plus1.y);
- //gp.curve3(point_plus1.x, point_plus1.y, point.x, point.y);
- gp.quadTo(point.x, point.y, point_plus1.x, point_plus1.y);
- offset++;
-
- } else {
- // s = new QuadCurve2D.Float(midValue(point_minus1.x, point.x), midValue(point_minus1.y, point.y), point.x, point.y,
- // midValue(point.x, point_plus1.x), midValue(point.y, point_plus1.y));
- //gp.curve3(midValue(point.x, point_plus1.x), midValue(point.y, point_plus1.y), point.x, point.y);
- gp.quadTo(point.x, point.y, midValue(point.x, point_plus1.x), midValue(point.y, point_plus1.y));
- offset++;
- }
- }
- }
- }
-
- private static int midValue(int a, int b) {
- return a + (b - a)/2;
- }
-}
+/**
+ * Copyright 2011 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 jogamp.graph.font.typecast;
+
+import java.util.ArrayList;
+
+import jogamp.graph.font.FontInt.GlyphInt;
+import jogamp.graph.font.typecast.ot.OTGlyph;
+import jogamp.graph.font.typecast.ot.Point;
+import jogamp.graph.geom.plane.AffineTransform;
+import jogamp.graph.geom.plane.Path2D;
+import jogamp.graph.geom.plane.PathIterator;
+
+import com.jogamp.graph.curve.OutlineShape;
+import com.jogamp.graph.font.Font;
+import com.jogamp.graph.font.Font.Glyph;
+import com.jogamp.graph.geom.Vertex;
+import com.jogamp.graph.geom.Vertex.Factory;
+
+/**
+ * Factory to build a {@link com.jogamp.graph.geom.Path2D Path2D} from
+ * {@link jogamp.graph.font.typecast.ot.OTGlyph Glyph}s.
+ */
+public class TypecastRenderer {
+
+ private static void getPaths(TypecastFont font,
+ CharSequence string, float pixelSize, AffineTransform transform, Path2D[] p)
+ {
+ if (string == null) {
+ return;
+ }
+ Font.Metrics metrics = font.getMetrics();
+ float advanceTotal = 0;
+ float lineGap = metrics.getLineGap(pixelSize) ;
+ float ascent = metrics.getAscent(pixelSize) ;
+ float descent = metrics.getDescent(pixelSize) ;
+ if (transform == null) {
+ transform = new AffineTransform();
+ }
+ AffineTransform t = new AffineTransform();
+
+ float advanceY = lineGap - descent + ascent;
+ float y = 0;
+ for (int i=0; i getOutlineShapes(TypecastFont font, CharSequence string, float pixelSize, AffineTransform transform, Factory extends Vertex> vertexFactory) {
+ Path2D[] paths = new Path2D[string.length()];
+ getPaths(font, string, pixelSize, transform, paths);
+
+ ArrayList shapes = new ArrayList();
+ final int numGlyps = paths.length;
+ for (int index=0;index vertexFactory, float[] coords, int segmentType){
+ switch(segmentType) {
+ case PathIterator.SEG_MOVETO:
+ shape.closeLastOutline();
+ shape.addEmptyOutline();
+ shape.addVertex(0, vertexFactory.create(coords, 0, 2, true));
+ break;
+ case PathIterator.SEG_LINETO:
+ shape.addVertex(0, vertexFactory.create(coords, 0, 2, true));
+ break;
+ case PathIterator.SEG_QUADTO:
+ shape.addVertex(0, vertexFactory.create(coords, 0, 2, false));
+ shape.addVertex(0, vertexFactory.create(coords, 2, 2, true));
+ break;
+ case PathIterator.SEG_CUBICTO:
+ shape.addVertex(0, vertexFactory.create(coords, 0, 2, false));
+ shape.addVertex(0, vertexFactory.create(coords, 2, 2, false));
+ shape.addVertex(0, vertexFactory.create(coords, 4, 2, true));
+ break;
+ case PathIterator.SEG_CLOSE:
+ shape.closeLastOutline();
+ break;
+ default:
+ throw new IllegalArgumentException("Unhandled Segment Type: "+segmentType);
+ }
+ }
+
+ /**
+ * Build a {@link com.jogamp.graph.geom.Path2D Path2D} from a
+ * {@link jogamp.graph.font.typecast.ot.OTGlyph Glyph}. This glyph path can then
+ * be transformed and rendered.
+ */
+ public static Path2D buildPath(OTGlyph glyph) {
+
+ if (glyph == null) {
+ return null;
+ }
+
+ Path2D glyphPath = new Path2D();
+
+ // Iterate through all of the points in the glyph. Each time we find a
+ // contour end point, add the point range to the path.
+ int firstIndex = 0;
+ int count = 0;
+ for (int i = 0; i < glyph.getPointCount(); i++) {
+ count++;
+ if (glyph.getPoint(i).endOfContour) {
+ addContourToPath(glyphPath, glyph, firstIndex, count);
+ firstIndex = i + 1;
+ count = 0;
+ }
+ }
+ return glyphPath;
+ }
+
+ private static void addContourToPath(Path2D gp, OTGlyph glyph, int startIndex, int count) {
+ int offset = 0;
+ while (offset < count) {
+ Point point = glyph.getPoint(startIndex + offset%count);
+ Point point_plus1 = glyph.getPoint(startIndex + (offset+1)%count);
+ Point point_plus2 = glyph.getPoint(startIndex + (offset+2)%count);
+ if(offset == 0)
+ {
+ gp.moveTo(point.x, point.y);
+ }
+
+ if (point.onCurve) {
+ if (point_plus1.onCurve) {
+ // s = new Line2D.Float(point.x, point.y, point_plus1.x, point_plus1.y);
+ gp.lineTo( point_plus1.x, point_plus1.y );
+ offset++;
+ } else {
+ if (point_plus2.onCurve) {
+ // s = new QuadCurve2D.Float( point.x, point.y, point_plus1.x, point_plus1.y, point_plus2.x, point_plus2.y);
+ gp.quadTo(point_plus1.x, point_plus1.y, point_plus2.x, point_plus2.y);
+ offset+=2;
+ } else {
+ // s = new QuadCurve2D.Float(point.x,point.y,point_plus1.x,point_plus1.y,
+ // midValue(point_plus1.x, point_plus2.x), midValue(point_plus1.y, point_plus2.y));
+ gp.quadTo(point_plus1.x, point_plus1.y, midValue(point_plus1.x, point_plus2.x), midValue(point_plus1.y, point_plus2.y));
+ offset+=2;
+ }
+ }
+ } else {
+ if (point_plus1.onCurve) {
+ // s = new QuadCurve2D.Float(midValue(point_minus1.x, point.x), midValue(point_minus1.y, point.y),
+ // point.x, point.y, point_plus1.x, point_plus1.y);
+ //gp.curve3(point_plus1.x, point_plus1.y, point.x, point.y);
+ gp.quadTo(point.x, point.y, point_plus1.x, point_plus1.y);
+ offset++;
+
+ } else {
+ // s = new QuadCurve2D.Float(midValue(point_minus1.x, point.x), midValue(point_minus1.y, point.y), point.x, point.y,
+ // midValue(point.x, point_plus1.x), midValue(point.y, point_plus1.y));
+ //gp.curve3(midValue(point.x, point_plus1.x), midValue(point.y, point_plus1.y), point.x, point.y);
+ gp.quadTo(point.x, point.y, midValue(point.x, point_plus1.x), midValue(point.y, point_plus1.y));
+ offset++;
+ }
+ }
+ }
+ }
+
+ private static int midValue(int a, int b) {
+ return a + (b - a)/2;
+ }
+}
diff --git a/src/jogl/classes/jogamp/graph/math/MathFloat.java b/src/jogl/classes/jogamp/graph/math/MathFloat.java
index 0b8d69eba..82e7823a6 100644
--- a/src/jogl/classes/jogamp/graph/math/MathFloat.java
+++ b/src/jogl/classes/jogamp/graph/math/MathFloat.java
@@ -1,45 +1,45 @@
-/**
- * Copyright 2011 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 jogamp.graph.math;
-
-public class MathFloat {
-
- public static final float E = 2.7182818284590452354f;
-
- public static final float PI = 3.14159265358979323846f;
-
- public static float abs(float a) { return (float) java.lang.Math.abs(a); }
- public static float pow(float a, float b) { return (float) java.lang.Math.pow(a, b); }
-
- public static float sin(float a) { return (float) java.lang.Math.sin(a); }
- public static float cos(float a) { return (float) java.lang.Math.cos(a); }
- public static float acos(float a) { return (float) java.lang.Math.acos(a); }
-
- public static float sqrt(float a) { return (float) java.lang.Math.sqrt(a); }
-
-}
+/**
+ * Copyright 2011 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 jogamp.graph.math;
+
+public class MathFloat {
+
+ public static final float E = 2.7182818284590452354f;
+
+ public static final float PI = 3.14159265358979323846f;
+
+ public static float abs(float a) { return (float) java.lang.Math.abs(a); }
+ public static float pow(float a, float b) { return (float) java.lang.Math.pow(a, b); }
+
+ public static float sin(float a) { return (float) java.lang.Math.sin(a); }
+ public static float cos(float a) { return (float) java.lang.Math.cos(a); }
+ public static float acos(float a) { return (float) java.lang.Math.acos(a); }
+
+ public static float sqrt(float a) { return (float) java.lang.Math.sqrt(a); }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/bugs/Bug427GLJPanelTest1.java b/src/test/com/jogamp/opengl/test/bugs/Bug427GLJPanelTest1.java
index 18a432428..9bf492e0f 100644
--- a/src/test/com/jogamp/opengl/test/bugs/Bug427GLJPanelTest1.java
+++ b/src/test/com/jogamp/opengl/test/bugs/Bug427GLJPanelTest1.java
@@ -1,72 +1,72 @@
-package com.jogamp.opengl.test.bugs;
-
-import javax.swing.*;
-import java.awt.*;
-import javax.media.opengl.*;
-import javax.media.opengl.awt.*;
-
-public class Bug427GLJPanelTest1 extends JFrame implements GLEventListener {
-
- public Bug427GLJPanelTest1() {
- super("Bug427GLJPanelTest1");
-
- setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- setLayout(new BorderLayout());
-
- setSize(600, 600);
- setLocation(40, 40);
- setVisible(true);
-
- GLProfile glp = GLProfile.get(GLProfile.GL2);
- GLCapabilities caps = new GLCapabilities(glp);
- caps.setDoubleBuffered(true);
- caps.setHardwareAccelerated(true);
-
- GLJPanel panel = new GLJPanel(caps);
- panel.addGLEventListener(this);
-
- add(panel, BorderLayout.CENTER);
- }
-
- public static void main(String[] args) {
- Bug427GLJPanelTest1 demo = new Bug427GLJPanelTest1();
- demo.setVisible(true);
- }
-
- public void display(GLAutoDrawable drawable) {
- GL2 gl = drawable.getGL().getGL2();
-
- gl.glClear(GL.GL_COLOR_BUFFER_BIT);
- gl.glBegin(GL.GL_TRIANGLES);
-
- gl.glColor3f(1, 0, 0);
- gl.glVertex3f(0.25f, 0.25f, 0);
-
- gl.glColor3f(0, 1, 0);
- gl.glVertex3f(0.5f, 0.25f, 0);
-
- gl.glColor3f(0, 0, 1);
- gl.glVertex3f(0.25f, 0.5f, 0);
-
- gl.glEnd();
- gl.glFlush();
- }
-
- public void init(GLAutoDrawable drawable) {
- GL2 gl = drawable.getGL().getGL2();
-
- gl.glClearColor(0, 0, 0, 0);
- gl.glMatrixMode(GL2.GL_PROJECTION);
- gl.glLoadIdentity();
- gl.glOrtho(0, 1, 0, 1, -1, 1);
- }
-
- public void reshape(GLAutoDrawable glDrawable, int x, int y, int w, int h) {
- }
-
- public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
- }
-
- public void dispose(GLAutoDrawable drawable) {
- }
-}
+package com.jogamp.opengl.test.bugs;
+
+import javax.swing.*;
+import java.awt.*;
+import javax.media.opengl.*;
+import javax.media.opengl.awt.*;
+
+public class Bug427GLJPanelTest1 extends JFrame implements GLEventListener {
+
+ public Bug427GLJPanelTest1() {
+ super("Bug427GLJPanelTest1");
+
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ setLayout(new BorderLayout());
+
+ setSize(600, 600);
+ setLocation(40, 40);
+ setVisible(true);
+
+ GLProfile glp = GLProfile.get(GLProfile.GL2);
+ GLCapabilities caps = new GLCapabilities(glp);
+ caps.setDoubleBuffered(true);
+ caps.setHardwareAccelerated(true);
+
+ GLJPanel panel = new GLJPanel(caps);
+ panel.addGLEventListener(this);
+
+ add(panel, BorderLayout.CENTER);
+ }
+
+ public static void main(String[] args) {
+ Bug427GLJPanelTest1 demo = new Bug427GLJPanelTest1();
+ demo.setVisible(true);
+ }
+
+ public void display(GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
+
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT);
+ gl.glBegin(GL.GL_TRIANGLES);
+
+ gl.glColor3f(1, 0, 0);
+ gl.glVertex3f(0.25f, 0.25f, 0);
+
+ gl.glColor3f(0, 1, 0);
+ gl.glVertex3f(0.5f, 0.25f, 0);
+
+ gl.glColor3f(0, 0, 1);
+ gl.glVertex3f(0.25f, 0.5f, 0);
+
+ gl.glEnd();
+ gl.glFlush();
+ }
+
+ public void init(GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
+
+ gl.glClearColor(0, 0, 0, 0);
+ gl.glMatrixMode(GL2.GL_PROJECTION);
+ gl.glLoadIdentity();
+ gl.glOrtho(0, 1, 0, 1, -1, 1);
+ }
+
+ public void reshape(GLAutoDrawable glDrawable, int x, int y, int w, int h) {
+ }
+
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
+ }
+
+ public void dispose(GLAutoDrawable drawable) {
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestRegionRendererNEWT01.java b/src/test/com/jogamp/opengl/test/junit/graph/TestRegionRendererNEWT01.java
index d451efb31..a6616945d 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestRegionRendererNEWT01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestRegionRendererNEWT01.java
@@ -1,222 +1,222 @@
-/**
- * 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.opengl.test.junit.graph;
-
-import java.io.IOException;
-
-import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLCapabilitiesImmutable;
-import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLException;
-import javax.media.opengl.GLProfile;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import com.jogamp.common.os.Platform;
-import com.jogamp.graph.curve.Region;
-import com.jogamp.graph.curve.opengl.RenderState;
-import com.jogamp.graph.geom.opengl.SVertex;
-import com.jogamp.newt.opengl.GLWindow;
-import com.jogamp.opengl.test.junit.graph.demos.GPURegionGLListener01;
-import com.jogamp.opengl.test.junit.graph.demos.GPURegionGLListener02;
-import com.jogamp.opengl.test.junit.graph.demos.GPURegionRendererListenerBase01;
-import com.jogamp.opengl.test.junit.util.UITestCase;
-import com.jogamp.opengl.util.glsl.ShaderState;
-
-
-public class TestRegionRendererNEWT01 extends UITestCase {
-
- public static void main(String args[]) throws IOException {
- String tstname = TestRegionRendererNEWT01.class.getName();
- org.junit.runner.JUnitCore.main(tstname);
- }
-
- static void destroyWindow(GLWindow window) {
- if(null!=window) {
- window.destroy();
- }
- }
-
- static GLWindow createWindow(String title, GLCapabilitiesImmutable caps, int width, int height) {
- Assert.assertNotNull(caps);
-
- GLWindow window = GLWindow.create(caps);
- window.setSize(width, height);
- window.setPosition(10, 10);
- window.setTitle(title);
- Assert.assertNotNull(window);
- window.setVisible(true);
-
- return window;
- }
-
- @Test
- public void testRegionRendererR2T01() throws InterruptedException {
- if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
- // FIXME: Disabled for now - since it doesn't seem fit for mobile (performance wise).
- System.err.println("disabled on non desktop (x86) arch for now ..");
- return;
- }
- GLProfile glp = GLProfile.getGL2ES2();
-
- GLCapabilities caps = new GLCapabilities(glp);
- //caps.setOnscreen(false);
- caps.setAlphaBits(4);
-
- GLWindow window = createWindow("shape-vbaa1-msaa0", caps, 800,400);
- RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory());
- GPURegionGLListener02 demo02Listener = new GPURegionGLListener02 (rs, Region.VBAA_RENDERING_BIT, 1140, false, false);
- demo02Listener.attachInputListenerTo(window);
- window.addGLEventListener(demo02Listener);
-
- RegionGLListener listener = new RegionGLListener(demo02Listener, window.getTitle(), "GPURegionNewtDemo02");
- window.addGLEventListener(listener);
-
- listener.setTech(-20, 00, 0f, -300, 400);
- window.display();
-
- listener.setTech(-20, 00, 0f, -150, 800);
- window.display();
-
- listener.setTech(-20, 00, 0f, -50, 1000);
- window.display();
-
- destroyWindow(window);
- }
-
- @Test
- public void testRegionRendererMSAA01() throws InterruptedException {
- GLProfile glp = GLProfile.get(GLProfile.GL2ES2);
- GLCapabilities caps = new GLCapabilities(glp);
- // caps.setOnscreen(false);
- caps.setAlphaBits(4);
- caps.setSampleBuffers(true);
- caps.setNumSamples(4);
-
- GLWindow window = createWindow("shape-vbaa0-msaa1", caps, 800, 400);
- RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory());
-
- GPURegionGLListener01 demo01Listener = new GPURegionGLListener01 (rs, 0, 0, false, false);
- demo01Listener.attachInputListenerTo(window);
- window.addGLEventListener(demo01Listener);
-
- RegionGLListener listener = new RegionGLListener(demo01Listener, window.getTitle(), "GPURegion01");
- window.addGLEventListener(listener);
-
- listener.setTech(-20, 00, 0f, -300, 400);
- window.display();
-
- listener.setTech(-20, 00, 0f, -150, 800);
- window.display();
-
- listener.setTech(-20, 00, 0f, -50, 1000);
- window.display();
-
- destroyWindow(window);
- }
-
- @Test
- public void testRegionRendererMSAA02() throws InterruptedException {
- if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
- // FIXME: Disabled for now - since it doesn't seem fit for mobile (performance wise).
- // FIXME: Also the GLSL code for VARIABLE_CURVE is not fit for mobile yet!
- System.err.println("disabled on non desktop (x86) arch for now ..");
- return;
- }
- GLProfile glp = GLProfile.get(GLProfile.GL2ES2);
- GLCapabilities caps = new GLCapabilities(glp);
- caps.setAlphaBits(4);
- caps.setSampleBuffers(true);
- caps.setNumSamples(4);
-
- GLWindow window = createWindow("shape-vbaa0-msaa1", caps, 800, 400);
- RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory());
-
- GPURegionGLListener01 demo01Listener = new GPURegionGLListener01 (rs, Region.VARIABLE_CURVE_WEIGHT_BIT, 0, false, false);
- demo01Listener.attachInputListenerTo(window);
- window.addGLEventListener(demo01Listener);
-
- RegionGLListener listener = new RegionGLListener(demo01Listener, window.getTitle(), "GPURegion02");
- window.addGLEventListener(listener);
-
- listener.setTech(-20, 00, 0f, -300, 400);
- window.display();
-
- listener.setTech(-20, 00, 0f, -150, 800);
- window.display();
-
- listener.setTech(-20, 00, 0f, -50, 1000);
- window.display();
-
- destroyWindow(window);
- }
-
- private class RegionGLListener implements GLEventListener {
- String winTitle;
- String name;
- GPURegionRendererListenerBase01 impl;
-
- public RegionGLListener(GPURegionRendererListenerBase01 impl, String title, String name) {
- this.impl = impl;
- this.winTitle = title;
- this.name = name;
- }
-
- public void setTech(float xt, float yt, float angle, int zoom, int fboSize){
- impl.setMatrix(xt, yt, angle, zoom, fboSize);
- }
-
- public void init(GLAutoDrawable drawable) {
- impl.init(drawable);
- }
-
- public void display(GLAutoDrawable drawable) {
- impl.display(drawable);
-
- try {
- impl.printScreen(drawable, "./", winTitle, name, false);
- } catch (GLException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- public void dispose(GLAutoDrawable drawable) {
- impl.dispose(drawable);
-
- }
-
- public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
- impl.reshape(drawable, x, y, width, height);
-
- }
- }
-}
+/**
+ * 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.opengl.test.junit.graph;
+
+import java.io.IOException;
+
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.common.os.Platform;
+import com.jogamp.graph.curve.Region;
+import com.jogamp.graph.curve.opengl.RenderState;
+import com.jogamp.graph.geom.opengl.SVertex;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.graph.demos.GPURegionGLListener01;
+import com.jogamp.opengl.test.junit.graph.demos.GPURegionGLListener02;
+import com.jogamp.opengl.test.junit.graph.demos.GPURegionRendererListenerBase01;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.glsl.ShaderState;
+
+
+public class TestRegionRendererNEWT01 extends UITestCase {
+
+ public static void main(String args[]) throws IOException {
+ String tstname = TestRegionRendererNEWT01.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+ static void destroyWindow(GLWindow window) {
+ if(null!=window) {
+ window.destroy();
+ }
+ }
+
+ static GLWindow createWindow(String title, GLCapabilitiesImmutable caps, int width, int height) {
+ Assert.assertNotNull(caps);
+
+ GLWindow window = GLWindow.create(caps);
+ window.setSize(width, height);
+ window.setPosition(10, 10);
+ window.setTitle(title);
+ Assert.assertNotNull(window);
+ window.setVisible(true);
+
+ return window;
+ }
+
+ @Test
+ public void testRegionRendererR2T01() throws InterruptedException {
+ if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
+ // FIXME: Disabled for now - since it doesn't seem fit for mobile (performance wise).
+ System.err.println("disabled on non desktop (x86) arch for now ..");
+ return;
+ }
+ GLProfile glp = GLProfile.getGL2ES2();
+
+ GLCapabilities caps = new GLCapabilities(glp);
+ //caps.setOnscreen(false);
+ caps.setAlphaBits(4);
+
+ GLWindow window = createWindow("shape-vbaa1-msaa0", caps, 800,400);
+ RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory());
+ GPURegionGLListener02 demo02Listener = new GPURegionGLListener02 (rs, Region.VBAA_RENDERING_BIT, 1140, false, false);
+ demo02Listener.attachInputListenerTo(window);
+ window.addGLEventListener(demo02Listener);
+
+ RegionGLListener listener = new RegionGLListener(demo02Listener, window.getTitle(), "GPURegionNewtDemo02");
+ window.addGLEventListener(listener);
+
+ listener.setTech(-20, 00, 0f, -300, 400);
+ window.display();
+
+ listener.setTech(-20, 00, 0f, -150, 800);
+ window.display();
+
+ listener.setTech(-20, 00, 0f, -50, 1000);
+ window.display();
+
+ destroyWindow(window);
+ }
+
+ @Test
+ public void testRegionRendererMSAA01() throws InterruptedException {
+ GLProfile glp = GLProfile.get(GLProfile.GL2ES2);
+ GLCapabilities caps = new GLCapabilities(glp);
+ // caps.setOnscreen(false);
+ caps.setAlphaBits(4);
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(4);
+
+ GLWindow window = createWindow("shape-vbaa0-msaa1", caps, 800, 400);
+ RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory());
+
+ GPURegionGLListener01 demo01Listener = new GPURegionGLListener01 (rs, 0, 0, false, false);
+ demo01Listener.attachInputListenerTo(window);
+ window.addGLEventListener(demo01Listener);
+
+ RegionGLListener listener = new RegionGLListener(demo01Listener, window.getTitle(), "GPURegion01");
+ window.addGLEventListener(listener);
+
+ listener.setTech(-20, 00, 0f, -300, 400);
+ window.display();
+
+ listener.setTech(-20, 00, 0f, -150, 800);
+ window.display();
+
+ listener.setTech(-20, 00, 0f, -50, 1000);
+ window.display();
+
+ destroyWindow(window);
+ }
+
+ @Test
+ public void testRegionRendererMSAA02() throws InterruptedException {
+ if(Platform.CPUFamily.X86 != Platform.CPU_ARCH.family) { // FIXME
+ // FIXME: Disabled for now - since it doesn't seem fit for mobile (performance wise).
+ // FIXME: Also the GLSL code for VARIABLE_CURVE is not fit for mobile yet!
+ System.err.println("disabled on non desktop (x86) arch for now ..");
+ return;
+ }
+ GLProfile glp = GLProfile.get(GLProfile.GL2ES2);
+ GLCapabilities caps = new GLCapabilities(glp);
+ caps.setAlphaBits(4);
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(4);
+
+ GLWindow window = createWindow("shape-vbaa0-msaa1", caps, 800, 400);
+ RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory());
+
+ GPURegionGLListener01 demo01Listener = new GPURegionGLListener01 (rs, Region.VARIABLE_CURVE_WEIGHT_BIT, 0, false, false);
+ demo01Listener.attachInputListenerTo(window);
+ window.addGLEventListener(demo01Listener);
+
+ RegionGLListener listener = new RegionGLListener(demo01Listener, window.getTitle(), "GPURegion02");
+ window.addGLEventListener(listener);
+
+ listener.setTech(-20, 00, 0f, -300, 400);
+ window.display();
+
+ listener.setTech(-20, 00, 0f, -150, 800);
+ window.display();
+
+ listener.setTech(-20, 00, 0f, -50, 1000);
+ window.display();
+
+ destroyWindow(window);
+ }
+
+ private class RegionGLListener implements GLEventListener {
+ String winTitle;
+ String name;
+ GPURegionRendererListenerBase01 impl;
+
+ public RegionGLListener(GPURegionRendererListenerBase01 impl, String title, String name) {
+ this.impl = impl;
+ this.winTitle = title;
+ this.name = name;
+ }
+
+ public void setTech(float xt, float yt, float angle, int zoom, int fboSize){
+ impl.setMatrix(xt, yt, angle, zoom, fboSize);
+ }
+
+ public void init(GLAutoDrawable drawable) {
+ impl.init(drawable);
+ }
+
+ public void display(GLAutoDrawable drawable) {
+ impl.display(drawable);
+
+ try {
+ impl.printScreen(drawable, "./", winTitle, name, false);
+ } catch (GLException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void dispose(GLAutoDrawable drawable) {
+ impl.dispose(drawable);
+
+ }
+
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ impl.reshape(drawable, x, y, width, height);
+
+ }
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
index e7031f3a0..a09cc76ac 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
@@ -1,236 +1,236 @@
-/**
- * Copyright 2012 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.opengl.test.junit.graph;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-import javax.media.opengl.GL;
-import javax.media.opengl.GL2ES2;
-import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLCapabilitiesImmutable;
-import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLException;
-import javax.media.opengl.GLProfile;
-import javax.media.opengl.GLRunnable;
-
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import com.jogamp.graph.curve.opengl.RenderState;
-import com.jogamp.graph.curve.opengl.TextRenderer;
-import com.jogamp.graph.font.Font;
-import com.jogamp.graph.font.FontFactory;
-import com.jogamp.graph.geom.AABBox;
-import com.jogamp.graph.geom.opengl.SVertex;
-import com.jogamp.newt.opengl.GLWindow;
-import com.jogamp.opengl.test.junit.util.UITestCase;
-import com.jogamp.opengl.util.GLReadBufferUtil;
-import com.jogamp.opengl.util.glsl.ShaderState;
-
-
-public class TestTextRendererNEWT00 extends UITestCase {
- static final boolean DEBUG = false;
- static final boolean TRACE = false;
- static long duration = 100; // ms
-
- static final float[] textPosition = new float[] {0,0,0};
- static final int[] texSize = new int[] { 0 };
- static final int fontSize = 24;
- static Font font;
-
- @BeforeClass
- public static void setup() throws IOException {
- font = FontFactory.get(FontFactory.UBUNTU).getDefault();
- }
-
- static int atoi(String a) {
- try {
- return Integer.parseInt(a);
- } catch (Exception ex) { throw new RuntimeException(ex); }
- }
-
- public static void main(String args[]) throws IOException {
- for(int i=0; irow) {
- row = lastRow + 1;
- }
- AABBox textBox = font.getStringBounds(text, fontSize);
- dx += font.getAdvanceWidth('X', fontSize) * column;
- dy -= (int)textBox.getHeight() * ( row + 1 );
- renderer.resetModelview(null);
- renderer.translate(gl, dx, dy, z0);
- renderer.drawString3D(gl, font, text, textPosition, fontSize, texSize);
-
- lastRow = row;
- }
-
- public class TextRendererListener implements GLEventListener {
- private GLReadBufferUtil screenshot;
- private TextRenderer renderer;
-
- public TextRendererListener(RenderState rs) {
- this.screenshot = new GLReadBufferUtil(false, false);
- this.renderer = TextRenderer.create(rs, 0);
- }
-
- public final TextRenderer getRenderer() { return renderer; }
-
- public void printScreen(GLAutoDrawable drawable, String dir, String objName, boolean exportAlpha) throws GLException, IOException {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- pw.printf("%s-%03dx%03d-T%04d", objName, drawable.getWidth(), drawable.getHeight(), texSize[0]);
-
- final String filename = dir + sw +".png";
- if(screenshot.readPixels(drawable.getGL(), drawable, false)) {
- screenshot.write(new File(filename));
- }
- }
-
- public void init(GLAutoDrawable drawable) {
- final GL2ES2 gl = drawable.getGL().getGL2ES2();
- gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
- renderer.init(gl);
- renderer.setAlpha(gl, 1.0f);
- renderer.setColorStatic(gl, 0.0f, 0.0f, 0.0f);
- }
-
- public void reshape(GLAutoDrawable drawable, int xstart, int ystart, int width, int height) {
- final GL2ES2 gl = drawable.getGL().getGL2ES2();
-
- gl.glViewport(xstart, ystart, width, height);
- // renderer.reshapePerspective(gl, 45.0f, width, height, 0.1f, 1000.0f);
- renderer.reshapeOrtho(gl, width, height, 0.1f, 1000.0f);
- }
-
- public void display(GLAutoDrawable drawable) {
- final GL2ES2 gl = drawable.getGL().getGL2ES2();
- gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
-
- renderString(drawable, renderer, "012345678901234567890123456789", 0, 0, -1000);
- renderString(drawable, renderer, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 0, -1, -1000);
- renderString(drawable, renderer, "Hello World", 0, -1, -1000);
- renderString(drawable, renderer, "4567890123456", 4, -1, -1000);
- renderString(drawable, renderer, "I like JogAmp", 4, -1, -1000);
- }
-
- public void dispose(GLAutoDrawable drawable) {
- final GL2ES2 gl = drawable.getGL().getGL2ES2();
- screenshot.dispose(gl);
- renderer.destroy(gl);
- }
- }
-
-}
+/**
+ * Copyright 2012 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.opengl.test.junit.graph;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLRunnable;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.jogamp.graph.curve.opengl.RenderState;
+import com.jogamp.graph.curve.opengl.TextRenderer;
+import com.jogamp.graph.font.Font;
+import com.jogamp.graph.font.FontFactory;
+import com.jogamp.graph.geom.AABBox;
+import com.jogamp.graph.geom.opengl.SVertex;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.glsl.ShaderState;
+
+
+public class TestTextRendererNEWT00 extends UITestCase {
+ static final boolean DEBUG = false;
+ static final boolean TRACE = false;
+ static long duration = 100; // ms
+
+ static final float[] textPosition = new float[] {0,0,0};
+ static final int[] texSize = new int[] { 0 };
+ static final int fontSize = 24;
+ static Font font;
+
+ @BeforeClass
+ public static void setup() throws IOException {
+ font = FontFactory.get(FontFactory.UBUNTU).getDefault();
+ }
+
+ static int atoi(String a) {
+ try {
+ return Integer.parseInt(a);
+ } catch (Exception ex) { throw new RuntimeException(ex); }
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; irow) {
+ row = lastRow + 1;
+ }
+ AABBox textBox = font.getStringBounds(text, fontSize);
+ dx += font.getAdvanceWidth('X', fontSize) * column;
+ dy -= (int)textBox.getHeight() * ( row + 1 );
+ renderer.resetModelview(null);
+ renderer.translate(gl, dx, dy, z0);
+ renderer.drawString3D(gl, font, text, textPosition, fontSize, texSize);
+
+ lastRow = row;
+ }
+
+ public class TextRendererListener implements GLEventListener {
+ private GLReadBufferUtil screenshot;
+ private TextRenderer renderer;
+
+ public TextRendererListener(RenderState rs) {
+ this.screenshot = new GLReadBufferUtil(false, false);
+ this.renderer = TextRenderer.create(rs, 0);
+ }
+
+ public final TextRenderer getRenderer() { return renderer; }
+
+ public void printScreen(GLAutoDrawable drawable, String dir, String objName, boolean exportAlpha) throws GLException, IOException {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ pw.printf("%s-%03dx%03d-T%04d", objName, drawable.getWidth(), drawable.getHeight(), texSize[0]);
+
+ final String filename = dir + sw +".png";
+ if(screenshot.readPixels(drawable.getGL(), drawable, false)) {
+ screenshot.write(new File(filename));
+ }
+ }
+
+ public void init(GLAutoDrawable drawable) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+ gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ renderer.init(gl);
+ renderer.setAlpha(gl, 1.0f);
+ renderer.setColorStatic(gl, 0.0f, 0.0f, 0.0f);
+ }
+
+ public void reshape(GLAutoDrawable drawable, int xstart, int ystart, int width, int height) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ gl.glViewport(xstart, ystart, width, height);
+ // renderer.reshapePerspective(gl, 45.0f, width, height, 0.1f, 1000.0f);
+ renderer.reshapeOrtho(gl, width, height, 0.1f, 1000.0f);
+ }
+
+ public void display(GLAutoDrawable drawable) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+
+ renderString(drawable, renderer, "012345678901234567890123456789", 0, 0, -1000);
+ renderString(drawable, renderer, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 0, -1, -1000);
+ renderString(drawable, renderer, "Hello World", 0, -1, -1000);
+ renderString(drawable, renderer, "4567890123456", 4, -1, -1000);
+ renderString(drawable, renderer, "I like JogAmp", 4, -1, -1000);
+ }
+
+ public void dispose(GLAutoDrawable drawable) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+ screenshot.dispose(gl);
+ renderer.destroy(gl);
+ }
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java
index 72b64c7da..ea02e930c 100755
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java
@@ -1,245 +1,245 @@
-/**
- * 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.opengl.test.junit.graph;
-
-import java.io.IOException;
-
-import javax.media.opengl.GL;
-import javax.media.opengl.GL2ES2;
-import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLCapabilitiesImmutable;
-import javax.media.opengl.GLException;
-import javax.media.opengl.GLProfile;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import com.jogamp.common.os.Platform;
-import com.jogamp.graph.curve.Region;
-import com.jogamp.graph.curve.opengl.RenderState;
-import com.jogamp.graph.curve.opengl.TextRenderer;
-import com.jogamp.graph.font.FontFactory;
-import com.jogamp.graph.geom.opengl.SVertex;
-import com.jogamp.newt.opengl.GLWindow;
-import com.jogamp.opengl.test.junit.graph.demos.GPUTextRendererListenerBase01;
-import com.jogamp.opengl.test.junit.util.UITestCase;
-import com.jogamp.opengl.util.glsl.ShaderState;
-
-
-public class TestTextRendererNEWT01 extends UITestCase {
- static final boolean DEBUG = false;
- static final boolean TRACE = false;
- static long duration = 100; // ms
-
- static int atoi(String a) {
- try {
- return Integer.parseInt(a);
- } catch (Exception ex) { throw new RuntimeException(ex); }
- }
-
- public static void main(String args[]) throws IOException {
- for(int i=0; i
- * Uses the SWT GLCanvas org.eclipse.swt.opengl.GLCanvas
.
- *
- * @author Wade Walker, et.al.
- */
-public class TestSWTEclipseGLCanvas01GLn extends UITestCase {
-
- static int duration = 250;
-
- static final int iwidth = 640;
- static final int iheight = 480;
-
- Display display = null;
- Shell shell = null;
- Composite composite = null;
-
- @BeforeClass
- public static void startup() {
- System.out.println( "GLProfile " + GLProfile.glAvailabilityToString() );
- }
-
- @Before
- public void init() {
- display = new Display();
- Assert.assertNotNull( display );
- shell = new Shell( display );
- Assert.assertNotNull( shell );
- shell.setLayout( new FillLayout() );
- composite = new Composite( shell, SWT.NONE );
- composite.setLayout( new FillLayout() );
- Assert.assertNotNull( composite );
- }
-
- @After
- public void release() {
- Assert.assertNotNull( display );
- Assert.assertNotNull( shell );
- Assert.assertNotNull( composite );
- try {
- composite.dispose();
- shell.dispose();
- display.dispose();
- }
- catch( Throwable throwable ) {
- throwable.printStackTrace();
- Assume.assumeNoException( throwable );
- }
- display = null;
- shell = null;
- composite = null;
- }
-
- protected void runTestAGL( GLProfile glprofile ) throws InterruptedException {
- GLData gldata = new GLData();
- gldata.doubleBuffer = true;
- // need SWT.NO_BACKGROUND to prevent SWT from clearing the window
- // at the wrong times (we use glClear for this instead)
- final GLCanvas glcanvas = new GLCanvas( composite, SWT.NO_BACKGROUND, gldata );
- Assert.assertNotNull( glcanvas );
- glcanvas.setCurrent();
- final GLContext glcontext = GLDrawableFactory.getFactory( glprofile ).createExternalGLContext();
- Assert.assertNotNull( glcontext );
-
- // fix the viewport when the user resizes the window
- glcanvas.addListener( SWT.Resize, new Listener() {
- public void handleEvent( Event event ) {
- Rectangle rectangle = glcanvas.getClientArea();
- glcanvas.setCurrent();
- glcontext.makeCurrent();
- GL2ES1 gl = glcontext.getGL().getGL2ES1();
- OneTriangle.setup( gl, rectangle.width, rectangle.height );
- glcontext.release();
- System.err.println("resize");
- }
- });
-
- // draw the triangle when the OS tells us that any part of the window needs drawing
- glcanvas.addPaintListener( new PaintListener() {
- public void paintControl( PaintEvent paintevent ) {
- Rectangle rectangle = glcanvas.getClientArea();
- glcanvas.setCurrent();
- glcontext.makeCurrent();
- GL2ES1 gl = glcontext.getGL().getGL2ES1();
- OneTriangle.render( gl, rectangle.width, rectangle.height );
- glcanvas.swapBuffers();
- glcontext.release();
- System.err.println("paint");
- }
- });
-
- shell.setText( getClass().getName() );
- shell.setSize( 640, 480 );
- shell.open();
-
- long lStartTime = System.currentTimeMillis();
- long lEndTime = lStartTime + duration;
- try {
- while( (System.currentTimeMillis() < lEndTime) && !glcanvas.isDisposed() ) {
- if( !display.readAndDispatch() ) {
- // blocks on linux .. display.sleep();
- Thread.sleep(10);
- }
- }
- } catch( Throwable throwable ) {
- throwable.printStackTrace();
- Assume.assumeNoException( throwable );
- }
- glcanvas.dispose();
- }
-
- @Test
- public void test() throws InterruptedException {
- GLProfile glprofile = GLProfile.getGL2ES1();
- runTestAGL( glprofile );
- }
-
- static int atoi(String a) {
- int i=0;
- try {
- i = Integer.parseInt(a);
- } catch (Exception ex) { ex.printStackTrace(); }
- return i;
- }
-
- public static void main(String args[]) {
- for(int i=0; i
+ * Uses the SWT GLCanvas org.eclipse.swt.opengl.GLCanvas
.
+ *
+ * @author Wade Walker, et.al.
+ */
+public class TestSWTEclipseGLCanvas01GLn extends UITestCase {
+
+ static int duration = 250;
+
+ static final int iwidth = 640;
+ static final int iheight = 480;
+
+ Display display = null;
+ Shell shell = null;
+ Composite composite = null;
+
+ @BeforeClass
+ public static void startup() {
+ System.out.println( "GLProfile " + GLProfile.glAvailabilityToString() );
+ }
+
+ @Before
+ public void init() {
+ display = new Display();
+ Assert.assertNotNull( display );
+ shell = new Shell( display );
+ Assert.assertNotNull( shell );
+ shell.setLayout( new FillLayout() );
+ composite = new Composite( shell, SWT.NONE );
+ composite.setLayout( new FillLayout() );
+ Assert.assertNotNull( composite );
+ }
+
+ @After
+ public void release() {
+ Assert.assertNotNull( display );
+ Assert.assertNotNull( shell );
+ Assert.assertNotNull( composite );
+ try {
+ composite.dispose();
+ shell.dispose();
+ display.dispose();
+ }
+ catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ display = null;
+ shell = null;
+ composite = null;
+ }
+
+ protected void runTestAGL( GLProfile glprofile ) throws InterruptedException {
+ GLData gldata = new GLData();
+ gldata.doubleBuffer = true;
+ // need SWT.NO_BACKGROUND to prevent SWT from clearing the window
+ // at the wrong times (we use glClear for this instead)
+ final GLCanvas glcanvas = new GLCanvas( composite, SWT.NO_BACKGROUND, gldata );
+ Assert.assertNotNull( glcanvas );
+ glcanvas.setCurrent();
+ final GLContext glcontext = GLDrawableFactory.getFactory( glprofile ).createExternalGLContext();
+ Assert.assertNotNull( glcontext );
+
+ // fix the viewport when the user resizes the window
+ glcanvas.addListener( SWT.Resize, new Listener() {
+ public void handleEvent( Event event ) {
+ Rectangle rectangle = glcanvas.getClientArea();
+ glcanvas.setCurrent();
+ glcontext.makeCurrent();
+ GL2ES1 gl = glcontext.getGL().getGL2ES1();
+ OneTriangle.setup( gl, rectangle.width, rectangle.height );
+ glcontext.release();
+ System.err.println("resize");
+ }
+ });
+
+ // draw the triangle when the OS tells us that any part of the window needs drawing
+ glcanvas.addPaintListener( new PaintListener() {
+ public void paintControl( PaintEvent paintevent ) {
+ Rectangle rectangle = glcanvas.getClientArea();
+ glcanvas.setCurrent();
+ glcontext.makeCurrent();
+ GL2ES1 gl = glcontext.getGL().getGL2ES1();
+ OneTriangle.render( gl, rectangle.width, rectangle.height );
+ glcanvas.swapBuffers();
+ glcontext.release();
+ System.err.println("paint");
+ }
+ });
+
+ shell.setText( getClass().getName() );
+ shell.setSize( 640, 480 );
+ shell.open();
+
+ long lStartTime = System.currentTimeMillis();
+ long lEndTime = lStartTime + duration;
+ try {
+ while( (System.currentTimeMillis() < lEndTime) && !glcanvas.isDisposed() ) {
+ if( !display.readAndDispatch() ) {
+ // blocks on linux .. display.sleep();
+ Thread.sleep(10);
+ }
+ }
+ } catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ glcanvas.dispose();
+ }
+
+ @Test
+ public void test() throws InterruptedException {
+ GLProfile glprofile = GLProfile.getGL2ES1();
+ runTestAGL( glprofile );
+ }
+
+ static int atoi(String a) {
+ int i=0;
+ try {
+ i = Integer.parseInt(a);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ return i;
+ }
+
+ public static void main(String args[]) {
+ for(int i=0; i
- * Uses JOGL's new SWT GLCanvas.
- *
- *
- * Holds AWT in it's test name, since our impl. still needs the AWT threading,
- * see {@link GLCanvas}.
- *
- * @author Wade Walker, et.al.
- */
-public class TestSWTJOGLGLCanvas01GLnAWT extends UITestCase {
-
- static int duration = 250;
-
- static final int iwidth = 640;
- static final int iheight = 480;
-
- Display display = null;
- Shell shell = null;
- Composite composite = null;
-
- @BeforeClass
- public static void startup() {
- System.out.println( "GLProfile " + GLProfile.glAvailabilityToString() );
- }
-
- @Before
- public void init() {
- display = new Display();
- Assert.assertNotNull( display );
- shell = new Shell( display );
- Assert.assertNotNull( shell );
- shell.setLayout( new FillLayout() );
- composite = new Composite( shell, SWT.NONE );
- composite.setLayout( new FillLayout() );
- Assert.assertNotNull( composite );
- }
-
- @After
- public void release() {
- Assert.assertNotNull( display );
- Assert.assertNotNull( shell );
- Assert.assertNotNull( composite );
- try {
- composite.dispose();
- shell.dispose();
- display.dispose();
- }
- catch( Throwable throwable ) {
- throwable.printStackTrace();
- Assume.assumeNoException( throwable );
- }
- display = null;
- shell = null;
- composite = null;
- }
-
- protected void runTestAGL( GLProfile glprofile ) throws InterruptedException {
- // need SWT.NO_BACKGROUND to prevent SWT from clearing the window
- // at the wrong times (we use glClear for this instead)
- final GLCapabilitiesImmutable caps = new GLCapabilities( glprofile );
-
- final GLCanvas canvas = new GLCanvas( composite, SWT.NO_BACKGROUND, caps, null, null);
- Assert.assertNotNull( canvas );
-
- canvas.addGLEventListener(new GLEventListener() {
- public void init(final GLAutoDrawable drawable) { }
- public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
- OneTriangle.setup( drawable.getGL().getGL2(), width, height );
- }
- public void display(final GLAutoDrawable drawable) {
- OneTriangle.render( drawable.getGL().getGL2(), drawable.getWidth(), drawable.getHeight());
- }
- public void dispose(final GLAutoDrawable drawable) {}
- });
-
- shell.setText( getClass().getName() );
- shell.setSize( 640, 480 );
- shell.open();
-
- long lStartTime = System.currentTimeMillis();
- long lEndTime = lStartTime + duration;
- try {
- while( (System.currentTimeMillis() < lEndTime) && !canvas.isDisposed() ) {
- if( !display.readAndDispatch() ) {
- // blocks on linux .. display.sleep();
- Thread.sleep(10);
- }
- }
- } catch( Throwable throwable ) {
- throwable.printStackTrace();
- Assume.assumeNoException( throwable );
- }
- canvas.dispose();
- }
-
- @Test
- public void test() throws InterruptedException {
- GLProfile glprofile = GLProfile.getGL2ES1();
- runTestAGL( glprofile );
- }
-
- static int atoi(String a) {
- int i=0;
- try {
- i = Integer.parseInt(a);
- } catch (Exception ex) { ex.printStackTrace(); }
- return i;
- }
-
- public static void main(String args[]) {
- for(int i=0; i
+ * Uses JOGL's new SWT GLCanvas.
+ *
+ *
+ * Holds AWT in it's test name, since our impl. still needs the AWT threading,
+ * see {@link GLCanvas}.
+ *
+ * @author Wade Walker, et.al.
+ */
+public class TestSWTJOGLGLCanvas01GLnAWT extends UITestCase {
+
+ static int duration = 250;
+
+ static final int iwidth = 640;
+ static final int iheight = 480;
+
+ Display display = null;
+ Shell shell = null;
+ Composite composite = null;
+
+ @BeforeClass
+ public static void startup() {
+ System.out.println( "GLProfile " + GLProfile.glAvailabilityToString() );
+ }
+
+ @Before
+ public void init() {
+ display = new Display();
+ Assert.assertNotNull( display );
+ shell = new Shell( display );
+ Assert.assertNotNull( shell );
+ shell.setLayout( new FillLayout() );
+ composite = new Composite( shell, SWT.NONE );
+ composite.setLayout( new FillLayout() );
+ Assert.assertNotNull( composite );
+ }
+
+ @After
+ public void release() {
+ Assert.assertNotNull( display );
+ Assert.assertNotNull( shell );
+ Assert.assertNotNull( composite );
+ try {
+ composite.dispose();
+ shell.dispose();
+ display.dispose();
+ }
+ catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ display = null;
+ shell = null;
+ composite = null;
+ }
+
+ protected void runTestAGL( GLProfile glprofile ) throws InterruptedException {
+ // need SWT.NO_BACKGROUND to prevent SWT from clearing the window
+ // at the wrong times (we use glClear for this instead)
+ final GLCapabilitiesImmutable caps = new GLCapabilities( glprofile );
+
+ final GLCanvas canvas = new GLCanvas( composite, SWT.NO_BACKGROUND, caps, null, null);
+ Assert.assertNotNull( canvas );
+
+ canvas.addGLEventListener(new GLEventListener() {
+ public void init(final GLAutoDrawable drawable) { }
+ public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
+ OneTriangle.setup( drawable.getGL().getGL2(), width, height );
+ }
+ public void display(final GLAutoDrawable drawable) {
+ OneTriangle.render( drawable.getGL().getGL2(), drawable.getWidth(), drawable.getHeight());
+ }
+ public void dispose(final GLAutoDrawable drawable) {}
+ });
+
+ shell.setText( getClass().getName() );
+ shell.setSize( 640, 480 );
+ shell.open();
+
+ long lStartTime = System.currentTimeMillis();
+ long lEndTime = lStartTime + duration;
+ try {
+ while( (System.currentTimeMillis() < lEndTime) && !canvas.isDisposed() ) {
+ if( !display.readAndDispatch() ) {
+ // blocks on linux .. display.sleep();
+ Thread.sleep(10);
+ }
+ }
+ } catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ canvas.dispose();
+ }
+
+ @Test
+ public void test() throws InterruptedException {
+ GLProfile glprofile = GLProfile.getGL2ES1();
+ runTestAGL( glprofile );
+ }
+
+ static int atoi(String a) {
+ int i=0;
+ try {
+ i = Integer.parseInt(a);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ return i;
+ }
+
+ public static void main(String args[]) {
+ for(int i=0; i