All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jogamp.graph.curve.tess.CDTriangulator2DExpAddOn Maven / Gradle / Ivy

/**
 * Copyright 2014 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.tess;

import com.jogamp.graph.geom.Triangle;
import com.jogamp.graph.geom.Vertex;
import com.jogamp.opengl.math.FloatUtil;
import com.jogamp.opengl.math.VectorUtil;

/**
 * Experimental Add-On ..
 *
 *  Disabled by default
 */
public class CDTriangulator2DExpAddOn {

    private final float[] tempV3a = new float[3];
    private final float[] tempV3b = new float[3];

    protected final void markLineInTriangle(final Triangle tri1, final float[] tempV2) {
        if( !tri1.isOnCurve() || !tri1.isLine() ) {
            return;
        }

        final boolean[] boundVs = tri1.getVerticesBoundary();
        final Vertex[] triVs = tri1.getVertices();
        final Vertex v0 = triVs[0];
        final Vertex v1 = triVs[1];
        final Vertex v2 = triVs[2];

        int lineSegCount = 0;
        final boolean v0IsLS, v1IsLS, v2IsLS;
        if( v0.isOnCurve() && VectorUtil.isVec2Zero(v0.getTexCoord(), 0) && !boundVs[0] ) {
            v0IsLS = true;
            lineSegCount++;
        } else {
            v0IsLS = false;
        }
        if( v1.isOnCurve() && VectorUtil.isVec2Zero(v1.getTexCoord(), 0) && !boundVs[1] ) {
            v1IsLS = true;
            lineSegCount++;
        } else {
            v1IsLS = false;
        }
        if( v2.isOnCurve() && VectorUtil.isVec2Zero(v2.getTexCoord(), 0) && !boundVs[2] ) {
            v2IsLS = true;
            lineSegCount++;
        } else {
            v2IsLS = false;
        }
        if( 2 > lineSegCount ) {
            return;
        } else {
            if(CDTriangulator2D.DEBUG) {
                System.err.println("CDTri.markLine.1: "+tri1);
                System.err.println("CDTri.markLine.1: count "+lineSegCount+", v0IsLS "+v0IsLS+", v1IsLS "+v1IsLS+", v2IsLS "+v2IsLS);
            }
            final float texZTag = 2f;
            if( true ) {
                if( v0IsLS ) {
                    v0.setTexCoord(0f, 0f, texZTag);
                }
                if( v1IsLS ) {
                    v1.setTexCoord(0f, 0f, texZTag);
                }
                if( v2IsLS ) {
                    v2.setTexCoord(0f, 0f, texZTag);
                }
            } else {
                if( v0IsLS ) {
                    final Vertex v = v0.clone();
                    v.setTexCoord(0f, 0f, texZTag);
                    triVs[0] = v;
                }
                if( v1IsLS ) {
                    final Vertex v = v1.clone();
                    v.setTexCoord(0f, 0f, texZTag);
                    triVs[1] = v;
                }
                if( v2IsLS ) {
                    final Vertex v = v2.clone();
                    v.setTexCoord(0f, 0f, texZTag);
                    triVs[2] = v;
                }
            }
            if ( false ) {
                final Vertex vL1, vL2, vL3, vO;
                if( 3 == lineSegCount ) {
                    vL1 = v0; vL2=v1; vL3=v2; vO=null;
                } else if( v0IsLS && v1IsLS ) {
                    vL1 = v0; vL2=v1; vL3=null; vO=v2;
                } else if( v0IsLS && v2IsLS ) {
                    vL1 = v0; vL2=v2; vL3=null; vO=v1;
                } else if( v1IsLS && v2IsLS ) {
                    vL1 = v1; vL2=v2; vL3=null; vO=v0;
                } else {
                    return; // unreachable
                }
                if( null != vL1 ) {
                    vL1.setTexCoord(texZTag, 0f, 0f);
                }
                if( null != vL2 ) {
                    vL2.setTexCoord(texZTag, 0f, 0f);
                }
                if( null != vL3 ) {
                    vL3.setTexCoord(texZTag, 0f, 0f);
                }
            }
        }
    }

    /**
     * If this and the other triangle compose a rectangle return the
     * given tempV2 array w/ shortest side first.
     * Otherwise return null;
     * 

* Experimental CODE, enabled only if {@link #TEST_LINE_AA} is set .. WIP *

*

One test uses method: ROESSLER-2012-OGLES *

*

* However, we would need to tesselate all lines appropriately, * i.e. create 2 triangles sharing the middle actual line using thickness+radius. * * This test simply used our default font w/ a line thickness of 2 pixels, * which produced mentioned rectangles. * This is of course not the case for arbitrary Outline shapes. *

* @param tri2 * @param checkThisOnCurve * @param tempV2 temp float[2] storage */ protected final float[] processLineAA(final int i, final Triangle tri1, final Triangle tri2, final float[] tempV2) { if(CDTriangulator2D.DEBUG){ System.err.println("CDTri.genP2["+i+"].1: ? t1 "+tri1); System.err.println("CDTri.genP2["+i+"].1: ? t2 "+tri2); } final float[] rect = processLineAAImpl(tri1, tri2, tempV2); if(CDTriangulator2D.DEBUG){ if( null != rect ) { System.err.println("CDTri.genP2["+i+"].1: RECT ["+rect[0]+", "+rect[1]+"]"); System.err.println("CDTri.genP2["+i+"].1: RECT t1 "+tri1); System.err.println("CDTri.genP2["+i+"].1: RECT t2 "+tri2); } else { System.err.println("CDTri.genP2["+i+"].1: RECT NOPE, t1 "+tri1); System.err.println("CDTri.genP2["+i+"].1: RECT NOPE, t2 "+tri2); } } return rect; } private final float[] processLineAAImpl(final Triangle tri1, final Triangle tri2, final float[] tempV2) { if( !tri1.isOnCurve() || !tri2.isOnCurve() || !tri1.isLine() || !tri2.isLine() ) { return null; } final float[] rect; int eqCount = 0; final int[] commonIdxA = { -1, -1 }; final int[] commonIdxB = { -1, -1 }; final Vertex[] verts1 = tri1.getVertices(); final Vertex[] verts2 = tri2.getVertices(); float[] coord = verts1[0].getCoord(); if( VectorUtil.isVec3Equal(coord, 0, verts2[0].getCoord(), 0, FloatUtil.EPSILON) ) { commonIdxA[eqCount] = 0; commonIdxB[eqCount] = 0; eqCount++; } else if( VectorUtil.isVec3Equal(coord, 0, verts2[1].getCoord(), 0, FloatUtil.EPSILON) ) { commonIdxA[eqCount] = 0; commonIdxB[eqCount] = 1; eqCount++; } else if( VectorUtil.isVec3Equal(coord, 0, verts2[2].getCoord(), 0, FloatUtil.EPSILON) ) { commonIdxA[eqCount] = 0; commonIdxB[eqCount] = 2; eqCount++; } coord = verts1[1].getCoord(); if( VectorUtil.isVec3Equal(coord, 0, verts2[0].getCoord(), 0, FloatUtil.EPSILON) ) { commonIdxA[eqCount] = 1; commonIdxB[eqCount] = 0; eqCount++; } else if( VectorUtil.isVec3Equal(coord, 0, verts2[1].getCoord(), 0, FloatUtil.EPSILON) ) { commonIdxA[eqCount] = 1; commonIdxB[eqCount] = 1; eqCount++; } else if( VectorUtil.isVec3Equal(coord, 0, verts2[2].getCoord(), 0, FloatUtil.EPSILON) ) { commonIdxA[eqCount] = 1; commonIdxB[eqCount] = 2; eqCount++; } final int otherIdxA; if( 2 == eqCount ) { otherIdxA = 3 - ( commonIdxA[0] + commonIdxA[1] ); } else { coord = verts1[2].getCoord(); if( VectorUtil.isVec3Equal(coord, 0, verts2[0].getCoord(), 0, FloatUtil.EPSILON) ) { commonIdxA[eqCount] = 2; commonIdxB[eqCount] = 0; eqCount++; } else if( VectorUtil.isVec3Equal(coord, 0, verts2[1].getCoord(), 0, FloatUtil.EPSILON) ) { commonIdxA[eqCount] = 2; commonIdxB[eqCount] = 1; eqCount++; } else if( VectorUtil.isVec3Equal(coord, 0, verts2[2].getCoord(), 0, FloatUtil.EPSILON) ) { commonIdxA[eqCount] = 2; commonIdxB[eqCount] = 2; eqCount++; } if( 2 == eqCount ) { otherIdxA = 3 - ( commonIdxA[0] + commonIdxA[1] ); } else { otherIdxA = -1; } } if( 0 <= otherIdxA && commonIdxB[0] != commonIdxB[1] ) { final int otherIdxB = 3 - ( commonIdxB[0] + commonIdxB[1] ); // Reference must be equal, i.e. sharing the actual same vertices! if( verts1[commonIdxA[0]] != verts2[commonIdxB[0]] || verts1[commonIdxA[1]] != verts2[commonIdxB[1]] ) { throw new InternalError("XXX: diff shared verts"); // FIXME remove when clear } final Vertex vC0A, vC1A, vOA, vOB; if( false ) { // Fetch only! vC0A = verts1[commonIdxA[0]]; vC1A = verts1[commonIdxA[1]]; vOA = verts1[otherIdxA]; vOB = verts2[otherIdxB]; } else { // Fetch and clone, write-back to triangles vC0A = verts1[commonIdxA[0]].clone(); verts1[commonIdxA[0]] = vC0A; verts2[commonIdxB[0]] = vC0A; vC1A = verts1[commonIdxA[1]].clone(); verts1[commonIdxA[1]] = vC1A; verts2[commonIdxB[1]] = vC1A; vOA = verts1[otherIdxA].clone(); verts1[otherIdxA] = vOA; vOB = verts2[otherIdxB].clone(); verts2[otherIdxB] = vOB; } final float texZTag = 2f; final float[] vOACoords = vOA.getCoord(); final float dOC0A = VectorUtil.distVec3(vOACoords, vC0A.getCoord()); final float dOC1A = VectorUtil.distVec3(vOACoords, vC1A.getCoord()); if( false ) { final float[] vec3Z = { 0f, 0f, -1f }; final float[] vecLongSide, vecLineHeight; if( dOC0A < dOC1A ) { tempV2[0] = dOC0A; // line width tempV2[1] = dOC1A; // long side vecLongSide = VectorUtil.normalizeVec3( VectorUtil.subVec2(tempV3a, vOACoords, vC1A.getCoord()) ); // normal long side vector vecLineHeight = VectorUtil.crossVec3(tempV3b, vec3Z, tempV3a); // the line-height vector (normal) vOA.setTexCoord(-1f, -1f, texZTag); vC1A.setTexCoord(1f, -1f, texZTag); vOB.setTexCoord(0f, 1f, texZTag); vC0A.setTexCoord(0f, 1f, texZTag); } else { tempV2[0] = dOC1A; // line width tempV2[1] = dOC0A; // long side vecLongSide = VectorUtil.normalizeVec3( VectorUtil.subVec2(tempV3a, vOACoords, vC0A.getCoord()) ); // normal long side vector vecLineHeight = VectorUtil.crossVec3(tempV3b, vec3Z, tempV3a); // the line-height vector (normal) } if(CDTriangulator2D.DEBUG){ System.err.println("RECT.0 : long-side-vec "+vecLongSide[0]+", "+vecLongSide[1]+", "+vecLongSide[2]); System.err.println("RECT.0 : line-height-vec "+vecLineHeight[0]+", "+vecLineHeight[1]+", "+vecLineHeight[2]); } } else { /** * Using method: ROESSLER-2012-OGLES * * Arbitrary but consistently pick left/right and set texCoords, FIXME: validate * * Testing w/ fixed line-width 1, and radius 1/3. */ final float lineWidth; final Vertex vL1, vL2, vR1, vR2; if( dOC0A < dOC1A ) { lineWidth = dOC0A; // line width tempV2[0] = dOC0A; // line width tempV2[1] = dOC1A; // long side // Left: vOA, vC1A // Right: vOB, vC0A vL1 = vOA; vL2 = vC1A; vR1 = vOB; vR2 = vC0A; } else { lineWidth = dOC1A; // line width tempV2[0] = dOC1A; // line width tempV2[1] = dOC0A; // long side // Left: vOB, vC1A // Right: vOA, vC0A vL1 = vOB; vL2 = vC1A; vR1 = vOA; vR2 = vC0A; } final float r = lineWidth/3f; final float wa = lineWidth + r; final float waHalf = wa / 2f; vL1.setTexCoord(lineWidth, waHalf, texZTag); vL2.setTexCoord(lineWidth, waHalf, texZTag); vR1.setTexCoord(lineWidth, -waHalf, texZTag); vR2.setTexCoord(lineWidth, -waHalf, texZTag); if(CDTriangulator2D.DEBUG){ System.err.println("RECT.0 : lineWidth: "+lineWidth+", dim "+dOC0A+" x "+dOC1A+", radius "+r); System.err.println("RECT Left.0: "+vL1+", "+vL2); System.err.println("RECT Right.0: "+vR1+", "+vR2); } } rect = tempV2; } else { rect = null; } return rect; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy