change 3d scaling and add ChunkLoader dummy
This commit is contained in:
parent
66662e49c3
commit
d97e375b6d
|
@ -12,6 +12,7 @@ class Palette {
|
|||
rgb: Uint8Array;
|
||||
colors: Array<Color>;
|
||||
abgr: Uint32Array;
|
||||
fl: Array<number>;
|
||||
alpha: number = 0;
|
||||
|
||||
constructor(colors: Array, alpha: number = 0) {
|
||||
|
@ -20,6 +21,7 @@ class Palette {
|
|||
this.rgb = new Uint8Array(this.length * 3);
|
||||
this.colors = new Array(this.length);
|
||||
this.abgr = new Uint32Array(this.length);
|
||||
this.fl = new Array(this.length);
|
||||
|
||||
let cnt = 0;
|
||||
for (let index = 0; index < colors.length; index++) {
|
||||
|
@ -31,6 +33,7 @@ class Palette {
|
|||
this.rgb[cnt++] = b;
|
||||
this.colors[index] = `rgb(${r}, ${g}, ${b})`;
|
||||
this.abgr[index] = (0xFF000000) | (b << 16) | (g << 8) | (r);
|
||||
this.fl[index] = [r / 256, g / 256, b / 256];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,8 @@ class ChunkLoader {
|
|||
return chunk.image;
|
||||
}
|
||||
return loadingTiles.getTile(canvasId);
|
||||
} if (fetch) {
|
||||
}
|
||||
if (fetch) {
|
||||
// fetch chunk
|
||||
const chunkRGB = new ChunkRGB(this.palette, chunkKey);
|
||||
this.chunks.set(chunkKey, chunkRGB);
|
||||
|
|
86
src/ui/ChunkLoader3D.js
Normal file
86
src/ui/ChunkLoader3D.js
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Loading 3D chunks
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import * as THREE from 'three';
|
||||
|
||||
import {
|
||||
THREE_CANVAS_HEIGHT,
|
||||
THREE_TILE_SIZE,
|
||||
} from '../core/constants';
|
||||
import {
|
||||
receiveBigChunk,
|
||||
} from '../actions';
|
||||
|
||||
import Chunk from './ChunkRGB3D';
|
||||
|
||||
|
||||
class ChunkLoader {
|
||||
store = null;
|
||||
canvasId: number;
|
||||
palette;
|
||||
chunks: Map<string, Chunk>;
|
||||
|
||||
constructor(store) {
|
||||
console.log("Created Chunk loader");
|
||||
this.store = store;
|
||||
const state = store.getState();
|
||||
const {
|
||||
canvasId,
|
||||
palette,
|
||||
} = state.canvas;
|
||||
this.canvasId = canvasId;
|
||||
this.palette = palette;
|
||||
this.chunks = new Map();
|
||||
}
|
||||
|
||||
getVoxelUpdate(
|
||||
xc: number,
|
||||
zc: number,
|
||||
offset: number,
|
||||
color: number,
|
||||
) {
|
||||
const key = `${xc}:${zc}`;
|
||||
const chunk = this.chunks.get(key);
|
||||
if (chunk) {
|
||||
/*
|
||||
const offsetXZ = offset % (THREE_TILE_SIZE ** 2);
|
||||
const iy = (offset - offsetXZ) / (THREE_TILE_SIZE ** 2);
|
||||
const ix = offsetXZ % THREE_TILE_SIZE;
|
||||
const iz = (offsetXZ - ix) / THREE_TILE_SIZE;
|
||||
*/
|
||||
chunk.setVoxelByOffset(offset, color);
|
||||
//this.store.dispatch(receiveBigChunk(key));
|
||||
}
|
||||
}
|
||||
|
||||
getChunk(xc, zc, fetch: boolean) {
|
||||
const chunkKey = `${xc}:${zc}`;
|
||||
console.log(`Get chunk ${chunkKey}`);
|
||||
let chunk = this.chunks.get(chunkKey);
|
||||
if (chunk) {
|
||||
if (chunk.ready) {
|
||||
return chunk.mesh;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (fetch) {
|
||||
// fetch chunk
|
||||
chunk = new Chunk(this.palette, chunkKey);
|
||||
this.chunks.set(chunkKey, chunk);
|
||||
this.fetchChunk(xc, zc, chunk);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async fetchChunk(xc: number, zc: number, chunk) {
|
||||
const { key } = chunk;
|
||||
console.log(`Fetch chunk ${key}`);
|
||||
await chunk.generateSin();
|
||||
this.store.dispatch(receiveBigChunk(key));
|
||||
}
|
||||
}
|
||||
|
||||
export default ChunkLoader;
|
|
@ -19,7 +19,7 @@ class ChunkRGB {
|
|||
// if true => chunk got requested from api/chunk and
|
||||
// receives websocket pixel updates
|
||||
// if false => chunk is an zoomed png tile
|
||||
this.isBasechunk = true;
|
||||
this.isBasechunk = false;
|
||||
this.palette = palette;
|
||||
this.image = document.createElement('canvas');
|
||||
this.image.width = TILE_SIZE;
|
||||
|
@ -69,7 +69,6 @@ class ChunkRGB {
|
|||
*/
|
||||
|
||||
fromBuffer(chunkBuffer: Uint8Array) {
|
||||
this.ready = true;
|
||||
const imageData = new ImageData(TILE_SIZE, TILE_SIZE);
|
||||
const imageView = new Uint32Array(imageData.data.buffer);
|
||||
const colors = this.palette.buffer2ABGR(chunkBuffer);
|
||||
|
@ -78,6 +77,7 @@ class ChunkRGB {
|
|||
});
|
||||
const ctx = this.image.getContext('2d');
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
this.ready = true;
|
||||
}
|
||||
|
||||
fromImage(img: Image) {
|
||||
|
|
292
src/ui/ChunkRGB3D.js
Normal file
292
src/ui/ChunkRGB3D.js
Normal file
|
@ -0,0 +1,292 @@
|
|||
/*
|
||||
* 3D Chunk
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import * as THREE from 'three';
|
||||
|
||||
import {
|
||||
THREE_TILE_SIZE,
|
||||
THREE_CANVAS_HEIGHT,
|
||||
} from '../core/constants';
|
||||
|
||||
|
||||
const faceDirs = [
|
||||
[-1, 0, 0],
|
||||
[1, 0, 0],
|
||||
[0, -1, 0],
|
||||
[0, 1, 0],
|
||||
[0, 0, -1],
|
||||
[0, 0, 1],
|
||||
];
|
||||
|
||||
const faceCorners = [
|
||||
// left
|
||||
[
|
||||
[0, 1, 0],
|
||||
[0, 0, 0],
|
||||
[0, 1, 1],
|
||||
[0, 0, 1],
|
||||
],
|
||||
// right
|
||||
[
|
||||
[1, 1, 1],
|
||||
[1, 0, 1],
|
||||
[1, 1, 0],
|
||||
[1, 0, 0],
|
||||
],
|
||||
// bottom
|
||||
[
|
||||
[1, 0, 1],
|
||||
[0, 0, 1],
|
||||
[1, 0, 0],
|
||||
[0, 0, 0],
|
||||
],
|
||||
// top
|
||||
[
|
||||
[0, 1, 1],
|
||||
[1, 1, 1],
|
||||
[0, 1, 0],
|
||||
[1, 1, 0],
|
||||
],
|
||||
// back
|
||||
[
|
||||
[1, 0, 0],
|
||||
[0, 0, 0],
|
||||
[1, 1, 0],
|
||||
[0, 1, 0],
|
||||
],
|
||||
// front
|
||||
[
|
||||
[0, 0, 1],
|
||||
[1, 0, 1],
|
||||
[0, 1, 1],
|
||||
[1, 1, 1],
|
||||
],
|
||||
];
|
||||
|
||||
const material = new THREE.MeshLambertMaterial({
|
||||
vertexColors: THREE.VertexColors,
|
||||
});
|
||||
|
||||
|
||||
class Chunk {
|
||||
key: string;
|
||||
ready: boolean = false;
|
||||
palette: Object;
|
||||
buffer: Uint8Array;
|
||||
mesh: THREE.Mesh = null;
|
||||
faceCnt: number;
|
||||
|
||||
constructor(palette, key) {
|
||||
this.key = key;
|
||||
this.palette = palette;
|
||||
}
|
||||
|
||||
getVoxel(x: number, y: number, z: number) {
|
||||
const { buffer } = this;
|
||||
if (!buffer) return 0;
|
||||
if (x < 0 || x >= THREE_TILE_SIZE || y >= THREE_CANVAS_HEIGHT
|
||||
|| z < 0 || z >= THREE_TILE_SIZE)
|
||||
return 0;
|
||||
if (y < 0)
|
||||
return 1;
|
||||
// z and y are swapped in api/pixel for compatibility
|
||||
// with 2D canvas
|
||||
const offset = Chunk.getOffsetOfVoxel(x, y, z)
|
||||
return this.buffer[offset];
|
||||
}
|
||||
|
||||
async generateSin() {
|
||||
let cnt = 0;
|
||||
this.buffer = new Uint8Array(THREE_TILE_SIZE * THREE_TILE_SIZE * THREE_CANVAS_HEIGHT);
|
||||
const cellSize = 64;
|
||||
for (let y = 0; y < THREE_CANVAS_HEIGHT; ++y) {
|
||||
for (let z = 0; z < THREE_TILE_SIZE; ++z) {
|
||||
for (let x = 0; x < THREE_TILE_SIZE; ++x) {
|
||||
const height = (Math.sin(x / cellSize * Math.PI * 2) + Math.sin(z / cellSize * Math.PI * 3)) * (cellSize / 6) + (cellSize / 2);
|
||||
if (y < height) {
|
||||
const offset = x
|
||||
+ z * THREE_TILE_SIZE
|
||||
+ y * THREE_TILE_SIZE * THREE_TILE_SIZE;
|
||||
const clr = 1 + Math.floor(Math.random() * 31);
|
||||
this.buffer[offset] = clr;
|
||||
cnt += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(`Created buffer with ${cnt} voxels`);
|
||||
this.faceCnt = Chunk.estimateNeededFaces(this.buffer);
|
||||
this.renderChunk();
|
||||
this.ready = true;
|
||||
}
|
||||
|
||||
static estimateNeededFaces(buffer: Uint8Array) {
|
||||
let totalCnt = 0;
|
||||
|
||||
let u = 0;
|
||||
for (let y = 0; y < THREE_CANVAS_HEIGHT; ++y) {
|
||||
for (let z = 0; z < THREE_TILE_SIZE; ++z) {
|
||||
for (let x = 0; x < THREE_TILE_SIZE; ++x) {
|
||||
if (buffer[u] !== 0) {
|
||||
if (x === 0
|
||||
|| buffer[u - 1] === 0) {
|
||||
totalCnt += 1;
|
||||
}
|
||||
if (x === THREE_TILE_SIZE - 1
|
||||
|| buffer[u + 1] === 0) {
|
||||
totalCnt += 1;
|
||||
}
|
||||
if (z === 0
|
||||
|| buffer[u - THREE_TILE_SIZE] === 0) {
|
||||
totalCnt += 1;
|
||||
}
|
||||
if (z === THREE_TILE_SIZE - 1
|
||||
|| buffer[u + THREE_TILE_SIZE] === 0) {
|
||||
totalCnt += 1;
|
||||
}
|
||||
if (y !== 0
|
||||
&& buffer[u - (THREE_TILE_SIZE ** 2)] === 0) {
|
||||
totalCnt += 1;
|
||||
}
|
||||
if (y === THREE_CANVAS_HEIGHT - 1
|
||||
|| buffer[u + (THREE_TILE_SIZE ** 2)] === 0) {
|
||||
totalCnt += 1;
|
||||
}
|
||||
}
|
||||
u += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return totalCnt;
|
||||
}
|
||||
|
||||
static getOffsetOfVoxel(x: number, y: number, z: number) {
|
||||
return x + z * THREE_TILE_SIZE + y * THREE_TILE_SIZE * THREE_TILE_SIZE;
|
||||
}
|
||||
|
||||
setVoxelByOffset(offset: number, clr: number) {
|
||||
this.buffer[offset] = clr;
|
||||
this.faceCnt += 6;
|
||||
this.renderChunk();
|
||||
}
|
||||
|
||||
setVoxel(x: number, y: number, z: number, clr: number) {
|
||||
const offset = Chunk.getOffsetOfVoxel(x, y, z);
|
||||
this.setVoxelByOffset(offset, clr);
|
||||
}
|
||||
|
||||
async fromBuffer(chunkBuffer: Uint8Array) {
|
||||
this.buffer = chunkBuffer;
|
||||
this.renderChunk();
|
||||
this.ready = true;
|
||||
}
|
||||
|
||||
renderChunk() {
|
||||
let time1 = Date.now();
|
||||
|
||||
let cnt = 0;
|
||||
let cntv = 0;
|
||||
let voxel;
|
||||
const faceCnt = this.faceCnt;
|
||||
const positions = new Float32Array(faceCnt * 4 * 3);
|
||||
const normals = new Float32Array(faceCnt * 4 * 3);
|
||||
const colors = new Uint8Array(faceCnt * 4 * 3);
|
||||
const indices = new Uint32Array(faceCnt * 6);
|
||||
const { rgb } = this.palette;
|
||||
// just render faces that do not have an adjescent voxel
|
||||
for (let y = 0; y < THREE_CANVAS_HEIGHT; ++y) {
|
||||
for (let z = 0; z < THREE_TILE_SIZE; ++z) {
|
||||
for (let x = 0; x < THREE_TILE_SIZE; ++x) {
|
||||
voxel = this.getVoxel(x, y, z);
|
||||
if (voxel !== 0) {
|
||||
voxel *= 3;
|
||||
cntv += 1;
|
||||
for (let i = 0; i < 6; ++i) {
|
||||
const dir = faceDirs[i];
|
||||
const corners = faceCorners[i];
|
||||
|
||||
const neighbor = this.getVoxel(
|
||||
x + dir[0],
|
||||
y + dir[1],
|
||||
z + dir[2],
|
||||
);
|
||||
if (neighbor === 0) {
|
||||
// this voxel has no neighbor in this direction
|
||||
// so we need a face
|
||||
let ndx = cnt * 4 * 3;
|
||||
for (let c = 0; c < 4; ++c) {
|
||||
const pos = corners[c];
|
||||
positions[ndx] = pos[0] + x;
|
||||
normals[ndx] = dir[0];
|
||||
colors[ndx++] = rgb[voxel];
|
||||
positions[ndx] = pos[1] + y;
|
||||
normals[ndx] = dir[1];
|
||||
colors[ndx++] = rgb[voxel + 1];
|
||||
positions[ndx] = pos[2] + z;
|
||||
normals[ndx] = dir[2];
|
||||
colors[ndx++] = rgb[voxel + 2];
|
||||
}
|
||||
const idx = cnt * 4;
|
||||
ndx = cnt * 6;
|
||||
indices[ndx++] = idx;
|
||||
indices[ndx++] = idx + 1;
|
||||
indices[ndx++] = idx + 2;
|
||||
indices[ndx++] = idx + 2;
|
||||
indices[ndx++] = idx + 1;
|
||||
indices[ndx] = idx + 3;
|
||||
|
||||
cnt += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let time2 = Date.now();
|
||||
|
||||
const geometry = (this.mesh)
|
||||
? this.mesh.geometry
|
||||
: new THREE.BufferGeometry();
|
||||
|
||||
geometry.setAttribute(
|
||||
'position',
|
||||
new THREE.BufferAttribute(
|
||||
positions,
|
||||
3,
|
||||
),
|
||||
);
|
||||
geometry.setAttribute(
|
||||
'normal',
|
||||
new THREE.BufferAttribute(
|
||||
normals,
|
||||
3,
|
||||
),
|
||||
);
|
||||
geometry.setAttribute(
|
||||
'color',
|
||||
new THREE.BufferAttribute(
|
||||
colors,
|
||||
3,
|
||||
true,
|
||||
),
|
||||
);
|
||||
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
|
||||
geometry.computeBoundingSphere();
|
||||
geometry.setDrawRange(0, cnt * 6);
|
||||
|
||||
this.faceCnt = cnt;
|
||||
|
||||
if (!this.mesh) {
|
||||
this.mesh = new THREE.Mesh(geometry, material);
|
||||
this.mesh.name = this.key;
|
||||
}
|
||||
|
||||
let time3 = Date.now();
|
||||
console.log(`Created mesh for ${cntv} voxels with ${cnt} faces in ${time3 - time2}ms webgl and ${time2 - time1}ms data creation`);
|
||||
}
|
||||
}
|
||||
|
||||
export default Chunk;
|
|
@ -7,6 +7,14 @@
|
|||
import * as THREE from 'three';
|
||||
|
||||
import VoxelPainterControls from '../controls/VoxelPainterControls';
|
||||
import ChunkLoader from './ChunkLoader3D';
|
||||
import {
|
||||
getChunkOfPixel,
|
||||
getOffsetOfPixel,
|
||||
} from '../core/utils';
|
||||
import {
|
||||
THREE_TILE_SIZE,
|
||||
} from '../core/constants';
|
||||
import {
|
||||
setHover,
|
||||
} from '../actions';
|
||||
|
@ -23,6 +31,7 @@ class Renderer {
|
|||
voxel: Object;
|
||||
voxelMaterials: Array<Object>;
|
||||
objects: Array<Object>;
|
||||
loadedChunks: Array<Object>;
|
||||
plane: Object;
|
||||
//--
|
||||
controls: Object;
|
||||
|
@ -31,20 +40,25 @@ class Renderer {
|
|||
mouse;
|
||||
raycaster;
|
||||
pressTime: number;
|
||||
//--
|
||||
chunkLoader: ChunkLoader = null;
|
||||
forceNextRender: boolean = false;
|
||||
|
||||
constructor(store) {
|
||||
this.store = store;
|
||||
const state = store.getState();
|
||||
this.objects = [];
|
||||
this.loadedChunks = new Map();
|
||||
this.chunkLoader = new ChunkLoader(store);
|
||||
|
||||
// camera
|
||||
const camera = new THREE.PerspectiveCamera(
|
||||
45,
|
||||
window.innerWidth / window.innerHeight,
|
||||
1,
|
||||
2000,
|
||||
200,
|
||||
);
|
||||
camera.position.set(100, 160, 260);
|
||||
camera.position.set(10, 16, 26);
|
||||
camera.lookAt(0, 0, 0);
|
||||
this.camera = camera;
|
||||
|
||||
|
@ -52,9 +66,11 @@ class Renderer {
|
|||
const scene = new THREE.Scene();
|
||||
scene.background = new THREE.Color(0xf0f0f0);
|
||||
this.scene = scene;
|
||||
window.scene = scene;
|
||||
window.THREE = THREE;
|
||||
|
||||
// hover helper
|
||||
const rollOverGeo = new THREE.BoxBufferGeometry(10, 10, 10);
|
||||
const rollOverGeo = new THREE.BoxBufferGeometry(1, 1, 1);
|
||||
const rollOverMaterial = new THREE.MeshBasicMaterial({
|
||||
color: 0xff0000,
|
||||
opacity: 0.5,
|
||||
|
@ -64,11 +80,11 @@ class Renderer {
|
|||
scene.add(this.rollOverMesh);
|
||||
|
||||
// cubes
|
||||
this.voxel = new THREE.BoxBufferGeometry(10, 10, 10);
|
||||
this.voxel = new THREE.BoxBufferGeometry(1, 1, 1);
|
||||
this.initCubeMaterials(state);
|
||||
|
||||
// grid
|
||||
const gridHelper = new THREE.GridHelper(1000, 100, 0x555555, 0x555555);
|
||||
const gridHelper = new THREE.GridHelper(100, 10, 0x555555, 0x555555);
|
||||
scene.add(gridHelper);
|
||||
|
||||
//
|
||||
|
@ -76,7 +92,7 @@ class Renderer {
|
|||
this.mouse = new THREE.Vector2();
|
||||
|
||||
// Plane Floor
|
||||
const geometry = new THREE.PlaneBufferGeometry(5000, 5000);
|
||||
const geometry = new THREE.PlaneBufferGeometry(500, 500);
|
||||
geometry.rotateX(-Math.PI / 2);
|
||||
const plane = new THREE.Mesh(
|
||||
geometry,
|
||||
|
@ -106,8 +122,8 @@ class Renderer {
|
|||
controls.enableDamping = true;
|
||||
controls.dampingFactor = 0.75;
|
||||
controls.maxPolarAngle = Math.PI / 2;
|
||||
controls.minDistance = 100.00;
|
||||
controls.maxDistance = 1000.00;
|
||||
controls.minDistance = 10.00;
|
||||
controls.maxDistance = 100.00;
|
||||
this.controls = controls;
|
||||
|
||||
const { domElement } = threeRenderer;
|
||||
|
@ -120,6 +136,8 @@ class Renderer {
|
|||
domElement.addEventListener('mousedown', this.onDocumentMouseDown, false);
|
||||
domElement.addEventListener('mouseup', this.onDocumentMouseUp, false);
|
||||
window.addEventListener('resize', this.onWindowResize, false);
|
||||
|
||||
this.forceNextRender = true;
|
||||
}
|
||||
|
||||
destructor() {
|
||||
|
@ -147,10 +165,50 @@ class Renderer {
|
|||
this.voxelMaterials = cubeMaterials;
|
||||
}
|
||||
|
||||
reloadChunks() {
|
||||
console.log('Reload Chunks');
|
||||
const renderDistance = 50;
|
||||
const state = this.store.getState();
|
||||
const { canvasSize, view } = state.canvas;
|
||||
// const [x,, z] = view;
|
||||
const [x, z] = [0, 0];
|
||||
const {
|
||||
scene,
|
||||
loadedChunks,
|
||||
chunkLoader,
|
||||
} = this;
|
||||
const [xcMin, zcMin] = getChunkOfPixel(canvasSize, x - 50, z - 50, 0);
|
||||
const [xcMax, zcMax] = getChunkOfPixel(canvasSize, x + 50, z + 50, 0);
|
||||
console.log(`Get ${xcMin} - ${xcMax} - ${zcMin} - ${zcMax}`);
|
||||
for (let zc = zcMin; zc <= zcMax; ++zc) {
|
||||
for (let xc = xcMin; xc <= xcMax; ++xc) {
|
||||
const chunkKey = `${xc}:${zc}`;
|
||||
const chunk = chunkLoader.getChunk(xc, zc, true);
|
||||
if (chunk) {
|
||||
console.log(`Got Chunk ${chunkKey}`);
|
||||
loadedChunks.set(chunkKey, chunk);
|
||||
this.objects.push(chunk);
|
||||
chunk.position.fromArray([
|
||||
xc * THREE_TILE_SIZE - canvasSize / 2,
|
||||
0,
|
||||
zc * THREE_TILE_SIZE - canvasSize / 2,
|
||||
]);
|
||||
window.chunk = chunk;
|
||||
scene.add(chunk);
|
||||
console.log(`added chunk`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.threeRenderer) {
|
||||
return;
|
||||
}
|
||||
if (this.forceNextRender) {
|
||||
this.reloadChunks();
|
||||
this.forceNextRender = false;
|
||||
}
|
||||
this.controls.update();
|
||||
this.threeRenderer.render(this.scene, this.camera);
|
||||
}
|
||||
|
@ -190,16 +248,13 @@ class Renderer {
|
|||
const intersect = intersects[0];
|
||||
rollOverMesh.position
|
||||
.copy(intersect.point)
|
||||
.add(intersect.face.normal);
|
||||
.add(intersect.face.normal.multiplyScalar(0.5));
|
||||
rollOverMesh.position
|
||||
.divideScalar(10)
|
||||
.floor()
|
||||
.multiplyScalar(10)
|
||||
.addScalar(5);
|
||||
.addScalar(0.5);
|
||||
}
|
||||
const hover = rollOverMesh.position
|
||||
.toArray()
|
||||
.map((u) => Math.floor(u / 10));
|
||||
.toArray().map((u) => Math.floor(u));
|
||||
this.store.dispatch(setHover(hover));
|
||||
}
|
||||
|
||||
|
@ -247,27 +302,55 @@ class Renderer {
|
|||
case 0: {
|
||||
// left mouse button
|
||||
const state = store.getState();
|
||||
const { selectedColor } = state.gui;
|
||||
const { selectedColor, hover } = state.gui;
|
||||
const { canvasSize } = state.canvas;
|
||||
//const pos = new THREE.Vector3();
|
||||
const [x, y, z] = hover;
|
||||
/*
|
||||
const [x, y, z] = pos.copy(intersect.point)
|
||||
.add(intersect.face.normal.multiplyScalar(0.5))
|
||||
.floor()
|
||||
.addScalar(0.5)
|
||||
.toArray();
|
||||
*/
|
||||
const offset = getOffsetOfPixel(canvasSize, x, z, y);
|
||||
const [xc, zc] = getChunkOfPixel(canvasSize, x, z, y);
|
||||
this.chunkLoader.getVoxelUpdate(xc, zc, offset, selectedColor);
|
||||
/*
|
||||
const newVoxel = new THREE.Mesh(
|
||||
voxel,
|
||||
voxelMaterials[selectedColor],
|
||||
);
|
||||
newVoxel.position.copy(intersect.point)
|
||||
.add(intersect.face.normal);
|
||||
newVoxel.position.divideScalar(10)
|
||||
newVoxel.position
|
||||
.copy(intersect.point)
|
||||
.add(intersect.face.normal.multiplyScalar(0.5));
|
||||
newVoxel.position
|
||||
.floor()
|
||||
.multiplyScalar(10)
|
||||
.addScalar(5);
|
||||
.addScalar(0.5);
|
||||
scene.add(newVoxel);
|
||||
objects.push(newVoxel);
|
||||
*/
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// right mouse button
|
||||
const state = store.getState();
|
||||
const { hover } = state.gui;
|
||||
const { canvasSize } = state.canvas;
|
||||
const normal = intersect.face.normal;
|
||||
let [x, y, z] = hover;
|
||||
x -= normal.x;
|
||||
y -= normal.y;
|
||||
z -= normal.z;
|
||||
const offset = getOffsetOfPixel(canvasSize, x, z, y);
|
||||
const [xc, zc] = getChunkOfPixel(canvasSize, x, z, y);
|
||||
this.chunkLoader.getVoxelUpdate(xc, zc, offset, 0);
|
||||
/*
|
||||
if (intersect.object !== plane) {
|
||||
scene.remove(intersect.object);
|
||||
objects.splice(objects.indexOf(intersect.object), 1);
|
||||
}
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue
Block a user