diff --git a/src/flower.js b/src/flower.js new file mode 100644 index 0000000..044738d --- /dev/null +++ b/src/flower.js @@ -0,0 +1,387 @@ + +import * as THREE from 'three'; + +import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; +import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + +import Stats from 'three/addons/libs/stats.module.js'; + +import './css/styles.scss'; + +const scene = new THREE.Scene(); +scene.background = new THREE.Color(0xf44f04); + + +const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 500 ); +camera.position.z = 12; +camera.position.x = 10; +camera.position.y = 4; + + +const renderer = new THREE.WebGLRenderer(); +renderer.setSize( window.innerWidth, window.innerHeight ); +renderer.shadowMap.enabled = true; +renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap +renderer.shadowMap.enabled = true; +renderer.shadowMap.type = THREE.PCFSoftShadowMap; +renderer.gammaFactor = 2.2; +renderer.outputEncoding = THREE.sRGBEncoding; +renderer.toneMapping = THREE.ACESFilmicToneMapping; +renderer.toneMappingExposure = 1; +renderer.physicallyCorrectLights +document.body.appendChild( renderer.domElement ); + +const controls = new OrbitControls( camera, renderer.domElement ); +controls.target.set( -4, 0, 0 ); + + +// const geometry_torus = new THREE.TorusGeometry( 2.5, 2.5, 32, 128 ); +// const material_torus = new THREE.MeshBasicMaterial( { color: 0x049ef4, wireframe: true, wireframeLinewidth: 1} ); +// const torus = new THREE.Mesh( geometry_torus, material_torus ); +// torus.rotation.x = Math.PI / 2; +// torus.castShadow = true; +// scene.add( torus ); + +// const icoGeometry = new THREE.IcosahedronGeometry( 5 ); +// const icoMaterial= new THREE.MeshBasicMaterial( {color: 0x049ef4, wireframe: true, wireframeLinewidth: 8 } ); +// const iso = new THREE.Mesh( icoGeometry, icoMaterial ); +// iso.castShadow = true; +// scene.add( iso ); + +// --------- Mekaraba ---------- // +// const tetraGeometry = new THREE.TetrahedronGeometry( 2 ); +// const tetraMaterial = new THREE.MeshBasicMaterial( {color: 0xffff00 } ); +// const tetra = new THREE.Mesh( tetraGeometry, tetraMaterial ); +// // tetra.position.y = - 0.81 + +// // tetra.rotation.x = Math.PI / 4 ; +// tetra.rotation.z = Math.PI / 6 ; +// // scene.add( tetra ); + +// const tetraEdges = new THREE.EdgesGeometry( tetraGeometry ); +// const tetraEdgesLine = new THREE.LineSegments( tetraEdges, new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 3 } ) ); +// // tetraEdgesLine.position.y = -0.81 + +// tetraEdgesLine.rotation.x = Math.PI / 4; +// // tetraEdgesLine.rotation.y = Math.PI ; +// // tetraEdgesLine.rotation.y = Math.PI / 6; + +// tetraEdgesLine.castShadow = true; +// scene.add( tetraEdgesLine ); + +// const tetraGeometry2 = new THREE.TetrahedronGeometry( 2 ); +// const tetraMaterial2 = new THREE.MeshBasicMaterial( {color: 0xffff00 } ); +// const tetra2 = new THREE.Mesh( tetraGeometry2, tetraMaterial2 ); +// tetra2.position.y = 0.81 +// tetra2.rotation.x = Math.PI / 4 ; +// // tetra2.rotation.y = Math.PI / 4 ; +// tetra2.rotation.z = Math.PI / 4 ; +// // scene.add( tetra2 ); + +// const tetraEdges2 = new THREE.EdgesGeometry( tetraGeometry2 ); +// const tetraEdgesLine2 = new THREE.LineSegments( tetraEdges2, new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 3 } ) ); +// tetraEdgesLine2.castShadow = true; +// tetraEdgesLine2.position.y = 0.81 +// tetraEdgesLine2.rotation.x = Math.PI / 4 ; +// // tetraEdgesLine2.rotation.y = Math.PI / 4 ; +// tetraEdgesLine2.rotation.z = Math.PI / 4 ; +// scene.add( tetraEdgesLine2 ); + + +// ---------- David ------------ // +// const tetraGeometry = new THREE.ConeGeometry( 2, 3, 3 ); +// const tetraMaterial = new THREE.MeshBasicMaterial( {color: 0xffff00 } ); +// const tetra = new THREE.Mesh( tetraGeometry, tetraMaterial ); +// tetra.rotation.y = Math.PI / 6 ; +// tetra.position.y = 1 / 2 +// scene.add( tetra ); + +// const tetraEdges = new THREE.EdgesGeometry( tetraGeometry ); +// const tetraEdgesLine = new THREE.LineSegments( tetraEdges, new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 15 } ) ); +// tetraEdgesLine.rotation.y = Math.PI / 6 ; +// tetraEdgesLine.position.y = 1 / 2 +// tetraEdgesLine.castShadow = true; +// scene.add( tetraEdgesLine ); + +// const tetraGeometry2 = new THREE.ConeGeometry( 2, 3, 3 ); +// const tetraMaterial2 = new THREE.MeshBasicMaterial( {color: 0xffff00 } ); +// const tetra2 = new THREE.Mesh( tetraGeometry2, tetraMaterial2 ); +// tetra2.rotation.y = Math.PI + Math.PI / 6 ; +// tetra2.rotation.z = Math.PI; +// tetra2.position.y = - 1 / 2 +// scene.add( tetra2 ); + +// const tetraEdges2 = new THREE.EdgesGeometry( tetraGeometry2 ); +// const tetraEdgesLine2 = new THREE.LineSegments( tetraEdges2, new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 15 } ) ); +// tetraEdgesLine2.castShadow = true; +// tetraEdgesLine2.rotation.y = Math.PI + Math.PI / 6 ; +// tetraEdgesLine2.rotation.z = Math.PI; +// tetraEdgesLine2.position.y = - 1 / 2 +// scene.add( tetraEdgesLine2 ); + +// ---------- Flower of life ------------ // + +// const circleGeometry = new THREE.CircleGeometry( 3, 64 ); +// const circleMaterial = new THREE.MeshBasicMaterial( { color: 0x049ef4, side: THREE.DoubleSide } ); +// const circle = new THREE.Mesh( circleGeometry, circleMaterial ); +// circle.castShadow = true; +// scene.add( circle ); + +// const circleLine = new THREE.LineSegments( circleGeometry, new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 3 } ) ); +// circleLine.castShadow = true; +// scene.add( circleLine ); + +let rotatePoint2D = (cx, cy, angle, px, py) => { + angle = - angle * (Math.PI / 180) + let s = Math.sin(angle); + let c = Math.cos(angle); + + // translate point back to origin: + px -= cx; + py -= cy; + + // rotatePoint3D point + let xnew = px * c + py * s; + let ynew = px * s - py * c; + + // translate point back: + px = xnew + cx; + py = ynew + cy; + return [px, py]; +} + +function rotatePoint3D(px, py, pz, pitch, roll, yaw) { + pitch = - pitch * (Math.PI / 180) + roll = - roll * (Math.PI / 180) + yaw = - yaw * (Math.PI / 180) + + var cosa = Math.cos(yaw); + var sina = Math.sin(yaw); + + var cosb = Math.cos(pitch); + var sinb = Math.sin(pitch); + + var cosc = Math.cos(roll); + var sinc = Math.sin(roll); + + var Axx = cosa*cosb; + var Axy = cosa*sinb*sinc - sina*cosc; + var Axz = cosa*sinb*cosc + sina*sinc; + + var Ayx = sina*cosb; + var Ayy = sina*sinb*sinc + cosa*cosc; + var Ayz = sina*sinb*cosc - cosa*sinc; + + var Azx = -sinb; + var Azy = cosb*sinc; + var Azz = cosb*cosc; + + let x = Axx*px + Axy*py + Axz*pz; + let y = Ayx*px + Ayy*py + Ayz*pz; + let z = Azx*px + Azy*py + Azz*pz; + + return [x, y, z] +} + +const params = { + xangle: 45, + yangle: 0, + zangle: 54.72972973, + size: 3, + radius: 1 +}; + +let sphere, circleCircum; +let spheres = []; +let spheresLines = []; + +let renderFlower = (size = 3, radius = 1) => { + spheres = []; + spheresLines = []; + + for (let x of Array.from(Array(size), (_, i) => i * 0.612 * (radius * 2))) { + x = x - ((size - 1) * (0.612 * (radius * 2))) / 2 + for (let y of Array.from(Array(size), (_, i) => i * 0.612 * (radius * 2))) { + y = y - ((size - 1) * (0.612 * (radius * 2))) / 2 + for (let z of Array.from(Array(size), (_, i) => i * 0.612 * (radius * 2))) { + z = z - ((size - 1) * (0.612 * (radius * 2))) / 2 + + let xtemp2, ytemp2, ztemp2; + + // [xtemp, ytemp, ztemp] = rotatePoint3D(x, y, z, 0, 45, 0) + + // console.log(xtemp, ytemp, ztemp); + + [xtemp2, ytemp2, ztemp2] = rotatePoint3D(x, y, z, params['yangle'], params['xangle'], params['zangle']) + + let sphereGeometry = new THREE.SphereGeometry( radius, 64, 64 ); + let sphereMaterial = new THREE.MeshStandardMaterial( { + color: 0x0063e4, + metalness: 0.7, + roughness: 0.3, + opacity: 0.8, + transparent: true + } ); + sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); + sphere.position.x = xtemp2; + sphere.position.y = ytemp2; + sphere.position.z = ztemp2; + scene.add( sphere ); + + let circleGeometry = new THREE.TorusGeometry( radius, 0.02, 64, 64 ); + let circleMaterial = new THREE.MeshBasicMaterial( { + color: 0x000000, + opacity: 0.1, + transparent: true + } ); + circleCircum = new THREE.Mesh( circleGeometry, circleMaterial ); + circleCircum.castShadow = true; + circleCircum.rotation.y = Math.PI / 2; + circleCircum.position.x = xtemp2; + circleCircum.position.y = ytemp2; + circleCircum.position.z = ztemp2; + scene.add( circleCircum ); + + sphere.start_x = x; + sphere.start_y = y; + sphere.start_z = z; + circleCircum.start_x = x; + circleCircum.start_y = y; + circleCircum.start_z = z; + + spheres.push(sphere) + spheresLines.push(circleCircum) + } + } + } + + // Big circle + let circleGeometry = new THREE.TorusGeometry( 5 * radius, 0.02, 64, 64); + let circleMaterial = new THREE.MeshBasicMaterial( { + color: 0x000000, + opacity: 0, + transparent: true + } ); + circleCircum = new THREE.Mesh( circleGeometry, circleMaterial ); + circleCircum.rotation.y = Math.PI / 2; + circleCircum.castShadow = true; + scene.add( circleCircum ); + + + const gui = new GUI(); + gui.add( params, 'xangle', 0, 360 ).step(0.1).onChange( (value) => { + for (let sphere of spheres) { + [sphere.position.x, sphere.position.y, sphere.position.z] = rotatePoint3D(sphere.start_x, sphere.start_y, sphere.start_z, params['yangle'], value, params['zangle']) + } + + for (let sphereLine of spheresLines) { + [sphereLine.position.x, sphereLine.position.y, sphereLine.position.z] = rotatePoint3D(sphereLine.start_x, sphereLine.start_y, sphereLine.start_z, params['yangle'], value, params['zangle']) + } + }); + gui.add( params, 'yangle', 0, 360 ).step(0.1).onChange( (value) => { + for (let sphere of spheres) { + [sphere.position.x, sphere.position.y, sphere.position.z] = rotatePoint3D(sphere.start_x, sphere.start_y, sphere.start_z, value, params['xangle'], params['zangle']) + } + + for (let sphereLine of spheresLines) { + [sphereLine.position.x, sphereLine.position.y, sphereLine.position.z] = rotatePoint3D(sphereLine.start_x, sphereLine.start_y, sphereLine.start_z, value, params['xangle'], params['zangle']) + } + }); + gui.add( params, 'zangle', 0, 360 ).step(0.1).onChange( (value) => { + for (let sphere of spheres) { + [sphere.position.x, sphere.position.y, sphere.position.z] = rotatePoint3D(sphere.start_x, sphere.start_y, sphere.start_z, params['yangle'], params['xangle'], value) + } + + for (let sphereLine of spheresLines) { + [sphereLine.position.x, sphereLine.position.y, sphereLine.position.z] = rotatePoint3D(sphereLine.start_x, sphereLine.start_y, sphereLine.start_z, params['yangle'], params['xangle'], value) + } + }); + gui.add( params, 'size', 2, 5).step(1).onChange( (value) => { + for (let sphere of spheres) { + scene.remove(sphere) + } + for (let sphereLine of spheresLines) { + scene.remove(sphereLine) + } + scene.remove(circleCircum) + renderFlower (value, params['radius']) + }); + gui.add( params, 'radius', 0.5, 3).onChange( (value) => { + for (let sphere of spheres) { + scene.remove(sphere) + } + for (let sphereLine of spheresLines) { + scene.remove(sphereLine) + } + scene.remove(circleCircum) + renderFlower (params['size'], value) + }); + gui.close(); +} + +renderFlower() + +// const spotLight = new THREE.SpotLight( 0xffffff ); +const spotLight = new THREE.DirectionalLight( 0xeaa7a7, 1.5); +spotLight.position.set( 10, 0, 0 ); +spotLight.castShadow = true; +// spotLight.shadow.mapSize.width = 8182; +// spotLight.shadow.mapSize.height = 8182; +spotLight.shadow.mapSize.width = 4096; +spotLight.shadow.mapSize.height = 4096; +spotLight.shadow.camera.far = 21; +spotLight.shadow.camera.left = -10; +spotLight.shadow.camera.right = 10; +spotLight.shadow.camera.top = 10; +spotLight.shadow.camera.bottom = -10; + +// spotLight.shadow.camera.fov = 35; +scene.add( spotLight ); + +//Create a plane that receives shadows (but does not cast them) +const planeGeometry = new THREE.PlaneGeometry( 20, 20, 10, 10 ); +const planeMaterial = new THREE.MeshStandardMaterial( { color: 0xffffff } ) +const plane = new THREE.Mesh( planeGeometry, planeMaterial ); +planeMaterial.side = THREE.DoubleSide; +plane.rotation.y = Math.PI / 2; +plane.position.x = -10 +plane.receiveShadow = true; +scene.add( plane ); + +//Create a helper for the shadow camera (optional) +const helper = new THREE.CameraHelper( spotLight.shadow.camera ); +// scene.add( helper ); + +const axesHelper = new THREE.AxesHelper( 40 ); +scene.add( axesHelper ); + +// const light = new THREE.HemisphereLight( 0xffffbb, 0x080820, 0.2 ); +// scene.add( light ); + +let stats = new Stats(); +document.body.appendChild( stats.dom ); + +// var axis = new THREE.Vector3(0, 1, 0); + +function animate () { + requestAnimationFrame( animate ); + + const time = performance.now() / 1000; + + // for (let sphere of spheres) { + // sphere.position.x = Math.cos( time ) * sphere.start_x; + // sphere.position.z = - Math.sin( time ) * sphere.start_z; + // } + + // for (let sphereLine of spheresLines) { + // sphereLine.position.x = Math.cos( time ) * sphereLine.start_x; + // sphereLine.position.z = - Math.sin( time ) * sphereLine.start_z; + // } + + controls.update(); + stats.update(); + + renderer.render( scene, camera ); +}; + +animate(); \ No newline at end of file diff --git a/src/index.js b/src/index.js index 8720b44..031aeca 100644 --- a/src/index.js +++ b/src/index.js @@ -11,18 +11,14 @@ import './css/styles.scss'; const scene = new THREE.Scene(); scene.background = new THREE.Color(0xf44f04); - const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 500 ); camera.position.z = 12; camera.position.x = 10; camera.position.y = 4; - const renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); renderer.shadowMap.enabled = true; -renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap -renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; renderer.gammaFactor = 2.2; renderer.outputEncoding = THREE.sRGBEncoding; @@ -121,17 +117,8 @@ controls.target.set( -4, 0, 0 ); // ---------- Flower of life ------------ // -// const circleGeometry = new THREE.CircleGeometry( 3, 64 ); -// const circleMaterial = new THREE.MeshBasicMaterial( { color: 0x049ef4, side: THREE.DoubleSide } ); -// const circle = new THREE.Mesh( circleGeometry, circleMaterial ); -// circle.castShadow = true; -// scene.add( circle ); -// const circleLine = new THREE.LineSegments( circleGeometry, new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 3 } ) ); -// circleLine.castShadow = true; -// scene.add( circleLine ); - -let rotatePoint = (cx, cy, angle, px, py) => { +let rotatePoint2D = (cx, cy, angle, px, py) => { angle = - angle * (Math.PI / 180) let s = Math.sin(angle); let c = Math.cos(angle); @@ -140,7 +127,7 @@ let rotatePoint = (cx, cy, angle, px, py) => { px -= cx; py -= cy; - // rotate point + // rotatePoint3D point let xnew = px * c + py * s; let ynew = px * s - py * c; @@ -150,7 +137,7 @@ let rotatePoint = (cx, cy, angle, px, py) => { return [px, py]; } -function rotate(px, py, pz, pitch, roll, yaw) { +function rotatePoint3D(px, py, pz, pitch, roll, yaw) { pitch = - pitch * (Math.PI / 180) roll = - roll * (Math.PI / 180) yaw = - yaw * (Math.PI / 180) @@ -183,40 +170,87 @@ function rotate(px, py, pz, pitch, roll, yaw) { return [x, y, z] } - const params = { xangle: 45, yangle: 0, zangle: 54.72972973, - size: 3, - radius: 1 + size: 5, + radius: 1, }; -let sphere, circleCircum; +// const params = { +// xangle: 0, +// yangle: 0, +// zangle: 0, +// size: 5, +// radius: 1 +// }; + +let sphere, circleCircum, cube, cubeLines; let spheres = []; let spheresLines = []; -let renderFlower = (size = 3, radius = 1) => { - let z_count = 0 +let renderFlower = (size = 5, radius = 1) => { spheres = []; spheresLines = []; + let x_count, y_count, z_count; + x_count = 1; for (let x of Array.from(Array(size), (_, i) => i * 0.612 * (radius * 2))) { + y_count = 1; x = x - ((size - 1) * (0.612 * (radius * 2))) / 2 + + for (let y of Array.from(Array(size), (_, i) => i * 0.612 * (radius * 2))) { + z_count = 1; y = y - ((size - 1) * (0.612 * (radius * 2))) / 2 + + for (let z of Array.from(Array(size), (_, i) => i * 0.612 * (radius * 2))) { z = z - ((size - 1) * (0.612 * (radius * 2))) / 2 - - + + + if (x_count % 2 == 0 || y_count % 2 == 0 || z_count % 2 == 0) { + z_count++; + continue; + } + + + if (x_count % 5 == 0 && y_count % 3 == 0 ) { + z_count++; + continue; + } + + if (x_count % 5 == 0 && z_count % 3 == 0 ) { + z_count++; + continue; + } + + + if (y_count % 5 == 0 && x_count % 3 == 0 ) { + z_count++; + continue; + } + + if (y_count % 5 == 0 && z_count % 3 == 0 ) { + z_count++; + continue; + } + + if (z_count % 5 == 0 && x_count % 3 == 0 ) { + z_count++; + continue; + } + + if (z_count % 5 == 0 && y_count % 3 == 0 ) { + z_count++; + continue; + } + + let xtemp, ytemp, ztemp; - let xtemp2, ytemp2, ztemp2; - // [xtemp, ytemp, ztemp] = rotate(x, y, z, 0, 45, 0) - - // console.log(xtemp, ytemp, ztemp); - - [xtemp2, ytemp2, ztemp2] = rotate(x, y, z, params['yangle'], params['xangle'], params['zangle']) + [xtemp, ytemp, ztemp] = rotatePoint3D(x, y, z, params['yangle'], params['xangle'], params['zangle']) let sphereGeometry = new THREE.SphereGeometry( radius, 64, 64 ); let sphereMaterial = new THREE.MeshStandardMaterial( { @@ -227,12 +261,12 @@ let renderFlower = (size = 3, radius = 1) => { transparent: true } ); sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); - sphere.position.x = xtemp2; - sphere.position.y = ytemp2; - sphere.position.z = ztemp2; + sphere.position.x = xtemp; + sphere.position.y = ytemp; + sphere.position.z = ztemp; scene.add( sphere ); - let circleGeometry = new THREE.TorusGeometry( radius, 0.02, 64, 64 ); + let circleGeometry = new THREE.TorusGeometry( radius, 0.03, 64, 64 ); let circleMaterial = new THREE.MeshBasicMaterial( { color: 0x000000, opacity: 0.1, @@ -241,9 +275,23 @@ let renderFlower = (size = 3, radius = 1) => { circleCircum = new THREE.Mesh( circleGeometry, circleMaterial ); circleCircum.castShadow = true; circleCircum.rotation.y = Math.PI / 2; - circleCircum.position.x = xtemp2; - circleCircum.position.y = ytemp2; - circleCircum.position.z = ztemp2; + circleCircum.position.x = xtemp; + circleCircum.position.y = ytemp; + circleCircum.position.z = ztemp; + scene.add( circleCircum ); + + circleGeometry = new THREE.TorusGeometry( 0.01, 0.01, 64, 64 ); + circleMaterial = new THREE.MeshBasicMaterial( { + color: 0x000000, + opacity: 0.1, + transparent: true + } ); + circleCircum = new THREE.Mesh( circleGeometry, circleMaterial ); + circleCircum.castShadow = true; + circleCircum.rotation.y = Math.PI / 2; + circleCircum.position.x = xtemp; + circleCircum.position.y = ytemp; + circleCircum.position.z = ztemp; scene.add( circleCircum ); sphere.start_x = x; @@ -255,11 +303,147 @@ let renderFlower = (size = 3, radius = 1) => { spheres.push(sphere) spheresLines.push(circleCircum) + + z_count++; } - z_count += 1; + y_count++; } + x_count++; } + + // earth + const boxGeometry = new THREE.BoxGeometry( 5 * radius, 5 * radius, 5 * radius ); + const boxMaterial = new THREE.MeshStandardMaterial( { + color: 0x994f28, + metalness: 0.7, + roughness: 0.3, + opacity: 0.8, + transparent: true, + // wireframe: true, + } ); + cube = new THREE.Mesh( boxGeometry, boxMaterial ); + cube.rotation.x = 30 * (Math.PI / 180) + cube.rotation.y = 144.75 * (Math.PI / 180) + cube.rotation.z = 45 * (Math.PI / 180) + + let cubeEdges = new THREE.EdgesGeometry( boxGeometry ); + cubeLines = new THREE.LineSegments( cubeEdges, new THREE.LineBasicMaterial( { color: 0x1b0a02, linewidth: 50000 } ) ); + cubeLines.rotation.x = 30 * (Math.PI / 180) + cubeLines.rotation.y = 144.8 * (Math.PI / 180) + cubeLines.rotation.z = 45 * (Math.PI / 180) + cubeLines.castShadow = true; + + scene.add( cubeLines ); + scene.add( cube ); + + // fire + const tetraGeometry = new THREE.TetrahedronGeometry( (5 - 2 / 3) * radius ) + const tetraMaterial = new THREE.MeshStandardMaterial( { + color: 0xdb1212, + metalness: 0.7, + roughness: 0.3, + opacity: 0.8, + transparent: true + } ); + let tetra = new THREE.Mesh( tetraGeometry, tetraMaterial ); + + let tetraEdges = new THREE.EdgesGeometry( tetraGeometry ); + let tetraLines = new THREE.LineSegments( tetraEdges, new THREE.LineBasicMaterial( { color: 0x140101, linewidth: 50000 } ) ); + + + + tetraLines.rotation.x = 90 * (Math.PI / 180) + tetraLines.rotation.y = 35.26530612 * (Math.PI / 180) + tetraLines.rotation.z = 45 * (Math.PI / 180) + + tetra.rotation.x = 90 * (Math.PI / 180) + tetra.rotation.y = 35.26530612 * (Math.PI / 180) + tetra.rotation.z = 45 * (Math.PI / 180) + tetraLines.castShadow = true; + + scene.add( tetraLines ); + scene.add( tetra ); + + const octaGeometry = new THREE.OctahedronGeometry( 5 * radius ) + const octaMaterial = new THREE.MeshStandardMaterial( { + color: 0x9dedf6, + metalness: 0.7, + roughness: 0.3, + opacity: 0.8, + transparent: true + } ); + let octa = new THREE.Mesh( octaGeometry, octaMaterial ); + + let octaEdges = new THREE.EdgesGeometry( octaGeometry ); + let octaLines = new THREE.LineSegments( octaEdges, new THREE.LineBasicMaterial( { color: 0x0a2528, linewidth: 50000 } ) ); + + octaLines.rotation.x = 90 * (Math.PI / 180) + octaLines.rotation.y = 35.26530612 * (Math.PI / 180) + octaLines.rotation.z = 45 * (Math.PI / 180) + + octa.rotation.x = 90 * (Math.PI / 180) + octa.rotation.y = 35.26530612 * (Math.PI / 180) + octa.rotation.z = 45 * (Math.PI / 180) + octaLines.castShadow = true; + + scene.add( octaLines ); + scene.add( octa ); + + const icosaGeometry = new THREE.IcosahedronGeometry( (3 + 1 / 3 + 0.028) * radius ) + const icosaMaterial = new THREE.MeshStandardMaterial( { + color: 0x0063e4, + metalness: 0.7, + roughness: 0.3, + opacity: 0.8, + transparent: true + } ); + let icosa = new THREE.Mesh( icosaGeometry, icosaMaterial ); + + let icosaEdges = new THREE.EdgesGeometry( icosaGeometry ); + let icosaLines = new THREE.LineSegments( icosaEdges, new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 50000 } ) ); + + icosaLines.rotation.x = 30 * (Math.PI / 180) + icosaLines.rotation.y = 159.1 * (Math.PI / 180) + icosaLines.rotation.z = 90 * (Math.PI / 180) + + icosa.rotation.x = 30 * (Math.PI / 180) + icosa.rotation.y = 159.1 * (Math.PI / 180) + icosa.rotation.z = 90 * (Math.PI / 180) + icosaLines.castShadow = true; + + scene.add( icosaLines ); + scene.add( icosa ); + + icosa.visible = false; + icosaLines.visible = false; + + const dodecaGeometry = new THREE.DodecahedronGeometry( (2 + 1 / 3 + 0.005) * radius ) + const dodecaMaterial = new THREE.MeshStandardMaterial( { + color: 0x0063e4, + metalness: 0.7, + roughness: 0.3, + opacity: 0.8, + transparent: true + } ); + let dodeca = new THREE.Mesh( dodecaGeometry, dodecaMaterial ); + + let dodecaEdges = new THREE.EdgesGeometry( dodecaGeometry ); + let dodecaLines = new THREE.LineSegments( dodecaEdges, new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 50000 } ) ); + + dodecaLines.rotation.x = 90 * (Math.PI / 180) + dodecaLines.rotation.y = 111 * (Math.PI / 180) + dodecaLines.rotation.z = 90 * (Math.PI / 180) + + dodeca.rotation.x = 90 * (Math.PI / 180) + dodeca.rotation.y = 111 * (Math.PI / 180) + dodeca.rotation.z = 90 * (Math.PI / 180) + dodecaLines.castShadow = true; + + scene.add( dodecaLines ); + scene.add( dodeca ); + + // Big circle let circleGeometry = new THREE.TorusGeometry( 5 * radius, 0.02, 64, 64); let circleMaterial = new THREE.MeshBasicMaterial( { @@ -271,175 +455,186 @@ let renderFlower = (size = 3, radius = 1) => { circleCircum.rotation.y = Math.PI / 2; circleCircum.castShadow = true; scene.add( circleCircum ); + + + const gui = new GUI(); + + let guiDict = {}; + + let fire = gui.addFolder('Fire'); + guiDict['fire'] = {'folder': fire, 'object': tetra, 'objectLines': tetraLines}; + + let air = gui.addFolder('Air'); + guiDict['air'] = {'folder': air, 'object': octa, 'objectLines': octaLines}; + + let earth = gui.addFolder('Earth'); + guiDict['earth'] = {'folder': earth, 'object': cube, 'objectLines': cubeLines}; + + let water = gui.addFolder('Water'); + guiDict['water'] = {'folder': water, 'object': icosa, 'objectLines': icosaLines}; + + let aether = gui.addFolder('Aether') + guiDict['aether'] = {'folder': aether, 'object': dodeca, 'objectLines': dodecaLines}; + + let circles = gui.addFolder('Circles') + guiDict['circles'] = {'folder': circles}; + + let folderStandard = { + show: true, + fill: true, + frame: true, + xAngle: 45, + yAngle: 0, + zAngle: 54.72972973, + size: 5, + radius: 1, + scale: 1, + } + + circles.add( folderStandard, 'show', true).onChange((value) => { + if (value) { + for (let sphere of spheres) { + sphere.visible = true; + } + for (let sphereLine of spheresLines) { + sphereLine.visible = true; + } + } else { + for (let sphere of spheres) { + sphere.visible = false; + } + for (let sphereLine of spheresLines) { + sphereLine.visible = false; + } + } + }); + + for (let fld of Object.keys(guiDict)) { + // guiDict[fld]['folder'].close() + if (fld === "circles") { + continue + } + if (fld === "water") { + folderStandard.show = false; + } else { + folderStandard.show = true; + } + + folderStandard.xAngle = guiDict[fld]['object'].rotation.x / (Math.PI / 180); + folderStandard.yAngle = guiDict[fld]['object'].rotation.y / (Math.PI / 180); + folderStandard.zAngle = guiDict[fld]['object'].rotation.z / (Math.PI / 180); + + guiDict[fld]['folder'].add( folderStandard, 'scale', 0, 2 ).step(0.001).onChange( (value) => { + guiDict[fld]['object'].scale.x = value + guiDict[fld]['object'].scale.y = value + guiDict[fld]['object'].scale.z = value + guiDict[fld]['objectLines'].scale.x = value + guiDict[fld]['objectLines'].scale.y = value + guiDict[fld]['objectLines'].scale.z = value + }); + + guiDict[fld]['folder'].add( folderStandard, 'show', true).onChange((value) => { + if (value) { + guiDict[fld]['object'].visible = true; + guiDict[fld]['objectLines'].visible = true; + } else { + guiDict[fld]['object'].visible = false; + guiDict[fld]['objectLines'].visible = false; + } + }); + guiDict[fld]['folder'].add( folderStandard, 'fill', true).onChange((value) => { + if (value) { + guiDict[fld]['object'].visible = true; + } else { + guiDict[fld]['object'].visible = false; + } + }); + guiDict[fld]['folder'].add( folderStandard, 'frame', true).onChange((value) => { + if (value) { + guiDict[fld]['objectLines'].visible = true; + } else { + guiDict[fld]['objectLines'].visible = false; + } + }); + + guiDict[fld]['folder'].add( folderStandard, 'xAngle', 0, 360 ).step(0.1).onChange( (value) => { + guiDict[fld]['object'].rotation.x = value * (Math.PI / 180) + guiDict[fld]['objectLines'].rotation.x = value * (Math.PI / 180) + }); + + guiDict[fld]['folder'].add( folderStandard, 'yAngle', 0, 360 ).step(0.1).onChange( (value) => { + guiDict[fld]['object'].rotation.y = value * (Math.PI / 180) + guiDict[fld]['objectLines'].rotation.y = value * (Math.PI / 180) + }); + guiDict[fld]['folder'].add( folderStandard, 'zAngle', 0, 360 ).step(0.1).onChange( (value) => { + guiDict[fld]['object'].rotation.z = value * (Math.PI / 180) + guiDict[fld]['objectLines'].rotation.z = value * (Math.PI / 180) + }); + } + + circles.add( params, 'xangle', 0, 360 ).step(0.1).onChange( (value) => { + for (let sphere of spheres) { + [sphere.position.x, sphere.position.y, sphere.position.z] = rotatePoint3D(sphere.start_x, sphere.start_y, sphere.start_z, params['yangle'], value, params['zangle']) + } + for (let sphereLine of spheresLines) { + [sphereLine.position.x, sphereLine.position.y, sphereLine.position.z] = rotatePoint3D(sphereLine.start_x, sphereLine.start_y, sphereLine.start_z, params['yangle'], value, params['zangle']) + } + + }); + circles.add( params, 'yangle', 0, 360 ).step(0.1).onChange( (value) => { + for (let sphere of spheres) { + [sphere.position.x, sphere.position.y, sphere.position.z] = rotatePoint3D(sphere.start_x, sphere.start_y, sphere.start_z, value, params['xangle'], params['zangle']) + } + for (let sphereLine of spheresLines) { + [sphereLine.position.x, sphereLine.position.y, sphereLine.position.z] = rotatePoint3D(sphereLine.start_x, sphereLine.start_y, sphereLine.start_z, value, params['xangle'], params['zangle']) + } + }); + circles.add( params, 'zangle', 0, 360 ).step(0.1).onChange( (value) => { + for (let sphere of spheres) { + [sphere.position.x, sphere.position.y, sphere.position.z] = rotatePoint3D(sphere.start_x, sphere.start_y, sphere.start_z, params['yangle'], params['xangle'], value) + } + for (let sphereLine of spheresLines) { + [sphereLine.position.x, sphereLine.position.y, sphereLine.position.z] = rotatePoint3D(sphereLine.start_x, sphereLine.start_y, sphereLine.start_z, params['yangle'], params['xangle'], value) + } + }); + gui.add( params, 'size', 2, 5).step(1).onChange( (value) => { + for (let sphere of spheres) { + scene.remove(sphere) + } + for (let sphereLine of spheresLines) { + scene.remove(sphereLine) + } + scene.remove(cube) + scene.remove(cubeLines) + scene.remove(circleCircum) + renderFlower (value, params['radius']) + }); + gui.add( params, 'radius', 0.5, 1.5).onChange( (value) => { + for (let sphere of spheres) { + scene.remove(sphere) + } + for (let sphereLine of spheresLines) { + scene.remove(sphereLine) + } + scene.remove(cube) + scene.remove(cubeLines) + scene.remove(circleCircum) + renderFlower (params['size'], value) + }); + + gui.close(); } renderFlower() -// z_count = 0 -// for (let z_angle of Array.from(Array(6), (_, i) => 360 / 6 * i)) { -// for (let i of Array.from(Array(4), (_, i) => i * 0.5)) { -// let x, y, z; - -// z = rotatePoint(0, 0, z_angle, i, 0)[1] -// y = rotatePoint(0, 0, z_angle, i, 0)[0] -// x = 0; - -// // [x, y ,z] = rotate(x, y, z, x_angle, 0, 0) - -// console.log(z_angle, x, y, z) - -// let sphereGeometry = new THREE.SphereGeometry( 0.5, 64, 64 ); -// let sphereMaterial = new THREE.MeshBasicMaterial( { -// color: 0x0063e4, -// metalness: 1, -// roughness: 1, -// opacity: 0.5, -// transparent: true -// } ); -// sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); -// sphere.position.x = x; -// sphere.position.y = y; -// sphere.position.z = z; -// scene.add( sphere ); - -// let circleGeometry = new THREE.TorusGeometry( 0.5, 0.02, 64, 64 ); -// let circleMaterial = new THREE.MeshBasicMaterial( { -// color: 0x000000, -// opacity: 0.1, -// transparent: true -// } ); -// circleCircum = new THREE.Mesh( circleGeometry, circleMaterial ); -// circleCircum.castShadow = true; -// circleCircum.rotation.y = Math.PI / 2; -// circleCircum.position.x = x; -// circleCircum.position.y = y; -// circleCircum.position.z = z; -// scene.add( circleCircum ); - -// sphere.start_x = x; -// sphere.start_z = z; -// circleCircum.start_x = x; -// circleCircum.start_z = z; - -// spheres.push(sphere) -// spheresLines.push(circleCircum) -// } -// z_count += 1; -// } - -// z_count = 0 -// for (let z_angle of Array.from(Array(13), (_, i) => 360 / 12 * i)) { -// for (let i of Array.from(Array(3), (_, i) => i * 0.87)) { -// let x, y, z; - -// if (i === 0 || z_count % 2 === 0) { -// continue; -// } -// z = rotatePoint(0, 0, z_angle, i, 0)[1] -// y = rotatePoint(0, 0, z_angle, i, 0)[0] -// x = 0; - -// // [x, y ,z] = rotate(x, y, z, x_angle, 0, 0) - -// console.log(z_angle, x, y, z) - -// let sphereGeometry = new THREE.SphereGeometry( 0.5, 64, 64 ); -// let sphereMaterial = new THREE.MeshBasicMaterial( { -// color: 0x0063e4, -// metalness: 1, -// roughness: 1, -// opacity: 0.5, -// transparent: true -// } ); -// sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); -// sphere.position.x = x; -// sphere.position.y = y; -// sphere.position.z = z; -// scene.add( sphere ); - -// let circleGeometry = new THREE.TorusGeometry( 0.5, 0.02, 16, 40 ); -// let circleMaterial = new THREE.MeshBasicMaterial( { -// color: 0x000000, -// opacity: 0.1, -// transparent: true -// } ); -// circleCircum = new THREE.Mesh( circleGeometry, circleMaterial ); -// circleCircum.castShadow = true; -// circleCircum.rotation.y = Math.PI / 2; -// circleCircum.position.x = x; -// circleCircum.position.y = y; -// circleCircum.position.z = z; -// scene.add( circleCircum ); - -// sphere.start_x = x; -// sphere.start_z = z; -// circleCircum.start_x = x; -// circleCircum.start_z = z; - -// spheres.push(sphere) -// spheresLines.push(circleCircum) -// } -// z_count += 1; -// } - -// ---------- Seed of Life ------------ // - -// for (let x_angle of Array.from(Array(4), (_, i) => 360 / 4 * i)) { -// for (let z_angle of Array.from(Array(6), (_, i) => 360 / 6 * i)) { -// for (let i of Array.from(Array(2), (_, i) => i* 0.5)) { -// if (z_count > 0 && i === 0) { -// continue; -// } -// let x, y, z; - -// z = rotatePoint(0, 0, z_angle, i, 0)[1] -// y = rotatePoint(0, 0, z_angle, i, 0)[0] -// x = 0; - -// [x, y ,z] = rotate(x, y, z, 0, x_angle, 0) - -// console.log(x_angle, z_angle, x, y, z) - -// let sphereGeometry = new THREE.SphereGeometry( 0.5, 64, 64 ); -// let sphereMaterial = new THREE.MeshBasicMaterial( { -// color: 0x0063e4, -// metalness: 1, -// roughness: 1, -// opacity: 0.5, -// transparent: true -// } ); -// let sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); -// sphere.position.x = x; -// sphere.position.y = y; -// sphere.position.z = z; -// scene.add( sphere ); - -// let circleGeometry = new THREE.TorusGeometry( 0.5, 0.01, 64, 64); -// let circleMaterial = new THREE.MeshBasicMaterial( { -// color: 0x000000, -// opacity: 0.1, -// transparent: true -// } ); -// let circleCircum = new THREE.Mesh( circleGeometry, circleMaterial ); -// circleCircum.castShadow = true; -// circleCircum.rotation.y = Math.PI / 2; -// circleCircum.position.x = x; -// circleCircum.position.y = y; -// circleCircum.position.z = z; -// scene.add( circleCircum ); -// } -// z_count += 1; -// } -// } - // const spotLight = new THREE.SpotLight( 0xffffff ); const spotLight = new THREE.DirectionalLight( 0xeaa7a7, 1.5); spotLight.position.set( 10, 0, 0 ); spotLight.castShadow = true; -// spotLight.shadow.mapSize.width = 8182; -// spotLight.shadow.mapSize.height = 8182; -spotLight.shadow.mapSize.width = 4096; -spotLight.shadow.mapSize.height = 4096; +spotLight.shadow.mapSize.width = 8182; +spotLight.shadow.mapSize.height = 8182; +// spotLight.shadow.mapSize.width = 4096; +// spotLight.shadow.mapSize.height = 4096; spotLight.shadow.camera.far = 21; spotLight.shadow.camera.left = -10; spotLight.shadow.camera.right = 10; @@ -461,65 +656,11 @@ scene.add( plane ); //Create a helper for the shadow camera (optional) const helper = new THREE.CameraHelper( spotLight.shadow.camera ); -// scene.add( helper ); +scene.add( helper ); const axesHelper = new THREE.AxesHelper( 40 ); scene.add( axesHelper ); -// const light = new THREE.HemisphereLight( 0xffffbb, 0x080820, 0.2 ); -// scene.add( light ); - -const gui = new GUI(); - -gui.add( params, 'xangle', 0, 360 ).step(0.1).onChange( (value) => { - for (let sphere of spheres) { - [sphere.position.x, sphere.position.y, sphere.position.z] = rotate(sphere.start_x, sphere.start_y, sphere.start_z, params['yangle'], value, params['zangle']) - } - - for (let sphereLine of spheresLines) { - [sphereLine.position.x, sphereLine.position.y, sphereLine.position.z] = rotate(sphereLine.start_x, sphereLine.start_y, sphereLine.start_z, params['yangle'], value, params['zangle']) - } -}); -gui.add( params, 'yangle', 0, 360 ).step(0.1).onChange( (value) => { - for (let sphere of spheres) { - [sphere.position.x, sphere.position.y, sphere.position.z] = rotate(sphere.start_x, sphere.start_y, sphere.start_z, value, params['xangle'], params['zangle']) - } - - for (let sphereLine of spheresLines) { - [sphereLine.position.x, sphereLine.position.y, sphereLine.position.z] = rotate(sphereLine.start_x, sphereLine.start_y, sphereLine.start_z, value, params['xangle'], params['zangle']) - } -}); -gui.add( params, 'zangle', 0, 360 ).step(0.1).onChange( (value) => { - for (let sphere of spheres) { - [sphere.position.x, sphere.position.y, sphere.position.z] = rotate(sphere.start_x, sphere.start_y, sphere.start_z, params['yangle'], params['xangle'], value) - } - - for (let sphereLine of spheresLines) { - [sphereLine.position.x, sphereLine.position.y, sphereLine.position.z] = rotate(sphereLine.start_x, sphereLine.start_y, sphereLine.start_z, params['yangle'], params['xangle'], value) - } -}); -gui.add( params, 'size', 2, 5).step(1).onChange( (value) => { - for (let sphere of spheres) { - scene.remove(sphere) - } - for (let sphereLine of spheresLines) { - scene.remove(sphereLine) - } - scene.remove(circleCircum) - renderFlower (value, params['radius']) -}); -gui.add( params, 'radius', 0.5, 3).onChange( (value) => { - for (let sphere of spheres) { - scene.remove(sphere) - } - for (let sphereLine of spheresLines) { - scene.remove(sphereLine) - } - scene.remove(circleCircum) - renderFlower (params['size'], value) -}); -gui.close(); - let stats = new Stats(); document.body.appendChild( stats.dom ); diff --git a/src/seed.js b/src/seed.js new file mode 100644 index 0000000..a8843f3 --- /dev/null +++ b/src/seed.js @@ -0,0 +1,439 @@ + +import * as THREE from 'three'; + +import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; +import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + +import Stats from 'three/addons/libs/stats.module.js'; + +import './css/styles.scss'; + +const scene = new THREE.Scene(); +scene.background = new THREE.Color(0xf44f04); + + +const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 500 ); +camera.position.z = 12; +camera.position.x = 10; +camera.position.y = 4; + + +const renderer = new THREE.WebGLRenderer(); +renderer.setSize( window.innerWidth, window.innerHeight ); +renderer.shadowMap.enabled = true; +renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap +renderer.shadowMap.enabled = true; +renderer.shadowMap.type = THREE.PCFSoftShadowMap; +renderer.gammaFactor = 2.2; +renderer.outputEncoding = THREE.sRGBEncoding; +renderer.toneMapping = THREE.ACESFilmicToneMapping; +renderer.toneMappingExposure = 1; +renderer.physicallyCorrectLights +document.body.appendChild( renderer.domElement ); + +const controls = new OrbitControls( camera, renderer.domElement ); +controls.target.set( -4, 0, 0 ); + + +// const geometry_torus = new THREE.TorusGeometry( 2.5, 2.5, 32, 128 ); +// const material_torus = new THREE.MeshBasicMaterial( { color: 0x049ef4, wireframe: true, wireframeLinewidth: 1} ); +// const torus = new THREE.Mesh( geometry_torus, material_torus ); +// torus.rotation.x = Math.PI / 2; +// torus.castShadow = true; +// scene.add( torus ); + +// const icoGeometry = new THREE.IcosahedronGeometry( 5 ); +// const icoMaterial= new THREE.MeshBasicMaterial( {color: 0x049ef4, wireframe: true, wireframeLinewidth: 8 } ); +// const iso = new THREE.Mesh( icoGeometry, icoMaterial ); +// iso.castShadow = true; +// scene.add( iso ); + +// --------- Mekaraba ---------- // +// const tetraGeometry = new THREE.TetrahedronGeometry( 2 ); +// const tetraMaterial = new THREE.MeshBasicMaterial( {color: 0xffff00 } ); +// const tetra = new THREE.Mesh( tetraGeometry, tetraMaterial ); +// // tetra.position.y = - 0.81 + +// // tetra.rotation.x = Math.PI / 4 ; +// tetra.rotation.z = Math.PI / 6 ; +// // scene.add( tetra ); + +// const tetraEdges = new THREE.EdgesGeometry( tetraGeometry ); +// const tetraEdgesLine = new THREE.LineSegments( tetraEdges, new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 3 } ) ); +// // tetraEdgesLine.position.y = -0.81 + +// tetraEdgesLine.rotation.x = Math.PI / 4; +// // tetraEdgesLine.rotation.y = Math.PI ; +// // tetraEdgesLine.rotation.y = Math.PI / 6; + +// tetraEdgesLine.castShadow = true; +// scene.add( tetraEdgesLine ); + +// const tetraGeometry2 = new THREE.TetrahedronGeometry( 2 ); +// const tetraMaterial2 = new THREE.MeshBasicMaterial( {color: 0xffff00 } ); +// const tetra2 = new THREE.Mesh( tetraGeometry2, tetraMaterial2 ); +// tetra2.position.y = 0.81 +// tetra2.rotation.x = Math.PI / 4 ; +// // tetra2.rotation.y = Math.PI / 4 ; +// tetra2.rotation.z = Math.PI / 4 ; +// // scene.add( tetra2 ); + +// const tetraEdges2 = new THREE.EdgesGeometry( tetraGeometry2 ); +// const tetraEdgesLine2 = new THREE.LineSegments( tetraEdges2, new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 3 } ) ); +// tetraEdgesLine2.castShadow = true; +// tetraEdgesLine2.position.y = 0.81 +// tetraEdgesLine2.rotation.x = Math.PI / 4 ; +// // tetraEdgesLine2.rotation.y = Math.PI / 4 ; +// tetraEdgesLine2.rotation.z = Math.PI / 4 ; +// scene.add( tetraEdgesLine2 ); + + +// ---------- David ------------ // +// const tetraGeometry = new THREE.ConeGeometry( 2, 3, 3 ); +// const tetraMaterial = new THREE.MeshBasicMaterial( {color: 0xffff00 } ); +// const tetra = new THREE.Mesh( tetraGeometry, tetraMaterial ); +// tetra.rotation.y = Math.PI / 6 ; +// tetra.position.y = 1 / 2 +// scene.add( tetra ); + +// const tetraEdges = new THREE.EdgesGeometry( tetraGeometry ); +// const tetraEdgesLine = new THREE.LineSegments( tetraEdges, new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 15 } ) ); +// tetraEdgesLine.rotation.y = Math.PI / 6 ; +// tetraEdgesLine.position.y = 1 / 2 +// tetraEdgesLine.castShadow = true; +// scene.add( tetraEdgesLine ); + +// const tetraGeometry2 = new THREE.ConeGeometry( 2, 3, 3 ); +// const tetraMaterial2 = new THREE.MeshBasicMaterial( {color: 0xffff00 } ); +// const tetra2 = new THREE.Mesh( tetraGeometry2, tetraMaterial2 ); +// tetra2.rotation.y = Math.PI + Math.PI / 6 ; +// tetra2.rotation.z = Math.PI; +// tetra2.position.y = - 1 / 2 +// scene.add( tetra2 ); + +// const tetraEdges2 = new THREE.EdgesGeometry( tetraGeometry2 ); +// const tetraEdgesLine2 = new THREE.LineSegments( tetraEdges2, new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 15 } ) ); +// tetraEdgesLine2.castShadow = true; +// tetraEdgesLine2.rotation.y = Math.PI + Math.PI / 6 ; +// tetraEdgesLine2.rotation.z = Math.PI; +// tetraEdgesLine2.position.y = - 1 / 2 +// scene.add( tetraEdgesLine2 ); + +// ---------- Flower of life ------------ // + +// const circleGeometry = new THREE.CircleGeometry( 3, 64 ); +// const circleMaterial = new THREE.MeshBasicMaterial( { color: 0x049ef4, side: THREE.DoubleSide } ); +// const circle = new THREE.Mesh( circleGeometry, circleMaterial ); +// circle.castShadow = true; +// scene.add( circle ); + +// const circleLine = new THREE.LineSegments( circleGeometry, new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 3 } ) ); +// circleLine.castShadow = true; +// scene.add( circleLine ); + +let rotatePoint = (cx, cy, angle, px, py) => { + angle = - angle * (Math.PI / 180) + let s = Math.sin(angle); + let c = Math.cos(angle); + + // translate point back to origin: + px -= cx; + py -= cy; + + // rotate point + let xnew = px * c + py * s; + let ynew = px * s - py * c; + + // translate point back: + px = xnew + cx; + py = ynew + cy; + return [px, py]; +} + +function rotate(px, py, pz, pitch, roll, yaw) { + pitch = - pitch * (Math.PI / 180) + roll = - roll * (Math.PI / 180) + yaw = - yaw * (Math.PI / 180) + + var cosa = Math.cos(yaw); + var sina = Math.sin(yaw); + + var cosb = Math.cos(pitch); + var sinb = Math.sin(pitch); + + var cosc = Math.cos(roll); + var sinc = Math.sin(roll); + + var Axx = cosa*cosb; + var Axy = cosa*sinb*sinc - sina*cosc; + var Axz = cosa*sinb*cosc + sina*sinc; + + var Ayx = sina*cosb; + var Ayy = sina*sinb*sinc + cosa*cosc; + var Ayz = sina*sinb*cosc - cosa*sinc; + + var Azx = -sinb; + var Azy = cosb*sinc; + var Azz = cosb*cosc; + + let x = Axx*px + Axy*py + Axz*pz; + let y = Ayx*px + Ayy*py + Ayz*pz; + let z = Azx*px + Azy*py + Azz*pz; + + return [x, y, z] +} + + +const params = { + xangle: 45, + yangle: 0, + zangle: 54.72972973, + size: 3, + radius: 1 +}; + +let sphere, circleCircum; +let spheres = []; +let spheresLines = []; + +let renderFlower = (size = 3, radius = 1) => { + spheres = []; + spheresLines = []; + + for (let x of Array.from(Array(size), (_, i) => i * 0.612 * (radius * 2))) { + x = x - ((size - 1) * (0.612 * (radius * 2))) / 2 + for (let y of Array.from(Array(size), (_, i) => i * 0.612 * (radius * 2))) { + y = y - ((size - 1) * (0.612 * (radius * 2))) / 2 + for (let z of Array.from(Array(size), (_, i) => i * 0.612 * (radius * 2))) { + z = z - ((size - 1) * (0.612 * (radius * 2))) / 2 + + let xtemp2, ytemp2, ztemp2; + + // [xtemp, ytemp, ztemp] = rotate(x, y, z, 0, 45, 0) + + // console.log(xtemp, ytemp, ztemp); + + [xtemp2, ytemp2, ztemp2] = rotate(x, y, z, params['yangle'], params['xangle'], params['zangle']) + + let sphereGeometry = new THREE.SphereGeometry( radius, 64, 64 ); + let sphereMaterial = new THREE.MeshStandardMaterial( { + color: 0x0063e4, + metalness: 0.7, + roughness: 0.3, + opacity: 0.8, + transparent: true + } ); + sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); + sphere.position.x = xtemp2; + sphere.position.y = ytemp2; + sphere.position.z = ztemp2; + scene.add( sphere ); + + let circleGeometry = new THREE.TorusGeometry( radius, 0.02, 64, 64 ); + let circleMaterial = new THREE.MeshBasicMaterial( { + color: 0x000000, + opacity: 0.1, + transparent: true + } ); + circleCircum = new THREE.Mesh( circleGeometry, circleMaterial ); + circleCircum.castShadow = true; + circleCircum.rotation.y = Math.PI / 2; + circleCircum.position.x = xtemp2; + circleCircum.position.y = ytemp2; + circleCircum.position.z = ztemp2; + scene.add( circleCircum ); + + sphere.start_x = x; + sphere.start_y = y; + sphere.start_z = z; + circleCircum.start_x = x; + circleCircum.start_y = y; + circleCircum.start_z = z; + + spheres.push(sphere) + spheresLines.push(circleCircum) + } + z_count += 1; + } + } + + // Big circle + let circleGeometry = new THREE.TorusGeometry( 5 * radius, 0.02, 64, 64); + let circleMaterial = new THREE.MeshBasicMaterial( { + color: 0x000000, + opacity: 0, + transparent: true + } ); + circleCircum = new THREE.Mesh( circleGeometry, circleMaterial ); + circleCircum.rotation.y = Math.PI / 2; + circleCircum.castShadow = true; + scene.add( circleCircum ); +} + +// renderFlower() + +// ---------- Seed of Life ------------ // +let z_count = 0 +for (let x_angle of Array.from(Array(4), (_, i) => 360 / 4 * i)) { + for (let z_angle of Array.from(Array(6), (_, i) => 360 / 6 * i)) { + for (let i of Array.from(Array(2), (_, i) => i* 0.5)) { + if (z_count > 0 && i === 0) { + continue; + } + let x, y, z; + + z = rotatePoint(0, 0, z_angle, i, 0)[1] + y = rotatePoint(0, 0, z_angle, i, 0)[0] + x = 0; + + [x, y ,z] = rotate(x, y, z, 0, x_angle, 0) + + console.log(x_angle, z_angle, x, y, z) + + let sphereGeometry = new THREE.SphereGeometry( 0.5, 64, 64 ); + let sphereMaterial = new THREE.MeshBasicMaterial( { + color: 0x0063e4, + metalness: 1, + roughness: 1, + opacity: 0.5, + transparent: true + } ); + let sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); + sphere.position.x = x; + sphere.position.y = y; + sphere.position.z = z; + scene.add( sphere ); + + let circleGeometry = new THREE.TorusGeometry( 0.5, 0.01, 64, 64); + let circleMaterial = new THREE.MeshBasicMaterial( { + color: 0x000000, + opacity: 0.1, + transparent: true + } ); + let circleCircum = new THREE.Mesh( circleGeometry, circleMaterial ); + circleCircum.castShadow = true; + circleCircum.rotation.y = Math.PI / 2; + circleCircum.position.x = x; + circleCircum.position.y = y; + circleCircum.position.z = z; + scene.add( circleCircum ); + } + z_count += 1; + } +} + +// const spotLight = new THREE.SpotLight( 0xffffff ); +const spotLight = new THREE.DirectionalLight( 0xeaa7a7, 1.5); +spotLight.position.set( 10, 0, 0 ); +spotLight.castShadow = true; +// spotLight.shadow.mapSize.width = 8182; +// spotLight.shadow.mapSize.height = 8182; +spotLight.shadow.mapSize.width = 4096; +spotLight.shadow.mapSize.height = 4096; +spotLight.shadow.camera.far = 21; +spotLight.shadow.camera.left = -10; +spotLight.shadow.camera.right = 10; +spotLight.shadow.camera.top = 10; +spotLight.shadow.camera.bottom = -10; + +// spotLight.shadow.camera.fov = 35; +scene.add( spotLight ); + +//Create a plane that receives shadows (but does not cast them) +const planeGeometry = new THREE.PlaneGeometry( 20, 20, 10, 10 ); +const planeMaterial = new THREE.MeshStandardMaterial( { color: 0xffffff } ) +const plane = new THREE.Mesh( planeGeometry, planeMaterial ); +planeMaterial.side = THREE.DoubleSide; +plane.rotation.y = Math.PI / 2; +plane.position.x = -10 +plane.receiveShadow = true; +scene.add( plane ); + +//Create a helper for the shadow camera (optional) +const helper = new THREE.CameraHelper( spotLight.shadow.camera ); +// scene.add( helper ); + +const axesHelper = new THREE.AxesHelper( 40 ); +scene.add( axesHelper ); + +// const light = new THREE.HemisphereLight( 0xffffbb, 0x080820, 0.2 ); +// scene.add( light ); + +// const gui = new GUI(); + +// gui.add( params, 'xangle', 0, 360 ).step(0.1).onChange( (value) => { +// for (let sphere of spheres) { +// [sphere.position.x, sphere.position.y, sphere.position.z] = rotate(sphere.start_x, sphere.start_y, sphere.start_z, params['yangle'], value, params['zangle']) +// } + +// for (let sphereLine of spheresLines) { +// [sphereLine.position.x, sphereLine.position.y, sphereLine.position.z] = rotate(sphereLine.start_x, sphereLine.start_y, sphereLine.start_z, params['yangle'], value, params['zangle']) +// } +// }); +// gui.add( params, 'yangle', 0, 360 ).step(0.1).onChange( (value) => { +// for (let sphere of spheres) { +// [sphere.position.x, sphere.position.y, sphere.position.z] = rotate(sphere.start_x, sphere.start_y, sphere.start_z, value, params['xangle'], params['zangle']) +// } + +// for (let sphereLine of spheresLines) { +// [sphereLine.position.x, sphereLine.position.y, sphereLine.position.z] = rotate(sphereLine.start_x, sphereLine.start_y, sphereLine.start_z, value, params['xangle'], params['zangle']) +// } +// }); +// gui.add( params, 'zangle', 0, 360 ).step(0.1).onChange( (value) => { +// for (let sphere of spheres) { +// [sphere.position.x, sphere.position.y, sphere.position.z] = rotate(sphere.start_x, sphere.start_y, sphere.start_z, params['yangle'], params['xangle'], value) +// } + +// for (let sphereLine of spheresLines) { +// [sphereLine.position.x, sphereLine.position.y, sphereLine.position.z] = rotate(sphereLine.start_x, sphereLine.start_y, sphereLine.start_z, params['yangle'], params['xangle'], value) +// } +// }); +// gui.add( params, 'size', 2, 5).step(1).onChange( (value) => { +// for (let sphere of spheres) { +// scene.remove(sphere) +// } +// for (let sphereLine of spheresLines) { +// scene.remove(sphereLine) +// } +// scene.remove(circleCircum) +// renderFlower (value, params['radius']) +// }); +// gui.add( params, 'radius', 0.5, 3).onChange( (value) => { +// for (let sphere of spheres) { +// scene.remove(sphere) +// } +// for (let sphereLine of spheresLines) { +// scene.remove(sphereLine) +// } +// scene.remove(circleCircum) +// renderFlower (params['size'], value) +// }); +// gui.close(); + +let stats = new Stats(); +document.body.appendChild( stats.dom ); + +// var axis = new THREE.Vector3(0, 1, 0); + +function animate () { + requestAnimationFrame( animate ); + + const time = performance.now() / 1000; + + // for (let sphere of spheres) { + // sphere.position.x = Math.cos( time ) * sphere.start_x; + // sphere.position.z = - Math.sin( time ) * sphere.start_z; + // } + + // for (let sphereLine of spheresLines) { + // sphereLine.position.x = Math.cos( time ) * sphereLine.start_x; + // sphereLine.position.z = - Math.sin( time ) * sphereLine.start_z; + // } + + controls.update(); + stats.update(); + + renderer.render( scene, camera ); +}; + +animate(); \ No newline at end of file