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];