Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <script setup>
- import { ref, onMounted, onUnmounted, render } from 'vue'
- const parent = ref()
- import * as THREE from 'three'
- import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js'
- onMounted(() => {
- const pobj = parent.value,
- prect = pobj.getBoundingClientRect(),
- width = prect.width,
- height = prect.height,
- //radians = Math.PI/180,
- offset = new THREE.Vector3( 0, 0, 0 ),
- renderer = new THREE.WebGLRenderer(),
- scene = new THREE.Scene(),
- camera = new THREE.PerspectiveCamera( // Alternate camera: Orthographic
- 45, // fov — field of view
- width / height, // aspect — aspect ratio
- 0.1, // near — near plane
- 1000 // far — far plane
- ),
- orbit = new OrbitControls(camera, renderer.domElement),
- dispose = []
- renderer.setSize(width, height)
- renderer.setClearColor( 0x444444 )
- // Items we must call dispose() on in order to free up memory
- dispose.push( renderer, orbit )
- const radius = 5, // Radius of points from center
- multi = radius / 5, // Adjustment for changes in Radius (5 being the original)
- //pcolor = [0x00FF00, 0x0000FF, 0xFF0000, 0xFFFFFF],
- pcolor = [0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFA500],
- //psize = [0.4, 0.3, 0.26, 0.26],
- psize = [0.06, 0.06, 0.06, 0.06],
- //psize = [0.4, 0.4, 0.4, 0.4],
- pOct = 1, // "Octahedral" Points (6 total, but forms 8 sides)
- pBox = 2, // "Box Mode" Points
- pOut = 3, // Outer Points (not sure what to call them yet)
- pMid = 4, // Middle Point
- points = {
- FTL: [ 35, 45, pOut], // Front Top Left
- FTC: [ 45, 0, pBox], // Front Top
- FTR: [ 35, -45, pOut], // Front Top Right
- FL: [ 0, 45, pBox], // Front Left
- FC: [ 0, 0, pOct], // Front
- FR: [ 0, -45, pBox], // Front Right
- FBL: [ -35, 45, pOut], // Front Bottom Left
- FBC: [ -45, 0, pBox], // Front Bottom Center
- FBR: [ -35, -45, pOut], // Front Bottom Right
- // Middle 9 Points
- MTL: [ 45, 90, pBox], // Middle Top Left
- MTC: [ 90, 0, pOct], // Middle Top
- MTR: [ 45, -90, pBox], // Middle Top Right
- ML: [ 0, 90, pOct], // Middle Left
- MC: [ 'C', 'C', pMid], // Middle
- MR: [ 0, -90, pOct], // Middle Right
- MBL: [ -45, 90, pBox], // Middle Bottom Left
- MBC: [ -90, 0, pOct], // Middle Bottom
- MBR: [ -45, -90, pBox], // Middle Bottom Right
- // Back 9 Points
- BTL: [ 145, -45, pOut], // Back Top Left
- BTC: [ 135, 0, pBox], // Back Top
- BTR: [ 145, 45, pOut], // Back Top Right
- BL: [ 180, -45, pBox], // Back Left
- BC: [ 180, 0, pOct], // Back
- BR: [ 180, 45, pBox], // Back Right
- BBL: [ 215, -45, pOut], // Back Bottom Left
- BBC: [ 225, 0, pBox], // Back Bottom
- BBR: [ 215, 45, pOut], // Back Bottom Right
- },
- pobjs = {},
- show = {}
- show[pOct] = true
- show[pBox] = true
- show[pOut] = true
- show[pMid] = true
- for ( let key in points ) {
- const p = points[key],
- sphere = new THREE.Mesh(
- new THREE.SphereGeometry(psize[p[2]-1] * multi, 20, 20),
- new THREE.MeshBasicMaterial({color: pcolor[p[2]-1], wireframe: false})
- )
- pobjs[key] = sphere
- if ( p[0] == 'C' && p[1] == 'C' ) {
- sphere.position.add(offset)
- } else {
- sphere.position.setFromSphericalCoords(radius, THREE.MathUtils.degToRad(90 - p[0]), THREE.MathUtils.degToRad(p[1])).add(offset)
- }
- if ( show[p[2]] ) {
- scene.add(sphere)
- }
- sphere.lookAt( offset.x, offset.y, offset.z ) // Use the object as a reference for rotation
- }
- // Detect clicks and write the item clicked
- // Builds an array and writes a list of them when the center point is clicked
- const raycaster = new THREE.Raycaster()
- const pointer = new THREE.Vector2()
- let ilist = []
- renderer.domElement.addEventListener("click", ( e )=>{
- pointer.x = ( e.clientX / window.innerWidth ) * 2 - 1
- pointer.y = - ( e.clientY / window.innerHeight ) * 2 + 1
- // update the picking ray with the camera and pointer position
- raycaster.setFromCamera( pointer, camera )
- // calculate objects intersecting the picking ray
- const intersects = raycaster.intersectObjects( scene.children )
- toploop: for ( let i = 0; i < intersects.length; i ++ ) {
- let obj = intersects[ i ].object
- for ( let key in pobjs ) {
- if ( pobjs[key].id == obj.id ) {
- if ( key == 'MC' ) {
- console.log( "'" + ilist.join("', '") + "'" )
- ilist = []
- } else {
- ilist.push( key )
- }
- console.log( "CLICKED: '" + key + "'" )
- break toploop
- }
- }
- }
- })
- const guideMat = new THREE.MeshBasicMaterial({color: 0xAAAAAA}),
- guideGeo = new THREE.TorusGeometry(radius, 0.01 * multi, 10, 100),
- norm = new THREE.Vector3(),
- vec0 = new THREE.Vector3(0, 0, 0),
- matrix = new THREE.Matrix4(),
- guides = [
- // Second two are opposite ends of the first, for generating angle of the "guide"
- ['MBC', 'MTL', 'MTR', 'MTC', 'MR', 'MBR', 'MBL', 'ML'],
- ['BC', 'FL', 'FC', 'FR', 'MR', 'BR', 'BL', 'ML'],
- ['MBC', 'BTC', 'FTC', 'MTC', 'FC', 'FBC', 'BBC', 'BC'],
- ['MBC', 'BTL', 'FTR', 'MTC', 'FR', 'FBR', 'BBL', 'BL'],
- ['MBC', 'FTL', 'BTR', 'MTC', 'BR', 'BBR', 'FBL', 'FL'],
- ['BBC', 'FTL', 'FTR', 'FTC', 'MR', 'BBR', 'BBL', 'ML'],
- ['FBC', 'BTR', 'BTL', 'BTC', 'ML', 'FBL', 'FBR', 'MR'],
- ['MBR', 'BTL', 'FTL', 'MTL', 'FC', 'FBR', 'BBR', 'BC'],
- ['MBL', 'FTR', 'BTR', 'MTR', 'BC', 'BBL', 'FBL', 'FC'],
- ['BBC', 'MTL', 'FR', 'FTC', 'MBR', 'BL'],
- ['FBC', 'MTR', 'BL', 'BTC', 'FR', 'MBL'],
- ['MBL', 'FTC', 'BR', 'MTR', 'BBC', 'FL'],
- ['MBR', 'BTC', 'MTL', 'FL', 'FBC', 'BR'],
- ['BTL', 'FL', 'FBR', 'BR'],
- ['FTR', 'BR', 'BBL', 'FL'],
- ['BTR', 'BL', 'FBL', 'FR'],
- ['FTL', 'FR', 'BBR', 'BL'],
- ['FTC', 'FBR', 'BBC', 'BTL'],
- ['MTR', 'BTL', 'MBL', 'FBR'],
- ['BTR', 'BBC', 'FBL', 'FTC'],
- ['MTL', 'FBL', 'MBR', 'BTR'],
- ['FTL', 'FBC', 'BBR', 'BTC'],
- ['FTR', 'BTC', 'BBL', 'FBC'],
- ['MTR', 'BBR', 'MBL', 'FTL'],
- ['MTL', 'FTR', 'MBR', 'BBL'],
- ],
- gobjs = [],
- gref = {}
- for ( let i=0; i<guides.length; i++ ) {
- const objs = guides[i],
- guide = new THREE.Mesh( guideGeo, guideMat ),
- triangle = new THREE.Triangle(
- pobjs[objs[0]].position,
- pobjs[objs[1]].position,
- pobjs[objs[2]].position
- )
- triangle.getNormal( norm )
- matrix.lookAt( norm, vec0, vec0)
- const euler = new THREE.Euler().setFromRotationMatrix( matrix )
- guide.position.add( offset )
- guide.rotation.set( euler.x, euler.y, euler.z )
- scene.add(guide)
- gobjs.push( guide )
- for ( let j=0; j<objs.length; j++ ) {
- const key = objs[j]
- if ( gref[key] === undefined ) {
- gref[key] = {}
- }
- for ( let k=0; k<objs.length; k++ ) {
- const key2 = objs[k]
- // Skip the same and opposing point
- if ( key == key2 || pobjs[key].position.distanceTo( pobjs[key2].position ) > (radius * 2) * 0.99 ) {
- continue
- }
- if ( gref[key][key2] !== undefined ) {
- console.log( 'OVERWRITE: ', key, objs[k] )
- }
- gref[key][key2] = i
- }
- }
- }
- //camera.position.set(-3.6648487120891953 * multi, 9.052174822127743 * multi, -13.214651524241402 * multi) // XYZ
- camera.position.set(0, 0, -13.5) // XYZ
- orbit.update() // Must be called whenever camera position is updated
- // --- Stuff to remove later
- const axesHelper = new THREE.AxesHelper(radius)
- scene.add(axesHelper)
- dispose.push(axesHelper)
- // ---
- const torus = new THREE.Mesh(
- new THREE.TorusGeometry( 0.5, 0.1 * multi, 16, 100),
- new THREE.MeshBasicMaterial({color: 0x00FF00}) // Standard (w/ light source, but is dim)
- )
- scene.add( torus )
- const pkeys = Object.keys( pobjs )
- // Strip the center point out
- for ( let a=0; a<pkeys.length; a++ ) {
- if ( pkeys[a] == 'MC' ) {
- pkeys.splice( a, 1 )
- }
- }
- let ttotal = 1000,
- tstart = -1,
- i=0,
- o1,
- o2 = pkeys[ Math.floor( pkeys.length * Math.random() ) ],
- obj1,
- obj2 = pobjs[o2],
- pnt1,
- pnt2 = points[o2]
- let sphericalStart = new THREE.Spherical(),
- sphericalEnd = new THREE.Spherical(radius, THREE.MathUtils.degToRad(90 - pnt2[0]), THREE.MathUtils.degToRad(pnt2[1])),
- vectorStart = new THREE.Vector3(),
- vectorEnd = new THREE.Vector3(),
- angleEnd,
- normal = new THREE.Vector3()
- let d1, d2, d3, q = new THREE.Quaternion()
- const animate = ((time)=>{
- const keys = Object.keys( gref[o2] )
- if ( tstart < 0 || time > tstart + ttotal ) {
- tstart = time
- i++
- if ( i == keys.length ) {
- i = 0
- }
- o1 = o2
- o2 = keys[i]
- o2 = keys[ Math.floor(Math.random() * keys.length) ]
- obj1 = obj2
- obj2 = pobjs[o2]
- pnt1 = pnt2
- pnt2 = points[o2]
- //console.log( o1, o2 )
- // Moves torus to the point
- //torus.position.setFromSphericalCoords(radius, THREE.MathUtils.degToRad(90 - pnt1[0]), THREE.MathUtils.degToRad(pnt1[1])).add(offset)
- //torus.lookAt( offset )
- sphericalStart.copy(sphericalEnd)
- sphericalEnd.set(radius,THREE.MathUtils.degToRad(90 - pnt2[0]), THREE.MathUtils.degToRad(pnt2[1]))
- vectorStart.setFromSpherical(sphericalStart)
- vectorEnd.setFromSpherical(sphericalEnd)
- normal.copy(vectorStart).cross(vectorEnd).normalize()
- angleEnd = vectorStart.angleTo(vectorEnd)
- }
- //.applyQuaternion ( quaternion : Quaternion )
- const perc = (time - tstart) / ttotal
- torus.rotation.x = q.x + (d1 * perc)
- torus.rotation.y = q.y + (d2 * perc)
- torus.rotation.z = q.y + (d3 * perc)
- // Animates between points
- torus.position.copy(vectorStart).applyAxisAngle(normal, perc * angleEnd)
- torus.lookAt( offset )
- renderer.render( scene, camera )
- })
- renderer.setAnimationLoop( animate )
- pobj.appendChild( renderer.domElement ) // Appends the Canvas object
- onUnmounted(() => {
- while ( dispose.length ) {
- const d = dispose.pop()
- if ( d.dispose ) {
- d.dispose()
- } else {
- console.warn( 'Object does not support .dispose()', dispose.length, d )
- }
- }
- })
- })
- </script>
- <template>
- <div ref="parent" class="PathsTest" />
- </template>
- <style scoped>
- .PathsTest {
- width: 100%;
- height: 100vh;
- }
- </style>
Advertisement
Add Comment
Please, Sign In to add comment