270 lines
8.0 KiB
JavaScript
270 lines
8.0 KiB
JavaScript
//xfg:title Arrows
|
|
|
|
import * as THREE from 'three';
|
|
import { VRButton } from 'three/examples/jsm/webxr/VRButton.js';
|
|
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
|
|
import { BoxLineGeometry } from 'three/examples/jsm/geometries/BoxLineGeometry.js';
|
|
|
|
import ThreeMeshUI from 'three-mesh-ui';
|
|
import Arrows from 'three-mesh-ui/examples/utils/Arrows';
|
|
import { Object3D } from 'three';
|
|
|
|
const WIDTH = window.innerWidth;
|
|
const HEIGHT = window.innerHeight;
|
|
|
|
let scene, camera, cameraP, renderer, controls;
|
|
let vrCam;
|
|
|
|
window.addEventListener('load', step1BuildThreeJSElements );
|
|
|
|
/***********************************************************************************************************************
|
|
* THREE-MESH-UI - BASIC SETUP
|
|
* ---------------------------
|
|
*
|
|
* This tutorial is made of 3 steps, split by functions:
|
|
* - step1BuildThreeJSElements()
|
|
* - step2BuildThreeMeshUIElements()
|
|
* - step3AnimationLoop()
|
|
*
|
|
* Be sure to read all of their comments, in the proper order before going for another tutorial.
|
|
**********************************************************************************************************************/
|
|
|
|
|
|
// three-mesh-ui requires working threejs setup
|
|
// We usually build the threejs stuff prior three-mesh-ui
|
|
function step1BuildThreeJSElements() {
|
|
|
|
scene = new THREE.Scene();
|
|
scene.background = new THREE.Color( 0x505050 );
|
|
|
|
cameraP = new THREE.PerspectiveCamera( 60, WIDTH / HEIGHT, 0.1, 100 );
|
|
|
|
camera = new Object3D();
|
|
camera.add( cameraP );
|
|
|
|
|
|
renderer = new THREE.WebGLRenderer( {
|
|
antialias: true
|
|
} );
|
|
renderer.setPixelRatio( window.devicePixelRatio );
|
|
renderer.setSize( WIDTH, HEIGHT );
|
|
renderer.xr.enabled = true;
|
|
document.body.appendChild( VRButton.createButton( renderer ) );
|
|
document.body.appendChild( renderer.domElement );
|
|
|
|
controls = new OrbitControls( cameraP, renderer.domElement );
|
|
camera.position.set( 0, 1.6, 0 );
|
|
controls.target = new THREE.Vector3( 0, 1, -1.8 );
|
|
controls.update();
|
|
|
|
|
|
|
|
renderer.xr.addEventListener('sessionstart', ()=>{
|
|
console.log("SEWSSIONB XR")
|
|
|
|
console.log( renderer.xr );
|
|
console.log( );
|
|
|
|
vrCam = renderer.xr.getCamera(null);
|
|
console.log( vrCam );
|
|
})
|
|
// ROOM
|
|
|
|
const room = new THREE.LineSegments(
|
|
new BoxLineGeometry( 6, 6, 6, 10, 10, 10 ).translate( 0, 3, 0 ),
|
|
new THREE.LineBasicMaterial( { color: 0x808080 } )
|
|
);
|
|
|
|
scene.add( room );
|
|
|
|
|
|
// Now that we have the threejs stuff up and running, we can build our three-mesh-ui stuff
|
|
// Let's read that function
|
|
step2BuildThreeMeshUIElements();
|
|
|
|
// three-mesh-ui requires to be updated prior each threejs render, let's go see what is in step3AnimationLoop()
|
|
renderer.setAnimationLoop( step3AnimationLoop );
|
|
|
|
|
|
window.addEventListener( 'resize', onWindowResize );
|
|
}
|
|
|
|
//
|
|
function step2BuildThreeMeshUIElements() {
|
|
|
|
// If we are going to display ThreeMeshUI Text elements
|
|
// It is important to know that a Text MUST have a Block as parent
|
|
// Using three-mesh-ui, we would usually have one or more rootBlock elements
|
|
const rootBlock = new ThreeMeshUI.Block( {
|
|
|
|
name: 'rootBlock',
|
|
// A Block must define its "box-sizing" properties
|
|
width: 1.2,
|
|
height: 'auto', // the text will define the output height
|
|
padding: 0.05,
|
|
boxSizing: 'border-box',
|
|
|
|
// A Block can define its "layout" properties
|
|
flexDirection: 'column',
|
|
justifyContent: 'center',
|
|
textAlign: 'left',
|
|
|
|
borderRadius: 0.015,
|
|
|
|
backgroundColor : 0x000000,
|
|
backgroundOpacity : 0.5,
|
|
|
|
// A Block can also define "text" properties that will propagate to any of its Text children
|
|
fontSize: 0.055,
|
|
|
|
fontFamily: './assets/fonts/msdf/roboto/regular.json',
|
|
fontTexture: './assets/fonts/msdf/roboto/regular.png',
|
|
// @Note: setting fontFamily
|
|
// This looks very easy, but this isn't the best way for handling fonts
|
|
// However it is perfect for a first glance on how to get started with three-mesh-ui
|
|
// Be sure you next step will be `Getting started - Preload fonts`
|
|
|
|
} );
|
|
|
|
|
|
// three-mesh-ui root elements must be added on threejs display stack
|
|
// In the scene, or in another Object3D of our choice
|
|
scene.add( rootBlock );
|
|
|
|
// three-mesh-ui Block are Object3D agreemented with three-mesh-ui capabilities
|
|
// so you can use any existing Object3D methods and properties
|
|
rootBlock.position.set( 0, 1, -1.8 );
|
|
rootBlock.rotation.x = -0.55;
|
|
|
|
const blockText = new ThreeMeshUI.Text({ textContent: "Block arrows", width: 'auto' });
|
|
|
|
|
|
|
|
const arrowLeft = new ThreeMeshUI.Block({width:0.1,height:0.1} );
|
|
const arrowRight = new ThreeMeshUI.Block({width:0.1,height:0.1, } );
|
|
const arrowTop = new ThreeMeshUI.Block({width:0.1,height:0.1,marginLeft: 0.05} );
|
|
const arrowBottom = new ThreeMeshUI.Block({width:0.1,height:0.1, marginLeft: 0.05} );
|
|
|
|
|
|
|
|
Arrows( arrowLeft, 0.04, "left", 0xffffff );
|
|
Arrows( arrowRight, 0.04, "right", 0xffffff );
|
|
Arrows( arrowTop, 0.04, "top", 0xffffff );
|
|
Arrows( arrowBottom, 0.04, "bottom", 0xffffff );
|
|
|
|
|
|
const blockArrows = new ThreeMeshUI.Block({flexDirection:'row',margin: '0.05 0'});
|
|
|
|
|
|
blockArrows.add(
|
|
|
|
arrowLeft, arrowRight, arrowTop, arrowBottom,
|
|
|
|
);
|
|
|
|
rootBlock.add( blockText, blockArrows)
|
|
|
|
|
|
|
|
const blockInlineText = new ThreeMeshUI.Text({ textContent: "Inline arrows", width: 'auto' });
|
|
|
|
|
|
|
|
const arrowInlineLeft = new ThreeMeshUI.InlineBlock({width:'50%', height:'50%',} );
|
|
const arrowInlineRight = new ThreeMeshUI.InlineBlock({width:'50%', height:'50%',} );
|
|
const arrowInlineTop = new ThreeMeshUI.InlineBlock({width:'50%', height:'50%', marginLeft: 0.025} );
|
|
const arrowInlineBottom = new ThreeMeshUI.InlineBlock({width:'50%', height:'50%', marginLeft: 0.025} );
|
|
|
|
|
|
|
|
Arrows( arrowInlineLeft, 0.008, "left", 0xffffff );
|
|
Arrows( arrowInlineRight, 0.008, "right", 0xffffff );
|
|
Arrows( arrowInlineTop, 0.008, "top", 0xffffff );
|
|
Arrows( arrowInlineBottom, 0.008, "bottom", 0xffffff );
|
|
|
|
|
|
const inlineArrows = new ThreeMeshUI.Text({textContent:"text arrows : "});
|
|
|
|
|
|
inlineArrows.add(
|
|
|
|
arrowInlineLeft, arrowInlineRight, arrowInlineTop, arrowInlineBottom,
|
|
|
|
);
|
|
|
|
rootBlock.add( blockInlineText, inlineArrows)
|
|
|
|
|
|
const but = new ThreeMeshUI.Text({textContent:"re-ordered"});
|
|
const arrow1 = new ThreeMeshUI.InlineBlock({width:'50%',height:'50%', order: -2});
|
|
const arrow2 = new ThreeMeshUI.InlineBlock({width:'50%',height:'50%', order: -1, marginRight: 0.025});
|
|
Arrows( arrow1, 0.014, 'right', 0x00ff99 );
|
|
Arrows( arrow2, 0.014, 'right', 0x00ff99 );
|
|
|
|
const arrow3 = new ThreeMeshUI.InlineBlock({width:'50%',height:'50%', marginLeft:0.025});
|
|
const arrow4 = new ThreeMeshUI.InlineBlock({width:'50%',height:'50%'});
|
|
Arrows( arrow3, 0.014, 'left', 0x00ff99 );
|
|
Arrows( arrow4, 0.014, 'left', 0x00ff99 );
|
|
|
|
but.add( arrow1, arrow2, arrow3, arrow4 );
|
|
|
|
rootBlock.add( but );
|
|
|
|
|
|
// but2
|
|
|
|
const but2 = new ThreeMeshUI.Text({textContent:"re-ordered"});
|
|
const arrow21 = new ThreeMeshUI.InlineBlock({width:'50%',height:'50%', order: -2});
|
|
const arrow22 = new ThreeMeshUI.InlineBlock({width:'50%',height:'50%', order: -1, marginRight: 0.025});
|
|
Arrows( arrow21, 0.014, 'left', 0x00ff99 );
|
|
Arrows( arrow22, 0.014, 'left', 0x00ff99 );
|
|
|
|
const arrow23 = new ThreeMeshUI.InlineBlock({width:'50%',height:'50%', marginLeft:0.025});
|
|
const arrow24 = new ThreeMeshUI.InlineBlock({width:'50%',height:'50%'});
|
|
Arrows( arrow23, 0.014, 'right', 0x00ff99 );
|
|
Arrows( arrow24, 0.014, 'right', 0x00ff99 );
|
|
// const arrow2 = arrow1.clone()
|
|
|
|
|
|
but2.add( arrow21, arrow22, arrow23, arrow24 );
|
|
|
|
rootBlock.add( but2 );
|
|
|
|
|
|
ThreeMeshUI.update();
|
|
console.log( arrow2._margin._value );
|
|
|
|
}
|
|
|
|
// In order to see things, we need to render them, usually on each frame
|
|
function step3AnimationLoop() {
|
|
|
|
// Don't forget, ThreeMeshUI must be updated manually.
|
|
// This has been introduced in version 3.0.0 in order
|
|
// to improve performance
|
|
ThreeMeshUI.update();
|
|
|
|
// camera.position.x = Math.random()*3;
|
|
//
|
|
// if( vrCam ) {
|
|
// renderer.xr.updateCamera(cameraP);
|
|
// }
|
|
|
|
controls.update();
|
|
renderer.render( scene, cameraP );
|
|
|
|
}
|
|
|
|
|
|
// handles resizing the renderer when the viewport is resized
|
|
// common threejs stuff
|
|
function onWindowResize() {
|
|
|
|
camera.aspect = window.innerWidth / window.innerHeight;
|
|
camera.updateProjectionMatrix();
|
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
|
|
|
}
|
|
|
|
|