adding convexivity test and fan method for convex polygon triangulation

This commit is contained in:
Rachel Hwang 2017-06-15 11:11:27 -04:00
parent 50d26f4fd7
commit 7e82e90b35

View File

@ -279,6 +279,29 @@ function loadObj(objPath, options) {
return index;
}
// Given a sequence of three points A B C, determine whether vector BC
// "turns" clockwise (positive) or counter-clockwise (negative) from vector AB
var scratch1 = new Cartesian3();
var scratch2 = new Cartesian3();
function getTurnDirection(pointA, pointB, pointC) {
var vector1 = Cartesian2.subtract(pointA, pointB, scratch1);
var vector2 = Cartesian2.subtract(pointC, pointB, scratch2);
return vector1.x * vector2.y - vector1.y * vector2.x;
}
// Given the cartesian 2 vertices of a polygon, determine if convex
function isConvex(positions2D) {
var i;
var turnDirection = getTurnDirection(positions2D[0], positions2D[1], positions2D[2]);
for (i=1; i < positions2D.length-2; ++i) {
var currentTurnDirection = getTurnDirection(positions2D[i], positions2D[i+1], positions2D[i+2]);
if (turnDirection * currentTurnDirection < 0) {
return false;
}
}
return true;
}
function addFace(vertices, positions, uvs, normals) {
var u1, u2, u3, n1, n2, n3;
@ -316,29 +339,39 @@ function loadObj(objPath, options) {
var index = addVertex(vertices[i], positions[i], u, n);
vertexIndices.push(index);
// Collect the vertex positions as 3D points
var pi = getOffset(index + 1, positions, 3);
var px = mesh.positions.get(pi + 0);
var py = mesh.positions.get(pi + 1);
var pz = mesh.positions.get(pi + 2);
positions3D.push(new Cartesian3(px, py, pz));
}
var positions2D = projectTo2D(positions3D);
var windingOrder = PolygonPipeline.computeWindingOrder2D(positions2D);
if (isConvex(positions2D)) {
// Use the fan method to triangulate
for (i=1; i < vertices.length-1; ++i) {
primitive.indices.push(vertexIndices[0]);
primitive.indices.push(vertexIndices[i]);
primitive.indices.push(vertexIndices[i+1]);
}
} else {
// Since the projection doesn't respect winding order, reverse the order of
// the vertices before triangulating to enforce counter clockwise.
var windingOrder = PolygonPipeline.computeWindingOrder2D(positions2D);
if (windingOrder === WindingOrder.CLOCKWISE) {
positions2D.reverse();
}
// Use an ear-clipping algorithm to triangulate
var positionIndices = PolygonPipeline.triangulate(positions2D);
for (i = 0; i < positionIndices.length; ++i) {
primitive.indices.push(vertexIndices[positionIndices[i]]);
}
}
}
}