make view a protected member

load view from store in child class renderers instead of parent
This commit is contained in:
HF 2024-01-21 02:41:09 +01:00
parent 7f684bb47a
commit 539c5120e7
5 changed files with 95 additions and 86 deletions

View File

@ -107,7 +107,7 @@ class PixelPainterControls {
const { clientX, clientY } = event;
this.clickTapStartTime = Date.now();
this.clickTapStartCoords = [clientX, clientY];
this.clickTapStartView = [...this.renderer.view];
this.clickTapStartView = this.renderer.view;
const { viewport } = this;
setTimeout(() => {
if (this.isClicking) {
@ -254,7 +254,7 @@ class PixelPainterControls {
this.renderer.cancelStoreViewInState();
this.clickTapStartTime = Date.now();
this.clickTapStartCoords = PixelPainterControls.getTouchCenter(event);
this.clickTapStartView = [...this.renderer.view];
this.clickTapStartView = this.renderer.view;
if (event.touches.length > 1) {
this.tapStartDist = PixelPainterControls.getMultiTouchDistance(event);
@ -321,7 +321,7 @@ class PixelPainterControls {
// if one finger got lifted or added, reset clickTabStart
this.isMultiTab = multiTouch;
this.clickTapStartCoords = [clientX, clientY];
this.clickTapStartView = [...this.renderer.view];
this.clickTapStartView = this.renderer.view;
this.tapStartDist = PixelPainterControls.getMultiTouchDistance(event);
} else {
// pan
@ -333,7 +333,7 @@ class PixelPainterControls {
if (deltaX > 2 || deltaY > 2) {
this.clearTabTimeout();
}
const { viewscale: scale } = this.renderer.view;
const { viewscale: scale } = this.renderer;
this.renderer.updateView([
lastPosX - (deltaX / scale),
lastPosY - (deltaY / scale),

View File

@ -25,8 +25,10 @@ import {
} from 'three';
import {
THREE_CANVAS_HEIGHT,
VIEW_UPDATE_DELAY,
} from '../core/constants';
const STORE_UPDATE_DELAY = VIEW_UPDATE_DELAY / 2;
// Mouse buttons
const MOUSE_BUTTONS = {
LEFT: MOUSE.ROTATE,
@ -127,7 +129,7 @@ class VoxelPainterControls {
// temp for update
quat;
quatInverse;
updateTime = Date.now();
storeViewInStateTime = Date.now();
prevTime = Date.now();
offset = new Vector3();
direction = new Vector3();
@ -176,8 +178,6 @@ class VoxelPainterControls {
this.quat = new Quaternion()
.setFromUnitVectors(camera.up, new Vector3(0, 1, 0));
this.quatInverse = this.quat.clone().invert();
this.update();
}
dispose() {
@ -261,7 +261,6 @@ class VoxelPainterControls {
this.rotateLeft(Math.PI * rotateDelta.x / element.clientHeight); // yes, height
this.rotateUp(Math.PI * rotateDelta.y / element.clientHeight);
this.rotateStart.copy(rotateEnd);
this.update();
}
handleMouseMoveDolly(event) {
@ -280,7 +279,6 @@ class VoxelPainterControls {
this.scale *= scaleDelta;
}
dollyStart.copy(this.dollyEnd);
this.update();
}
handleMouseMovePan(event) {
@ -294,7 +292,6 @@ class VoxelPainterControls {
panDelta.subVectors(panEnd, panStart).multiplyScalar(panSpeed);
this.pan(panDelta.x, panDelta.y);
panStart.copy(panEnd);
this.update();
}
// eslint-disable-next-line class-methods-use-this
@ -593,28 +590,24 @@ class VoxelPainterControls {
return;
}
this.handleTouchMoveRotate(event);
this.update();
break;
case STATE.TOUCH_PAN:
if (!enablePan) {
return;
}
this.handleTouchMovePan(event);
this.update();
break;
case STATE.TOUCH_DOLLY_PAN:
if (!enableZoom && !enablePan) {
return;
}
this.handleTouchMoveDollyPan(event);
this.update();
break;
case STATE.TOUCH_DOLLY_ROTATE:
if (!enableZoom && !enableRotate) {
return;
}
this.handleTouchMoveDollyRotate(event);
this.update();
break;
default:
this.state = STATE.NONE;
@ -713,11 +706,10 @@ class VoxelPainterControls {
this.camera.zoom = this.zoom0;
this.camera.updateProjectionMatrix();
this.update();
this.state = STATE.NONE;
}
update() {
update(force) {
const {
moveRight,
moveLeft,
@ -727,7 +719,8 @@ class VoxelPainterControls {
moveBackward,
} = this;
if (!(this.state !== STATE.NONE
if (!(force
|| this.state !== STATE.NONE
|| this.forceNextUpdate
|| moveRight || moveLeft
|| moveUp || moveDown
@ -852,6 +845,10 @@ class VoxelPainterControls {
panOffset.set(0, 0, 0);
this.scale = 1;
if (this.storeViewInStateTime + STORE_UPDATE_DELAY < time) {
this.renderer.storeViewInState();
}
return true;
}
}

View File

@ -1,6 +1,9 @@
/*
* parent class for Renderer
*/
/* eslint-disable no-underscore-dangle */
import {
VIEW_UPDATE_DELAY,
} from '../core/constants';
@ -23,17 +26,19 @@ class Renderer {
// to "subrender" known view next tick
forceNextRender = true;
forceNextSubrender = true;
// current position (subclass decies what it means),
// will be changed by controls
// TODO might be better as private and with a getter but no setter to avoid
// misconseption of it being writeable. Might have performance impact.
view = [0, 0, 0];
// current position
// third value can be scale (2d) or z axis (3d)
_view = [0, 0, 0];
//
#storeViewTimeout = null;
constructor(store) {
this.store = store;
this.loadViewFromState();
//this.loadViewFromState();
}
get view() {
return [...this._view];
}
get chunks() {
@ -52,7 +57,7 @@ class Renderer {
updateView(view) {
for (let i = 0; i < view.length; i += 1) {
this.view[i] = view[i];
this._view[i] = view[i];
}
}
@ -83,7 +88,7 @@ class Renderer {
}
render() {
return this.controls.update();
return this.controls.update(this.forceNextRender);
}
renderPixel() {}

View File

@ -3,6 +3,8 @@
*
*/
/* eslint-disable no-underscore-dangle */
import {
TILE_ZOOM_LEVEL,
TILE_SIZE,
@ -29,40 +31,28 @@ import pixelNotify from './PixelNotify';
class Renderer2D extends Renderer {
canvasId = null;
viewscale;
viewscale = 0;
//--
centerChunk;
tiledScale;
tiledZoom;
hover;
centerChunk = [null, null];
tiledScale = 0;
tiledZoom = 4;
hover = false;
//--
viewport = null;
//--
forceNextRender;
forceNextSubrender;
lastFetch = 0;
canvas;
lastFetch;
//--
oldHistoricalTime;
oldHistoricalTime = null;
constructor(store) {
super(store);
this.is3D = false;
[,, this.viewscale] = this.view;
this.centerChunk = [null, null];
this.tiledScale = 0;
this.tiledZoom = 4;
this.canvasMaxTiledZoom = 0;
this.historicalCanvasMaxTiledZoom = 0;
this.hover = false;
this.scaleThreshold = 1;
//--
this.forceNextRender = true;
this.forceNextSubrender = true;
this.lastFetch = 0;
this.oldHistoricalTime = null;
//--
const viewport = document.createElement('canvas');
viewport.className = 'viewport';
const viewportCtx = viewport.getContext('2d', { alpha: false });
@ -124,6 +114,7 @@ class Renderer2D extends Renderer {
canvasId,
} = state.canvas;
if (canvasId !== this.canvasId) {
// TODO doesn't immediatelly reload when change from 3d to 2d
this.canvasId = canvasId;
if (canvasId !== null) {
const {
@ -141,9 +132,8 @@ class Renderer2D extends Renderer {
canvases[canvasId].historicalSizes,
);
}
// scale of 0 is impossible, so it always updates
this.view[2] = 0;
this.updateView(state.canvas.view);
this.forceNextRender = true;
}
}
@ -202,7 +192,7 @@ class Renderer2D extends Renderer {
this.viewscale = scale;
}
} else {
[,, scale] = this.view;
[,, scale] = this._view;
}
// clamp coords
const canvasMinXY = -canvasSize / 2;
@ -253,7 +243,6 @@ class Renderer2D extends Renderer {
}
}
renderPixel(
i,
j,
@ -450,8 +439,8 @@ class Renderer2D extends Renderer {
state,
) {
const {
_view,
viewport,
view,
viewscale,
} = this;
const {
@ -468,7 +457,7 @@ class Renderer2D extends Renderer {
hover,
} = state.canvas;
const [x, y] = view;
const [x, y] = _view;
const [cx, cy] = this.centerChunk;
// if we have to render pixelnotify
@ -553,18 +542,18 @@ class Renderer2D extends Renderer {
}
if (showGrid && viewscale >= 8) {
renderGrid(state, viewport, view, viewscale, isLightGrid);
renderGrid(state, viewport, _view, viewscale, isLightGrid);
}
if (doRenderPixelnotify) {
pixelNotify.render(state, viewport, view, viewscale);
pixelNotify.render(state, viewport, _view, viewscale);
}
if (hover && doRenderPlaceholder) {
renderPlaceholder(state, viewport, view, viewscale);
renderPlaceholder(state, viewport, _view, viewscale);
}
if (hover && doRenderPotatoPlaceholder) {
renderPotatoPlaceholder(state, viewport, view, viewscale);
renderPotatoPlaceholder(state, viewport, _view, viewscale);
}
}
@ -704,7 +693,6 @@ class Renderer2D extends Renderer {
) {
const {
viewport,
view,
viewscale,
} = this;
const {
@ -715,7 +703,7 @@ class Renderer2D extends Renderer {
historicalCanvasSize,
} = state.canvas;
const [x, y] = view;
const [x, y] = this._view;
const [cx, cy] = this.centerChunk;
if (!this.forceNextRender && !this.forceNextSubrender) {

View File

@ -44,12 +44,17 @@ const renderDistance = 150;
class Renderer3D extends Renderer {
scene;
camera;
// current chunk in center of view
centerChunk = [null, null];
// position camera is looking at
target = new Vector3();
// red voxel cursor cube
rollOverMesh;
objects;
loadedChunks;
// loaded objects in scene
objects = [];
// map of chunkId to chunk mesh
loadedChunks = new Map();
// plane object
plane;
oobGeometry;
oobMaterial;
@ -67,8 +72,8 @@ class Renderer3D extends Renderer {
constructor(store) {
super(store);
this.is3D = true;
this.loadViewFromState();
const state = store.getState();
this.objects = [];
// camera
const camera = new PerspectiveCamera(
@ -212,16 +217,14 @@ class Renderer3D extends Renderer {
window.addEventListener('resize', this.onWindowResize, false);
this.updateCanvasData(state);
// TODO REMOVE
window.renderer = this;
}
get view() {
return this.target.toArray();
}
set view(view) {
this.target.set(...view);
}
destructor() {
window.removeEventListener('resize', this.onWindowResize, false);
this.threeRenderer.dispose();
@ -236,7 +239,8 @@ class Renderer3D extends Renderer {
if (view.length !== 3) {
return;
}
this.view = view;
console.log('go to', view);
this.target.set(...view);
this.forceNextRender = true;
}
@ -252,18 +256,18 @@ class Renderer3D extends Renderer {
if (canvasId !== this.canvasId) {
this.canvasId = canvasId;
if (canvasId !== null) {
if (this.chunkLoader) {
// destroy old chunks,
// meshes need to get disposed
if (this.loadedChunks) {
this.loadedChunks.forEach((chunk) => {
this.scene.remove(chunk);
this.objects = [this.plane];
});
this.chunkLoader.destructor();
}
// destroy old chunks,
// meshes need to get disposed
if (this.loadedChunks.length) {
this.loadedChunks.forEach((chunk) => {
this.scene.remove(chunk);
});
this.loadedChunks = new Map();
}
this.loadedChunks = new Map();
if (this.chunkLoader) {
this.chunkLoader.destructor();
}
this.objects = [this.plane];
const {
palette,
canvasSize,
@ -275,9 +279,9 @@ class Renderer3D extends Renderer {
canvasSize,
);
}
this.updateView(view);
this.forceNextRender = true;
}
this.updateView(view);
this.forceNextRender = true;
}
renderPixel(
@ -290,6 +294,7 @@ class Renderer3D extends Renderer {
if (chunkLoader) {
chunkLoader.getVoxelUpdate(i, j, offset, color);
}
this.forceNextSubrender = true;
}
isChunkInView(yc, xc, zc) {
@ -304,18 +309,13 @@ class Renderer3D extends Renderer {
if (!this.chunkLoader) {
return;
}
const state = this.store.getState();
const {
canvasSize,
view,
} = state.canvas;
const x = view[0];
const z = view[2] || 0;
const { canvasSize } = this.store.getState().canvas;
const {
scene,
loadedChunks,
chunkLoader,
} = this;
const { x, z } = this.target;
const [xcMin, zcMin] = getChunkOfPixel(
canvasSize,
x - renderDistance,
@ -374,13 +374,31 @@ class Renderer3D extends Renderer {
return;
}
const controlUpdate = super.render();
if (this.forceNextRender) {
this.reloadChunks();
// check if we enter new chunk
if (controlUpdate) {
const { canvasSize } = this.store.getState().canvas;
const prevCenterChunk = this.centerChunk;
const { x, z } = this.target;
const centerChunk = getChunkOfPixel(canvasSize, x, 0, z);
if (!prevCenterChunk
|| prevCenterChunk[0] !== centerChunk[0]
|| prevCenterChunk[1] !== centerChunk[1]
) {
this.centerChunk = centerChunk;
this.forceNextRender = true;
console.log('new cc', this.centerChunk);
}
}
if (this.forceNextRender
|| this.forceNextSubrender
|| controlUpdate
) {
if (this.forceNextRender) {
this.reloadChunks();
}
if (this.forceNextRender) {
if (this.lol !== 'force') {
console.log(this.lol, this.lola);
@ -421,6 +439,7 @@ class Renderer3D extends Renderer {
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.threeRenderer.setSize(window.innerWidth, window.innerHeight);
this.forceNextSubrender = true;
}
updateRollOverMesh(sx, sy) {