From 88990bf454e312a8b18553e5a118d07f8e9029db Mon Sep 17 00:00:00 2001 From: HF Date: Wed, 22 Jan 2020 05:35:01 +0100 Subject: [PATCH] lazy load test --- src/client.js | 7 +- src/components/Menu.jsx | 2 + src/components/VoxelButton.jsx | 24 ++++ src/components/base.tcss | 4 + src/controls/VoxelPainterControls.js | 3 +- src/voxel.js | 21 +-- src/voxelSA.js | 199 +++++++++++++++++++++++++++ tools/webpack.config.js | 18 +-- 8 files changed, 249 insertions(+), 29 deletions(-) create mode 100644 src/components/VoxelButton.jsx create mode 100644 src/voxelSA.js diff --git a/src/client.js b/src/client.js index 1c0e6d8..4fd8bb0 100644 --- a/src/client.js +++ b/src/client.js @@ -237,11 +237,12 @@ document.addEventListener('DOMContentLoaded', () => { store.dispatch(initTimer()); - function animationLoop() { + window.animationLoop = function animationLoop() { renderer.render(viewport); - window.requestAnimationFrame(animationLoop); + window.requestAnimationFrame(window.animationLoop); } - animationLoop(); + window.animationLoop(); + window.store = store; store.dispatch(fetchMe()); ProtocolClient.connect(); diff --git a/src/components/Menu.jsx b/src/components/Menu.jsx index 64bc672..bb1c2bc 100644 --- a/src/components/Menu.jsx +++ b/src/components/Menu.jsx @@ -11,6 +11,7 @@ import LogInButton from './LogInButton'; import DownloadButton from './DownloadButton'; import MinecraftTPButton from './MinecraftTPButton'; import MinecraftButton from './MinecraftButton'; +import VoxelButton from './VoxelButton'; const Menu = ({ menuOpen, minecraftname, messages, canvasId, @@ -21,6 +22,7 @@ const Menu = ({ {(menuOpen) ? : null} {(menuOpen) ? : null} {(menuOpen) ? : null} + {(menuOpen) ? : null} {(minecraftname && !messages.includes('not_mc_verified') && canvasId == 0) ? : null} ); diff --git a/src/components/VoxelButton.jsx b/src/components/VoxelButton.jsx new file mode 100644 index 0000000..a27182e --- /dev/null +++ b/src/components/VoxelButton.jsx @@ -0,0 +1,24 @@ +/** + * + * @flow + */ + +import React from 'react'; +import { connect } from 'react-redux'; +import type { State } from '../reducers'; + +async function switchVoxel() { + await import(/* webpackChunkName: "voxel" */ '../voxel'); + console.log("Chunk voxel loaded"); +} + + +const VoxelButton = ({ + canvasId, canvasIdent, canvasSize, view, +}) => ( +
+ ♠ +
+); + +export default VoxelButton; diff --git a/src/components/base.tcss b/src/components/base.tcss index 8a1e332..04a64de 100644 --- a/src/components/base.tcss +++ b/src/components/base.tcss @@ -153,6 +153,10 @@ kbd { left: 98px; top: 16px; } +:global(#voxelbutton) { + left: 180px; + top: 16px; +} :global(#canvasbutton) { left: 57px; top: 16px; diff --git a/src/controls/VoxelPainterControls.js b/src/controls/VoxelPainterControls.js index 492bbfd..f127961 100644 --- a/src/controls/VoxelPainterControls.js +++ b/src/controls/VoxelPainterControls.js @@ -162,7 +162,8 @@ var VoxelPainterControls = function ( object, domElement ) { velocity.x -= velocity.x * 50.0 * delta; velocity.y -= velocity.y * 50.0 * delta; velocity.z -= velocity.z * 50.0 * delta; - if (velocity.length() < 1) { + const length = velocity.length(); + if (length < 1 || length > 10) { velocity.set(0, 0, 0); } diff --git a/src/voxel.js b/src/voxel.js index 8e9e8f3..6dc4d3f 100644 --- a/src/voxel.js +++ b/src/voxel.js @@ -1,6 +1,7 @@ import * as THREE from 'three'; import { VoxelPainterControls } from './controls/VoxelPainterControls'; // import { OrbitControls } from './controls/OrbitControls'; +import store from './ui/store'; var camera, scene, renderer; var plane; @@ -13,12 +14,9 @@ var controls; var objects = []; -document.addEventListener('DOMContentLoaded', () => { - init(); - render(); -}); - function init() { + // quit 2d rendering + const canvas = document.getElementById('gameWindow').remove(); camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 ); camera.position.set( 100, 160, 260 ); @@ -121,10 +119,12 @@ function init() { } -function render() { +init(); + +window.animationLoop = () => { controls.update(); renderer.render( scene, camera ); - requestAnimationFrame(render); + requestAnimationFrame(window.animationLoop); } function onWindowResize() { @@ -178,8 +178,13 @@ function onDocumentMouseUp( event ) { switch ( event.button ) { case 0: // left mouse button + const state = store.getState(); + const clri = state.gui.selectedColor; + const clr = state.canvas.palette.colors[clri]; + const material = new THREE.MeshLambertMaterial( { color: clr } ); + console.log("set voxel"); - var voxel = new THREE.Mesh( cubeGeo, cubeMaterial ); + var voxel = new THREE.Mesh( cubeGeo, material ); voxel.position.copy( intersect.point ).add( intersect.face.normal ); voxel.position.divideScalar( 10 ).floor().multiplyScalar( 10 ).addScalar( 5 ); scene.add( voxel ); diff --git a/src/voxelSA.js b/src/voxelSA.js new file mode 100644 index 0000000..8e9e8f3 --- /dev/null +++ b/src/voxelSA.js @@ -0,0 +1,199 @@ +import * as THREE from 'three'; +import { VoxelPainterControls } from './controls/VoxelPainterControls'; +// import { OrbitControls } from './controls/OrbitControls'; + +var camera, scene, renderer; +var plane; +var mouse, raycaster; + +var rollOverMesh, rollOverMaterial; +var cubeGeo, cubeMaterial; + +var controls; + +var objects = []; + +document.addEventListener('DOMContentLoaded', () => { + init(); + render(); +}); + +function init() { + + camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 ); + camera.position.set( 100, 160, 260 ); + camera.lookAt( 0, 0, 0 ); + + scene = new THREE.Scene(); + scene.background = new THREE.Color( 0xf0f0f0 ); + + // roll-over helpers + + var rollOverGeo = new THREE.BoxBufferGeometry( 10, 10, 10 ); + rollOverMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, opacity: 0.5, transparent: true } ); + rollOverMesh = new THREE.Mesh( rollOverGeo, rollOverMaterial ); + scene.add( rollOverMesh ); + + // cubes + cubeGeo = new THREE.BoxBufferGeometry( 10, 10, 10 ); + cubeMaterial = new THREE.MeshLambertMaterial( { color: 0xfeb74c } ); + + // grid + var gridHelper = new THREE.GridHelper( 1000, 100, 0x555555, 0x555555 ); + scene.add( gridHelper ); + + // + raycaster = new THREE.Raycaster(); + mouse = new THREE.Vector2(); + + + // Floor with random cold color triangles + var floorGeometry = new THREE.PlaneBufferGeometry( 1000, 1000, 100, 100 ); + floorGeometry.rotateX( - Math.PI / 2 ); + // vertex displacement + var vertex = new THREE.Vector3(); + var color = new THREE.Color(); + var position = floorGeometry.attributes.position; + for ( var i = 0, l = position.count; i < l; i ++ ) { + vertex.fromBufferAttribute( position, i ); + vertex.x += Math.random() * 20 - 10; + vertex.y += Math.random() * 2; + vertex.z += Math.random() * 20 - 10; + position.setXYZ( i, vertex.x, vertex.y, vertex.z ); + } + floorGeometry = floorGeometry.toNonIndexed(); // ensure each face has unique vertices + position = floorGeometry.attributes.position; + var colors = []; + for ( var i = 0, l = position.count; i < l; i ++ ) { + color.setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 ); + colors.push( color.r, color.g, color.b ); + } + floorGeometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) ); + var floorMaterial = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } ); + plane = new THREE.Mesh( floorGeometry, floorMaterial ); + scene.add( plane ); + objects.push( plane ); + + /* + // Plane Floor + var geometry = new THREE.PlaneBufferGeometry( 5000, 5000 ); + geometry.rotateX( - Math.PI / 2 ); + plane = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial({ color: 0x009900 }) ); + scene.add( plane ); + objects.push( plane ); + */ + + + // lights + + var ambientLight = new THREE.AmbientLight( 0x606060 ); + scene.add( ambientLight ); + + var directionalLight = new THREE.DirectionalLight( 0xffffff ); + directionalLight.position.set( 1, 0.75, 0.5 ).normalize(); + scene.add( directionalLight ); + + renderer = new THREE.WebGLRenderer( { antialias: true } ); + renderer.setPixelRatio( window.devicePixelRatio ); + renderer.setSize( window.innerWidth, window.innerHeight ); + document.body.appendChild( renderer.domElement ); + + controls = new VoxelPainterControls(camera, renderer.domElement); + controls.enableDamping = true; + controls.dampingFactor = 0.75; + controls.maxPolarAngle = Math.PI / 2; + controls.minDistance = 100.00; + controls.maxDistance = 1000.00; + /*controls.rotateSpeed = 1.5; + controls.zoomSpeed = 10.0; + controls.panSpeed = 0.3; + controls.keys = [65, 83, 68]; // ASD + controls.dynamicDampingFactor = 0.2; + */ + + renderer.domElement.addEventListener( 'mousemove', onDocumentMouseMove, false ); + renderer.domElement.addEventListener( 'mousedown', onDocumentMouseDown, false ); + renderer.domElement.addEventListener( 'mouseup', onDocumentMouseUp, false ); + //document.addEventListener( 'keydown', onDocumentKeyDown, false ); + //document.addEventListener( 'keyup', onDocumentKeyUp, false ); + // + window.addEventListener( 'resize', onWindowResize, false ); + +} + +function render() { + controls.update(); + renderer.render( scene, camera ); + requestAnimationFrame(render); +} + +function onWindowResize() { + + camera.aspect = window.innerWidth / window.innerHeight; + camera.updateProjectionMatrix(); + renderer.setSize( window.innerWidth, window.innerHeight ); + +} + +function onDocumentMouseMove( event ) { + + event.preventDefault(); + + mouse.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1 ); + + raycaster.setFromCamera( mouse, camera ); + + var intersects = raycaster.intersectObjects( objects ); + + if ( intersects.length > 0 ) { + + var intersect = intersects[ 0 ]; + + rollOverMesh.position.copy( intersect.point ).add( intersect.face.normal ); + rollOverMesh.position.divideScalar( 10 ).floor().multiplyScalar( 10 ).addScalar( 5 ); + + } +} + +var pressTime = 0; +function onDocumentMouseDown( event ) { + pressTime = Date.now(); +} + +function onDocumentMouseUp( event ) { + if (Date.now() - pressTime > 600) { + return; + } + + event.preventDefault(); + mouse.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1 ); + + raycaster.setFromCamera( mouse, camera ); + + var intersects = raycaster.intersectObjects( objects ); + + if ( intersects.length > 0 ) { + var intersect = intersects[ 0 ]; + + switch ( event.button ) { + case 0: + // left mouse button + console.log("set voxel"); + var voxel = new THREE.Mesh( cubeGeo, cubeMaterial ); + voxel.position.copy( intersect.point ).add( intersect.face.normal ); + voxel.position.divideScalar( 10 ).floor().multiplyScalar( 10 ).addScalar( 5 ); + scene.add( voxel ); + + objects.push( voxel ); + break; + case 2: + // right mouse button + console.log("remove voxel"); + if ( intersect.object !== plane ) { + scene.remove( intersect.object ); + objects.splice( objects.indexOf( intersect.object ), 1 ); + } + break; + } + } +} diff --git a/tools/webpack.config.js b/tools/webpack.config.js index 84dc09a..8698849 100644 --- a/tools/webpack.config.js +++ b/tools/webpack.config.js @@ -234,7 +234,6 @@ const clientConfig = { entry: { client: ['./src/client.js'], globe: ['./src/globe.js'], - voxel: ['./src/voxel.js'], }, output: { @@ -294,20 +293,6 @@ const clientConfig = { }; -const voxelConfig = { - ...clientConfig, - entry: { - voxel: ['./src/voxel.js'], - }, - output: { - ...config.output, - filename: '[name].js', - }, - optimization: { - }, -}; - - const webConfig = { ...config, @@ -379,5 +364,4 @@ const webConfig = { }; -// export default [clientConfig, webConfig]; -export default [clientConfig, voxelConfig, webConfig]; +export default [clientConfig, webConfig];