Guest User

Untitled

a guest
May 10th, 2024
232
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <script setup>
  2.  
  3.   import { ref, onMounted, onUnmounted, render } from 'vue'
  4.   const parent = ref()
  5.  
  6.   import * as THREE from 'three'
  7.   import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js'
  8.  
  9.  
  10.   onMounted(() => {
  11.  
  12.     const pobj   = parent.value,
  13.           prect  = pobj.getBoundingClientRect(),
  14.           width  = prect.width,
  15.           height = prect.height,
  16.           //radians = Math.PI/180,
  17.  
  18.           offset = new THREE.Vector3( 0, 0, 0 ),
  19.  
  20.           renderer = new THREE.WebGLRenderer(),
  21.           scene    = new THREE.Scene(),
  22.           camera   = new THREE.PerspectiveCamera( // Alternate camera: Orthographic
  23.             45,                   // fov —    field of view
  24.             width / height,       // aspect — aspect ratio
  25.             0.1,                  // near —   near plane
  26.             1000                  // far —    far plane
  27.           ),
  28.           orbit = new OrbitControls(camera, renderer.domElement),
  29.           dispose = []
  30.    
  31.     renderer.setSize(width, height)
  32.     renderer.setClearColor( 0x444444 )
  33.    
  34.     // Items we must call dispose() on in order to free up memory
  35.     dispose.push( renderer, orbit )
  36.  
  37.     const radius = 5, // Radius of points from center
  38.  
  39.           multi  = radius / 5, // Adjustment for changes in Radius (5 being the original)
  40.  
  41.           //pcolor = [0x00FF00, 0x0000FF, 0xFF0000, 0xFFFFFF],
  42.           pcolor = [0xFFFF00, 0x00FFFF, 0xFF00FF, 0xFFA500],
  43.           //psize  = [0.4,      0.3,      0.26,     0.26],
  44.           psize  = [0.06,     0.06,     0.06,     0.06],
  45.           //psize  = [0.4,      0.4,      0.4,      0.4],
  46.  
  47.           pOct = 1, // "Octahedral" Points (6 total, but forms 8 sides)
  48.           pBox = 2, // "Box Mode" Points
  49.           pOut = 3, // Outer Points (not sure what to call them yet)
  50.           pMid = 4, // Middle Point
  51.  
  52.           points = {
  53.             FTL: [  35,   45,  pOut], // Front Top Left
  54.             FTC: [  45,   0,   pBox], // Front Top
  55.             FTR: [  35,  -45,  pOut], // Front Top Right
  56.             FL:  [  0,    45,  pBox], // Front Left
  57.             FC:  [  0,    0,   pOct], // Front
  58.             FR:  [  0,   -45,  pBox], // Front Right
  59.             FBL: [ -35,   45,  pOut], // Front Bottom Left
  60.             FBC: [ -45,   0,   pBox], // Front Bottom Center
  61.             FBR: [ -35,  -45,  pOut], // Front Bottom Right
  62.             // Middle 9 Points
  63.             MTL: [  45,   90,  pBox], // Middle Top Left
  64.             MTC: [  90,    0,  pOct], // Middle Top
  65.             MTR: [  45,  -90,  pBox], // Middle Top Right
  66.             ML:  [  0,    90,  pOct], // Middle Left
  67.             MC:  [  'C', 'C',  pMid], // Middle
  68.             MR:  [  0,   -90,  pOct], // Middle Right
  69.             MBL: [ -45,   90,  pBox], // Middle Bottom Left
  70.             MBC: [ -90,   0,   pOct], // Middle Bottom
  71.             MBR: [ -45,  -90,  pBox], // Middle Bottom Right
  72.             // Back 9 Points
  73.             BTL: [ 145,  -45,  pOut], // Back Top Left
  74.             BTC: [ 135,   0,   pBox], // Back Top
  75.             BTR: [ 145,   45,  pOut], // Back Top Right
  76.             BL:  [ 180,  -45,  pBox], // Back Left
  77.             BC:  [ 180,   0,   pOct], // Back
  78.             BR:  [ 180,   45,  pBox], // Back Right
  79.             BBL: [ 215,  -45,  pOut], // Back Bottom Left
  80.             BBC: [ 225,   0,   pBox], // Back Bottom
  81.             BBR: [ 215,   45,  pOut], // Back Bottom Right
  82.           },
  83.  
  84.           pobjs = {},
  85.  
  86.           show = {}
  87.  
  88.     show[pOct] = true
  89.     show[pBox] = true
  90.     show[pOut] = true
  91.     show[pMid] = true
  92.  
  93.     for ( let key in points ) {
  94.       const p = points[key],
  95.             sphere = new THREE.Mesh(
  96.               new THREE.SphereGeometry(psize[p[2]-1] * multi, 20, 20),
  97.               new THREE.MeshBasicMaterial({color: pcolor[p[2]-1], wireframe: false})
  98.             )
  99.       pobjs[key] = sphere
  100.       if ( p[0] == 'C' && p[1] == 'C' ) {
  101.         sphere.position.add(offset)
  102.       } else {
  103.         sphere.position.setFromSphericalCoords(radius, THREE.MathUtils.degToRad(90 - p[0]), THREE.MathUtils.degToRad(p[1])).add(offset)
  104.       }
  105.       if ( show[p[2]] ) {
  106.         scene.add(sphere)
  107.       }
  108.       sphere.lookAt( offset.x, offset.y, offset.z ) // Use the object as a reference for rotation
  109.     }
  110.  
  111.     // Detect clicks and write the item clicked
  112.     // Builds an array and writes a list of them when the center point is clicked
  113.     const raycaster = new THREE.Raycaster()
  114.     const pointer = new THREE.Vector2()
  115.     let ilist = []
  116.     renderer.domElement.addEventListener("click", ( e )=>{
  117.       pointer.x = ( e.clientX / window.innerWidth ) * 2 - 1
  118.         pointer.y = - ( e.clientY / window.innerHeight ) * 2 + 1
  119.       // update the picking ray with the camera and pointer position
  120.       raycaster.setFromCamera( pointer, camera )
  121.       // calculate objects intersecting the picking ray
  122.       const intersects = raycaster.intersectObjects( scene.children )
  123.       toploop: for ( let i = 0; i < intersects.length; i ++ ) {
  124.         let obj = intersects[ i ].object
  125.         for ( let key in pobjs ) {
  126.           if ( pobjs[key].id == obj.id ) {
  127.             if ( key == 'MC' ) {
  128.               console.log( "'" + ilist.join("', '") + "'" )
  129.               ilist = []
  130.             } else {
  131.               ilist.push( key )
  132.             }
  133.             console.log( "CLICKED: '" + key + "'" )
  134.             break toploop
  135.           }
  136.         }
  137.       }      
  138.     })
  139.    
  140.     const guideMat = new THREE.MeshBasicMaterial({color: 0xAAAAAA}),
  141.           guideGeo = new THREE.TorusGeometry(radius, 0.01 * multi, 10, 100),
  142.           norm = new THREE.Vector3(),
  143.           vec0 =  new THREE.Vector3(0, 0, 0),
  144.           matrix = new THREE.Matrix4(),
  145.  
  146.           guides = [
  147.             // Second two are opposite ends of the first, for generating angle of the "guide"
  148.             ['MBC', 'MTL', 'MTR', 'MTC', 'MR', 'MBR', 'MBL', 'ML'],
  149.             ['BC', 'FL', 'FC', 'FR', 'MR', 'BR', 'BL', 'ML'],
  150.             ['MBC', 'BTC', 'FTC', 'MTC', 'FC', 'FBC', 'BBC', 'BC'],
  151.             ['MBC', 'BTL', 'FTR', 'MTC', 'FR', 'FBR', 'BBL', 'BL'],
  152.             ['MBC', 'FTL', 'BTR', 'MTC', 'BR', 'BBR', 'FBL', 'FL'],
  153.             ['BBC', 'FTL', 'FTR', 'FTC', 'MR', 'BBR', 'BBL', 'ML'],
  154.             ['FBC', 'BTR', 'BTL', 'BTC', 'ML', 'FBL', 'FBR', 'MR'],
  155.             ['MBR', 'BTL', 'FTL', 'MTL', 'FC', 'FBR', 'BBR', 'BC'],
  156.             ['MBL', 'FTR', 'BTR', 'MTR', 'BC', 'BBL', 'FBL', 'FC'],
  157.             ['BBC', 'MTL', 'FR', 'FTC', 'MBR', 'BL'],
  158.             ['FBC', 'MTR', 'BL', 'BTC', 'FR', 'MBL'],
  159.             ['MBL', 'FTC', 'BR', 'MTR', 'BBC', 'FL'],
  160.             ['MBR', 'BTC', 'MTL', 'FL', 'FBC', 'BR'],
  161.             ['BTL', 'FL', 'FBR', 'BR'],
  162.             ['FTR', 'BR', 'BBL', 'FL'],
  163.             ['BTR', 'BL', 'FBL', 'FR'],
  164.             ['FTL', 'FR', 'BBR', 'BL'],
  165.             ['FTC', 'FBR', 'BBC', 'BTL'],
  166.             ['MTR', 'BTL', 'MBL', 'FBR'],
  167.             ['BTR', 'BBC', 'FBL', 'FTC'],
  168.             ['MTL', 'FBL', 'MBR', 'BTR'],
  169.             ['FTL', 'FBC', 'BBR', 'BTC'],
  170.             ['FTR', 'BTC', 'BBL', 'FBC'],
  171.             ['MTR', 'BBR', 'MBL', 'FTL'],
  172.             ['MTL', 'FTR', 'MBR', 'BBL'],
  173.           ],
  174.           gobjs = [],
  175.           gref = {}
  176.  
  177.     for ( let i=0; i<guides.length; i++ ) {
  178.       const objs = guides[i],
  179.             guide = new THREE.Mesh( guideGeo, guideMat ),
  180.             triangle = new THREE.Triangle(
  181.               pobjs[objs[0]].position,
  182.               pobjs[objs[1]].position,
  183.               pobjs[objs[2]].position
  184.             )
  185.       triangle.getNormal( norm )
  186.       matrix.lookAt( norm, vec0, vec0)
  187.       const euler = new THREE.Euler().setFromRotationMatrix( matrix )
  188.       guide.position.add( offset )
  189.       guide.rotation.set( euler.x, euler.y, euler.z )
  190.       scene.add(guide)
  191.  
  192.       gobjs.push( guide )
  193.       for ( let j=0; j<objs.length; j++ ) {
  194.         const key = objs[j]
  195.         if ( gref[key] === undefined ) {
  196.           gref[key] = {}
  197.         }
  198.         for ( let k=0; k<objs.length; k++ ) {
  199.           const key2 = objs[k]
  200.           // Skip the same and opposing point
  201.           if ( key == key2 || pobjs[key].position.distanceTo( pobjs[key2].position ) > (radius * 2) * 0.99 ) {
  202.             continue
  203.           }
  204.           if ( gref[key][key2] !== undefined ) {
  205.             console.log( 'OVERWRITE: ', key, objs[k] )
  206.           }
  207.           gref[key][key2] = i
  208.         }
  209.       }
  210.     }
  211.  
  212.     //camera.position.set(-3.6648487120891953 * multi, 9.052174822127743 * multi, -13.214651524241402 * multi) // XYZ
  213.     camera.position.set(0, 0, -13.5) // XYZ
  214.     orbit.update() // Must be called whenever camera position is updated
  215.  
  216.     // --- Stuff to remove later
  217.  
  218.     const axesHelper = new THREE.AxesHelper(radius)
  219.     scene.add(axesHelper)
  220.     dispose.push(axesHelper)
  221.  
  222.     // ---
  223.  
  224.     const torus = new THREE.Mesh(
  225.             new THREE.TorusGeometry( 0.5, 0.1 * multi, 16, 100),
  226.             new THREE.MeshBasicMaterial({color: 0x00FF00}) // Standard (w/ light source, but is dim)
  227.           )
  228.     scene.add( torus )
  229.  
  230.     const pkeys = Object.keys( pobjs )
  231.     // Strip the center point out
  232.     for ( let a=0; a<pkeys.length; a++ ) {
  233.       if ( pkeys[a] == 'MC' ) {
  234.         pkeys.splice( a, 1 )
  235.       }
  236.     }
  237.  
  238.     let ttotal = 1000,
  239.         tstart = -1,
  240.         i=0,
  241.         o1,
  242.         o2 = pkeys[ Math.floor( pkeys.length * Math.random() ) ],
  243.         obj1,
  244.         obj2 = pobjs[o2],
  245.         pnt1,
  246.         pnt2 = points[o2]
  247.  
  248.     let sphericalStart = new THREE.Spherical(),
  249.         sphericalEnd = new THREE.Spherical(radius, THREE.MathUtils.degToRad(90 - pnt2[0]), THREE.MathUtils.degToRad(pnt2[1])),
  250.         vectorStart = new THREE.Vector3(),
  251.         vectorEnd = new THREE.Vector3(),
  252.         angleEnd,
  253.         normal = new THREE.Vector3()
  254.  
  255.     let d1, d2, d3, q = new THREE.Quaternion()
  256.          
  257.  
  258.     const animate = ((time)=>{
  259.       const keys = Object.keys( gref[o2] )
  260.      
  261.       if ( tstart < 0 || time > tstart + ttotal ) {
  262.         tstart = time
  263.         i++
  264.         if ( i == keys.length ) {
  265.           i = 0
  266.         }
  267.         o1 = o2
  268.         o2 = keys[i]
  269.         o2 = keys[ Math.floor(Math.random() * keys.length) ]
  270.         obj1 = obj2
  271.         obj2 = pobjs[o2]
  272.         pnt1 = pnt2
  273.         pnt2 = points[o2]
  274.        
  275.         //console.log( o1, o2 )
  276.  
  277.         // Moves torus to the point
  278.         //torus.position.setFromSphericalCoords(radius, THREE.MathUtils.degToRad(90 - pnt1[0]), THREE.MathUtils.degToRad(pnt1[1])).add(offset)
  279.         //torus.lookAt( offset )
  280.  
  281.         sphericalStart.copy(sphericalEnd)
  282.         sphericalEnd.set(radius,THREE.MathUtils.degToRad(90 - pnt2[0]), THREE.MathUtils.degToRad(pnt2[1]))
  283.         vectorStart.setFromSpherical(sphericalStart)
  284.         vectorEnd.setFromSpherical(sphericalEnd)
  285.         normal.copy(vectorStart).cross(vectorEnd).normalize()
  286.         angleEnd = vectorStart.angleTo(vectorEnd)
  287.       }
  288.  
  289.       //.applyQuaternion ( quaternion : Quaternion )
  290.  
  291.       const perc = (time - tstart) / ttotal
  292.  
  293.       torus.rotation.x = q.x + (d1 * perc)
  294.       torus.rotation.y = q.y + (d2 * perc)
  295.       torus.rotation.z = q.y + (d3 * perc)
  296.      
  297.       // Animates between points
  298.       torus.position.copy(vectorStart).applyAxisAngle(normal, perc * angleEnd)
  299.       torus.lookAt( offset )
  300.  
  301.       renderer.render( scene, camera )
  302.     })
  303.     renderer.setAnimationLoop( animate )
  304.  
  305.     pobj.appendChild( renderer.domElement ) // Appends the Canvas object
  306.  
  307.     onUnmounted(() => {
  308.       while ( dispose.length ) {
  309.         const d = dispose.pop()
  310.         if ( d.dispose ) {
  311.           d.dispose()
  312.         } else {
  313.           console.warn( 'Object does not support .dispose()', dispose.length, d )
  314.         }
  315.       }
  316.     })
  317.   })
  318.  
  319. </script>
  320.  
  321. <template>
  322.   <div ref="parent" class="PathsTest" />
  323. </template>
  324.  
  325. <style scoped>
  326.   .PathsTest {
  327.     width: 100%;
  328.     height: 100vh;
  329.   }
  330. </style>
  331.  
Advertisement
Add Comment
Please, Sign In to add comment