forked from ppfun/pixelplanet
add voxelpainter test
This commit is contained in:
parent
cc3fc29e89
commit
b8e1436efa
21
public/voxeltest.html
Normal file
21
public/voxeltest.html
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>three.js webgl - interactive - voxel painter</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
|
||||||
|
<link type="text/css" rel="stylesheet" href="main.css">
|
||||||
|
<script src="assets/voxel.js"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
color: #444;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #08f;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
1164
src/controls/OrbitControls.js
Normal file
1164
src/controls/OrbitControls.js
Normal file
File diff suppressed because it is too large
Load Diff
1248
src/controls/VoxelPainterControls.js
Normal file
1248
src/controls/VoxelPainterControls.js
Normal file
File diff suppressed because it is too large
Load Diff
199
src/voxel.js
Normal file
199
src/voxel.js
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,16 +21,16 @@ const basePackageValues = {
|
||||||
start: 'node --nouse-idle-notification --expose-gc web.js',
|
start: 'node --nouse-idle-notification --expose-gc web.js',
|
||||||
},
|
},
|
||||||
dependencies: {
|
dependencies: {
|
||||||
"mysql2": "^2.1.0",
|
mysql2: '^2.1.0',
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
const versionsPackageFilename = path.resolve(__dirname, '../package.json');
|
const versionsPackageFilename = path.resolve(__dirname, '../package.json');
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
|
|
||||||
context: path.resolve(__dirname, '..'),
|
context: path.resolve(__dirname, '..'),
|
||||||
|
|
||||||
mode: (isDebug) ? "development" : "production",
|
mode: (isDebug) ? 'development' : 'production',
|
||||||
|
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, '../build/public/assets'),
|
path: path.resolve(__dirname, '../build/public/assets'),
|
||||||
|
@ -39,13 +39,13 @@ const config = {
|
||||||
},
|
},
|
||||||
|
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['.js', '.jsx', '.json'],
|
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
|
||||||
},
|
},
|
||||||
|
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.(js|jsx)$/,
|
test: /\.(js|jsx|ts|tsx)$/,
|
||||||
loader: 'babel-loader',
|
loader: 'babel-loader',
|
||||||
include: [
|
include: [
|
||||||
path.resolve(__dirname, '../src'),
|
path.resolve(__dirname, '../src'),
|
||||||
|
@ -70,18 +70,20 @@ const config = {
|
||||||
},
|
},
|
||||||
debug: false,
|
debug: false,
|
||||||
}],
|
}],
|
||||||
|
"@babel/typescript",
|
||||||
// JSX, Flow
|
// JSX, Flow
|
||||||
// https://github.com/babel/babel/tree/master/packages/babel-preset-react
|
// https://github.com/babel/babel/tree/master/packages/babel-preset-react
|
||||||
'@babel/react',
|
'@babel/react',
|
||||||
],
|
],
|
||||||
plugins: [
|
plugins: [
|
||||||
'@babel/transform-flow-strip-types',
|
'@babel/transform-flow-strip-types',
|
||||||
["@babel/plugin-proposal-decorators", { "legacy": true }],
|
['@babel/plugin-proposal-decorators', { legacy: true }],
|
||||||
"@babel/plugin-proposal-function-sent",
|
'@babel/plugin-proposal-function-sent',
|
||||||
"@babel/plugin-proposal-export-namespace-from",
|
'@babel/plugin-proposal-export-namespace-from',
|
||||||
"@babel/plugin-proposal-numeric-separator",
|
'@babel/plugin-proposal-numeric-separator',
|
||||||
"@babel/plugin-proposal-throw-expressions",
|
'@babel/plugin-proposal-throw-expressions',
|
||||||
["@babel/plugin-proposal-class-properties", { "loose": true }],
|
['@babel/plugin-proposal-class-properties', { loose: true }],
|
||||||
|
'@babel/proposal-object-rest-spread',
|
||||||
// Adds component stack to warning messages
|
// Adds component stack to warning messages
|
||||||
// https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx-source
|
// https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx-source
|
||||||
...isDebug ? ['@babel/transform-react-jsx-source'] : [],
|
...isDebug ? ['@babel/transform-react-jsx-source'] : [],
|
||||||
|
@ -89,10 +91,10 @@ const config = {
|
||||||
// https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx-self
|
// https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx-self
|
||||||
...isDebug ? ['@babel/transform-react-jsx-self'] : [],
|
...isDebug ? ['@babel/transform-react-jsx-self'] : [],
|
||||||
// react-optimize
|
// react-optimize
|
||||||
"@babel/transform-react-constant-elements",
|
'@babel/transform-react-constant-elements',
|
||||||
"@babel/transform-react-inline-elements",
|
'@babel/transform-react-inline-elements',
|
||||||
"transform-react-remove-prop-types",
|
'transform-react-remove-prop-types',
|
||||||
"transform-react-pure-class-to-function",
|
'transform-react-pure-class-to-function',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -100,14 +102,14 @@ const config = {
|
||||||
test: /\.svg$/,
|
test: /\.svg$/,
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
loader: "babel-loader"
|
loader: 'babel-loader',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
loader: "react-svg-loader",
|
loader: 'react-svg-loader',
|
||||||
options: {
|
options: {
|
||||||
svgo: {
|
svgo: {
|
||||||
plugins: [
|
plugins: [
|
||||||
{
|
{
|
||||||
removeViewBox: false,
|
removeViewBox: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -115,10 +117,10 @@ const config = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
jsx: false // true outputs JSX tags
|
jsx: false, // true outputs JSX tags
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.html/,
|
test: /\.html/,
|
||||||
|
@ -126,10 +128,10 @@ const config = {
|
||||||
{
|
{
|
||||||
loader: 'html-loader',
|
loader: 'html-loader',
|
||||||
options: {
|
options: {
|
||||||
attrs: [':data-src']
|
attrs: [':data-src'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.tcss/,
|
test: /\.tcss/,
|
||||||
|
@ -148,7 +150,7 @@ const config = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.scss/,
|
test: /\.scss/,
|
||||||
use: [
|
use: [
|
||||||
'style-loader',
|
'style-loader',
|
||||||
{
|
{
|
||||||
loader: 'css-loader',
|
loader: 'css-loader',
|
||||||
|
@ -165,7 +167,7 @@ const config = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.css/,
|
test: /\.css/,
|
||||||
use: [ 'style-loader',
|
use: ['style-loader',
|
||||||
{
|
{
|
||||||
loader: 'css-loader',
|
loader: 'css-loader',
|
||||||
options: {
|
options: {
|
||||||
|
@ -232,6 +234,7 @@ const clientConfig = {
|
||||||
entry: {
|
entry: {
|
||||||
client: ['./src/client.js'],
|
client: ['./src/client.js'],
|
||||||
globe: ['./src/globe.js'],
|
globe: ['./src/globe.js'],
|
||||||
|
voxel: ['./src/voxel.js'],
|
||||||
},
|
},
|
||||||
|
|
||||||
output: {
|
output: {
|
||||||
|
@ -271,18 +274,18 @@ const clientConfig = {
|
||||||
vendors: false,
|
vendors: false,
|
||||||
|
|
||||||
vendor: {
|
vendor: {
|
||||||
name: "vendor",
|
name: 'vendor',
|
||||||
chunks: chunk => chunk.name === "client",
|
chunks: (chunk) => chunk.name === 'client',
|
||||||
test: /node_modules/,
|
test: /node_modules/,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
// Some libraries import Node modules but don't use them in the browser.
|
// Some libraries import Node modules but don't use them in the browser.
|
||||||
// Tell Webpack to provide empty mocks for them so importing them works.
|
// Tell Webpack to provide empty mocks for them so importing them works.
|
||||||
// https://webpack.github.io/docs/configuration.html#node
|
// https://webpack.github.io/docs/configuration.html#node
|
||||||
// https://github.com/webpack/node-libs-browser/tree/master/mock
|
// https://github.com/webpack/node-libs-browser/tree/master/mock
|
||||||
node: {
|
node: {
|
||||||
fs: 'empty',
|
fs: 'empty',
|
||||||
net: 'empty',
|
net: 'empty',
|
||||||
|
@ -291,6 +294,20 @@ const clientConfig = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const voxelConfig = {
|
||||||
|
...clientConfig,
|
||||||
|
entry: {
|
||||||
|
voxel: ['./src/voxel.js'],
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
...config.output,
|
||||||
|
filename: '[name].js',
|
||||||
|
},
|
||||||
|
optimization: {
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const webConfig = {
|
const webConfig = {
|
||||||
...config,
|
...config,
|
||||||
|
|
||||||
|
@ -313,11 +330,11 @@ const webConfig = {
|
||||||
...config.module,
|
...config.module,
|
||||||
|
|
||||||
// Override babel-preset-env configuration for Node.js
|
// Override babel-preset-env configuration for Node.js
|
||||||
rules: config.module.rules.map(rule => (rule.loader !== 'babel-loader' ? rule : {
|
rules: config.module.rules.map((rule) => (rule.loader !== 'babel-loader' ? rule : {
|
||||||
...rule,
|
...rule,
|
||||||
query: {
|
query: {
|
||||||
...rule.query,
|
...rule.query,
|
||||||
presets: rule.query.presets.map(preset => (preset[0] !== '@babel/preset-env' ? preset : ['@babel/preset-env', {
|
presets: rule.query.presets.map((preset) => (preset[0] !== '@babel/preset-env' ? preset : ['@babel/preset-env', {
|
||||||
targets: {
|
targets: {
|
||||||
node: pkg.engines.node.replace(/^\D+/g, ''),
|
node: pkg.engines.node.replace(/^\D+/g, ''),
|
||||||
},
|
},
|
||||||
|
@ -333,9 +350,8 @@ const webConfig = {
|
||||||
externals: [
|
externals: [
|
||||||
/^\.\/assets\.json$/,
|
/^\.\/assets\.json$/,
|
||||||
(context, request, callback) => {
|
(context, request, callback) => {
|
||||||
const isExternal =
|
const isExternal = request.match(/^[@a-z][a-z/.\-0-9]*$/i)
|
||||||
request.match(/^[@a-z][a-z/.\-0-9]*$/i) &&
|
&& !request.match(/\.(css|less|scss|sss)$/i);
|
||||||
!request.match(/\.(css|less|scss|sss)$/i);
|
|
||||||
callback(null, Boolean(isExternal));
|
callback(null, Boolean(isExternal));
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -363,4 +379,5 @@ const webConfig = {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default [clientConfig, webConfig];
|
// export default [clientConfig, webConfig];
|
||||||
|
export default [clientConfig, voxelConfig, webConfig];
|
||||||
|
|
Loading…
Reference in New Issue
Block a user