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

Implemented @timothypratley 's Polyhedron code.

Keeping the old IcosahadrenGeometry and OctahedronGeometry to double check results later.
上级 be70d486
此差异已折叠。
因为 它太大了无法显示 source diff 。你可以改为 查看blob
......@@ -39,7 +39,7 @@
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.y = 200;
camera.position.y = 400;
scene.add( camera );
var light, object, materials;
......@@ -56,16 +56,24 @@
];
object = THREE.SceneUtils.createMultiMaterialObject( new THREE.CubeGeometry( 100, 100, 100, 4, 4, 4 ), materials );
object.position.set( -200, 0, 200 );
object.position.set( -200, 0, 400 );
scene.add( object );
object = THREE.SceneUtils.createMultiMaterialObject( new THREE.CylinderGeometry( 25, 75, 100, 40, 5 ), materials );
object.position.set( 0, 0, 400 );
scene.add( object );
object = THREE.SceneUtils.createMultiMaterialObject( new THREE.IcosahedronGeometry( 75, 1 ), materials );
object.position.set( -200, 0, 200 );
scene.add( object );
object = THREE.SceneUtils.createMultiMaterialObject( new THREE.OctahedronGeometry( 75, 0 ), materials );
object.position.set( 0, 0, 200 );
scene.add( object );
object = THREE.SceneUtils.createMultiMaterialObject( new THREE.IcosahedronGeometry( 2 ), materials );
object = THREE.SceneUtils.createMultiMaterialObject( new THREE.TetrahedronGeometry( 75, 0 ), materials );
object.position.set( 200, 0, 200 );
object.scale.x = object.scale.y = object.scale.z = 75;
scene.add( object );
object = THREE.SceneUtils.createMultiMaterialObject( new THREE.PlaneGeometry( 100, 100, 4, 4 ), materials );
......
/**
* @author oosmoxiecode
*
* uvs are messed up in this one, and commented away for now. There is an ugly "seam" by the shared vertices
* when it "wraps" around, that needs to be fixed. It's because they share the first and the last vertices
* so it draws the entire texture on the seam-faces, I think...
* @author timothypratley / https://github.com/timothypratley
*/
THREE.IcosahedronGeometry = function ( subdivisions ) {
var scope = this;
var tempScope = new THREE.Geometry();
var tempFaces;
this.subdivisions = subdivisions || 0;
THREE.Geometry.call( this );
// create 12 vertices of a Icosahedron
THREE.IcosahedronGeometry = function ( radius, detail ) {
var t = ( 1 + Math.sqrt( 5 ) ) / 2;
v(-1, t, 0);
v( 1, t, 0);
v(-1, -t, 0);
v( 1, -t, 0);
v( 0, -1, t);
v( 0, 1, t);
v( 0, -1, -t);
v( 0, 1, -t);
v( t, 0, -1);
v( t, 0, 1);
v(-t, 0, -1);
v(-t, 0, 1);
// 5 faces around point 0
f3(0, 11, 5, tempScope);
f3(0, 5, 1, tempScope);
f3(0, 1, 7, tempScope);
f3(0, 7, 10, tempScope);
f3(0, 10, 11, tempScope);
// 5 adjacent faces
f3(1, 5, 9, tempScope);
f3(5, 11, 4, tempScope);
f3(11, 10, 2, tempScope);
f3(10, 7, 6, tempScope);
f3(7, 1, 8, tempScope);
// 5 faces around point 3
f3(3, 9, 4, tempScope);
f3(3, 4, 2, tempScope);
f3(3, 2, 6, tempScope);
f3(3, 6, 8, tempScope);
f3(3, 8, 9, tempScope);
// 5 adjacent faces
f3(4, 9, 5, tempScope);
f3(2, 4, 11, tempScope);
f3(6, 2, 10, tempScope);
f3(8, 6, 7, tempScope);
f3(9, 8, 1, tempScope);
// subdivide faces to refine the triangles
for ( var i = 0; i < this.subdivisions; i ++ ) {
tempFaces = new THREE.Geometry();
for ( var i = 0, l = tempScope.faces.length; i < l; i ++ ) {
// replace each triangle by 4 triangles
var face = tempScope.faces[ i ];
var a = getMiddlePoint( face.a, face.b );
var b = getMiddlePoint( face.b, face.c );
var c = getMiddlePoint( face.c, face.a );
f3( face.a, a, c, tempFaces );
f3( face.b, b, a, tempFaces );
f3( face.c, c, b, tempFaces );
f3( a, b, c, tempFaces );
}
tempScope.faces = tempFaces.faces;
tempScope.faceVertexUvs[ 0 ] = tempFaces.faceVertexUvs[ 0 ];
}
scope.faces = tempScope.faces;
scope.faceVertexUvs[ 0 ] = tempScope.faceVertexUvs[ 0 ];
this.mergeVertices();
this.computeCentroids();
this.computeFaceNormals();
function v( x, y, z ) {
var length = Math.sqrt( x * x + y * y + z * z );
var i = scope.vertices.push( new THREE.Vertex( new THREE.Vector3( x/length, y/length, z/length ) ) );
return i-1;
}
function f3( a, b, c, inscope ) {
var v1 = scope.vertices[ a ].position;
var v2 = scope.vertices[ b ].position;
var v3 = scope.vertices[ c ].position;
var face = new THREE.Face3( a, b, c );
face.vertexNormals.push( v1.clone().normalize(), v2.clone().normalize(), v3.clone().normalize() );
inscope.faces.push( face );
inscope.faceVertexUvs[ 0 ].push( [
new THREE.UV( 1 - ( ( ( Math.atan2( v1.z, v1.x ) + Math.PI ) % Math.PI ) / Math.PI * 0.5 ), 0.5 - v1.y / 2 ),
new THREE.UV( 1 - ( ( ( Math.atan2( v2.z, v2.x ) + Math.PI ) % Math.PI ) / Math.PI * 0.5 ), 0.5 - v2.y / 2 ),
new THREE.UV( 1 - ( ( ( Math.atan2( v3.z, v3.x ) + Math.PI ) % Math.PI ) / Math.PI * 0.5 ), 0.5 - v3.y / 2 )
] );
}
function getMiddlePoint( p1, p2 ) {
var pos1 = scope.vertices[ p1 ].position;
var pos2 = scope.vertices[ p2 ].position;
var x = ( pos1.x + pos2.x ) / 2;
var y = ( pos1.y + pos2.y ) / 2;
var z = ( pos1.z + pos2.z ) / 2;
var i = v(x, y, z);
return i;
var vertices = [
[ -1, t, 0 ], [ 1, t, 0 ], [ -1, -t, 0 ], [ 1, -t, 0 ],
[ 0, -1, t ], [ 0, 1, t ], [ 0, -1, -t ], [ 0, 1, -t ],
[ t, 0, -1 ], [ t, 0, 1 ], [ -t, 0, -1 ], [ -t, 0, 1 ]
];
}
var faces = [
[ 0, 11, 5 ], [ 0, 5, 1 ], [ 0, 1, 7 ], [ 0, 7, 10 ], [ 0, 10, 11 ],
[ 1, 5, 9 ], [ 5, 11, 4 ], [ 11, 10, 2 ], [ 10, 7, 6 ], [ 7, 1, 8 ],
[ 3, 9, 4 ], [ 3, 4, 2 ], [ 3, 2, 6 ], [ 3, 6, 8 ], [ 3, 8, 9 ],
[ 4, 9, 5 ], [ 2, 4, 11 ], [ 6, 2, 10 ], [ 8, 6, 7 ], [ 9, 8, 1 ]
];
}
THREE.PolyhedronGeometry.call( this, vertices, faces, radius, detail );
};
THREE.IcosahedronGeometry.prototype = new THREE.Geometry();
THREE.IcosahedronGeometry.prototype.constructor = THREE.IcosahedronGeometry;
/**
* @author oosmoxiecode
*
* uvs are messed up in this one, and commented away for now. There is an ugly "seam" by the shared vertices
* when it "wraps" around, that needs to be fixed. It's because they share the first and the last vertices
* so it draws the entire texture on the seam-faces, I think...
*/
THREE.IcosahedronGeometry_ = function ( subdivisions ) {
var scope = this;
var tempScope = new THREE.Geometry();
var tempFaces;
this.subdivisions = subdivisions || 0;
THREE.Geometry.call( this );
// create 12 vertices of a Icosahedron
var t = ( 1 + Math.sqrt( 5 ) ) / 2;
v(-1, t, 0);
v( 1, t, 0);
v(-1, -t, 0);
v( 1, -t, 0);
v( 0, -1, t);
v( 0, 1, t);
v( 0, -1, -t);
v( 0, 1, -t);
v( t, 0, -1);
v( t, 0, 1);
v(-t, 0, -1);
v(-t, 0, 1);
// 5 faces around point 0
f3(0, 11, 5, tempScope);
f3(0, 5, 1, tempScope);
f3(0, 1, 7, tempScope);
f3(0, 7, 10, tempScope);
f3(0, 10, 11, tempScope);
// 5 adjacent faces
f3(1, 5, 9, tempScope);
f3(5, 11, 4, tempScope);
f3(11, 10, 2, tempScope);
f3(10, 7, 6, tempScope);
f3(7, 1, 8, tempScope);
// 5 faces around point 3
f3(3, 9, 4, tempScope);
f3(3, 4, 2, tempScope);
f3(3, 2, 6, tempScope);
f3(3, 6, 8, tempScope);
f3(3, 8, 9, tempScope);
// 5 adjacent faces
f3(4, 9, 5, tempScope);
f3(2, 4, 11, tempScope);
f3(6, 2, 10, tempScope);
f3(8, 6, 7, tempScope);
f3(9, 8, 1, tempScope);
// subdivide faces to refine the triangles
for ( var i = 0; i < this.subdivisions; i ++ ) {
tempFaces = new THREE.Geometry();
for ( var i = 0, l = tempScope.faces.length; i < l; i ++ ) {
// replace each triangle by 4 triangles
var face = tempScope.faces[ i ];
var a = getMiddlePoint( face.a, face.b );
var b = getMiddlePoint( face.b, face.c );
var c = getMiddlePoint( face.c, face.a );
f3( face.a, a, c, tempFaces );
f3( face.b, b, a, tempFaces );
f3( face.c, c, b, tempFaces );
f3( a, b, c, tempFaces );
}
tempScope.faces = tempFaces.faces;
tempScope.faceVertexUvs[ 0 ] = tempFaces.faceVertexUvs[ 0 ];
}
scope.faces = tempScope.faces;
scope.faceVertexUvs[ 0 ] = tempScope.faceVertexUvs[ 0 ];
this.mergeVertices();
this.computeCentroids();
this.computeFaceNormals();
function v( x, y, z ) {
var length = Math.sqrt( x * x + y * y + z * z );
var i = scope.vertices.push( new THREE.Vertex( new THREE.Vector3( x/length, y/length, z/length ) ) );
return i-1;
}
function f3( a, b, c, inscope ) {
var v1 = scope.vertices[ a ].position;
var v2 = scope.vertices[ b ].position;
var v3 = scope.vertices[ c ].position;
var face = new THREE.Face3( a, b, c );
face.vertexNormals.push( v1.clone().normalize(), v2.clone().normalize(), v3.clone().normalize() );
inscope.faces.push( face );
inscope.faceVertexUvs[ 0 ].push( [
new THREE.UV( 1 - ( ( ( Math.atan2( v1.z, v1.x ) + Math.PI ) % Math.PI ) / Math.PI * 0.5 ), 0.5 - v1.y / 2 ),
new THREE.UV( 1 - ( ( ( Math.atan2( v2.z, v2.x ) + Math.PI ) % Math.PI ) / Math.PI * 0.5 ), 0.5 - v2.y / 2 ),
new THREE.UV( 1 - ( ( ( Math.atan2( v3.z, v3.x ) + Math.PI ) % Math.PI ) / Math.PI * 0.5 ), 0.5 - v3.y / 2 )
] );
}
function getMiddlePoint( p1, p2 ) {
var pos1 = scope.vertices[ p1 ].position;
var pos2 = scope.vertices[ p2 ].position;
var x = ( pos1.x + pos2.x ) / 2;
var y = ( pos1.y + pos2.y ) / 2;
var z = ( pos1.z + pos2.z ) / 2;
var i = v(x, y, z);
return i;
}
}
THREE.IcosahedronGeometry_.prototype = new THREE.Geometry();
THREE.IcosahedronGeometry_.prototype.constructor = THREE.IcosahedronGeometry_;
/**
* Octahedrons have 8 sides. This octahedron supports subdivision.
*
* Vertices have 'smooth' normals,
* to make a sharp edge choose a material that uses face normals instead.
*
* @author daniel.deady@knectar.com
* @param radius
* @param detail Final number of triangles = 4^detail * 8
* @author timothypratley / https://github.com/timothypratley
*/
THREE.OctahedronGeometry = function ( radius, detail ) {
THREE.Geometry.call( this );
var vertices = [
[ 1, 0, 0 ], [ -1, 0, 0 ], [ 0, 1, 0 ], [ 0, -1, 0 ], [ 0, 0, 1 ], [ 0, 0, -1 ]
];
detail = detail || 0;
var that = this; // ugly scope hack
prepare( new THREE.Vector3( +1, 0, 0 ) ); // right
prepare( new THREE.Vector3( -1, 0, 0 ) ); // left
prepare( new THREE.Vector3( 0, +1, 0 ) ); // up
prepare( new THREE.Vector3( 0, -1, 0 ) ); // down
prepare( new THREE.Vector3( 0, 0, +1 ) ); // front
prepare( new THREE.Vector3( 0, 0, -1 ) ); // back
var midpoints = [], p = this.vertices;
// careful to output faces counter-clockwise, that is required for meshes
make( p[0], p[2], p[4], detail );
make( p[0], p[4], p[3], detail );
make( p[0], p[3], p[5], detail );
make( p[0], p[5], p[2], detail );
make( p[1], p[2], p[5], detail );
make( p[1], p[5], p[3], detail );
make( p[1], p[3], p[4], detail );
make( p[1], p[4], p[2], detail );
/**
* Project vector onto sphere's surface
*/
function prepare( vector ) {
var normal = vector.clone().normalize();
var vertex = new THREE.Vertex( normal.clone().multiplyScalar( radius ) );
vertex.index = that.vertices.push( vertex ) - 1;
// Texture coords are equivalent to map coords, calculate angle and convert to fraction of a circle.
var u = azimuth( vector ) / 2 / Math.PI + 0.5;
var v = inclination( vector ) / Math.PI + 0.5;
vertex.uv = new THREE.UV( u, v );
return vertex;
}
/**
* Approximate a curved face with recursively sub-divided triangles.
*/
function make( v1, v2, v3, detail ) {
if ( detail < 1 ) {
var face = new THREE.Face3( v1.index, v2.index, v3.index, [ v1.position, v2.position, v3.position ] );
face.centroid.addSelf( v1.position ).addSelf( v2.position ).addSelf( v3.position ).divideScalar( 3 );
face.normal = face.centroid.clone().normalize();
that.faces.push( face );
var azi = azimuth( face.centroid );
that.faceVertexUvs[ 0 ].push( [
correctUV( v1.uv, v1.position, azi ),
correctUV( v2.uv, v2.position, azi ),
correctUV( v3.uv, v3.position, azi )
] );
}
else {
detail -= 1;
// split triangle into 4 smaller triangles
make( v1, midpoint( v1, v2 ), midpoint( v1, v3 ), detail ); // top quadrant
make( midpoint( v1, v2 ), v2, midpoint( v2, v3 ), detail ); // left quadrant
make( midpoint( v1, v3 ), midpoint( v2, v3 ), v3, detail ); // right quadrant
make( midpoint( v1, v2 ), midpoint( v2, v3 ), midpoint( v1, v3 ), detail ); // center quadrant
}
}
function midpoint( v1, v2 ) {
if ( !midpoints[ v1.index ] ) midpoints[ v1.index ] = [];
if ( !midpoints[ v2.index ] ) midpoints[ v2.index ] = [];
var mid = midpoints[ v1.index ][ v2.index ];
if ( mid === undefined ) {
// generate mean point and project to surface with prepare()
midpoints[ v1.index ][ v2.index ] = midpoints[ v2.index ][ v1.index ] = mid = prepare(
new THREE.Vector3().add( v1.position, v2.position ).divideScalar( 2 )
);
}
return mid;
}
/**
* Angle around the Y axis, counter-clockwise when looking from above.
*/
function azimuth( vector ) {
return Math.atan2( vector.z, -vector.x );
}
/**
* Angle above the XZ plane.
*/
function inclination( vector ) {
return Math.atan2( -vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );
}
/**
* Texture fixing helper. Spheres have some odd behaviours.
*/
function correctUV( uv, vector, azimuth ) {
if ( (azimuth < 0) && (uv.u === 1) ) uv = new THREE.UV( uv.u - 1, uv.v );
if ( (vector.x === 0) && (vector.z === 0) ) uv = new THREE.UV( azimuth / 2 / Math.PI + 0.5, uv.v );
return uv;
}
this.boundingSphere = { radius: radius };
var faces = [
[ 0, 2, 4 ], [ 0, 4, 3 ], [ 0, 3, 5 ], [ 0, 5, 2 ], [ 1, 2, 5 ], [ 1, 5, 3 ], [ 1, 3, 4 ], [ 1, 4, 2 ]
];
THREE.PolyhedronGeometry.call( this, vertices, faces, radius, detail );
};
THREE.OctahedronGeometry.prototype = new THREE.Geometry();
THREE.OctahedronGeometry.prototype.constructor = THREE.OctahedronGeometry;
/**
* Octahedrons have 8 sides. This octahedron supports subdivision.
*
* Vertices have 'smooth' normals,
* to make a sharp edge choose a material that uses face normals instead.
*
* @author daniel.deady@knectar.com
* @param radius
* @param detail Final number of triangles = 4^detail * 8
*/
THREE.OctahedronGeometry_ = function ( radius, detail ) {
THREE.Geometry.call( this );
detail = detail || 0;
var that = this; // ugly scope hack
prepare( new THREE.Vector3( +1, 0, 0 ) ); // right
prepare( new THREE.Vector3( -1, 0, 0 ) ); // left
prepare( new THREE.Vector3( 0, +1, 0 ) ); // up
prepare( new THREE.Vector3( 0, -1, 0 ) ); // down
prepare( new THREE.Vector3( 0, 0, +1 ) ); // front
prepare( new THREE.Vector3( 0, 0, -1 ) ); // back
var midpoints = [], p = this.vertices;
// careful to output faces counter-clockwise, that is required for meshes
make( p[0], p[2], p[4], detail );
make( p[0], p[4], p[3], detail );
make( p[0], p[3], p[5], detail );
make( p[0], p[5], p[2], detail );
make( p[1], p[2], p[5], detail );
make( p[1], p[5], p[3], detail );
make( p[1], p[3], p[4], detail );
make( p[1], p[4], p[2], detail );
/**
* Project vector onto sphere's surface
*/
function prepare( vector ) {
var normal = vector.clone().normalize();
var vertex = new THREE.Vertex( normal.clone().multiplyScalar( radius ) );
vertex.index = that.vertices.push( vertex ) - 1;
// Texture coords are equivalent to map coords, calculate angle and convert to fraction of a circle.
var u = azimuth( vector ) / 2 / Math.PI + 0.5;
var v = inclination( vector ) / Math.PI + 0.5;
vertex.uv = new THREE.UV( u, v );
return vertex;
}
/**
* Approximate a curved face with recursively sub-divided triangles.
*/
function make( v1, v2, v3, detail ) {
if ( detail < 1 ) {
var face = new THREE.Face3( v1.index, v2.index, v3.index, [ v1.position, v2.position, v3.position ] );
face.centroid.addSelf( v1.position ).addSelf( v2.position ).addSelf( v3.position ).divideScalar( 3 );
face.normal = face.centroid.clone().normalize();
that.faces.push( face );
var azi = azimuth( face.centroid );
that.faceVertexUvs[ 0 ].push( [
correctUV( v1.uv, v1.position, azi ),
correctUV( v2.uv, v2.position, azi ),
correctUV( v3.uv, v3.position, azi )
] );
}
else {
detail -= 1;
// split triangle into 4 smaller triangles
make( v1, midpoint( v1, v2 ), midpoint( v1, v3 ), detail ); // top quadrant
make( midpoint( v1, v2 ), v2, midpoint( v2, v3 ), detail ); // left quadrant
make( midpoint( v1, v3 ), midpoint( v2, v3 ), v3, detail ); // right quadrant
make( midpoint( v1, v2 ), midpoint( v2, v3 ), midpoint( v1, v3 ), detail ); // center quadrant
}
}
function midpoint( v1, v2 ) {
if ( !midpoints[ v1.index ] ) midpoints[ v1.index ] = [];
if ( !midpoints[ v2.index ] ) midpoints[ v2.index ] = [];
var mid = midpoints[ v1.index ][ v2.index ];
if ( mid === undefined ) {
// generate mean point and project to surface with prepare()
midpoints[ v1.index ][ v2.index ] = midpoints[ v2.index ][ v1.index ] = mid = prepare(
new THREE.Vector3().add( v1.position, v2.position ).divideScalar( 2 )
);
}
return mid;
}
/**
* Angle around the Y axis, counter-clockwise when looking from above.
*/
function azimuth( vector ) {
return Math.atan2( vector.z, -vector.x );
}
/**
* Angle above the XZ plane.
*/
function inclination( vector ) {
return Math.atan2( -vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );
}
/**
* Texture fixing helper. Spheres have some odd behaviours.
*/
function correctUV( uv, vector, azimuth ) {
if ( (azimuth < 0) && (uv.u === 1) ) uv = new THREE.UV( uv.u - 1, uv.v );
if ( (vector.x === 0) && (vector.z === 0) ) uv = new THREE.UV( azimuth / 2 / Math.PI + 0.5, uv.v );
return uv;
}
this.boundingSphere = { radius: radius };
};
THREE.OctahedronGeometry_.prototype = new THREE.Geometry();
THREE.OctahedronGeometry_.prototype.constructor = THREE.OctahedronGeometry_;
/**
* @author clockworkgeek / https://github.com/clockworkgeek
* @author timothypratley / https://github.com/timothypratley
*/
THREE.PolyhedronGeometry = function ( vertices, faces, radius, detail ) {
THREE.Geometry.call( this );
radius = radius || 1;
detail = detail || 0;
var that = this;
for ( var i = 0, l = vertices.length; i < l; i ++ ) {
prepare( new THREE.Vector3( vertices[ i ][ 0 ], vertices[ i ][ 1 ], vertices[ i ][ 2 ] ) );
}
var midpoints = [], p = this.vertices;
for ( var i = 0, l = faces.length; i < l; i ++ ) {
make( p[ faces[ i ][ 0 ] ], p[ faces[ i ][ 1 ] ], p[ faces[ i ][ 2 ] ], detail );
}
this.mergeVertices();
/**
* Project vector onto sphere's surface
*/
function prepare( vector ) {
var normal = vector.clone().normalize();
var vertex = new THREE.Vertex( normal.clone().multiplyScalar( radius ) );
vertex.index = that.vertices.push( vertex ) - 1;
// Texture coords are equivalent to map coords, calculate angle and convert to fraction of a circle.
var u = azimuth( vector ) / 2 / Math.PI + 0.5;
var v = inclination( vector ) / Math.PI + 0.5;
vertex.uv = new THREE.UV( u, v );
return vertex;
}
/**
* Approximate a curved face with recursively sub-divided triangles.
*/
function make( v1, v2, v3, detail ) {
if ( detail < 1 ) {
var face = new THREE.Face3( v1.index, v2.index, v3.index, [ v1.position, v2.position, v3.position ] );
face.centroid.addSelf( v1.position ).addSelf( v2.position ).addSelf( v3.position ).divideScalar( 3 );
face.normal = face.centroid.clone().normalize();
that.faces.push( face );
var azi = azimuth( face.centroid );
that.faceVertexUvs[ 0 ].push( [
correctUV( v1.uv, v1.position, azi ),
correctUV( v2.uv, v2.position, azi ),
correctUV( v3.uv, v3.position, azi )
] );
}
else {
detail -= 1;
// split triangle into 4 smaller triangles
make( v1, midpoint( v1, v2 ), midpoint( v1, v3 ), detail ); // top quadrant
make( midpoint( v1, v2 ), v2, midpoint( v2, v3 ), detail ); // left quadrant
make( midpoint( v1, v3 ), midpoint( v2, v3 ), v3, detail ); // right quadrant
make( midpoint( v1, v2 ), midpoint( v2, v3 ), midpoint( v1, v3 ), detail ); // center quadrant
}
}
function midpoint( v1, v2 ) {
if ( !midpoints[ v1.index ] ) midpoints[ v1.index ] = [];
if ( !midpoints[ v2.index ] ) midpoints[ v2.index ] = [];
var mid = midpoints[ v1.index ][ v2.index ];
if ( mid === undefined ) {
// generate mean point and project to surface with prepare()
midpoints[ v1.index ][ v2.index ] = midpoints[ v2.index ][ v1.index ] = mid = prepare(
new THREE.Vector3().add( v1.position, v2.position ).divideScalar( 2 )
);
}
return mid;
}
/**
* Angle around the Y axis, counter-clockwise when looking from above.
*/
function azimuth( vector ) {
return Math.atan2( vector.z, -vector.x );
}
/**
* Angle above the XZ plane.
*/
function inclination( vector ) {
return Math.atan2( -vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );
}
/**
* Texture fixing helper. Spheres have some odd behaviours.
*/
function correctUV( uv, vector, azimuth ) {
if ( (azimuth < 0) && (uv.u === 1) ) uv = new THREE.UV( uv.u - 1, uv.v );
if ( (vector.x === 0) && (vector.z === 0) ) uv = new THREE.UV( azimuth / 2 / Math.PI + 0.5, uv.v );
return uv;
}
this.boundingSphere = { radius: radius };
};
THREE.PolyhedronGeometry.prototype = new THREE.Geometry();
THREE.PolyhedronGeometry.prototype.constructor = THREE.PolyhedronGeometry;
/**
* @author timothypratley / https://github.com/timothypratley
*/
THREE.TetrahedronGeometry = function ( radius, detail ) {
var vertices = [
[ 1, 1, 1 ], [ -1, -1, 1 ], [ -1, 1, -1 ], [ 1, -1, -1 ]
];
var faces = [
[ 2, 1, 0 ], [ 0, 3, 2 ], [ 1, 3, 0 ], [ 2, 3, 1 ]
];
THREE.PolyhedronGeometry.call( this, vertices, faces, radius, detail );
};
THREE.TetrahedronGeometry.prototype = new THREE.Geometry();
THREE.TetrahedronGeometry.prototype.constructor = THREE.TetrahedronGeometry;
......@@ -116,14 +116,16 @@ EXTRAS_FILES = [
'extras/geometries/CubeGeometry.js',
'extras/geometries/CylinderGeometry.js',
'extras/geometries/ExtrudeGeometry.js',
'extras/geometries/IcosahedronGeometry.js',
'extras/geometries/LatheGeometry.js',
'extras/geometries/OctahedronGeometry.js',
'extras/geometries/PlaneGeometry.js',
'extras/geometries/SphereGeometry.js',
'extras/geometries/TextGeometry.js',
'extras/geometries/TorusGeometry.js',
'extras/geometries/TorusKnotGeometry.js',
'extras/geometries/PolyhedronGeometry.js',
'extras/geometries/IcosahedronGeometry.js',
'extras/geometries/OctahedronGeometry.js',
'extras/geometries/TetrahedronGeometry.js',
'extras/helpers/AxisHelper.js',
'extras/helpers/CameraHelper.js',
'extras/modifiers/SubdivisionModifier.js',
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册