Dies ist das Repository meines kleinen Portfolios.
Im Hintergrund läuft eine Planetensimulation, geschrieben in JavaScript und Three.js.
Die zu sehenden Texturen stammen von:
https://www.solarsystemscope.com/textures/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
811 lines
18 KiB
811 lines
18 KiB
/** |
|
* Creates extruded geometry from a path shape. |
|
* |
|
* parameters = { |
|
* |
|
* curveSegments: <int>, // number of points on the curves |
|
* steps: <int>, // number of points for z-side extrusions / used for subdividing segments of extrude spline too |
|
* depth: <float>, // Depth to extrude the shape |
|
* |
|
* bevelEnabled: <bool>, // turn on bevel |
|
* bevelThickness: <float>, // how deep into the original shape bevel goes |
|
* bevelSize: <float>, // how far from shape outline (including bevelOffset) is bevel |
|
* bevelOffset: <float>, // how far from shape outline does bevel start |
|
* bevelSegments: <int>, // number of bevel layers |
|
* |
|
* extrudePath: <THREE.Curve> // curve to extrude shape along |
|
* |
|
* UVGenerator: <Object> // object that provides UV generator functions |
|
* |
|
* } |
|
*/ |
|
|
|
import { BufferGeometry } from '../core/BufferGeometry.js'; |
|
import { Float32BufferAttribute } from '../core/BufferAttribute.js'; |
|
import * as Curves from '../extras/curves/Curves.js'; |
|
import { Vector2 } from '../math/Vector2.js'; |
|
import { Vector3 } from '../math/Vector3.js'; |
|
import { Shape } from '../extras/core/Shape.js'; |
|
import { ShapeUtils } from '../extras/ShapeUtils.js'; |
|
|
|
class ExtrudeGeometry extends BufferGeometry { |
|
|
|
constructor( shapes = new Shape( [ new Vector2( 0.5, 0.5 ), new Vector2( - 0.5, 0.5 ), new Vector2( - 0.5, - 0.5 ), new Vector2( 0.5, - 0.5 ) ] ), options = {} ) { |
|
|
|
super(); |
|
|
|
this.type = 'ExtrudeGeometry'; |
|
|
|
this.parameters = { |
|
shapes: shapes, |
|
options: options |
|
}; |
|
|
|
shapes = Array.isArray( shapes ) ? shapes : [ shapes ]; |
|
|
|
const scope = this; |
|
|
|
const verticesArray = []; |
|
const uvArray = []; |
|
|
|
for ( let i = 0, l = shapes.length; i < l; i ++ ) { |
|
|
|
const shape = shapes[ i ]; |
|
addShape( shape ); |
|
|
|
} |
|
|
|
// build geometry |
|
|
|
this.setAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) ); |
|
this.setAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) ); |
|
|
|
this.computeVertexNormals(); |
|
|
|
// functions |
|
|
|
function addShape( shape ) { |
|
|
|
const placeholder = []; |
|
|
|
// options |
|
|
|
const curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12; |
|
const steps = options.steps !== undefined ? options.steps : 1; |
|
let depth = options.depth !== undefined ? options.depth : 1; |
|
|
|
let bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; |
|
let bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 0.2; |
|
let bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 0.1; |
|
let bevelOffset = options.bevelOffset !== undefined ? options.bevelOffset : 0; |
|
let bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3; |
|
|
|
const extrudePath = options.extrudePath; |
|
|
|
const uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator; |
|
|
|
// deprecated options |
|
|
|
if ( options.amount !== undefined ) { |
|
|
|
console.warn( 'THREE.ExtrudeBufferGeometry: amount has been renamed to depth.' ); |
|
depth = options.amount; |
|
|
|
} |
|
|
|
// |
|
|
|
let extrudePts, extrudeByPath = false; |
|
let splineTube, binormal, normal, position2; |
|
|
|
if ( extrudePath ) { |
|
|
|
extrudePts = extrudePath.getSpacedPoints( steps ); |
|
|
|
extrudeByPath = true; |
|
bevelEnabled = false; // bevels not supported for path extrusion |
|
|
|
// SETUP TNB variables |
|
|
|
// TODO1 - have a .isClosed in spline? |
|
|
|
splineTube = extrudePath.computeFrenetFrames( steps, false ); |
|
|
|
// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length); |
|
|
|
binormal = new Vector3(); |
|
normal = new Vector3(); |
|
position2 = new Vector3(); |
|
|
|
} |
|
|
|
// Safeguards if bevels are not enabled |
|
|
|
if ( ! bevelEnabled ) { |
|
|
|
bevelSegments = 0; |
|
bevelThickness = 0; |
|
bevelSize = 0; |
|
bevelOffset = 0; |
|
|
|
} |
|
|
|
// Variables initialization |
|
|
|
const shapePoints = shape.extractPoints( curveSegments ); |
|
|
|
let vertices = shapePoints.shape; |
|
const holes = shapePoints.holes; |
|
|
|
const reverse = ! ShapeUtils.isClockWise( vertices ); |
|
|
|
if ( reverse ) { |
|
|
|
vertices = vertices.reverse(); |
|
|
|
// Maybe we should also check if holes are in the opposite direction, just to be safe ... |
|
|
|
for ( let h = 0, hl = holes.length; h < hl; h ++ ) { |
|
|
|
const ahole = holes[ h ]; |
|
|
|
if ( ShapeUtils.isClockWise( ahole ) ) { |
|
|
|
holes[ h ] = ahole.reverse(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
const faces = ShapeUtils.triangulateShape( vertices, holes ); |
|
|
|
/* Vertices */ |
|
|
|
const contour = vertices; // vertices has all points but contour has only points of circumference |
|
|
|
for ( let h = 0, hl = holes.length; h < hl; h ++ ) { |
|
|
|
const ahole = holes[ h ]; |
|
|
|
vertices = vertices.concat( ahole ); |
|
|
|
} |
|
|
|
|
|
function scalePt2( pt, vec, size ) { |
|
|
|
if ( ! vec ) console.error( 'THREE.ExtrudeGeometry: vec does not exist' ); |
|
|
|
return vec.clone().multiplyScalar( size ).add( pt ); |
|
|
|
} |
|
|
|
const vlen = vertices.length, flen = faces.length; |
|
|
|
|
|
// Find directions for point movement |
|
|
|
|
|
function getBevelVec( inPt, inPrev, inNext ) { |
|
|
|
// computes for inPt the corresponding point inPt' on a new contour |
|
// shifted by 1 unit (length of normalized vector) to the left |
|
// if we walk along contour clockwise, this new contour is outside the old one |
|
// |
|
// inPt' is the intersection of the two lines parallel to the two |
|
// adjacent edges of inPt at a distance of 1 unit on the left side. |
|
|
|
let v_trans_x, v_trans_y, shrink_by; // resulting translation vector for inPt |
|
|
|
// good reading for geometry algorithms (here: line-line intersection) |
|
// http://geomalgorithms.com/a05-_intersect-1.html |
|
|
|
const v_prev_x = inPt.x - inPrev.x, |
|
v_prev_y = inPt.y - inPrev.y; |
|
const v_next_x = inNext.x - inPt.x, |
|
v_next_y = inNext.y - inPt.y; |
|
|
|
const v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y ); |
|
|
|
// check for collinear edges |
|
const collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x ); |
|
|
|
if ( Math.abs( collinear0 ) > Number.EPSILON ) { |
|
|
|
// not collinear |
|
|
|
// length of vectors for normalizing |
|
|
|
const v_prev_len = Math.sqrt( v_prev_lensq ); |
|
const v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y ); |
|
|
|
// shift adjacent points by unit vectors to the left |
|
|
|
const ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len ); |
|
const ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len ); |
|
|
|
const ptNextShift_x = ( inNext.x - v_next_y / v_next_len ); |
|
const ptNextShift_y = ( inNext.y + v_next_x / v_next_len ); |
|
|
|
// scaling factor for v_prev to intersection point |
|
|
|
const sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y - |
|
( ptNextShift_y - ptPrevShift_y ) * v_next_x ) / |
|
( v_prev_x * v_next_y - v_prev_y * v_next_x ); |
|
|
|
// vector from inPt to intersection point |
|
|
|
v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x ); |
|
v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y ); |
|
|
|
// Don't normalize!, otherwise sharp corners become ugly |
|
// but prevent crazy spikes |
|
const v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y ); |
|
if ( v_trans_lensq <= 2 ) { |
|
|
|
return new Vector2( v_trans_x, v_trans_y ); |
|
|
|
} else { |
|
|
|
shrink_by = Math.sqrt( v_trans_lensq / 2 ); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// handle special case of collinear edges |
|
|
|
let direction_eq = false; // assumes: opposite |
|
|
|
if ( v_prev_x > Number.EPSILON ) { |
|
|
|
if ( v_next_x > Number.EPSILON ) { |
|
|
|
direction_eq = true; |
|
|
|
} |
|
|
|
} else { |
|
|
|
if ( v_prev_x < - Number.EPSILON ) { |
|
|
|
if ( v_next_x < - Number.EPSILON ) { |
|
|
|
direction_eq = true; |
|
|
|
} |
|
|
|
} else { |
|
|
|
if ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) { |
|
|
|
direction_eq = true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if ( direction_eq ) { |
|
|
|
// console.log("Warning: lines are a straight sequence"); |
|
v_trans_x = - v_prev_y; |
|
v_trans_y = v_prev_x; |
|
shrink_by = Math.sqrt( v_prev_lensq ); |
|
|
|
} else { |
|
|
|
// console.log("Warning: lines are a straight spike"); |
|
v_trans_x = v_prev_x; |
|
v_trans_y = v_prev_y; |
|
shrink_by = Math.sqrt( v_prev_lensq / 2 ); |
|
|
|
} |
|
|
|
} |
|
|
|
return new Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by ); |
|
|
|
} |
|
|
|
|
|
const contourMovements = []; |
|
|
|
for ( let i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) { |
|
|
|
if ( j === il ) j = 0; |
|
if ( k === il ) k = 0; |
|
|
|
// (j)---(i)---(k) |
|
// console.log('i,j,k', i, j , k) |
|
|
|
contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] ); |
|
|
|
} |
|
|
|
const holesMovements = []; |
|
let oneHoleMovements, verticesMovements = contourMovements.concat(); |
|
|
|
for ( let h = 0, hl = holes.length; h < hl; h ++ ) { |
|
|
|
const ahole = holes[ h ]; |
|
|
|
oneHoleMovements = []; |
|
|
|
for ( let i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) { |
|
|
|
if ( j === il ) j = 0; |
|
if ( k === il ) k = 0; |
|
|
|
// (j)---(i)---(k) |
|
oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] ); |
|
|
|
} |
|
|
|
holesMovements.push( oneHoleMovements ); |
|
verticesMovements = verticesMovements.concat( oneHoleMovements ); |
|
|
|
} |
|
|
|
|
|
// Loop bevelSegments, 1 for the front, 1 for the back |
|
|
|
for ( let b = 0; b < bevelSegments; b ++ ) { |
|
|
|
//for ( b = bevelSegments; b > 0; b -- ) { |
|
|
|
const t = b / bevelSegments; |
|
const z = bevelThickness * Math.cos( t * Math.PI / 2 ); |
|
const bs = bevelSize * Math.sin( t * Math.PI / 2 ) + bevelOffset; |
|
|
|
// contract shape |
|
|
|
for ( let i = 0, il = contour.length; i < il; i ++ ) { |
|
|
|
const vert = scalePt2( contour[ i ], contourMovements[ i ], bs ); |
|
|
|
v( vert.x, vert.y, - z ); |
|
|
|
} |
|
|
|
// expand holes |
|
|
|
for ( let h = 0, hl = holes.length; h < hl; h ++ ) { |
|
|
|
const ahole = holes[ h ]; |
|
oneHoleMovements = holesMovements[ h ]; |
|
|
|
for ( let i = 0, il = ahole.length; i < il; i ++ ) { |
|
|
|
const vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs ); |
|
|
|
v( vert.x, vert.y, - z ); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
const bs = bevelSize + bevelOffset; |
|
|
|
// Back facing vertices |
|
|
|
for ( let i = 0; i < vlen; i ++ ) { |
|
|
|
const vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ]; |
|
|
|
if ( ! extrudeByPath ) { |
|
|
|
v( vert.x, vert.y, 0 ); |
|
|
|
} else { |
|
|
|
// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x ); |
|
|
|
normal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x ); |
|
binormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y ); |
|
|
|
position2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal ); |
|
|
|
v( position2.x, position2.y, position2.z ); |
|
|
|
} |
|
|
|
} |
|
|
|
// Add stepped vertices... |
|
// Including front facing vertices |
|
|
|
for ( let s = 1; s <= steps; s ++ ) { |
|
|
|
for ( let i = 0; i < vlen; i ++ ) { |
|
|
|
const vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ]; |
|
|
|
if ( ! extrudeByPath ) { |
|
|
|
v( vert.x, vert.y, depth / steps * s ); |
|
|
|
} else { |
|
|
|
// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x ); |
|
|
|
normal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x ); |
|
binormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y ); |
|
|
|
position2.copy( extrudePts[ s ] ).add( normal ).add( binormal ); |
|
|
|
v( position2.x, position2.y, position2.z ); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
// Add bevel segments planes |
|
|
|
//for ( b = 1; b <= bevelSegments; b ++ ) { |
|
for ( let b = bevelSegments - 1; b >= 0; b -- ) { |
|
|
|
const t = b / bevelSegments; |
|
const z = bevelThickness * Math.cos( t * Math.PI / 2 ); |
|
const bs = bevelSize * Math.sin( t * Math.PI / 2 ) + bevelOffset; |
|
|
|
// contract shape |
|
|
|
for ( let i = 0, il = contour.length; i < il; i ++ ) { |
|
|
|
const vert = scalePt2( contour[ i ], contourMovements[ i ], bs ); |
|
v( vert.x, vert.y, depth + z ); |
|
|
|
} |
|
|
|
// expand holes |
|
|
|
for ( let h = 0, hl = holes.length; h < hl; h ++ ) { |
|
|
|
const ahole = holes[ h ]; |
|
oneHoleMovements = holesMovements[ h ]; |
|
|
|
for ( let i = 0, il = ahole.length; i < il; i ++ ) { |
|
|
|
const vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs ); |
|
|
|
if ( ! extrudeByPath ) { |
|
|
|
v( vert.x, vert.y, depth + z ); |
|
|
|
} else { |
|
|
|
v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z ); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
/* Faces */ |
|
|
|
// Top and bottom faces |
|
|
|
buildLidFaces(); |
|
|
|
// Sides faces |
|
|
|
buildSideFaces(); |
|
|
|
|
|
///// Internal functions |
|
|
|
function buildLidFaces() { |
|
|
|
const start = verticesArray.length / 3; |
|
|
|
if ( bevelEnabled ) { |
|
|
|
let layer = 0; // steps + 1 |
|
let offset = vlen * layer; |
|
|
|
// Bottom faces |
|
|
|
for ( let i = 0; i < flen; i ++ ) { |
|
|
|
const face = faces[ i ]; |
|
f3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset ); |
|
|
|
} |
|
|
|
layer = steps + bevelSegments * 2; |
|
offset = vlen * layer; |
|
|
|
// Top faces |
|
|
|
for ( let i = 0; i < flen; i ++ ) { |
|
|
|
const face = faces[ i ]; |
|
f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset ); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// Bottom faces |
|
|
|
for ( let i = 0; i < flen; i ++ ) { |
|
|
|
const face = faces[ i ]; |
|
f3( face[ 2 ], face[ 1 ], face[ 0 ] ); |
|
|
|
} |
|
|
|
// Top faces |
|
|
|
for ( let i = 0; i < flen; i ++ ) { |
|
|
|
const face = faces[ i ]; |
|
f3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps ); |
|
|
|
} |
|
|
|
} |
|
|
|
scope.addGroup( start, verticesArray.length / 3 - start, 0 ); |
|
|
|
} |
|
|
|
// Create faces for the z-sides of the shape |
|
|
|
function buildSideFaces() { |
|
|
|
const start = verticesArray.length / 3; |
|
let layeroffset = 0; |
|
sidewalls( contour, layeroffset ); |
|
layeroffset += contour.length; |
|
|
|
for ( let h = 0, hl = holes.length; h < hl; h ++ ) { |
|
|
|
const ahole = holes[ h ]; |
|
sidewalls( ahole, layeroffset ); |
|
|
|
//, true |
|
layeroffset += ahole.length; |
|
|
|
} |
|
|
|
|
|
scope.addGroup( start, verticesArray.length / 3 - start, 1 ); |
|
|
|
|
|
} |
|
|
|
function sidewalls( contour, layeroffset ) { |
|
|
|
let i = contour.length; |
|
|
|
while ( -- i >= 0 ) { |
|
|
|
const j = i; |
|
let k = i - 1; |
|
if ( k < 0 ) k = contour.length - 1; |
|
|
|
//console.log('b', i,j, i-1, k,vertices.length); |
|
|
|
for ( let s = 0, sl = ( steps + bevelSegments * 2 ); s < sl; s ++ ) { |
|
|
|
const slen1 = vlen * s; |
|
const slen2 = vlen * ( s + 1 ); |
|
|
|
const a = layeroffset + j + slen1, |
|
b = layeroffset + k + slen1, |
|
c = layeroffset + k + slen2, |
|
d = layeroffset + j + slen2; |
|
|
|
f4( a, b, c, d ); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
function v( x, y, z ) { |
|
|
|
placeholder.push( x ); |
|
placeholder.push( y ); |
|
placeholder.push( z ); |
|
|
|
} |
|
|
|
|
|
function f3( a, b, c ) { |
|
|
|
addVertex( a ); |
|
addVertex( b ); |
|
addVertex( c ); |
|
|
|
const nextIndex = verticesArray.length / 3; |
|
const uvs = uvgen.generateTopUV( scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1 ); |
|
|
|
addUV( uvs[ 0 ] ); |
|
addUV( uvs[ 1 ] ); |
|
addUV( uvs[ 2 ] ); |
|
|
|
} |
|
|
|
function f4( a, b, c, d ) { |
|
|
|
addVertex( a ); |
|
addVertex( b ); |
|
addVertex( d ); |
|
|
|
addVertex( b ); |
|
addVertex( c ); |
|
addVertex( d ); |
|
|
|
|
|
const nextIndex = verticesArray.length / 3; |
|
const uvs = uvgen.generateSideWallUV( scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1 ); |
|
|
|
addUV( uvs[ 0 ] ); |
|
addUV( uvs[ 1 ] ); |
|
addUV( uvs[ 3 ] ); |
|
|
|
addUV( uvs[ 1 ] ); |
|
addUV( uvs[ 2 ] ); |
|
addUV( uvs[ 3 ] ); |
|
|
|
} |
|
|
|
function addVertex( index ) { |
|
|
|
verticesArray.push( placeholder[ index * 3 + 0 ] ); |
|
verticesArray.push( placeholder[ index * 3 + 1 ] ); |
|
verticesArray.push( placeholder[ index * 3 + 2 ] ); |
|
|
|
} |
|
|
|
|
|
function addUV( vector2 ) { |
|
|
|
uvArray.push( vector2.x ); |
|
uvArray.push( vector2.y ); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
toJSON() { |
|
|
|
const data = super.toJSON(); |
|
|
|
const shapes = this.parameters.shapes; |
|
const options = this.parameters.options; |
|
|
|
return toJSON( shapes, options, data ); |
|
|
|
} |
|
|
|
static fromJSON( data, shapes ) { |
|
|
|
const geometryShapes = []; |
|
|
|
for ( let j = 0, jl = data.shapes.length; j < jl; j ++ ) { |
|
|
|
const shape = shapes[ data.shapes[ j ] ]; |
|
|
|
geometryShapes.push( shape ); |
|
|
|
} |
|
|
|
const extrudePath = data.options.extrudePath; |
|
|
|
if ( extrudePath !== undefined ) { |
|
|
|
data.options.extrudePath = new Curves[ extrudePath.type ]().fromJSON( extrudePath ); |
|
|
|
} |
|
|
|
return new ExtrudeGeometry( geometryShapes, data.options ); |
|
|
|
} |
|
|
|
} |
|
|
|
const WorldUVGenerator = { |
|
|
|
generateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) { |
|
|
|
const a_x = vertices[ indexA * 3 ]; |
|
const a_y = vertices[ indexA * 3 + 1 ]; |
|
const b_x = vertices[ indexB * 3 ]; |
|
const b_y = vertices[ indexB * 3 + 1 ]; |
|
const c_x = vertices[ indexC * 3 ]; |
|
const c_y = vertices[ indexC * 3 + 1 ]; |
|
|
|
return [ |
|
new Vector2( a_x, a_y ), |
|
new Vector2( b_x, b_y ), |
|
new Vector2( c_x, c_y ) |
|
]; |
|
|
|
}, |
|
|
|
generateSideWallUV: function ( geometry, vertices, indexA, indexB, indexC, indexD ) { |
|
|
|
const a_x = vertices[ indexA * 3 ]; |
|
const a_y = vertices[ indexA * 3 + 1 ]; |
|
const a_z = vertices[ indexA * 3 + 2 ]; |
|
const b_x = vertices[ indexB * 3 ]; |
|
const b_y = vertices[ indexB * 3 + 1 ]; |
|
const b_z = vertices[ indexB * 3 + 2 ]; |
|
const c_x = vertices[ indexC * 3 ]; |
|
const c_y = vertices[ indexC * 3 + 1 ]; |
|
const c_z = vertices[ indexC * 3 + 2 ]; |
|
const d_x = vertices[ indexD * 3 ]; |
|
const d_y = vertices[ indexD * 3 + 1 ]; |
|
const d_z = vertices[ indexD * 3 + 2 ]; |
|
|
|
if ( Math.abs( a_y - b_y ) < Math.abs( a_x - b_x ) ) { |
|
|
|
return [ |
|
new Vector2( a_x, 1 - a_z ), |
|
new Vector2( b_x, 1 - b_z ), |
|
new Vector2( c_x, 1 - c_z ), |
|
new Vector2( d_x, 1 - d_z ) |
|
]; |
|
|
|
} else { |
|
|
|
return [ |
|
new Vector2( a_y, 1 - a_z ), |
|
new Vector2( b_y, 1 - b_z ), |
|
new Vector2( c_y, 1 - c_z ), |
|
new Vector2( d_y, 1 - d_z ) |
|
]; |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
function toJSON( shapes, options, data ) { |
|
|
|
data.shapes = []; |
|
|
|
if ( Array.isArray( shapes ) ) { |
|
|
|
for ( let i = 0, l = shapes.length; i < l; i ++ ) { |
|
|
|
const shape = shapes[ i ]; |
|
|
|
data.shapes.push( shape.uuid ); |
|
|
|
} |
|
|
|
} else { |
|
|
|
data.shapes.push( shapes.uuid ); |
|
|
|
} |
|
|
|
if ( options.extrudePath !== undefined ) data.options.extrudePath = options.extrudePath.toJSON(); |
|
|
|
return data; |
|
|
|
} |
|
|
|
|
|
export { ExtrudeGeometry, ExtrudeGeometry as ExtrudeBufferGeometry };
|
|
|