|
@@ -25,62 +25,166 @@ THREE.TubeGeometry = function( path, segments, radius, segmentsRadius, closed, d
|
|
|
this.grid = [];
|
|
|
|
|
|
var scope = this,
|
|
|
- tangent = new THREE.Vector3(),
|
|
|
- normal = new THREE.Vector3(),
|
|
|
- binormal = new THREE.Vector3(),
|
|
|
-
|
|
|
- vec = new THREE.Vector3(),
|
|
|
- mat = new THREE.Matrix4(),
|
|
|
|
|
|
- tangents = [],
|
|
|
- normals = [],
|
|
|
- binormals = [],
|
|
|
+ tangent,
|
|
|
+ normal,
|
|
|
+ binormal,
|
|
|
|
|
|
numpoints = this.segments + 1,
|
|
|
- theta,
|
|
|
- epsilon = 0.0001,
|
|
|
- smallest,
|
|
|
+
|
|
|
x, y, z,
|
|
|
tx, ty, tz,
|
|
|
u, v,
|
|
|
- p1, p2,
|
|
|
+
|
|
|
cx, cy,
|
|
|
- pos, pos2,
|
|
|
+ pos, pos2 = new THREE.Vector3(),
|
|
|
i, j,
|
|
|
ip, jp,
|
|
|
a, b, c, d,
|
|
|
uva, uvb, uvc, uvd;
|
|
|
|
|
|
- // expose internals
|
|
|
+ var frames = new THREE.TubeGeometry.FrenetFrames(path, segments, closed),
|
|
|
+ tangents = frames.tangents,
|
|
|
+ normals = frames.normals,
|
|
|
+ binormals = frames.binormals;
|
|
|
+
|
|
|
+ // proxy internals
|
|
|
this.tangents = tangents;
|
|
|
this.normals = normals;
|
|
|
this.binormals = binormals;
|
|
|
|
|
|
-
|
|
|
+
|
|
|
function vert( x, y, z ) {
|
|
|
|
|
|
return scope.vertices.push( new THREE.Vertex( new THREE.Vector3( x, y, z ) ) ) - 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // consruct the grid
|
|
|
+
|
|
|
+ for ( i = 0; i < numpoints; i++ ) {
|
|
|
+
|
|
|
+ this.grid[ i ] = [];
|
|
|
+
|
|
|
+ u = i / ( numpoints - 1 );
|
|
|
+
|
|
|
+ pos = path.getPointAt( u );
|
|
|
+
|
|
|
+ tangent = tangents[ i ];
|
|
|
+ normal = normals[ i ];
|
|
|
+ binormal = binormals[ i ];
|
|
|
+
|
|
|
+ if ( this.debug ) {
|
|
|
+
|
|
|
+ this.debug.add(new THREE.ArrowHelper(tangent, pos, radius, 0x0000ff));
|
|
|
+ this.debug.add(new THREE.ArrowHelper(normal, pos, radius, 0xff0000));
|
|
|
+ this.debug.add(new THREE.ArrowHelper(binormal, pos, radius, 0x00ff00));
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ for ( j = 0; j < this.segmentsRadius; j++ ) {
|
|
|
+
|
|
|
+ v = j / this.segmentsRadius * 2 * Math.PI;
|
|
|
+
|
|
|
+ cx = -this.radius * Math.cos( v ); // TODO: Hack: Negating it so it faces outside.
|
|
|
+ cy = this.radius * Math.sin( v );
|
|
|
+
|
|
|
+ pos2.copy( pos );
|
|
|
+ pos2.x += cx * normal.x + cy * binormal.x;
|
|
|
+ pos2.y += cx * normal.y + cy * binormal.y;
|
|
|
+ pos2.z += cx * normal.z + cy * binormal.z;
|
|
|
+
|
|
|
+ this.grid[ i ][ j ] = vert( pos2.x, pos2.y, pos2.z );
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // construct the mesh
|
|
|
+
|
|
|
+ for ( i = 0; i < this.segments; i++ ) {
|
|
|
+
|
|
|
+ for ( j = 0; j < this.segmentsRadius; j++ ) {
|
|
|
+
|
|
|
+ ip = ( closed ) ? (i + 1) % this.segments : i + 1;
|
|
|
+ jp = (j + 1) % this.segmentsRadius;
|
|
|
+
|
|
|
+ a = this.grid[ i ][ j ]; // *** NOT NECESSARILY PLANAR ! ***
|
|
|
+ b = this.grid[ ip ][ j ];
|
|
|
+ c = this.grid[ ip ][ jp ];
|
|
|
+ d = this.grid[ i ][ jp ];
|
|
|
+
|
|
|
+ uva = new THREE.UV( i / this.segments, j / this.segmentsRadius );
|
|
|
+ uvb = new THREE.UV( ( i + 1 ) / this.segments, j / this.segmentsRadius );
|
|
|
+ uvc = new THREE.UV( ( i + 1 ) / this.segments, ( j + 1 ) / this.segmentsRadius );
|
|
|
+ uvd = new THREE.UV( i / this.segments, ( j + 1 ) / this.segmentsRadius );
|
|
|
+
|
|
|
+ this.faces.push( new THREE.Face4( a, b, c, d ) );
|
|
|
+ this.faceVertexUvs[ 0 ].push( [ uva, uvb, uvc, uvd ] );
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ this.computeCentroids();
|
|
|
+ this.computeFaceNormals();
|
|
|
+ this.computeVertexNormals();
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+THREE.TubeGeometry.prototype = new THREE.Geometry();
|
|
|
+THREE.TubeGeometry.prototype.constructor = THREE.TubeGeometry;
|
|
|
+
|
|
|
+
|
|
|
+// For computing of Frenet frames, exposing the tangents, normals and binormals the spline
|
|
|
+THREE.TubeGeometry.FrenetFrames = function(path, segments, closed) {
|
|
|
+
|
|
|
+ var
|
|
|
+ tangent = new THREE.Vector3(),
|
|
|
+ normal = new THREE.Vector3(),
|
|
|
+ binormal = new THREE.Vector3(),
|
|
|
+
|
|
|
+ tangents = [],
|
|
|
+ normals = [],
|
|
|
+ binormals = [],
|
|
|
+
|
|
|
+ vec = new THREE.Vector3(),
|
|
|
+ mat = new THREE.Matrix4(),
|
|
|
+
|
|
|
+ numpoints = segments + 1,
|
|
|
+ theta,
|
|
|
+ epsilon = 0.0001,
|
|
|
+ smallest,
|
|
|
+
|
|
|
+ tx, ty, tz,
|
|
|
+ i, u, v;
|
|
|
+
|
|
|
+
|
|
|
+ // expose internals
|
|
|
+ this.tangents = tangents;
|
|
|
+ this.normals = normals;
|
|
|
+ this.binormals = binormals;
|
|
|
+
|
|
|
// compute the tangent vectors for each segment on the path
|
|
|
|
|
|
for ( i = 0; i < numpoints; i++ ) {
|
|
|
|
|
|
u = i / ( numpoints - 1 );
|
|
|
|
|
|
- tangents[ i ] = this.path.getTangentAt( u );
|
|
|
+ tangents[ i ] = path.getTangentAt( u );
|
|
|
tangents[ i ].normalize();
|
|
|
|
|
|
}
|
|
|
|
|
|
initialNormal3();
|
|
|
|
|
|
- function initialNormal1() {
|
|
|
+ function initialNormal1(lastBinormal) {
|
|
|
// fixed start binormal. Has dangers of 0 vectors
|
|
|
normals[ 0 ] = new THREE.Vector3();
|
|
|
binormals[ 0 ] = new THREE.Vector3();
|
|
|
- var lastBinormal = new THREE.Vector3( 0, 0, 1 );
|
|
|
+ if (lastBinormal===undefined) lastBinormal = new THREE.Vector3( 0, 0, 1 );
|
|
|
normals[ 0 ].cross( lastBinormal, tangents[ 0 ] ).normalize();
|
|
|
binormals[ 0 ].cross( tangents[ 0 ], normals[ 0 ] ).normalize();
|
|
|
}
|
|
@@ -90,7 +194,7 @@ THREE.TubeGeometry = function( path, segments, radius, segmentsRadius, closed, d
|
|
|
// This uses the Frenet-Serret formula for deriving binormal
|
|
|
var t2 = path.getTangentAt( epsilon );
|
|
|
|
|
|
- normals[ 0 ] = new THREE.Vector3().sub( t2, tangents[ 0 ] ).normalize()
|
|
|
+ normals[ 0 ] = new THREE.Vector3().sub( t2, tangents[ 0 ] ).normalize();
|
|
|
binormals[ 0 ] = new THREE.Vector3().cross( tangents[ 0 ], normals[ 0 ] );
|
|
|
|
|
|
normals[ 0 ].cross( binormals[ 0 ], tangents[ 0 ] ).normalize(); // last binormal x tangent
|
|
@@ -157,7 +261,7 @@ THREE.TubeGeometry = function( path, segments, radius, segmentsRadius, closed, d
|
|
|
|
|
|
// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same
|
|
|
|
|
|
- if ( this.closed ) {
|
|
|
+ if ( closed ) {
|
|
|
|
|
|
theta = Math.acos( normals[ 0 ].dot( normals[ numpoints-1 ] ) );
|
|
|
theta /= ( numpoints - 1 );
|
|
@@ -177,78 +281,4 @@ THREE.TubeGeometry = function( path, segments, radius, segmentsRadius, closed, d
|
|
|
}
|
|
|
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
- // consruct the grid
|
|
|
-
|
|
|
- for ( i = 0; i < numpoints; i++ ) {
|
|
|
-
|
|
|
- this.grid[ i ] = [];
|
|
|
-
|
|
|
- u = i / ( numpoints - 1 );
|
|
|
-
|
|
|
- pos = this.path.getPointAt( u );
|
|
|
-
|
|
|
- tangent = tangents[ i ];
|
|
|
- normal = normals[ i ];
|
|
|
- binormal = binormals[ i ];
|
|
|
-
|
|
|
- if ( this.debug ) {
|
|
|
-
|
|
|
- this.debug.add(new THREE.ArrowHelper(tangent, pos, radius, 0x0000ff));
|
|
|
- this.debug.add(new THREE.ArrowHelper(normal, pos, radius, 0xff0000));
|
|
|
- this.debug.add(new THREE.ArrowHelper(binormal, pos, radius, 0x00ff00));
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- for ( j = 0; j < this.segmentsRadius; j++ ) {
|
|
|
-
|
|
|
- v = j / this.segmentsRadius * 2 * Math.PI;
|
|
|
-
|
|
|
- cx = -this.radius * Math.cos( v ); // TODO: Hack: Negating it so it faces outside.
|
|
|
- cy = this.radius * Math.sin( v );
|
|
|
-
|
|
|
- pos2 = new THREE.Vector3().copy( pos );
|
|
|
- pos2.x += cx * normal.x + cy * binormal.x;
|
|
|
- pos2.y += cx * normal.y + cy * binormal.y;
|
|
|
- pos2.z += cx * normal.z + cy * binormal.z;
|
|
|
-
|
|
|
- this.grid[ i ][ j ] = vert( pos2.x, pos2.y, pos2.z );
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- // construct the mesh
|
|
|
-
|
|
|
- for ( i = 0; i < this.segments; i++ ) {
|
|
|
-
|
|
|
- for ( j = 0; j < this.segmentsRadius; j++ ) {
|
|
|
-
|
|
|
- ip = ( closed ) ? (i + 1) % this.segments : i + 1;
|
|
|
- jp = (j + 1) % this.segmentsRadius;
|
|
|
-
|
|
|
- a = this.grid[ i ][ j ]; // *** NOT NECESSARILY PLANAR ! ***
|
|
|
- b = this.grid[ ip ][ j ];
|
|
|
- c = this.grid[ ip ][ jp ];
|
|
|
- d = this.grid[ i ][ jp ];
|
|
|
-
|
|
|
- uva = new THREE.UV( i / this.segments, j / this.segmentsRadius );
|
|
|
- uvb = new THREE.UV( ( i + 1 ) / this.segments, j / this.segmentsRadius );
|
|
|
- uvc = new THREE.UV( ( i + 1 ) / this.segments, ( j + 1 ) / this.segmentsRadius );
|
|
|
- uvd = new THREE.UV( i / this.segments, ( j + 1 ) / this.segmentsRadius );
|
|
|
-
|
|
|
- this.faces.push( new THREE.Face4( a, b, c, d ) );
|
|
|
- this.faceVertexUvs[ 0 ].push( [ uva, uvb, uvc, uvd ] );
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- this.computeCentroids();
|
|
|
- this.computeFaceNormals();
|
|
|
- this.computeVertexNormals();
|
|
|
-
|
|
|
-};
|
|
|
-
|
|
|
-THREE.TubeGeometry.prototype = new THREE.Geometry();
|
|
|
-THREE.TubeGeometry.prototype.constructor = THREE.TubeGeometry;
|
|
|
+};
|