提交 d1f5c680 编写于 作者: M Mr.doob

Merging with alteredq's dev.

上级 f96e48d0
因为 它太大了无法显示 source diff 。你可以改为 查看blob
此差异已折叠。
此差异已折叠。
......@@ -62,21 +62,70 @@
scene = new THREE.Scene();
var light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 0, 0, 1 );
light.position.normalize();
scene.addLight( light );
parent = new THREE.Object3D();
parent.position.y = 50;
scene.addChild( parent );
function addGeometry( geometry, color, x, y, z, rx, ry, rz, s ) {
function addGeometry( geometry, points, spacedPoints, color, x, y, z, rx, ry, rz, s ) {
// 3d shape
var mesh = new THREE.Mesh( geometry, [ new THREE.MeshBasicMaterial( { color: color } ), new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true } ) ] );
mesh.position.set( x, y, z );
var mesh = new THREE.Mesh( geometry, [ new THREE.MeshLambertMaterial( { color: color } ), new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true } ) ] );
mesh.position.set( x, y, z - 75 );
mesh.rotation.set( rx, ry, rz );
mesh.scale.set( s, s, s );
parent.addChild( mesh );
// solid line
var line = new THREE.Line( points, new THREE.LineBasicMaterial( { color: color, linewidth: 2 } ) );
line.position.set( x, y, z + 25 );
line.rotation.set( rx, ry, rz );
line.scale.set( s, s, s );
parent.addChild( line );
// transparent line from real points
var line = new THREE.Line( points, new THREE.LineBasicMaterial( { color: color, opacity: 0.5 } ) );
line.position.set( x, y, z + 75 );
line.rotation.set( rx, ry, rz );
line.scale.set( s, s, s );
parent.addChild( line );
// vertices from real points
var pgeo = THREE.GeometryUtils.clone( points );
var particles = new THREE.ParticleSystem( pgeo, new THREE.ParticleBasicMaterial( { color: color, size: 2, opacity: 0.75 } ) );
particles.position.set( x, y, z + 75 );
particles.rotation.set( rx, ry, rz );
particles.scale.set( s, s, s );
parent.addChild( particles );
// transparent line from equidistance sampled points
var line = new THREE.Line( spacedPoints, new THREE.LineBasicMaterial( { color: color, opacity: 0.2 } ) );
line.position.set( x, y, z + 100 );
line.rotation.set( rx, ry, rz );
line.scale.set( s, s, s );
parent.addChild( line );
// equidistance sampled points
var pgeo = THREE.GeometryUtils.clone( spacedPoints );
var particles2 = new THREE.ParticleSystem( pgeo, new THREE.ParticleBasicMaterial( { color: color, size: 2, opacity: 0.5 } ) );
particles2.position.set( x, y, z + 100 );
particles2.rotation.set( rx, ry, rz );
particles2.scale.set( s, s, s );
parent.addChild( particles2 );
}
var extrudeSettings = { amount: 20 };
var extrudeSettings = { amount: 20, bevelEnabled: true, bevelSegments: 2, steps: 2 }; // amount: 40, steps: 2
// California
......@@ -106,7 +155,10 @@
californiaPts.push( new THREE.Vector2 ( 610, 320 ) );
var californiaShape = new THREE.Shape( californiaPts );
var california3d = new THREE.ExtrudeGeometry( californiaShape, { amount: 20 } );
var californiaPoints = californiaShape.createPointsGeometry();
var californiaSpacedPoints = californiaShape.createSpacedPointsGeometry( 100 );
// Triangle
......@@ -117,6 +169,8 @@
triangleShape.lineTo( 80, 20 ); // close path
var triangle3d = triangleShape.extrude( extrudeSettings );
var trianglePoints = triangleShape.createPointsGeometry();
var triangleSpacedPoints = triangleShape.createSpacedPointsGeometry();
// Heart
......@@ -134,6 +188,8 @@
heartShape.bezierCurveTo( x + 35, y, x + 25, y + 25, x + 25, y + 25 );
var heart3d = heartShape.extrude( extrudeSettings );
var heartPoints = heartShape.createPointsGeometry();
var heartSpacedPoints = heartShape.createSpacedPointsGeometry();
//heartShape.debug( document.getElementById("debug") );
......@@ -149,6 +205,8 @@
squareShape.lineTo( 0, 0 );
var square3d = squareShape.extrude( extrudeSettings );
var squarePoints = squareShape.createPointsGeometry();
var squareSpacedPoints = squareShape.createSpacedPointsGeometry();
// Rectangle
......@@ -162,6 +220,8 @@
rectShape.lineTo( 0, 0 );
var rect3d = rectShape.extrude( extrudeSettings );
var rectPoints = rectShape.createPointsGeometry();
var rectSpacedPoints = rectShape.createSpacedPointsGeometry();
// Rounded rectangle
......@@ -169,6 +229,8 @@
roundedRect( roundedRectShape, 0, 0, 50, 50, 20 );
var roundedRect3d = roundedRectShape.extrude( extrudeSettings );
var roundedRectPoints = roundedRectShape.createPointsGeometry();
var roundedRectSpacedPoints = roundedRectShape.createSpacedPointsGeometry();
function roundedRect( ctx, x, y, width, height, radius ){
......@@ -195,6 +257,8 @@
circleShape.quadraticCurveTo( -circleRadius, circleRadius, 0, circleRadius );
var circle3d = circleShape.extrude( extrudeSettings );
var circlePoints = circleShape.createPointsGeometry();
var circleSpacedPoints = circleShape.createSpacedPointsGeometry();
// Fish
......@@ -210,8 +274,25 @@
fishShape.quadraticCurveTo( x + 50, y - 80, x, y );
var fish3d = fishShape.extrude( extrudeSettings );
var fishPoints = fishShape.createPointsGeometry();
var fishSpacedPoints = fishShape.createSpacedPointsGeometry();
// Arc circle
var arcShape = new THREE.Shape();
arcShape.moveTo( 0, 0 );
arcShape.arc( 10, 10, 40, 0, Math.PI*2, false );
// Spline shape + Path Extrusion
var holePath = new THREE.Path();
holePath.moveTo( 0, 0 );
holePath.arc( 10, 10, 10, 0, Math.PI*2, true );
arcShape.holes.push( holePath );
var arc3d = arcShape.extrude( extrudeSettings );
var arcPoints = arcShape.createPointsGeometry();
var arcSpacedPoints = arcShape.createSpacedPointsGeometry();
// Spline shape + path extrusion
var splinepts = [];
splinepts.push( new THREE.Vector2 ( 350, 100 ) );
......@@ -227,24 +308,31 @@
var extrudePath = new THREE.Path();
extrudePath.moveTo( 0, 0 );
extrudePath.lineTo( 10, 10 );
extrudePath.quadraticCurveTo( 80, 60, 160, 10 );
extrudePath.quadraticCurveTo( 240, -40, 320, 10 );
extrudeSettings.path = extrudePath;
extrudeSettings.bevelEnabled = false;
var splineShape3d = splineShape.extrude( extrudeSettings );
addGeometry( california3d, 0xffaa00, -300, -100, 0, 0, 0, 0, 0.25 );
addGeometry( triangle3d, 0xffee00, -180, 0, 0, 0, 0, 0, 1 );
addGeometry( roundedRect3d, 0x005500, -150, 150, 0, 0, 0, 0, 1 );
addGeometry( square3d, 0x0055ff, 150, 100, 0, 0, 0, 0, 1 );
addGeometry( heart3d, 0xff1100, 0, 100, 0, 3.14, 0, 0, 1 );
addGeometry( circle3d, 0x00ff11, 150, 0, 0, 0, 0, 0, 1 );
addGeometry( fish3d, 0x222222, -50, 200, 0, 0, 0, 0, 1 );
addGeometry( splineShape3d, 0x888888, -50, -100, -50, 0, 0, 0, 0.2 );
renderer = new THREE.CanvasRenderer();
var splinePoints = splineShape.createPointsGeometry( );
var splineSpacedPoints = splineShape.createSpacedPointsGeometry( );
addGeometry( california3d, californiaPoints, californiaSpacedPoints, 0xffaa00, -300, -100, 0, 0, 0, 0, 0.25 );
addGeometry( triangle3d, trianglePoints, triangleSpacedPoints, 0xffee00, -180, 0, 0, 0, 0, 0, 1 );
addGeometry( roundedRect3d, roundedRectPoints, roundedRectSpacedPoints, 0x005500, -150, 150, 0, 0, 0, 0, 1 );
addGeometry( square3d, squarePoints, squareSpacedPoints, 0x0055ff, 150, 100, 0, 0, 0, 0, 1 );
addGeometry( heart3d, heartPoints, heartSpacedPoints, 0xff1100, 0, 100, 0, 3.14, 0, 0, 1 );
addGeometry( circle3d, circlePoints, circleSpacedPoints, 0x00ff11, 120, 250, 0, 0, 0, 0, 1 );
addGeometry( fish3d, fishPoints, fishSpacedPoints, 0x222222, -50, 200, 0, 0, 0, 0, 1 );
addGeometry( splineShape3d, splinePoints, splineSpacedPoints, 0x888888, -50, -100, -50, 0, 0, 0, 0.2 );
addGeometry( arc3d, arcPoints, arcSpacedPoints, 0xbb4422, 150, 0, 0, 0, 0, 0, 1 );
//
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
......
......@@ -26,14 +26,14 @@
<body>
<div id="info">
<a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> - procedural 3D text by <a href="http://www.lab4games.net/zz85/blog" target="_blank">zz85</a> &amp; alteredq
<a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> - procedural 3D text by <a href="http://www.lab4games.net/zz85/blog" target="_blank">zz85</a> &amp; alteredq
(fonts from <a href="http://typeface.neocracy.org/">typeface.js</a> and <a href="http://en.wikipedia.org/wiki/Droid_%28font%29">Droid</a>)
<br/>type to enter new text, drag to spin the text
<br/><span class="button" id="color">change color</span>,
<span class="button" id="font">change font</span>,
<br/><span class="button" id="color">change color</span>,
<span class="button" id="font">change font</span>,
<span class="button" id="weight">change weight</span>,
<span class="button" id="bezel">change bezel</span>,
<span class="button" id="postprocessing">change postprocessing</span>,
<span class="button" id="bevel">change bevel</span>,
<span class="button" id="postprocessing">change postprocessing</span>,
<a id="permalink" href="#">permalink</a>
</div>
......@@ -43,12 +43,12 @@
<script type="text/javascript" src="js/Detector.js"></script>
<script type="text/javascript" src="js/RequestAnimationFrame.js"></script>
<script type="text/javascript" src="js/Stats.js"></script>
<!-- load the font file from canvas-text -->
<!--
-->
<script type="text/javascript" src="fonts/gentilis_bold.typeface.js"></script>
<script type="text/javascript" src="fonts/gentilis_regular.typeface.js"></script>
......@@ -60,7 +60,7 @@
<script type="text/javascript" src="fonts/droid/droid_sans_bold.typeface.js"></script>
<script type="text/javascript" src="fonts/droid/droid_serif_regular.typeface.js"></script>
<script type="text/javascript" src="fonts/droid/droid_serif_bold.typeface.js"></script>
<script type="text/javascript">
......@@ -82,9 +82,9 @@
curveSegments = 6,
bezelThickness = 2,
bezelSize = 1.5,
bezelEnabled = true,
bevelThickness = 2,
bevelSize = 1.5,
bevelEnabled = true,
font = "optimer", // helvetiker, optimer, gentilis, droid sans, droid serif
weight = "bold", // normal bold
......@@ -134,9 +134,9 @@
}
function decimalToHex( d ) {
var hex = Number( d ).toString( 16 );
hex = "000000".substr( 0, 6 - hex.length ) + hex;
hex = "000000".substr( 0, 6 - hex.length ) + hex;
return hex.toUpperCase();
}
......@@ -180,7 +180,7 @@
var fonthash = hash.substring( 6, 7 );
var weighthash = hash.substring( 7, 8 );
var pphash = hash.substring( 8, 9 );
var bezelhash = hash.substring( 9, 10 );
var bevelhash = hash.substring( 9, 10 );
var texthash = hash.substring( 11 );
hex = colorhash;
......@@ -190,7 +190,7 @@
weight = reverseWeightMap[ parseInt( weighthash ) ];
postprocessing.enabled = parseInt( pphash );
bezelEnabled = parseInt( bezelhash );
bevelEnabled = parseInt( bevelhash );
text = decodeURI( texthash );
......@@ -206,7 +206,7 @@
textGeo = new THREE.TextGeometry( text, {
size: size,
size: size,
height: height,
curveSegments: curveSegments,
......@@ -214,16 +214,16 @@
weight: weight,
style: style,
bezelThickness: bezelThickness,
bezelSize: bezelSize,
bezelEnabled: bezelEnabled
bevelThickness: bevelThickness,
bevelSize: bevelSize,
bevelEnabled: bevelEnabled
});
textMaterial = new THREE.MeshPhongMaterial( { color: 0xffffff, wireframe: false } );
parent = new THREE.Object3D();
textMesh1 = new THREE.Mesh( textGeo, textMaterial );
textMesh1.position.x = 0;
......@@ -247,7 +247,7 @@
textMesh2.rotation.y = Math.PI * 2;
parent.addChild( textMesh2 );
}
parent.position.y = 100;
......@@ -260,7 +260,7 @@
renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( scene.fog.color, 1 );
container.appendChild( renderer.domElement );
......@@ -277,91 +277,91 @@
document.addEventListener( 'keydown', onDocumentKeyDown, false );
document.getElementById( "color" ).addEventListener( 'click', function() {
pointLight.color.setHSV( Math.random(), 0.95, 0.85 );
pointLight.color.updateHex();
hex = decimalToHex( pointLight.color.hex );
updatePermalink();
}, false );
document.getElementById( "font" ).addEventListener( 'click', function() {
if ( font == "helvetiker" ) {
font = "optimer";
} else if ( font == "optimer" ) {
font = "gentilis";
} else if ( font == "gentilis" ) {
font = "droid sans";
} else if ( font == "droid sans" ) {
font = "droid serif";
} else {
font = "helvetiker";
}
refreshText();
}, false );
document.getElementById( "weight" ).addEventListener( 'click', function() {
if ( weight == "bold" ) {
weight = "normal";
} else {
weight = "bold";
}
refreshText();
}, false );
document.getElementById( "bezel" ).addEventListener( 'click', function() {
bezelEnabled = !bezelEnabled;
document.getElementById( "bevel" ).addEventListener( 'click', function() {
bevelEnabled = !bevelEnabled;
refreshText();
}, false );
document.getElementById( "postprocessing" ).addEventListener( 'click', function() {
postprocessing.enabled = !postprocessing.enabled;
updatePermalink();
}, false );
initPostprocessing();
renderer.autoClear = false;
}
//
function boolToNum( b ) {
return b ? 1 : 0;
}
function updatePermalink() {
var link = hex + fontMap[ font ] + weightMap[ weight ] + boolToNum( postprocessing.enabled ) + boolToNum( bezelEnabled ) + "#" + encodeURI( text );
var link = hex + fontMap[ font ] + weightMap[ weight ] + boolToNum( postprocessing.enabled ) + boolToNum( bevelEnabled ) + "#" + encodeURI( text );
permalink.href = "#" + link;
window.location.hash = link;
......@@ -370,14 +370,14 @@
function onDocumentKeyDown( event ) {
if ( firstLetter ) {
firstLetter = false;
text = "";
}
var keyCode = event.keyCode;
// backspace
if ( keyCode == 8 ) {
......@@ -388,23 +388,23 @@
refreshText();
return false;
}
}
function onDocumentKeyPress( event ) {
var keyCode = event.which;
// backspace
if ( keyCode == 8 ) {
event.preventDefault();
} else {
var ch = String.fromCharCode( keyCode );
text += ch;
......@@ -413,16 +413,16 @@
}
}
function refreshText() {
updatePermalink();
scene.removeChild( textMesh1 );
textGeo = new THREE.TextGeometry( text, {
size: size,
size: size,
height: height,
curveSegments: curveSegments,
......@@ -430,9 +430,9 @@
weight: weight,
style: style,
bezelThickness: bezelThickness,
bezelSize: bezelSize,
bezelEnabled: bezelEnabled
bevelThickness: bevelThickness,
bevelSize: bevelSize,
bevelEnabled: bevelEnabled
});
......@@ -459,14 +459,14 @@
textMesh2.rotation.x = Math.PI;
textMesh2.rotation.y = Math.PI * 2;
parent.addChild( textMesh2 );
}
}
function onDocumentMouseDown( event ) {
event.preventDefault();
......@@ -531,7 +531,7 @@
}
//
function initPostprocessing() {
postprocessing.scene = new THREE.Scene();
......@@ -621,9 +621,9 @@
time = new Date().getTime();
delta = 0.1 * ( time - oldTime );
oldTime = time;
parent.rotation.y += ( targetRotation - parent.rotation.y ) * 0.05;
if ( postprocessing.enabled ) {
renderer.clear();
......@@ -669,7 +669,7 @@
renderer.clear();
renderer.render( scene, camera );
}
}
}
......
......@@ -518,7 +518,9 @@ THREE.Matrix4.prototype = {
e = Math.cos( z ), f = Math.sin( z );
switch ( order ) {
case 'YXZ':
var ce = c * e, cf = c * f, de = d * e, df = d * f;
this.n11 = ce + df * b;
......@@ -535,6 +537,7 @@ THREE.Matrix4.prototype = {
break;
case 'ZXY':
var ce = c * e, cf = c * f, de = d * e, df = d * f;
this.n11 = ce - df * b;
......@@ -551,6 +554,7 @@ THREE.Matrix4.prototype = {
break;
case 'ZYX':
var ae = a * e, af = a * f, be = b * e, bf = b * f;
this.n11 = c * e;
......@@ -567,6 +571,7 @@ THREE.Matrix4.prototype = {
break;
case 'YZX':
var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
this.n11 = c * e;
......@@ -583,6 +588,7 @@ THREE.Matrix4.prototype = {
break;
case 'XZY':
var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
this.n11 = c * e;
......@@ -599,6 +605,7 @@ THREE.Matrix4.prototype = {
break;
default: // 'XYZ'
var ae = a * e, af = a * f, be = b * e, bf = b * f;
this.n11 = c * e;
......@@ -613,6 +620,7 @@ THREE.Matrix4.prototype = {
this.n32 = be + af * d;
this.n33 = a * c;
break;
}
return this;
......
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
*/
THREE.GeometryUtils = {
......@@ -19,6 +20,8 @@ THREE.GeometryUtils = {
isMesh && object2.matrixAutoUpdate && object2.updateMatrix();
// vertices
for ( var i = 0, il = vertices2.length; i < il; i ++ ) {
var vertex = vertices2[ i ];
......@@ -31,6 +34,8 @@ THREE.GeometryUtils = {
}
// faces
for ( i = 0, il = faces2.length; i < il; i ++ ) {
var face = faces2[ i ], faceCopy, normal, color,
......@@ -73,6 +78,8 @@ THREE.GeometryUtils = {
}
// uvs
for ( i = 0, il = uvs2.length; i < il; i ++ ) {
var uv = uvs2[ i ], uvCopy = [];
......@@ -87,6 +94,91 @@ THREE.GeometryUtils = {
}
},
clone: function ( geometry ) {
var cloneGeo = new THREE.Geometry();
var i, il;
var vertices = geometry.vertices,
faces = geometry.faces,
uvs = geometry.faceVertexUvs[ 0 ];
// vertices
for ( i = 0, il = vertices.length; i < il; i ++ ) {
var vertex = vertices[ i ];
var vertexCopy = new THREE.Vertex( vertex.position.clone() );
cloneGeo.vertices.push( vertexCopy );
}
// faces
for ( i = 0, il = faces.length; i < il; i ++ ) {
var face = faces[ i ], faceCopy, normal, color,
faceVertexNormals = face.vertexNormals,
faceVertexColors = face.vertexColors;
if ( face instanceof THREE.Face3 ) {
faceCopy = new THREE.Face3( face.a, face.b, face.c );
} else if ( face instanceof THREE.Face4 ) {
faceCopy = new THREE.Face4( face.a, face.b, face.c, face.d );
}
faceCopy.normal.copy( face.normal );
for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {
normal = faceVertexNormals[ j ];
faceCopy.vertexNormals.push( normal.clone() );
}
faceCopy.color.copy( face.color );
for ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {
color = faceVertexColors[ j ];
faceCopy.vertexColors.push( color.clone() );
}
faceCopy.materials = face.materials.slice();
faceCopy.centroid.copy( face.centroid );
cloneGeo.faces.push( faceCopy );
}
// uvs
for ( i = 0, il = uvs.length; i < il; i ++ ) {
var uv = uvs[ i ], uvCopy = [];
for ( var j = 0, jl = uv.length; j < jl; j ++ ) {
uvCopy.push( new THREE.UV( uv[ j ].u, uv[ j ].v ) );
}
cloneGeo.faceVertexUvs[ 0 ].push( uvCopy );
}
return cloneGeo;
}
};
/**
* @author zz85 / http://www.lab4games.net/zz85/blog
* Extensible curve object
*
* This file contains following classes:
*
* THREE.Curve
* THREE.LineCurve
* THREE.QuadraticBezierCurve
* THREE.CubicBezierCurve
* THREE.SplineCurve
* THREE.ArcCurve
*
**/
/**************************************************************
* Abstract Curve base class
**************************************************************/
THREE.Curve = function () {
};
// Virtual base class method to overwrite and implement in subclasses
// - t [0 .. 1]
THREE.Curve.prototype.getPoint = function ( t ) {
console.log( "Warning, getPoint() not implemented!" );
return null;
};
// Get point at relative position in curve according to arc length
// - u [0 .. 1]
THREE.Curve.prototype.getPointAt = function ( u ) {
var t = this.getUtoTmapping( u );
return this.getPoint( t );
};
// Get sequence of points using getPoint( t )
THREE.Curve.prototype.getPoints = function ( divisions ) {
if ( !divisions ) divisions = 5;
var d, pts = [];
for ( d = 0; d <= divisions; d ++ ) {
pts.push( this.getPoint( d / divisions ) );
};
return pts;
};
// Get sequence of points using getPointAt( u )
THREE.Curve.prototype.getSpacedPoints = function ( divisions ) {
if ( !divisions ) divisions = 5;
var d, pts = [];
for ( d = 0; d <= divisions; d ++ ) {
pts.push( this.getPointAt( d / divisions ) );
};
return pts;
};
// Get total curve length
THREE.Curve.prototype.getLength = function () {
var lengths = this.getLengths();
return lengths[ lengths.length - 1 ];
};
// Get list of cumulative segment lengths
THREE.Curve.prototype.getLengths = function ( divisions ) {
if ( !divisions ) divisions = 200;
if ( this.cacheLengths && ( this.cacheLengths.length == divisions ) ) {
//console.log( "cached", this.cacheLengths );
return this.cacheLengths;
}
var cache = [];
var current, last = this.getPoint( 0 );
var p, sum = 0;
for ( p = 1; p <= divisions; p++ ) {
current = this.getPoint ( p / divisions );
sum += current.distanceTo( last );
cache.push( sum );
last = current;
}
this.cacheLengths = cache;
return cache; // { sums: cache, sum:sum }; Sum is in the last element.
};
// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equi distance
THREE.Curve.prototype.getUtoTmapping = function ( u, distance ) {
var lengths = this.getLengths();
var i = 0, il = lengths.length;
var distanceForU;
if ( distance ) {
distanceForU = distance;
} else {
distanceForU = u * lengths[ il - 1 ];
}
// TODO Should do binary search + sub division + interpolation when needed
while ( i < il ) {
if ( lengths[ i ] > distanceForU ) break;
i++;
}
var t = i / il;
return t;
};
/**************************************************************
* Line
**************************************************************/
THREE.LineCurve = function ( x1, y1, x2, y2 ) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
};
THREE.LineCurve.prototype = new THREE.Curve();
THREE.LineCurve.prototype.constructor = THREE.LineCurve;
THREE.LineCurve.prototype.getPoint = function ( t ) {
var dx = this.x2 - this.x1;
var dy = this.y2 - this.y1;
var tx = this.x1 + dx * t;
var ty = this.y1 + dy * t;
return new THREE.Vector2( tx, ty );
};
/**************************************************************
* Quadratic Bezier curve
**************************************************************/
THREE.QuadraticBezierCurve = function ( x0, y0, x1, y1, x2, y2 ) {
this.x0 = x0;
this.y0 = y0;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
};
THREE.QuadraticBezierCurve.prototype = new THREE.Curve();
THREE.QuadraticBezierCurve.prototype.constructor = THREE.QuadraticBezierCurve;
THREE.QuadraticBezierCurve.prototype.getPoint = function ( t ) {
var tx, ty;
tx = THREE.FontUtils.b2( t, this.x0, this.x1, this.x2 );
ty = THREE.FontUtils.b2( t, this.y0, this.y1, this.y2 );
return new THREE.Vector2( tx, ty );
};
THREE.QuadraticBezierCurve.prototype.getNormalVector = function( t ) {
// iterate sub segments
// get lengths for sub segments
// if segment is bezier
// perform subdivisions or perform integrals
var x0, y0, x1, y1, x2, y2;
x0 = this.actions[ 0 ].args[ 0 ];
y0 = this.actions[ 0 ].args[ 1 ];
x1 = this.actions[ 1 ].args[ 0 ];
y1 = this.actions[ 1 ].args[ 1 ];
x2 = this.actions[ 1 ].args[ 2 ];
y2 = this.actions[ 1 ].args[ 3 ];
var tx, ty;
tx = THREE.Curve.Utils.tangentQuadraticBezier( t, this.x0, this.x1, this.x2 );
ty = THREE.Curve.Utils.tangentQuadraticBezier( t, this.y0, this.y1, this.y2 );
// return normal unit vector
return new THREE.Vector2( -ty , tx ).unit();
};
/**************************************************************
* Cubic Bezier curve
**************************************************************/
THREE.CubicBezierCurve = function ( x0, y0, x1, y1, x2, y2, x3, y3 ) {
this.x0 = x0;
this.y0 = y0;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.x3 = x3;
this.y3 = y3;
};
THREE.CubicBezierCurve.prototype = new THREE.Curve();
THREE.CubicBezierCurve.prototype.constructor = THREE.CubicBezierCurve;
THREE.CubicBezierCurve.prototype.getPoint = function ( t ) {
var tx, ty;
tx = THREE.FontUtils.b3( t, this.x0, this.x1, this.x2, this.x3 );
ty = THREE.FontUtils.b3( t, this.y0, this.y1, this.y2, this.y3 );
return new THREE.Vector2( tx, ty );
};
/**************************************************************
* Spline curve
**************************************************************/
THREE.SplineCurve = function ( points ) {
this.points = points;
};
THREE.SplineCurve.prototype = new THREE.Curve();
THREE.SplineCurve.prototype.constructor = THREE.SplineCurve;
THREE.SplineCurve.prototype.getPoint = function ( t ) {
var v = new THREE.Vector2();
var c = [];
var points = this.points, point, intPoint, weight;
point = ( points.length - 1 ) * t;
intPoint = Math.floor( point );
weight = point - intPoint;
c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1;
c[ 1 ] = intPoint;
c[ 2 ] = intPoint > points.length - 2 ? intPoint : intPoint + 1;
c[ 3 ] = intPoint > points.length - 3 ? intPoint : intPoint + 2;
v.x = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].x, points[ c[ 1 ] ].x, points[ c[ 2 ] ].x, points[ c[ 3 ] ].x, weight );
v.y = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].y, points[ c[ 1 ] ].y, points[ c[ 2 ] ].y, points[ c[ 3 ] ].y, weight );
return v;
};
/**************************************************************
* Arc curve
**************************************************************/
THREE.ArcCurve = function ( aX, aY, aRadius,
aStartAngle, aEndAngle,
aClockwise ) {
this.aX = aX;
this.aY = aY;
this.aRadius = aRadius;
this.aStartAngle = aStartAngle;
this.aEndAngle = aEndAngle;
this.aClockwise = aClockwise;
};
THREE.ArcCurve.prototype = new THREE.Curve();
THREE.ArcCurve.prototype.constructor = THREE.ArcCurve;
THREE.ArcCurve.prototype.getPoint = function ( t ) {
var deltaAngle = this.aEndAngle - this.aStartAngle;
if ( !this.aClockwise ) {
t = 1 - t;
}
var angle = this.aStartAngle + t * deltaAngle;
var tx = this.aX + this.aRadius * Math.cos( angle );
var ty = this.aY + this.aRadius * Math.sin( angle );
return new THREE.Vector2( tx, ty );
};
/**************************************************************
* Utils
**************************************************************/
THREE.Curve.Utils = {
tangentQuadraticBezier: function ( t, p0, p1, p2 ) {
return 2 * ( 1 - t ) * ( p1 - p0 ) + 2 * t * ( p2 - p1 );
},
tangentSpline: function ( t, p0, p1, p2, p3 ) {
// To check if my formulas are correct
var h00 = 6 * t * t - 6 * t; // derived from 2t^3 − 3t^2 + 1
var h10 = 3 * t * t - 4 * t + 1; // t^3 − 2t^2 + t
var h01 = -6 * t * t + 6 * t; // − 2t3 + 3t2
var h11 = 3 * t * t - 2 * t; // t3 − t2
},
// Catmull-Rom
interpolate: function( p0, p1, p2, p3, t ) {
var v0 = ( p2 - p0 ) * 0.5;
var v1 = ( p3 - p1 ) * 0.5;
var t2 = t * t;
var t3 = t * t2;
return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
}
};
/*
getPoint DONE
getLength DONE
getLengths DONE
curve.getPoints(); DONE
curve.getPointAtArcLength(t); DONE
curve.transform(params);
curve.getTangentAt(t)
*/
\ No newline at end of file
/**
* @author zz85 / http://www.lab4games.net/zz85/blog
* Creates extruded geometry form path.
* Creates extruded geometry from a path shape.
**/
THREE.ExtrudeGeometry = function( shape, options ) {
THREE.ExtrudeGeometry = function ( shape, options ) {
var amount = options.amount !== undefined ? options.amount : 100;
// todo: bezel
// todo: bevel
var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 8; // 10
var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness; // 8
var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false
var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
// We should set bevel segments to 0 if bevel is not enabled.
if ( !bevelEnabled ) bevelSegments = 0;
var bezelThickness = options.bezelThickness !== undefined ? options.bezelThickness : 10;
var bezelSize = options.bezelSize !== undefined ? options.bezelSize : 8;
var bezelEnabled = options.bezelEnabled !== undefined ? options.bezelEnabled : false;
var steps = options.steps !== undefined ? options.steps : 1;
var extrudePath = options.path !== undefined ? options.path : null;
var extrudePath = options.path !== undefined ? options.path : null;
var extrudePts, extrudeByPath = false;
if ( extrudePath ) {
......@@ -26,41 +32,184 @@ THREE.ExtrudeGeometry = function( shape, options ) {
}
// TODO, extrude by path's tangents? also via 3d path?
THREE.Geometry.call( this );
var vertices = shape.getPoints();
var faces = shape.triangulate();
var contour = vertices;
// Variables initalization
var ahole, h, hl; // looping of holes
var scope = this;
var bevelPoints = [];
var shapePoints = shape.extractAllPoints(); // use shape.extractAllSpacedPoints() for points with equal divisions
var vertices = shapePoints.shape;
var holes = shapePoints.holes;
var reverse = !THREE.Shape.Utils.isClockWise( vertices ) ;
if ( reverse ) {
vertices = vertices.reverse();
// Maybe we should also check if holes are in the opposite direction, just to be safe ...
for ( h = 0, hl = holes.length; h < hl; h ++ ) {
ahole = holes[ h ];
if ( THREE.Shape.Utils.isClockWise( ahole ) ) {
holes[ h ] = ahole.reverse();
}
}
reverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!
}
var faces = THREE.Shape.Utils.triangulateShape ( vertices, holes );
//var faces = THREE.Shape.Utils.triangulate2( vertices, holes );
//console.log(faces);
////
/// Handle Vertices
////
var contour = vertices; // vertices has all points but contour has only points of circumference
for ( h = 0, hl = holes.length; h < hl; h ++ ) {
ahole = holes[ h ];
vertices = vertices.concat( ahole );
}
// Find all centroids of shapes and holes
var i, il;
var sum = new THREE.Vector2();
var scope = this;
for ( i = 0, il = contour.length; i < il; i ++ ) {
var bezelPoints = [];
sum.addSelf( contour[ i ] );
var reverse = THREE.FontUtils.Triangulate.area( vertices ) > 0 ;
}
var contourCentroid = sum.divideScalar( contour.length );
var holesCentroids = [];
for ( h = 0, hl = holes.length; h < hl; h ++ ) {
sum = new THREE.Vector2();
ahole = holes[ h ];
for ( i=0, il = ahole.length; i < il; i ++ ) {
sum.addSelf( ahole[ i ] );
}
holesCentroids[ h ] = sum.divideScalar( ahole.length );
}
function scalePt ( pt, centroid, size, expandOutwards /* Boolean */ ) {
var vectorFromCentroid = pt.clone().subSelf( centroid );
var adj = size / vectorFromCentroid.length();
if ( expandOutwards ) {
adj = 1 + adj;
} else {
adj = 1 - adj;
}
return vectorFromCentroid.multiplyScalar( adj ).addSelf( centroid );
}
//console.log(reverse);
var i,
var b, bs, t, z,
vert, vlen = vertices.length,
face, flen = faces.length,
bezelPt, blen = bezelPoints.length;
cont, clen = contour.length;
// Loop bevelSegments, 1 for the front, 1 for the back
for ( b = bevelSegments; b > 0; b -- ) {
t = b / bevelSegments;
z = bevelThickness * t;
// Formula could probably be simplified
bs = bevelSize * ( 1 - Math.sin ( ( 1 - t ) * Math.PI/2 ) ) ; // bevelSize * t ;
// contract shape
for ( i = 0, il = contour.length; i < il; i ++ ) {
vert = scalePt( contour[ i ], contourCentroid, bs, false );
v( vert.x, vert.y, -z );
}
// expand holes
for ( h = 0, hl = holes.length; h < hl; h++ ) {
ahole = holes[ h ];
for ( i = 0, il = ahole.length; i < il; i++ ) {
vert = scalePt( ahole[ i ], holesCentroids[ h ], bs, true );
v( vert.x, vert.y, -z );
}
}
}
// Back facing vertices
for ( i = 0; i < vlen; i++ ) {
for ( i = 0; i < vlen; i ++ ) {
vert = vertices[ i ];
v( vert.x, vert.y, 0 );
//v( vert.x, vert.y, 0 );
if ( !extrudeByPath ) {
v( vert.x, vert.y, 0 );
} else {
v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );
}
}
// Add steped vertices...
// Add stepped vertices...
// Including front facing vertices
var s = 1;
for ( ; s <= steps; s++ ) {
var s;
for ( s = 1; s <= steps; s ++ ) {
for ( i = 0; i < vlen; i ++ ) {
......@@ -68,7 +217,7 @@ THREE.ExtrudeGeometry = function( shape, options ) {
if ( !extrudeByPath ) {
v( vert.x, vert.y, amount/steps * s );
v( vert.x, vert.y, amount / steps * s );
} else {
......@@ -80,119 +229,155 @@ THREE.ExtrudeGeometry = function( shape, options ) {
}
/*
// Front facing vertices
for ( i = 0; i < vlen; i++ ) {
vert = vertices[ i ];
v( vert.x, vert.y, amount );
// Add bevel segments planes
}
*/
for ( b = 1; b <= bevelSegments; b ++ ) {
t = b / bevelSegments;
z = bevelThickness * t;
bs = bevelSize * ( 1-Math.sin ( ( 1 - t ) * Math.PI/2 ) );
if ( bezelEnabled ) {
// contract shape
for ( i = 0; i < blen; i++ ) {
for ( i = 0, il = contour.length; i < il; i++ ) {
bezelPt = bezelPoints[ i ];
v( bezelPt.x, bezelPt.y, bezelThickness );
vert = scalePt( contour[ i ], contourCentroid, bs, false );
v( vert.x, vert.y, amount + z);
}
for ( i = 0; i < blen; i++ ) {
// expand holes
for ( h = 0, hl = holes.length; h < hl; h++ ) {
ahole = holes[ h ];
for ( i = 0, il = ahole.length; i < il; i++ ) {
vert = scalePt( ahole[ i ], holesCentroids[h], bs, true );
if ( !extrudeByPath ) {
v( vert.x, vert.y, amount + z );
} else {
bezelPt = bezelPoints[ i ];
v( bezelPt.x, bezelPt.y, amount - bezelThickness );
v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x +z );
}
}
}
}
// Bottom faces
for ( i = 0; i < flen; i++ ) {
////
/// Handle Faces
////
face = faces[ i ];
f3( face[ 2 ], face[ 1 ], face[ 0 ] );
// not used anywhere
// var layers = ( steps + bevelSegments * 2 ) * vlen;
}
// Bottom faces
// Top faces
if ( bevelEnabled ) {
for ( i = 0; i < flen; i++ ) {
var layer = 0 ; // steps + 1
var offset = vlen * layer;
face = faces[ i ];
f3( face[ 0 ] + vlen* steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );
for ( i = 0; i < flen; i ++ ) {
}
face = faces[ i ];
f3( face[ 2 ]+ offset, face[ 1 ]+ offset, face[ 0 ] + offset );
var lastV;
var j, k, l, m;
}
// Sides faces
layer = steps + bevelSegments * 2;
offset = vlen * layer;
//contour.push( contour[ 0 ] ); // in order not to check for boundary indices every time
// Top faces
i = contour.length;
for ( i = 0; i < flen; i ++ ) {
while ( --i >= 0 ) {
face = faces[ i ];
f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );
lastV = contour[ i ];
}
// TO OPTIMISE. Reduce this step of checking vertices.
} else {
/*
for ( j = 0; j < vlen; j++ ) {
for ( i = 0; i < flen; i++ ) {
if ( vertices[ j ].equals( contour[ i ] ) ) break;
face = faces[ i ];
f3( face[ 2 ], face[ 1 ], face[ 0 ] );
}
for ( k = 0; k < vlen; k++ ) {
// Top faces
for ( i = 0; i < flen; i ++ ) {
if ( vertices[ k ].equals( contour[ i - 1 ] ) ) break;
face = faces[ i ];
f3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );
}
*/
//TOREMOVE
//console.log('a', i,j, i-1, k);
}
j = i;
//if (j==vertices.length) j = 0;
var tmpPt;
var j, k, l, m;
k = i - 1;
var layeroffset = 0;
if ( k < 0 ) k = vertices.length - 1;
// Sides faces
//console.log('b', i,j, i-1, k,vertices.length);
sidewalls( contour );
layeroffset += contour.length;
// Create faces for the z-sides of the text
for ( h = 0, hl = holes.length; h < hl; h ++ ) {
//f4( j, k, k + vlen, j + vlen );
ahole = holes[ h ];
sidewalls( ahole );
// Reverse
//f4( k, j, j + vlen, k + vlen);
//, true
layeroffset += ahole.length;
//
}
var s = 0;
// Create faces for the z-sides of the shape
for ( ; s < steps; s++ ) {
function sidewalls( contour ) {
var slen1 = vlen * s;
var slen2 = vlen * ( s + 1 );
i = contour.length;
f4( j + slen1, k + slen1, k + slen2, j + slen2 );
while ( --i >= 0 ) {
}
tmpPt = contour[ i ];
//
j = i;
k = i - 1;
}
if ( k < 0 ) k = contour.length - 1;
//console.log('b', i,j, i-1, k,vertices.length);
var s = 0;
for ( s = 0; s < ( steps + bevelSegments * 2 ); s ++ ) {
var slen1 = vlen * s;
var slen2 = vlen * ( s + 1 );
f4( layeroffset + j + slen1, layeroffset + k + slen1, layeroffset + k + slen2, layeroffset + j + slen2 );
}
}
}
// UVs to be added
......@@ -208,29 +393,22 @@ THREE.ExtrudeGeometry = function( shape, options ) {
function f3( a, b, c ) {
if ( reverse ) {
scope.faces.push( new THREE.Face3( c, b, a ) );
} else {
scope.faces.push( new THREE.Face3( a, b, c ) );
}
// if ( reverse ) { // Can now be removed
//
// scope.faces.push( new THREE.Face3( c, b, a ) );
//
// } else {
//
scope.faces.push( new THREE.Face3( a, b, c ) );
//
// }
}
function f4( a, b, c, d ) {
if ( reverse ) {
scope.faces.push( new THREE.Face4( d, c, b, a ) );
} else {
scope.faces.push( new THREE.Face4( a, b, c, d ) );
}
scope.faces.push( new THREE.Face4( a, b, c, d ) );
}
......
/**
* @author zz85 / http://www.lab4games.net/zz85/blog
* Creates free form path.
* Creates free form 2d path using series of points, lines or curves.
*
**/
THREE.Path = function ( points ) {
this.actions = [];
this.curves = [];
if ( points ) {
......@@ -19,20 +21,24 @@ THREE.PathActions = {
MOVE_TO: 'moveTo',
LINE_TO: 'lineTo',
QUADRATIC_CURVE_TO: 'quadraticCurveTo', // BEZIER quadratic CURVE
BEZIER_CURVE_TO: 'bezierCurveTo', // BEZIER cubic CURVE
CSPLINE_THRU: 'splineThru' // TODO cardinal splines
QUADRATIC_CURVE_TO: 'quadraticCurveTo', // Bezier quadratic curve
BEZIER_CURVE_TO: 'bezierCurveTo', // Bezier cubic curve
CSPLINE_THRU: 'splineThru', // Catmull-rom spline
ARC: 'arc' // Circle
};
/* Create path using straight lines to connect all points */
// TODO Clean up PATH API
THREE.Path.prototype.fromPoints = function( vectors /*Array of Vector*/ ) {
// Create path using straight lines to connect all points
// - vectors: array of Vector2
var v = 0, vlen = vectors.length;
THREE.Path.prototype.fromPoints = function ( vectors ) {
this.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );
var v, vlen = vectors.length;
for ( v = 1; v < vlen; v++ ) {
this.lineTo( vectors[ v ].x, vectors[ v ].y );
......@@ -41,48 +47,151 @@ THREE.Path.prototype.fromPoints = function( vectors /*Array of Vector*/ ) {
};
THREE.Path.prototype.moveTo = function( x, y ) {
// startPath() endPath()?
THREE.Path.prototype.moveTo = function ( x, y ) {
var args = Array.prototype.slice.call( arguments );
this.actions.push( { action: THREE.PathActions.MOVE_TO, args: args } );
};
THREE.Path.prototype.lineTo = function( x, y ) {
THREE.Path.prototype.lineTo = function ( x, y ) {
var args = Array.prototype.slice.call( arguments );
this.actions.push( { action: THREE.PathActions.LINE_TO, args: args } );
var lastargs = this.actions[ this.actions.length - 1 ].args;
var x0 = lastargs[ lastargs.length - 2 ];
var y0 = lastargs[ lastargs.length - 1 ];
var curve = new THREE.LineCurve( x0, y0, x, y );
this.curves.push( curve );
this.actions.push( { action: THREE.PathActions.LINE_TO, args: args, curve: curve } );
};
THREE.Path.prototype.quadraticCurveTo = function( aCPx, aCPy, aX, aY ) {
var args = Array.prototype.slice.call( arguments );
this.actions.push( { action: THREE.PathActions.QUADRATIC_CURVE_TO, args: args });
var lastargs = this.actions[ this.actions.length - 1 ].args;
var x0 = lastargs[ lastargs.length - 2 ];
var y0 = lastargs[ lastargs.length - 1 ];
var curve = new THREE.QuadraticBezierCurve( x0, y0, aCPx, aCPy, aX, aY );
this.curves.push( curve );
this.actions.push( { action: THREE.PathActions.QUADRATIC_CURVE_TO, args: args, curve: curve } );
//console.log( curve, curve.getPoints(), curve.getSpacedPoints() );
//console.log( curve.getPointAt(0), curve.getPointAt(0), curve.getUtoTmapping(0), curve.getSpacedPoints() );
};
THREE.Path.prototype.bezierCurveTo = function( aCP1x, aCP1y,
aCP2x, aCP2y,
aX, aY) {
aX, aY ) {
var args = Array.prototype.slice.call( arguments );
this.actions.push( { action: THREE.PathActions.BEZIER_CURVE_TO, args: args } );
var lastargs = this.actions[ this.actions.length - 1 ].args;
var x0 = lastargs[ lastargs.length - 2 ];
var y0 = lastargs[ lastargs.length - 1 ];
var curve = new THREE.CubicBezierCurve( x0, y0, aCP1x, aCP1y,
aCP2x, aCP2y,
aX, aY );
this.curves.push( curve );
this.actions.push( { action: THREE.PathActions.BEZIER_CURVE_TO, args: args, curve: curve } );
};
THREE.Path.prototype.splineThru = function( pts /*Array of Vector*/ ) {
var args = Array.prototype.slice.call( arguments );
this.actions.push( { action: THREE.PathActions.CSPLINE_THRU, args: args } );
var lastargs = this.actions[ this.actions.length - 1 ].args;
var x0 = lastargs[ lastargs.length - 2 ];
var y0 = lastargs[ lastargs.length - 1 ];
var npts = [ new THREE.Vector2( x0, y0 ) ];
npts = npts.concat( pts );
var curve = new THREE.SplineCurve( npts );
this.curves.push( curve );
this.actions.push( { action: THREE.PathActions.CSPLINE_THRU, args: args, curve: curve } );
//console.log( curve, curve.getPoints(), curve.getSpacedPoints() );
};
}
// FUTURE: Change the API or follow canvas API?
// TODO ARC ( x, y, x - radius, y - radius, startAngle, endAngle )
THREE.Path.prototype.arc = function ( aX, aY, aRadius,
aStartAngle, aEndAngle, aClockwise ) {
var args = Array.prototype.slice.call( arguments );
var curve = new THREE.ArcCurve( aX, aY, aRadius,
aStartAngle, aEndAngle, aClockwise );
this.curves.push( curve );
// console.log( 'arc', args );
this.actions.push( { action: THREE.PathActions.ARC, args: args } );
};
/*
// FUTURE ENHANCEMENTS
example usage?
Path.addExprFunc('sineCurveTo', sineCurveGetPtFunction)
Path.sineCurveTo(x,y, amptitude);
sineCurve.getPoint(t);
return sine(disnt) * ampt
// Create a new func eg. sin (theta) x
THREE.Path.prototype.addExprFunc = function(exprName, func) {
};
*/
THREE.Path.prototype.getSpacedPoints = function ( divisions, closedPath ) {
if ( !divisions ) divisions = 40;
var points = [];
for ( var i = 0; i < divisions; i++ ) {
points.push( this.getPoint( i / divisions ) );
//if( !this.getPoint( i / divisions ) ) throw "DIE";
}
// TODO ARC
if ( closedPath ) {
points.push( points[ 0 ] );
}
return points;
};
/* Return an array of vectors based on contour of the path */
THREE.Path.prototype.getPoints = function( divisions ) {
THREE.Path.prototype.getPoints = function( divisions, closedPath ) {
divisions = divisions || 12;
......@@ -104,7 +213,7 @@ THREE.Path.prototype.getPoints = function( divisions ) {
case THREE.PathActions.MOVE_TO:
//points.push( new THREE.Vector2( args[ 0 ], args[ 1 ] ) );
// points.push( new THREE.Vector2( args[ 0 ], args[ 1 ] ) );
break;
......@@ -140,8 +249,6 @@ THREE.Path.prototype.getPoints = function( divisions ) {
for ( j = 1; j <= divisions; j ++ ) {
// TODO use LOD for divisions
t = j / divisions;
tx = THREE.FontUtils.b2( t, cpx0, cpx1, cpx );
......@@ -197,73 +304,87 @@ THREE.Path.prototype.getPoints = function( divisions ) {
case THREE.PathActions.CSPLINE_THRU:
laste = this.actions[ i - 1 ].args;
var last = new THREE.Vector2( laste[ laste.length - 2 ], laste[ laste.length - 1 ] );
var spts = args[ 0 ];
var n = divisions * spts.length;
var spts = [ last ];
spts.unshift( last );
var n = divisions * args[ 0 ].length;
var spline = new Spline2();
spts = spts.concat( args[ 0 ] );
for ( j = 0; j < n; j ++ ) {
var spline = new THREE.SplineCurve( spts );
for ( j = 1; j <= n; j ++ ) {
points.push( spline.get2DPoint( spts, j / n ) ) ;
points.push( spline.getPointAt( j / n ) ) ;
}
break;
}
case THREE.PathActions.ARC:
}
laste = this.actions[ i - 1 ].args;
return points;
var aX = args[ 0 ], aY = args[ 1 ],
aRadius = args[ 2 ],
aStartAngle = args[ 3 ], aEndAngle = args[ 4 ],
aClockwise = !!args[ 5 ];
};
var lastx = laste[ laste.length - 2 ],
lasty = laste[ laste.length - 1 ];
var Spline2 = function () {
if ( laste.length == 0 ) {
var c = [], v2,
point, intPoint, weight;
lastx = lasty = 0;
this.get2DPoint = function ( points, k ) {
}
v2 = new THREE.Vector2();
point = ( points.length - 1 ) * k;
intPoint = Math.floor( point );
weight = point - intPoint;
var deltaAngle = aEndAngle - aStartAngle;
var angle;
var tdivisions = divisions * 2;
var t;
c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1;
c[ 1 ] = intPoint;
c[ 2 ] = intPoint > points.length - 2 ? intPoint : intPoint + 1;
c[ 3 ] = intPoint > points.length - 3 ? intPoint : intPoint + 2;
for ( j = 1; j <= tdivisions; j ++ ) {
v2.x = interpolate( points[ c[ 0 ] ].x, points[ c[ 1 ] ].x, points[ c[ 2 ] ].x, points[ c[ 3 ] ].x, weight );
v2.y = interpolate( points[ c[ 0 ] ].y, points[ c[ 1 ] ].y, points[ c[ 2 ] ].y, points[ c[ 3 ] ].y, weight );
t = j / tdivisions;
//console.log('point',point, v2);
if ( !aClockwise ) {
return v2;
t = 1 - t;
}
}
angle = aStartAngle + t * deltaAngle;
tx = lastx + aX + aRadius * Math.cos( angle );
ty = lasty + aY + aRadius * Math.sin( angle );
//console.log('t', t, 'angle', angle, 'tx', tx, 'ty', ty);
points.push( new THREE.Vector2( tx, ty ) );
// Catmull-Rom
}
//console.log(points);
function interpolate( p0, p1, p2, p3, t ) {
break;
var v0 = ( p2 - p0 ) * 0.5;
var v1 = ( p3 - p1 ) * 0.5;
var t2 = t * t;
var t3 = t * t2;
return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
} // end switch
}
};
if ( closedPath ) {
points.push( points[ 0 ] );
THREE.Path.prototype.getMinAndMax = function() {
}
return points;
};
THREE.Path.prototype.getMinAndMax = function () {
var points = this.getPoints();
......@@ -287,7 +408,7 @@ THREE.Path.prototype.getMinAndMax = function() {
}
// TODO find mid-pt?
// TODO Include CG or find mid-pt?
return {
......@@ -300,12 +421,190 @@ THREE.Path.prototype.getMinAndMax = function() {
};
// To get accurate point with reference to
// entire path distance at time t,
// following has to be done
// 1. Length of each sub path have to be known
// 2. Locate and identify type of curve
// 3. Get t for the curve
// 4. Return curve.getPointAt(t')
THREE.Path.prototype.getPoint = function( t ) {
var d = t * this.getLength();
var curveLengths = this.sums;
var i = 0, diff, curve;
// To think about boundaries points.
while ( i < curveLengths.length ) {
if ( curveLengths[ i ] >= d ) {
diff = curveLengths[ i ] - d;
curve = this.curves[ i ];
var u = 1 - diff / curve.getLength();
return curve.getPointAt( u );
break;
}
i++;
}
return null;
// loop where sum != 0, sum > d , sum+1 <d
};
// Compute lengths and cache them
THREE.Path.prototype.getLength = function() {
// Loop all actions/path
// Push sums into cached array
var lengths = [], sums = 0;
var i, il = this.curves.length;
for ( i = 0; i < il ; i++ ) {
sums += this.curves[ i ].getLength();
lengths.push( sums );
}
this.sums = lengths;
return sums;
};
/// Generate geometry from path points (for Line or ParticleSystem objects)
THREE.Path.prototype.createPointsGeometry = function( divisions ) {
var pts = this.getPoints( divisions, true );
return this.createGeometry( pts );
};
// Generate geometry from equidistance sampling along the path
THREE.Path.prototype.createSpacedPointsGeometry = function( divisions ) {
var pts = this.getSpacedPoints( divisions, true );
return this.createGeometry( pts );
};
THREE.Path.prototype.createGeometry = function( points ) {
var geometry = new THREE.Geometry();
for( var i = 0; i < points.length; i ++ ) {
geometry.vertices.push( new THREE.Vertex( new THREE.Vector3( points[ i ].x, points[ i ].y, 0 ) ) );
}
return geometry;
};
// ALL THINGS BELOW TO BE REFACTORED
// QN: Transform final pts or transform ACTIONS or add transform filters?
// FUTURE refactor path = an array of lines -> straight, bezier, splines, arc, funcexpr lines
// Read http://www.planetclegg.com/projects/WarpingTextToSplines.html
THREE.Path.prototype.transform = function( path ) {
path = new THREE.Path();
path.moveTo( 0, 0 );
path.quadraticCurveTo( 100, 20, 140, 80 );
console.log( path.cacheArcLengths() );
var thisBounds = this.getMinAndMax();
var oldPts = this.getPoints();
var i, il, p, oldX, oldY, xNorm;
for ( i = 0, il = oldPts.length; i < il; i ++ ) {
p = oldPts[ i ];
oldX = p.x;
oldY = p.y;
var xNorm = oldX/ thisBounds.maxX;
// If using actual distance, for length > path, requires line extrusions
//xNorm = path.getUtoTmapping(xNorm, oldX); // 3 styles. 1) wrap stretched. 2) wrap stretch by arc length 3) warp by actual distance
var pathPt = path.getPoint( xNorm );
var normal = path.getNormalVector( xNorm ).multiplyScalar( oldY );
p.x = pathPt.x + normal.x;
p.y = pathPt.y + normal.y;
//p.x = a * oldX + b * oldY + c;
//p.y = d * oldY + e * oldX + f;
}
return oldPts;
};
// Read http://www.tinaja.com/glib/nonlingr.pdf
// nonlinear transforms
THREE.Path.prototype.nltransform = function( a, b, c, d, e, f ) {
// a - horizontal size
// b - lean
// c - x offset
// d - vertical size
// e - climb
// f - y offset
var oldPts = this.getPoints();
var i, il, p, oldX, oldY;
for ( i = 0, il = oldPts.length; i < il; i ++ ) {
p = oldPts[i];
oldX = p.x;
oldY = p.y;
p.x = a * oldX + b * oldY + c;
p.y = d * oldY + e * oldX + f;
}
return oldPts;
};
// FUTURE Export JSON Format
/* Draws this path onto a 2d canvas easily */
THREE.Path.prototype.debug = function( canvas ) {
// JUST A STUB
var bounds = this.getMinAndMax();
if ( !canvas ) {
......@@ -376,11 +675,32 @@ THREE.Path.prototype.debug = function( canvas ) {
ctx.stroke();
ctx.closePath();
// DebugPoints
// Debug Points
ctx.strokeStyle = "red";
var p, points = this.getPoints();
/* TO CLEAN UP */
//var p, points = this.getPoints();
var theta = -90 /180 * Math.PI;
var p, points = this.transform( 0.866, - 0.866,0, 0.500 , 0.50,-50 );
//0.866, - 0.866,0, 0.500 , 0.50,-50
// Math.cos(theta),Math.sin(theta),100,
// Math.cos(theta),-Math.sin(theta),-50
// translate, scale, rotation
// a - horizontal size
// b - lean
// c - x offset
// d - vertical size
// e - climb
// f - y offset
// 1,0,0,
// -1,0,100
for ( i = 0, il = points.length; i < il; i ++ ) {
......
......@@ -5,9 +5,9 @@
// STEP 1 Create a path.
// STEP 2 Turn path into shape.
// STEP 3 Extrude Geometry takes in Shape/Shapes
// STEP 3 ExtrudeGeometry takes in Shape/Shapes
// STEP 3a - Extract points from each shape, turn to vertices
// STEP 3b - Triangulate Each Shape
// STEP 3b - Triangulate each shape
THREE.Shape = function ( ) {
......@@ -19,27 +19,396 @@ THREE.Shape = function ( ) {
THREE.Shape.prototype = new THREE.Path();
THREE.Shape.prototype.constructor = THREE.Path;
/* Returns vertices of triangulated faces | get faces */
// Convenience method to return ExtrudeGeometry
THREE.Shape.prototype.triangulate = function() {
THREE.Shape.prototype.extrude = function ( options ) {
var pts = this.getPoints();
var extruded = new THREE.ExtrudeGeometry( this, options );
return extruded;
};
// Get points of holes
THREE.Shape.prototype.getPointsHoles = function () {
var i, il = this.holes.length, holesPts = [];
for ( i = 0; i < il; i ++ ) {
holesPts[ i ] = this.holes[ i ].getPoints();
}
return holesPts;
};
// Get points of holes (spaced by regular distance)
THREE.Shape.prototype.getSpacedPointsHoles = function () {
var i, il = this.holes.length, holesPts = [];
for ( i = 0; i < il; i ++ ) {
holesPts[ i ] = this.holes[ i ].getSpacedPoints();
}
if ( THREE.FontUtils.Triangulate.area( pts ) > 0 ) {
return holesPts;
pts = pts.reverse();
};
// Get points of shape and holes (keypoints based on segments parameter)
THREE.Shape.prototype.extractAllPoints = function () {
return {
shape: this.getPoints(),
holes: this.getPointsHoles()
};
return THREE.FontUtils.Triangulate( pts, true );
};
// Get points of shape and holes (spaced by regular distance)
THREE.Shape.prototype.extractAllSpacedPoints = function () {
return {
shape: this.getSpacedPoints(),
holes: this.getSpacedPointsHoles()
};
};
/* Convenience method to return ExtrudeGeometry */
THREE.Shape.Utils = {
THREE.Shape.prototype.extrude = function( options ) {
/*
contour - array of vector2 for contour
holes - array of array of vector2
*/
var extruded = new THREE.ExtrudeGeometry( this, options );
return extruded;
removeHoles: function ( contour, holes ) {
var shape = contour.concat(); // work on this shape
var allpoints = shape.concat();
/* For each isolated shape, find the closest points and break to the hole to allow triangulation */
var prevShapeVert, nextShapeVert,
prevHoleVert, nextHoleVert,
holeIndex, shapeIndex,
shapeId, shapeGroup,
h, h2,
hole, shortest, d,
p, pts1, pts2,
tmpShape1, tmpShape2,
tmpHole1, tmpHole2,
verts = [];
for ( h = 0; h < holes.length; h++ ) {
//for ( h = holes.length; h-- > 0; ) {
hole = holes[ h ];
/*
shapeholes[ h ].concat(); // preserves original
holes.push( hole );
*/
allpoints = allpoints.concat( hole );
shortest = Number.POSITIVE_INFINITY;
// THIS THING NEEDS TO BE DONE CORRECTLY AGAIN :(
// Find the shortest pair of pts between shape and hole
// TODO 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
for ( h2 = 0; h2 < hole.length; h2 ++ ) {
pts1 = hole[ h2 ];
var dist = [];
for ( p = 0; p < shape.length; p++ ) {
pts2 = shape[ p ];
d = pts1.distanceTo( pts2 );
dist.push( d );
if ( d < shortest ) {
shortest = d;
holeIndex = h2;
shapeIndex = p;
}
}
}
//console.log("shortest", shortest, dist);
prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;
var areaapts = [
hole[ holeIndex ],
shape[ shapeIndex ],
shape[ prevShapeVert ]
];
var areaa = THREE.FontUtils.Triangulate.area( areaapts );
var areabpts = [
hole[ holeIndex ],
hole[ prevHoleVert ],
shape[ shapeIndex ]
];
var areab = THREE.FontUtils.Triangulate.area( areabpts );
var shapeOffset = 1;
var holeOffset = -1;
var oldShapeIndex = shapeIndex, oldHoleIndex = holeIndex;
shapeIndex += shapeOffset;
holeIndex += holeOffset;
if ( shapeIndex < 0 ) { shapeIndex += shape.length; }
shapeIndex %= shape.length;
if ( holeIndex < 0 ) { holeIndex += hole.length; }
holeIndex %= hole.length;
prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;
areaapts = [
hole[ holeIndex ],
shape[ shapeIndex ],
shape[ prevShapeVert ]
];
var areaa2 = THREE.FontUtils.Triangulate.area( areaapts );
areabpts = [
hole[ holeIndex ],
hole[ prevHoleVert ],
shape[ shapeIndex ]
];
var areab2 = THREE.FontUtils.Triangulate.area( areabpts );
//console.log(areaa,areab ,areaa2,areab2, ( areaa + areab ), ( areaa2 + areab2 ));
if ( ( areaa + areab ) > ( areaa2 + areab2 ) ) {
// In case areas are not correct.
//console.log("USE THIS");
shapeIndex = oldShapeIndex;
holeIndex = oldHoleIndex ;
if ( shapeIndex < 0 ) { shapeIndex += shape.length; }
shapeIndex %= shape.length;
if ( holeIndex < 0 ) { holeIndex += hole.length; }
holeIndex %= hole.length;
prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;
} else {
//console.log("USE THAT ")
}
tmpShape1 = shape.slice( 0, shapeIndex );
tmpShape2 = shape.slice( shapeIndex );
tmpHole1 = hole.slice( holeIndex );
tmpHole2 = hole.slice( 0, holeIndex );
// Should check orders here again?
var trianglea = [
hole[ holeIndex ],
shape[ shapeIndex ],
shape[ prevShapeVert ]
];
var triangleb = [
hole[ holeIndex ] ,
hole[ prevHoleVert ],
shape[ shapeIndex ]
];
verts.push( trianglea );
verts.push( triangleb );
shape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );
//shape = tmpHole1.concat( tmpHole2 );
}
return {
shape:shape, /* shape with no holes */
isolatedPts: verts, /* isolated faces */
allpoints: allpoints
}
},
triangulateShape: function ( contour, holes ) {
var shapeWithoutHoles = THREE.Shape.Utils.removeHoles( contour, holes );
var shape = shapeWithoutHoles.shape,
allpoints = shapeWithoutHoles.allpoints,
isolatedPts = shapeWithoutHoles.isolatedPts;
var triangles = THREE.FontUtils.Triangulate( shape, false ); // True returns indices for points of spooled shape
// To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.
//console.log("triangles",triangles, triangles.length);
//console.log("allpoints",allpoints, allpoints.length);
var v, f, i, face;
for ( v = 0; v < triangles.length; v++ ) {
face = triangles[ v ];
for ( f = 0; f < 3; f++ ) { // For 3 pts in faces
for ( i = 0; i < allpoints.length; i++ ) { // Go through all points
if ( allpoints[ i ].equals( face[ f ] ) ) { // If matches
face[ f ] = i; // face now has reference to index
}
}
}
}
for ( v = 0; v < isolatedPts.length; v++ ) {
face = isolatedPts[ v ];
for ( f = 0; f < 3; f++ ) { // For 3 pts in faces
for ( i = 0; i < allpoints.length; i++ ) { // Go thru all points
if ( allpoints[ i ].equals( face[ f ] ) ) { // If matches
face[ f ] = i; // face now has reference to index
}
}
}
}
//console.log("edited?" , triangles);
return triangles.concat( isolatedPts );
}, // end triangulate shapes
/*
triangulate2 : function( pts, holes ) {
// For use Poly2Tri.js
//var pts = this.getPoints();
var allpts = pts.concat();
var shape = [];
for (var p in pts) {
shape.push(new js.poly2tri.Point(pts[p].x, pts[p].y));
}
var swctx = new js.poly2tri.SweepContext(shape);
for (var h in holes) {
var aHole = holes[h];
var newHole = []
for (i in aHole) {
newHole.push(new js.poly2tri.Point(aHole[i].x, aHole[i].y));
allpts.push(aHole[i]);
}
swctx.AddHole(newHole);
}
var find;
var findIndexForPt = function (pt) {
find = new THREE.Vector2(pt.x, pt.y);
var p;
for (p=0, pl = allpts.length; p<pl; p++) {
if (allpts[p].equals(find)) return p;
}
return -1;
};
// triangulate
js.poly2tri.sweep.Triangulate(swctx);
var triangles = swctx.GetTriangles();
var tr ;
var facesPts = [];
for (var t in triangles) {
tr = triangles[t];
facesPts.push([
findIndexForPt(tr.GetPoint(0)),
findIndexForPt(tr.GetPoint(1)),
findIndexForPt(tr.GetPoint(2))
]);
}
// console.log(facesPts);
// console.log("triangles", triangles.length, triangles);
// Returns array of faces with 3 element each
return facesPts;
},
*/
isClockWise: function ( pts ) {
return THREE.FontUtils.Triangulate.area( pts ) < 0;
}
};
......@@ -15,9 +15,9 @@
* weight: <string>, // font weight (normal, bold)
* style: <string>, // font style (normal, italics)
*
* bezelEnabled: <bool>, // turn on bezel
* bezelThickness: <float>, // how deep into text bezel goes
* bezelSize: <float>, // how far from text outline is bezel
* bevelEnabled: <bool>, // turn on bevel
* bevelThickness: <float>, // how deep into text bevel goes
* bevelSize: <float>, // how far from text outline is bevel
* }
*
* It uses techniques used in:
......@@ -60,9 +60,9 @@ THREE.TextGeometry.prototype.set = function ( text, parameters ) {
var weight = parameters.weight !== undefined ? parameters.weight : "normal";
var style = parameters.style !== undefined ? parameters.style : "normal";
var bezelThickness = parameters.bezelThickness !== undefined ? parameters.bezelThickness : 10;
var bezelSize = parameters.bezelSize !== undefined ? parameters.bezelSize : 8;
var bezelEnabled = parameters.bezelEnabled !== undefined ? parameters.bezelEnabled : false;
var bevelThickness = parameters.bevelThickness !== undefined ? parameters.bevelThickness : 10;
var bevelSize = parameters.bevelSize !== undefined ? parameters.bevelSize : 8;
var bevelEnabled = parameters.bevelEnabled !== undefined ? parameters.bevelEnabled : false;
THREE.FontUtils.size = size;
THREE.FontUtils.divisions = curveSegments;
......@@ -71,7 +71,7 @@ THREE.TextGeometry.prototype.set = function ( text, parameters ) {
THREE.FontUtils.weight = weight;
THREE.FontUtils.style = style;
THREE.FontUtils.bezelSize = bezelSize;
THREE.FontUtils.bevelSize = bevelSize;
// Get a Font data json object
......@@ -80,7 +80,7 @@ THREE.TextGeometry.prototype.set = function ( text, parameters ) {
var vertices = data.points;
var faces = data.faces;
var contour = data.contour;
var bezelPoints = data.bezel;
var bevelPoints = data.bevel;
var scope = this;
......@@ -90,7 +90,7 @@ THREE.TextGeometry.prototype.set = function ( text, parameters ) {
var i,
vert, vlen = vertices.length,
face, flen = faces.length,
bezelPt, blen = bezelPoints.length;
bevelPt, blen = bevelPoints.length;
// Back facing vertices
......@@ -110,19 +110,19 @@ THREE.TextGeometry.prototype.set = function ( text, parameters ) {
}
if ( bezelEnabled ) {
if ( bevelEnabled ) {
for ( i = 0; i < blen; i++ ) {
bezelPt = bezelPoints[ i ];
v( bezelPt.x, bezelPt.y, bezelThickness );
bevelPt = bevelPoints[ i ];
v( bevelPt.x, bevelPt.y, bevelThickness );
}
for ( i = 0; i < blen; i++ ) {
bezelPt = bezelPoints[ i ];
v( bezelPt.x, bezelPt.y, height - bezelThickness );
bevelPt = bevelPoints[ i ];
v( bevelPt.x, bevelPt.y, height - bevelThickness );
}
......@@ -149,9 +149,9 @@ THREE.TextGeometry.prototype.set = function ( text, parameters ) {
var lastV;
var j, k, l, m;
if ( bezelEnabled ) {
if ( bevelEnabled ) {
i = bezelPoints.length;
i = bevelPoints.length;
while ( --i > 0 ) {
......@@ -666,16 +666,21 @@ THREE.FontUtils = {
var fontPaths = [];
var path = new THREE.Path();
for ( i = 0; i < length; i++ ) {
var ret = this.extractGlyphPoints( chars[ i ], face, scale, offset );
var ret = this.extractGlyphPoints( chars[ i ], face, scale, offset, path );
offset += ret.offset;
characterPts.push( ret.points );
allPts = allPts.concat( ret.points );
fontPaths.push( ret.path );
//fontPaths.push( ret.path );
}
//path.debug(document.getElementById("boo"));
console.log(path);
// get the width
var width = offset / 2;
......@@ -689,7 +694,7 @@ THREE.FontUtils = {
var extract = this.extractPoints( allPts, characterPts );
extract.contour = allPts;
var bezelPoints = [];
var bevelPoints = [];
var centroids = [], forCentroids = [], expandOutwards = [], sum = new THREE.Vector2(), lastV;
......@@ -734,7 +739,7 @@ THREE.FontUtils = {
centroid = centroids[ p ];
dirV = pt.clone().subSelf( centroid );
adj = this.bezelSize / dirV.length();
adj = this.bevelSize / dirV.length();
if ( expandOutwards[ p ] ) {
......@@ -747,7 +752,7 @@ THREE.FontUtils = {
}
adj = dirV.multiplyScalar( adj ).addSelf( centroid );
bezelPoints.unshift( adj );
bevelPoints.unshift( adj );
if ( !lastV ) {
......@@ -771,12 +776,12 @@ THREE.FontUtils = {
for ( p = 0; p < allPts.length; p++ ) {
pt = allPts[ p ];
bezelPoints.push( new THREE.Vector2( pt.x + this.bezelSize, pt.y + this.bezelSize ) );
bevelPoints.push( new THREE.Vector2( pt.x + this.bevelSize, pt.y + this.bevelSize ) );
}
*/
extract.bezel = bezelPoints;
extract.bevel = bevelPoints;
return extract;
......@@ -849,10 +854,10 @@ THREE.FontUtils = {
},
extractGlyphPoints : function( c, face, scale, offset ) {
extractGlyphPoints : function( c, face, scale, offset, path ) {
var pts = [];
var path = new THREE.Path();
var i, i2,
......@@ -875,7 +880,7 @@ THREE.FontUtils = {
for ( i = 0; i < length; ) {
action = outline[ i++ ];
//console.log(action);
switch( action ) {
case 'm':
......@@ -941,7 +946,7 @@ THREE.FontUtils = {
cpx2 = outline[ i++ ] * scaleX + offset;
cpy2 = outline[ i++ ] * -scaleY;
path.quadraticCurveTo( cpx, cpy, cpx1, cpy1, cpx2, cpy2 );
path.bezierCurveTo( cpx, cpy, cpx1, cpy1, cpx2, cpy2 );
laste = pts[ pts.length - 1 ];
......@@ -968,8 +973,7 @@ THREE.FontUtils = {
}
}
path.debug(document.getElementById("boo"));
console.log(path);
return { offset: glyph.ha*scale, points:pts, path:path};
}
......@@ -1065,9 +1069,15 @@ THREE.FontUtils = {
/* output Triangle */
/*
result.push( contour[ a ] );
result.push( contour[ b ] );
result.push( contour[ c ] );
*/
result.push( [ contour[ a ],
contour[ b ],
contour[ c ] ] );
vertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );
......
......@@ -93,6 +93,7 @@ EXTRAS_FILES = [
'extras/cameras/RollCamera.js',
'extras/cameras/TrackballCamera.js',
'extras/cameras/QuakeCamera.js',
'extras/geometries/Curve.js',
'extras/geometries/Path.js',
'extras/geometries/Shape.js',
'extras/geometries/CubeGeometry.js',
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册