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.
179 lines
3.8 KiB
179 lines
3.8 KiB
import { Float32BufferAttribute } from '../core/BufferAttribute.js'; |
|
import { BufferGeometry } from '../core/BufferGeometry.js'; |
|
import { Vector3 } from '../math/Vector3.js'; |
|
import { Vector2 } from '../math/Vector2.js'; |
|
import * as MathUtils from '../math/MathUtils.js'; |
|
|
|
class LatheGeometry extends BufferGeometry { |
|
|
|
constructor( points = [ new Vector2( 0, 0.5 ), new Vector2( 0.5, 0 ), new Vector2( 0, - 0.5 ) ], segments = 12, phiStart = 0, phiLength = Math.PI * 2 ) { |
|
|
|
super(); |
|
|
|
this.type = 'LatheGeometry'; |
|
|
|
this.parameters = { |
|
points: points, |
|
segments: segments, |
|
phiStart: phiStart, |
|
phiLength: phiLength |
|
}; |
|
|
|
segments = Math.floor( segments ); |
|
|
|
// clamp phiLength so it's in range of [ 0, 2PI ] |
|
|
|
phiLength = MathUtils.clamp( phiLength, 0, Math.PI * 2 ); |
|
|
|
// buffers |
|
|
|
const indices = []; |
|
const vertices = []; |
|
const uvs = []; |
|
const initNormals = []; |
|
const normals = []; |
|
|
|
// helper variables |
|
|
|
const inverseSegments = 1.0 / segments; |
|
const vertex = new Vector3(); |
|
const uv = new Vector2(); |
|
const normal = new Vector3(); |
|
const curNormal = new Vector3(); |
|
const prevNormal = new Vector3(); |
|
let dx = 0; |
|
let dy = 0; |
|
|
|
// pre-compute normals for initial "meridian" |
|
|
|
for ( let j = 0; j <= ( points.length - 1 ); j ++ ) { |
|
|
|
switch ( j ) { |
|
|
|
case 0: // special handling for 1st vertex on path |
|
|
|
dx = points[ j + 1 ].x - points[ j ].x; |
|
dy = points[ j + 1 ].y - points[ j ].y; |
|
|
|
normal.x = dy * 1.0; |
|
normal.y = - dx; |
|
normal.z = dy * 0.0; |
|
|
|
prevNormal.copy( normal ); |
|
|
|
normal.normalize(); |
|
|
|
initNormals.push( normal.x, normal.y, normal.z ); |
|
|
|
break; |
|
|
|
case ( points.length - 1 ): // special handling for last Vertex on path |
|
|
|
initNormals.push( prevNormal.x, prevNormal.y, prevNormal.z ); |
|
|
|
break; |
|
|
|
default: // default handling for all vertices in between |
|
|
|
dx = points[ j + 1 ].x - points[ j ].x; |
|
dy = points[ j + 1 ].y - points[ j ].y; |
|
|
|
normal.x = dy * 1.0; |
|
normal.y = - dx; |
|
normal.z = dy * 0.0; |
|
|
|
curNormal.copy( normal ); |
|
|
|
normal.x += prevNormal.x; |
|
normal.y += prevNormal.y; |
|
normal.z += prevNormal.z; |
|
|
|
normal.normalize(); |
|
|
|
initNormals.push( normal.x, normal.y, normal.z ); |
|
|
|
prevNormal.copy( curNormal ); |
|
|
|
} |
|
|
|
} |
|
|
|
// generate vertices, uvs and normals |
|
|
|
for ( let i = 0; i <= segments; i ++ ) { |
|
|
|
const phi = phiStart + i * inverseSegments * phiLength; |
|
|
|
const sin = Math.sin( phi ); |
|
const cos = Math.cos( phi ); |
|
|
|
for ( let j = 0; j <= ( points.length - 1 ); j ++ ) { |
|
|
|
// vertex |
|
|
|
vertex.x = points[ j ].x * sin; |
|
vertex.y = points[ j ].y; |
|
vertex.z = points[ j ].x * cos; |
|
|
|
vertices.push( vertex.x, vertex.y, vertex.z ); |
|
|
|
// uv |
|
|
|
uv.x = i / segments; |
|
uv.y = j / ( points.length - 1 ); |
|
|
|
uvs.push( uv.x, uv.y ); |
|
|
|
// normal |
|
|
|
const x = initNormals[ 3 * j + 0 ] * sin; |
|
const y = initNormals[ 3 * j + 1 ]; |
|
const z = initNormals[ 3 * j + 0 ] * cos; |
|
|
|
normals.push( x, y, z ); |
|
|
|
} |
|
|
|
} |
|
|
|
// indices |
|
|
|
for ( let i = 0; i < segments; i ++ ) { |
|
|
|
for ( let j = 0; j < ( points.length - 1 ); j ++ ) { |
|
|
|
const base = j + i * points.length; |
|
|
|
const a = base; |
|
const b = base + points.length; |
|
const c = base + points.length + 1; |
|
const d = base + 1; |
|
|
|
// faces |
|
|
|
indices.push( a, b, d ); |
|
indices.push( b, c, d ); |
|
|
|
} |
|
|
|
} |
|
|
|
// build geometry |
|
|
|
this.setIndex( indices ); |
|
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); |
|
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); |
|
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); |
|
|
|
} |
|
|
|
static fromJSON( data ) { |
|
|
|
return new LatheGeometry( data.points, data.segments, data.phiStart, data.phiLength ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
export { LatheGeometry, LatheGeometry as LatheBufferGeometry };
|
|
|