aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/com/jogamp/graph/curve/OutlineShape.java159
-rw-r--r--src/com/jogamp/graph/geom/AABBox.java115
-rw-r--r--src/com/jogamp/graph/geom/Outline.java2
-rw-r--r--src/com/jogamp/graph/geom/Vertex.java2
-rw-r--r--src/com/jogamp/graph/geom/opengl/SVertex.java11
-rw-r--r--src/demo/GPURendererListenerBase01.java2
-rw-r--r--src/jogamp/graph/curve/text/GlyphShape.java16
-rw-r--r--src/jogamp/graph/geom/plane/Path2D.java6
8 files changed, 221 insertions, 92 deletions
diff --git a/src/com/jogamp/graph/curve/OutlineShape.java b/src/com/jogamp/graph/curve/OutlineShape.java
index 9373808f1..c385b83f5 100755
--- a/src/com/jogamp/graph/curve/OutlineShape.java
+++ b/src/com/jogamp/graph/curve/OutlineShape.java
@@ -44,33 +44,85 @@ import com.jogamp.graph.curve.tess.CDTriangulator2D;
* closed region defined by the outlines.
*
* One or more OutlineShape Object can be associated to a region
- * this is left high-level representation of the Objects. For
- * possible Optimizations.
+ * this is left as a high-level representation of the Objects. For
+ * optimizations, flexibility requirements for future features.
*
+ * <br><br>
+ * Example to creating an Outline Shape:
+ * <pre>
+ addVertex(...)
+ addVertex(...)
+ addVertex(...)
+ addEnptyOutline()
+ addVertex(...)
+ addVertex(...)
+ addVertex(...)
+ * </pre>
+ *
+ * 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.
+ * <br>
+ *
+ * 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).
+ * <br>
+ * 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.
+ *
+ * <br>Example: <br>
+ * <pre>
+ addVertex(0,0, true);
+ addVertex(0,1, false);
+ addVertex(1,1, false);
+ addVertex(1,0, true);
+ * </pre>
+ *
+ * The above snippet defines a cubic nurbs curve where (0,1 and 1,1)
+ * do not belong to the final rendered shape.
+ *
+ * <i>Implementation Notes:</i><br>
+ * <ul>
+ * <li> The first vertex of any outline belonging to the shape should be on-curve</li>
+ * <li> Intersections between off-curved parts of the outline is not handled</li>
+ * </ul>
+ *
+ * @see Outline
* @see Region
*/
public class OutlineShape {
+
public static final int QUADRATIC_NURBS = 10;
- private final Vertex.Factory<? extends Vertex> pointFactory;
+ private final Vertex.Factory<? extends Vertex> vertexFactory;
+
+ /** The list of outlines that are part of this
+ * outline shape.
+ */
private ArrayList<Outline<Vertex>> outlines = new ArrayList<Outline<Vertex>>(3);
-
+
/** Create a new Outline based Shape
*/
public OutlineShape(Vertex.Factory<? extends Vertex> factory) {
- pointFactory = factory;
+ vertexFactory = factory;
outlines.add(new Outline<Vertex>());
}
-
- public final Vertex.Factory<? extends Vertex> pointFactory() { return pointFactory; }
-
+
+ /** Returns the associated vertex factory of this outline shape
+ * @return Vertex.Factory object
+ */
+ public final Vertex.Factory<? extends Vertex> vertexFactory() { return vertexFactory; }
+
/** Add a new empty outline
* to the shape, this new outline will
* be placed at the end of the outline list.
+ *
+ * After a call to this function all new vertices added
+ * will belong to the new outline
*/
public void addEmptyOutline(){
outlines.add(new Outline<Vertex>());
}
-
+
/** Adds an outline to the OutlineShape object
* if last outline of the shape is empty, it will replace
* that last Outline with the new one. If outline is empty,
@@ -86,27 +138,52 @@ public class OutlineShape {
}
outlines.add(outline);
}
-
+
/** Adds a vertex to the last open outline in the
- * shape
- * @param point
+ * shape.
+ * @param v the vertex to be added to the OutlineShape
*/
- public final void addVertex(Vertex point){
- getLastOutline().addVertex(point);
+ public final void addVertex(Vertex v){
+ getLastOutline().addVertex(v);
}
-
+
+ /** Add a 2D 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) {
- getLastOutline().addVertex(pointFactory, x, y, onCurve);
+ getLastOutline().addVertex(vertexFactory, x, y, onCurve);
}
-
+
+ /** Add a 3D vertex to the last outline by defining the coordniate attribute
+ * of the vertex.
+ * @param x the x coordinate
+ * @param y the y coordniate
+ * @param z the z 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, float z, boolean onCurve) {
- getLastOutline().addVertex(pointFactory, x, y, z, onCurve);
+ getLastOutline().addVertex(vertexFactory, 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) {
- getLastOutline().addVertex(pointFactory, coordsBuffer, offset, length, onCurve);
+ getLastOutline().addVertex(vertexFactory, 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
@@ -115,7 +192,7 @@ public class OutlineShape {
public void closeLastOutline(){
getLastOutline().setClosed(true);
}
-
+
/** Get the last added outline to the list
* of outlines that define the shape
* @return the last outline
@@ -125,7 +202,7 @@ public class OutlineShape {
}
/** Make sure that the outlines represent
* the specified destinationType, if not
- * transform outlines to destinationType.
+ * transform outlines to destination type.
* @param destinationType The curve type needed
*/
public void transformOutlines(int destinationType){
@@ -133,7 +210,7 @@ public class OutlineShape {
transformOutlinesQuadratic();
}
}
-
+
private void transformOutlinesQuadratic(){
ArrayList<Outline<Vertex>> newOutlines = new ArrayList<Outline<Vertex>>(3);
@@ -150,9 +227,9 @@ public class OutlineShape {
Vertex nextVertex = vertices.get((i+1)%size);
if(!(currentVertex.isOnCurve()) && !(nextVertex.isOnCurve())) {
newOutline.addVertex(currentVertex);
-
+
float[] newCoords = VectorUtil.mid(currentVertex.getCoord(), nextVertex.getCoord());
- newOutline.addVertex(pointFactory, newCoords, 0, 3, true);
+ newOutline.addVertex(vertexFactory, newCoords, 0, 3, true);
}
else {
newOutline.addVertex(currentVertex);
@@ -162,7 +239,7 @@ public class OutlineShape {
}
outlines = newOutlines;
}
-
+
private void generateVertexIds(){
int maxVertexId = 0;
for(Outline<Vertex> outline:outlines){
@@ -173,7 +250,7 @@ public class OutlineShape {
}
}
}
-
+
/** @return the list of vertices associated with the
* {@code Outline} list of this object
*/
@@ -184,10 +261,20 @@ public class OutlineShape {
}
return vertices;
}
-
- /** Triangluate the graph object
- * @param sharpness sharpness of the curved regions default = 0.5
+ /** Triangulate the outline shape generating a list of triangles
+ * @return an arraylist of triangles representing the filled region
+ * which is produced by the combination of the outlines
+ */
+ public ArrayList<Triangle<Vertex>> triangulate(){
+ return triangulate(0.5f);
+ }
+
+ /**Triangulate the outline shape generating a list of triangles
+ * @param sharpness defines the curvature strength around the off-curve vertices.
+ * defaults to 0.5f
+ * @return an arraylist of triangles representing the filled region
+ * which is produced by the combination of the outlines
*/
public ArrayList<Triangle<Vertex>> triangulate(float sharpness){
if(outlines.size() == 0){
@@ -195,20 +282,20 @@ public class OutlineShape {
}
sortOutlines();
generateVertexIds();
-
+
CDTriangulator2D<Vertex> triangulator2d = new CDTriangulator2D<Vertex>(sharpness);
-
+
for(int index = 0; index< outlines.size();index++){
Outline<Vertex> outline = outlines.get(index);
triangulator2d.addCurve(outline);
}
-
+
ArrayList<Triangle<Vertex>> triangles = triangulator2d.generateTriangulation();
triangulator2d.reset();
-
+
return triangles;
}
-
+
/** Sort the outlines from large
* to small depending on the AABox
*/
diff --git a/src/com/jogamp/graph/geom/AABBox.java b/src/com/jogamp/graph/geom/AABBox.java
index a2566b91f..f97c43a57 100644
--- a/src/com/jogamp/graph/geom/AABBox.java
+++ b/src/com/jogamp/graph/geom/AABBox.java
@@ -30,15 +30,29 @@ package com.jogamp.graph.geom;
import com.jogamp.graph.math.VectorUtil;
/**
- * Axis Aligned Bounding Box.
+ * Axis Aligned Bounding Box. Defined by two 3D coordinates (low and high)
+ * The low being the the lower left corner of the box, and the high being the upper
+ * right corner of the box.
+ *
*/
public class AABBox {
private float[] low = {Float.MAX_VALUE,Float.MAX_VALUE,Float.MAX_VALUE};
private float[] high = {-1*Float.MAX_VALUE,-1*Float.MAX_VALUE,-1*Float.MAX_VALUE};
private float[] center = new float[3];
+ /** Create a Axis Aligned bounding box (AABBox) where the low and and high MAX float Values.
+ */
public AABBox() {}
+ /** Create an AABBox specifying the coordinates of the low and high
+ *
+ * @param lx min x-coordinate
+ * @param ly min y-coordnate
+ * @param lz min z-coordinate
+ * @param hx max x-coordinate
+ * @param hy max y-coordinate
+ * @param hz max z-coordinate
+ */
public AABBox(float lx, float ly, float lz,
float hx, float hy, float hz)
{
@@ -48,12 +62,10 @@ public class AABBox {
computeCenter();
}
- public String toString() {
- return "[ "+low[0]+"/"+low[1]+"/"+low[1]+" .. "+high[0]+"/"+high[0]+"/"+high[0]+", ctr "+
- center[0]+"/"+center[1]+"/"+center[1]+" ]";
- }
-
-
+ /** Create a AABBox defining the low and high
+ * @param low min xyz-coordinates
+ * @param high max xyz-coordinates
+ */
public AABBox(float[] low, float[] high)
{
this.low = low;
@@ -62,27 +74,39 @@ public class AABBox {
computeCenter();
}
+ /** Get the max xyz-coordinates
+ * @return a float array containing the max xyz coordinates
+ */
public float[] getHigh()
{
return high;
}
- public void setHigh(float hx, float hy, float hz)
+
+ private void setHigh(float hx, float hy, float hz)
{
this.high[0] = hx;
this.high[1] = hy;
this.high[2] = hz;
}
+
+ /** Get the min xyz-coordinates
+ * @return a float array containing the min xyz coordinates
+ */
public float[] getLow()
{
return low;
}
- public void setLow(float lx, float ly, float lz)
+
+ private void setLow(float lx, float ly, float lz)
{
this.low[0] = lx;
this.low[1] = ly;
this.low[2] = lz;
}
+ /** Resize the AABBox to encapsulate another AABox
+ * @param newBox AABBox to be encapsulated in
+ */
public void resize(AABBox newBox)
{
float[] newLow = newBox.getLow();
@@ -114,6 +138,12 @@ public class AABBox {
center[2] = (high[2] + low[2])/2;
}
+ /** Resize the AABBox to encapsulate the passed
+ * xyz-coordinates.
+ * @param x x-axis coordinate value
+ * @param y y-axis coordinate value
+ * @param z z-axis coordinate value
+ */
public void resize(float x, float y, float z)
{
/** test low */
@@ -135,6 +165,13 @@ public class AABBox {
computeCenter();
}
+ /** Check if the x & y coordinates are bounded/contained
+ * by this AABBox
+ * @param x x-axis coordinate value
+ * @param y y-axis coordinate value
+ * @return true if x belong to (low.x, high.x) and
+ * y belong to (low.y, high.y)
+ */
public boolean contains(float x, float y){
if(x<low[0] || x>high[0]){
return false;
@@ -145,6 +182,14 @@ public class AABBox {
return true;
}
+ /** Check if the xyz coordinates are bounded/contained
+ * by this AABBox.
+ * @param x x-axis coordinate value
+ * @param y y-axis coordinate value
+ * @param z z-axis coordinate value
+ * @return true if x belong to (low.x, high.x) and
+ * y belong to (low.y, high.y) and z belong to (low.z, high.z)
+ */
public boolean contains(float x, float y, float z){
if(x<low[0] || x>high[0]){
return false;
@@ -158,14 +203,15 @@ public class AABBox {
return true;
}
- /**
- * @return true if area is empty
- */
- boolean isEmpty() {
- return getWidth() <=0 || getHeight() <= 0 ;
- }
-
- public boolean intersects(double x, double y, double w, double h) {
+ /** Check if there is a common region between this AABBox and the passed
+ * 2D region irrespective of z range
+ * @param x lower left x-coord
+ * @param y lower left y-coord
+ * @param w width
+ * @param h hight
+ * @return true if this AABBox might have a common region with this 2D region
+ */
+ public boolean intersects(float x, float y, float w, float h) {
if (w <= 0 || h <= 0) {
return false;
}
@@ -176,8 +222,8 @@ public class AABBox {
return false;
}
- final float x0 = getX();
- final float y0 = getY();
+ final float x0 = getMinX();
+ final float y0 = getMinY();
return (x + w > x0 &&
y + h > y0 &&
x < x0 + _w &&
@@ -185,26 +231,24 @@ public class AABBox {
}
+ /** Get the size of the Box where the size is represented by the
+ * length of the vector between low and high.
+ * @return a float representing the size of the AABBox
+ */
public float getSize(){
return VectorUtil.computeLength(low, high);
}
+ /**Get the Center of the AABBox
+ * @return the xyz-coordinates of the center of the AABBox
+ */
public float[] getCenter() {
return center;
}
- public void setCenter(float[] center) {
- this.center = center;
- }
-
- public void setHigh(float[] high) {
- this.high = high;
- }
-
- public void setLow(float[] low) {
- this.low = low;
- }
-
+ /** Scale the AABBox by a constant
+ * @param size a constant float value
+ */
public void scale(float size) {
float[] diffH = new float[3];
diffH[0] = high[0] - center[0];
@@ -224,11 +268,11 @@ public class AABBox {
low = VectorUtil.vectorAdd(center, diffL);
}
- public float getX() {
+ public float getMinX() {
return low[0];
}
- public float getY() {
+ public float getMinY() {
return low[1];
}
@@ -246,4 +290,9 @@ public class AABBox {
public AABBox clone(){
return new AABBox(this.low, this.high);
}
+
+ public String toString() {
+ return "[ "+low[0]+"/"+low[1]+"/"+low[1]+" .. "+high[0]+"/"+high[0]+"/"+high[0]+", ctr "+
+ center[0]+"/"+center[1]+"/"+center[1]+" ]";
+ }
}
diff --git a/src/com/jogamp/graph/geom/Outline.java b/src/com/jogamp/graph/geom/Outline.java
index 4e588623e..4f8d26783 100644
--- a/src/com/jogamp/graph/geom/Outline.java
+++ b/src/com/jogamp/graph/geom/Outline.java
@@ -41,9 +41,7 @@ import com.jogamp.graph.math.VectorUtil;
*
* Note: An outline should be closed to be rendered as a region.
*
- *
* @see OutlineShape, Region
- *
*/
public class Outline<T extends Vertex> implements Comparable<Outline<T>>{
diff --git a/src/com/jogamp/graph/geom/Vertex.java b/src/com/jogamp/graph/geom/Vertex.java
index 9d19c89f6..0e4e5e8df 100644
--- a/src/com/jogamp/graph/geom/Vertex.java
+++ b/src/com/jogamp/graph/geom/Vertex.java
@@ -40,8 +40,6 @@ public interface Vertex extends Comparable<Vertex>, Cloneable {
T create(float x, float y, float z);
T create(float[] coordsBuffer, int offset, int length);
-
- // T[] create(T ... v);
}
void setCoord(float x, float y);
diff --git a/src/com/jogamp/graph/geom/opengl/SVertex.java b/src/com/jogamp/graph/geom/opengl/SVertex.java
index 076ac7456..681067e40 100644
--- a/src/com/jogamp/graph/geom/opengl/SVertex.java
+++ b/src/com/jogamp/graph/geom/opengl/SVertex.java
@@ -31,6 +31,10 @@ package com.jogamp.graph.geom.opengl;
import com.jogamp.graph.geom.Vertex;
import com.jogamp.graph.math.VectorUtil;
+/** A Simple Vertex Implementation. Where the coordinates, and other attributes are
+ * float based, and the coordinates and texture coordinates are saved in two float arrays.
+ *
+ */
public class SVertex implements Vertex {
private int id = Integer.MAX_VALUE;
protected float[] coord = new float[3];
@@ -61,11 +65,6 @@ public class SVertex implements Vertex {
public SVertex create(float[] coordsBuffer, int offset, int length) {
return new SVertex(coordsBuffer, offset, length);
}
-
- /* @Override
- public Vertex[] create(Vertex ... v) {
- return v;
- } */
}
public SVertex() {
@@ -98,7 +97,7 @@ public class SVertex implements Vertex {
throw new IndexOutOfBoundsException("coordsBuffer too small: "+coordsBuffer.length+" - "+offset+" < "+length);
}
if(length > 3) {
- throw new IndexOutOfBoundsException("length too bug: "+length+" > "+3);
+ throw new IndexOutOfBoundsException("length too big: "+length+" > "+3);
}
int i=0;
while(i<length) {
diff --git a/src/demo/GPURendererListenerBase01.java b/src/demo/GPURendererListenerBase01.java
index ae72e6f66..e8dec4c01 100644
--- a/src/demo/GPURendererListenerBase01.java
+++ b/src/demo/GPURendererListenerBase01.java
@@ -207,7 +207,7 @@ public abstract class GPURendererListenerBase01 implements GLEventListener {
else if(arg0.getKeyCode() == KeyEvent.VK_9){
rotate(-1);
}
- else if(arg0.getKeyChar() == 'v') {
+ else if(arg0.getKeyCode() == KeyEvent.VK_V) {
if(null != autoDrawable) {
autoDrawable.invoke(false, new GLRunnable() {
public void run(GLAutoDrawable drawable) {
diff --git a/src/jogamp/graph/curve/text/GlyphShape.java b/src/jogamp/graph/curve/text/GlyphShape.java
index 712633f4b..16983fed9 100644
--- a/src/jogamp/graph/curve/text/GlyphShape.java
+++ b/src/jogamp/graph/curve/text/GlyphShape.java
@@ -70,7 +70,7 @@ public class GlyphShape {
shape.transformOutlines(OutlineShape.QUADRATIC_NURBS);
}
- public final Vertex.Factory<? extends Vertex> pointFactory() { return shape.pointFactory(); }
+ public final Vertex.Factory<? extends Vertex> vertexFactory() { return shape.vertexFactory(); }
private void addVertexToLastOutline(Vertex vertex){
shape.addVertex(vertex);
@@ -81,40 +81,40 @@ public class GlyphShape {
if(!shape.getLastOutline().isEmpty()){
shape.addEmptyOutline();
}
- Vertex vert = pointFactory().create(coords[0],coords[1]);
+ Vertex vert = vertexFactory().create(coords[0],coords[1]);
vert.setOnCurve(true);
addVertexToLastOutline(vert);
numVertices++;
}
else if(segmentType == PathIterator.SEG_LINETO){
- Vertex vert1 = pointFactory().create(coords[0],coords[1]);
+ Vertex vert1 = vertexFactory().create(coords[0],coords[1]);
vert1.setOnCurve(true);
addVertexToLastOutline(vert1);
numVertices++;
}
else if(segmentType == PathIterator.SEG_QUADTO){
- Vertex vert1 = pointFactory().create(coords[0],coords[1]);
+ Vertex vert1 = vertexFactory().create(coords[0],coords[1]);
vert1.setOnCurve(false);
addVertexToLastOutline(vert1);
- Vertex vert2 = pointFactory().create(coords[2],coords[3]);
+ Vertex vert2 = vertexFactory().create(coords[2],coords[3]);
vert2.setOnCurve(true);
addVertexToLastOutline(vert2);
numVertices+=2;
}
else if(segmentType == PathIterator.SEG_CUBICTO){
- Vertex vert1 = pointFactory().create(coords[0],coords[1]);
+ Vertex vert1 = vertexFactory().create(coords[0],coords[1]);
vert1.setOnCurve(false);
addVertexToLastOutline(vert1);
- Vertex vert2 = pointFactory().create(coords[2],coords[3]);
+ Vertex vert2 = vertexFactory().create(coords[2],coords[3]);
vert2.setOnCurve(false);
addVertexToLastOutline(vert2);
- Vertex vert3 = pointFactory().create(coords[4],coords[5]);
+ Vertex vert3 = vertexFactory().create(coords[4],coords[5]);
vert3.setOnCurve(true);
addVertexToLastOutline(vert3);
diff --git a/src/jogamp/graph/geom/plane/Path2D.java b/src/jogamp/graph/geom/plane/Path2D.java
index e25ae0e84..431891361 100644
--- a/src/jogamp/graph/geom/plane/Path2D.java
+++ b/src/jogamp/graph/geom/plane/Path2D.java
@@ -360,8 +360,6 @@ public final class Path2D implements Cloneable {
}
}
}
- // FIXME: Rami's code had this in, but AABBox uses upper left - lower right - right ?
- // return new AABBox(rx1, ry1, 0f, rx2 - rx1, ry2 - ry1, 0f);
return new AABBox(rx1, ry1, 0f, rx2, ry2, 0f);
}
@@ -396,11 +394,11 @@ public final class Path2D implements Cloneable {
}
public boolean contains(AABBox r) {
- return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ return contains(r);
}
public boolean intersects(AABBox r) {
- return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ return intersects(r.getMinX(), r.getMinY(), r.getWidth(), r.getHeight());
}
public PathIterator iterator() {