/** * @author zz85 / http://www.lab4games.net/zz85/blog * * For creating 3D text geometry in three.js * * Text = 3D Text * * parameters = { * size: size of the text * height: thickness to extrude text, * curveSegments: number of points on the curves, * font: font name, * } * * It utilizes techniques used in * * typeface.js and canvastext * For converting fonts and rendering with javascript * http://typeface.neocracy.org * * Triangulation ported from AS3 * Simple Polygon Triangulation * http://actionsnippet.com/?p=1462 * * A Method to triangulate shapes with holes * http://www.sakri.net/blog/2009/06/12/an-approach-to-triangulating-polygons-with-holes/ * */ THREE.Text = function (text, parameters) { THREE.Geometry.call( this ); this.parameters = parameters || {}; this.set(text); }; THREE.Text.prototype = new THREE.Geometry(); THREE.Text.prototype.constructor = THREE.Text; THREE.Text.prototype.set = function (text, parameters) { this.text = text; var parameters = parameters || this.parameters; var size = parameters.size !== undefined ? parameters.size : 100; var height = parameters.height !== undefined ? parameters.height : 50; var curveSegments = parameters.curveSegments !== undefined ? parameters.curveSegments: 4; var font = parameters.font !== undefined ? parameters.font : "helvetiker"; THREE.FontUtils.size = size; THREE.FontUtils.divisions = curveSegments; THREE.FontUtils.face = font; // Get a Font data json object var data = THREE.FontUtils.drawText(text); //console.log("data", data); vertices = data.points; faces = data.faces; contour = data.contour; var scope = this; scope.vertices = []; scope.faces = []; //console.log(this); var vlen = 0; for (var i in vertices) { var vert = vertices[i]; v(vert.x, vert.y, 0); vlen++; } for (var i in vertices) { var vert = vertices[i]; v(vert.x, vert.y, height); } // Bottom faces for (var i in faces) { var face = faces[i]; f3(face[2], face[1], face[0]); } // Top Faces for (var i in faces) { var face = faces[i]; f3(face[0]+vlen, face[1]+vlen, face[2]+vlen); } var i = contour.length; var lastV; var j; while (--i > 0) { if (!lastV) { lastV = contour[i]; } else if (lastV.equals(contour[i])) { lastV = null; continue; } var j,k; for (j=0; j0) { isolatedShapes.push({shape: shape, holes: holes}); } // Save the old shapes, then work on new additional seperated shape shape = contours; holes = []; } else { holes.push(contours); } } else { if (this.Triangulate.area(contours)<0) { isolatedShapes.push({shape: contours, holes: holes}); holes = []; } else { holes.push(contours); } } endPt++; } if (shapesFirst) { isolatedShapes.push({shape: shape, holes: holes}); } } //console.log("isolatedShapes", isolatedShapes); /* For each isolated shape, find the closest points and break to the hole to allow triangulation*/ // Find closest points between holes // we could optimize with // http://en.wikipedia.org/wiki/Proximity_problems // http://en.wikipedia.org/wiki/Closest_pair_of_points // http://stackoverflow.com/questions/1602164/shortest-distance-between-points-algorithm var verts = []; for (var shapeId in isolatedShapes) { var shapeGroup = isolatedShapes[shapeId]; shape = shapeGroup.shape; holes = shapeGroup.holes; for (var h in holes) { // we slice to each hole when neccessary var hole = holes[h]; var shortest = Number.POSITIVE_INFINITY; var holeIndex, shapeIndex; for (var h2 in hole) { var pts1 = hole[h2]; for (var p in shape) { var pts2 = shape[p]; d = pts1.distanceTo(pts2); if (d=0 ? shapeIndex-1:shape.length-1 ; nextShapeVert = (shapeIndex+1)=0 ? holeIndex-1:hole.length-1; nextHoleVert = (holeIndex+1)2; ) { /* if we loop, it is probably a non-simple polygon */ if (0 >= (count--)){ //** Triangulate: ERROR - probable bad polygon! throw ("Warning, unable to triangulate polygon!"); return null; } /* three consecutive vertices in current polygon, */ var u = v; if (nv <= u) u = 0; /* previous */ v = u+1; if (nv <= v) v = 0; /* new v */ var w = v+1; if (nv <= w) w = 0; /* next */ if ( snip(contour,u,v,w,nv,verts)){ var a,b,c,s,t; /* true names of the vertices */ a = verts[u]; b = verts[v]; c = verts[w]; /* output Triangle */ result.push( contour[a] ); result.push( contour[b] ); result.push( contour[c] ); vertIndics.push([verts[u], verts[v],verts[w]]); //vertIndics.push(THREE.Face3(verts[u], verts[v],verts[w])); m++; /* remove v from remaining polygon */ for(s=v,t=v+1;t= 0.0) && (bCROSScp >= 0.0) && (cCROSSap >= 0.0)); }; var snip = function (contour, u, v, w, n, verts) { var p; var ax, ay, bx, by; var cx, cy, px, py; ax = contour[verts[u]].x; ay = contour[verts[u]].y; bx = contour[verts[v]].x; by = contour[verts[v]].y; cx = contour[verts[w]].x; cy = contour[verts[w]].y; if ( EPSILON > (((bx-ax)*(cy-ay)) - ((by-ay)*(cx-ax))) ) return false; for (p=0;p