|
@@ -1,7 +1,7 @@
|
|
|
import { Engine } from 'babylonjs/Engines/engine';
|
|
|
import { Scene } from 'babylonjs/scene';
|
|
|
import { Vector3, Vector2 } from 'babylonjs/Maths/math.vector';
|
|
|
-import { Color4 } from 'babylonjs/Maths/math.color';
|
|
|
+import { Color4, Color3 } from 'babylonjs/Maths/math.color';
|
|
|
import { FreeCamera } from 'babylonjs/Cameras/freeCamera';
|
|
|
import { Nullable } from 'babylonjs/types'
|
|
|
|
|
@@ -13,11 +13,10 @@ import { BaseTexture } from 'babylonjs/Materials/Textures/baseTexture';
|
|
|
import { HtmlElementTexture } from 'babylonjs/Materials/Textures/htmlElementTexture';
|
|
|
import { InternalTexture } from 'babylonjs/Materials/Textures/internalTexture';
|
|
|
import { Texture } from 'babylonjs/Materials/Textures/texture';
|
|
|
-import { NodeMaterial } from 'babylonjs/Materials/Node/nodeMaterial';
|
|
|
-import { PBRMaterial } from 'babylonjs/Materials/PBR/pbrMaterial';
|
|
|
import { RawCubeTexture } from 'babylonjs/Materials/Textures/rawCubeTexture';
|
|
|
import { CubeTexture } from 'babylonjs/Materials/Textures/cubeTexture';
|
|
|
-
|
|
|
+import { ShaderMaterial } from 'babylonjs/Materials/shaderMaterial';
|
|
|
+import { StandardMaterial } from 'babylonjs/Materials/standardMaterial';
|
|
|
|
|
|
import { ISize } from 'babylonjs/Maths/math.size';
|
|
|
import { Tools } from 'babylonjs/Misc/tools';
|
|
@@ -25,12 +24,19 @@ import { Tools } from 'babylonjs/Misc/tools';
|
|
|
import { PointerEventTypes, PointerInfo } from 'babylonjs/Events/pointerEvents';
|
|
|
import { KeyboardEventTypes } from 'babylonjs/Events/keyboardEvents';
|
|
|
|
|
|
-import { TextureHelper, TextureChannelsToDisplay } from '../../../../../../textureHelper';
|
|
|
+import { TextureHelper } from '../../../../../../textureHelper';
|
|
|
+
|
|
|
+import { ITool } from './toolBar';
|
|
|
+import { IChannel } from './channelsBar';
|
|
|
+import { TextBlock } from 'babylonjs-gui/2D/controls/textBlock';
|
|
|
+import { Rectangle } from 'babylonjs-gui/2D/controls/rectangle';
|
|
|
+import { StackPanel } from 'babylonjs-gui/2D/controls/stackPanel';
|
|
|
+import { Control } from 'babylonjs-gui/2D/controls/control';
|
|
|
+import { Style } from 'babylonjs-gui/2D/style';
|
|
|
+import { AdvancedDynamicTexture } from 'babylonjs-gui/2D/advancedDynamicTexture';
|
|
|
|
|
|
-import { Tool } from './toolBar';
|
|
|
-import { Channel } from './channelsBar';
|
|
|
|
|
|
-export interface PixelData {
|
|
|
+export interface IPixelData {
|
|
|
x? : number;
|
|
|
y? : number;
|
|
|
r? : number;
|
|
@@ -39,6 +45,14 @@ export interface PixelData {
|
|
|
a? : number;
|
|
|
}
|
|
|
|
|
|
+export interface IToolGUI {
|
|
|
+ adt: AdvancedDynamicTexture;
|
|
|
+ toolWindow: StackPanel;
|
|
|
+ isDragging: boolean;
|
|
|
+ dragCoords: Nullable<Vector2>;
|
|
|
+ style: Style;
|
|
|
+}
|
|
|
+
|
|
|
export class TextureCanvasManager {
|
|
|
private _engine: Engine;
|
|
|
private _scene: Scene;
|
|
@@ -55,12 +69,18 @@ export class TextureCanvasManager {
|
|
|
|
|
|
/* The canvas we paint onto using the canvas API */
|
|
|
private _2DCanvas : HTMLCanvasElement;
|
|
|
+ /* The canvas we apply post processes to */
|
|
|
+ private _3DCanvas : HTMLCanvasElement;
|
|
|
+ /* The canvas which handles channel filtering */
|
|
|
+ private _channelsTexture : HtmlElementTexture;
|
|
|
|
|
|
- private _displayCanvas : HTMLCanvasElement;
|
|
|
- private _channels : Channel[] = [];
|
|
|
+ private _3DEngine : Engine;
|
|
|
+ private _3DPlane : Mesh;
|
|
|
+ private _3DCanvasTexture : HtmlElementTexture;
|
|
|
+ private _3DScene : Scene;
|
|
|
+
|
|
|
+ private _channels : IChannel[] = [];
|
|
|
private _face : number = 0;
|
|
|
- /* The texture that we are actually displaying. It is created by sampling a combination of channels from _texture */
|
|
|
- private _displayTexture : HtmlElementTexture;
|
|
|
|
|
|
/* The texture from the original engine that we invoked the editor on */
|
|
|
private _originalTexture: BaseTexture;
|
|
@@ -72,8 +92,7 @@ export class TextureCanvasManager {
|
|
|
private _didEdit : boolean = false;
|
|
|
|
|
|
private _plane : Mesh;
|
|
|
- private _planeMaterial : NodeMaterial;
|
|
|
- private _planeFallbackMaterial : PBRMaterial;
|
|
|
+ private _planeMaterial : ShaderMaterial;
|
|
|
|
|
|
/* Tracks which keys are currently pressed */
|
|
|
private _keyMap : any = {};
|
|
@@ -84,31 +103,36 @@ export class TextureCanvasManager {
|
|
|
private static ZOOM_OUT_KEY : string = '-';
|
|
|
|
|
|
private static PAN_SPEED : number = 0.002;
|
|
|
- private static PAN_MOUSE_BUTTON : number = 0; // LMB
|
|
|
- private static PAN_KEY : string = ' ';
|
|
|
+ private static PAN_MOUSE_BUTTON : number = 1; // MMB
|
|
|
|
|
|
private static MIN_SCALE : number = 0.01;
|
|
|
private static MAX_SCALE : number = 10;
|
|
|
|
|
|
- private _tool : Nullable<Tool>;
|
|
|
+ private _tool : Nullable<ITool>;
|
|
|
+
|
|
|
+ private _setPixelData : (pixelData : IPixelData) => void;
|
|
|
+
|
|
|
+ private _GUI : IToolGUI;
|
|
|
|
|
|
- private _setPixelData : (pixelData : PixelData) => void;
|
|
|
+ private _window : Window;
|
|
|
|
|
|
- public metadata : any = {
|
|
|
- color: '#ffffff',
|
|
|
- opacity: 1.0
|
|
|
- };
|
|
|
+ public metadata : any = {};
|
|
|
+
|
|
|
+ private _editing3D : boolean = false;
|
|
|
|
|
|
public constructor(
|
|
|
texture: BaseTexture,
|
|
|
+ window: Window,
|
|
|
canvasUI: HTMLCanvasElement,
|
|
|
canvas2D: HTMLCanvasElement,
|
|
|
- canvasDisplay: HTMLCanvasElement,
|
|
|
- setPixelData : (pixelData : PixelData) => void
|
|
|
+ canvas3D: HTMLCanvasElement,
|
|
|
+ setPixelData: (pixelData : IPixelData) => void
|
|
|
) {
|
|
|
+ this._window = window;
|
|
|
+
|
|
|
this._UICanvas = canvasUI;
|
|
|
this._2DCanvas = canvas2D;
|
|
|
- this._displayCanvas = canvasDisplay;
|
|
|
+ this._3DCanvas = canvas3D;
|
|
|
this._setPixelData = setPixelData;
|
|
|
|
|
|
this._size = texture.getSize();
|
|
@@ -118,34 +142,178 @@ export class TextureCanvasManager {
|
|
|
this._scene = new Scene(this._engine);
|
|
|
this._scene.clearColor = new Color4(0.11, 0.11, 0.11, 1.0);
|
|
|
|
|
|
- this._camera = new FreeCamera("Camera", new Vector3(0, 0, -1), this._scene);
|
|
|
+ this._camera = new FreeCamera('camera', new Vector3(0, 0, -1), this._scene);
|
|
|
this._camera.mode = Camera.ORTHOGRAPHIC_CAMERA;
|
|
|
|
|
|
- this._planeFallbackMaterial = new PBRMaterial('fallback_material', this._scene);
|
|
|
- this._planeFallbackMaterial.albedoTexture = this._displayTexture;
|
|
|
- this._planeFallbackMaterial.disableLighting = true;
|
|
|
- this._planeFallbackMaterial.unlit = true;
|
|
|
+ this._channelsTexture = new HtmlElementTexture('ct', this._2DCanvas, {engine: this._engine, scene: null, samplingMode: Engine.TEXTURE_NEAREST_LINEAR});
|
|
|
+
|
|
|
+ this._3DEngine = new Engine(this._3DCanvas);
|
|
|
+ this._3DScene = new Scene(this._3DEngine);
|
|
|
+ this._3DScene.clearColor = new Color4(0,0,0,0);
|
|
|
+ this._3DCanvasTexture = new HtmlElementTexture('canvas', this._2DCanvas, {engine: this._3DEngine, scene: this._3DScene});
|
|
|
+ this._3DCanvasTexture.hasAlpha = true;
|
|
|
+ const cam = new FreeCamera('camera', new Vector3(0,0,-1), this._3DScene);
|
|
|
+ cam.mode = Camera.ORTHOGRAPHIC_CAMERA;
|
|
|
+ [cam.orthoBottom, cam.orthoLeft, cam.orthoTop, cam.orthoRight] = [-0.5, -0.5, 0.5, 0.5];
|
|
|
+ this._3DPlane = PlaneBuilder.CreatePlane('texture', {width: 1, height: 1}, this._3DScene);
|
|
|
+ const mat = new StandardMaterial('material', this._3DScene);
|
|
|
+ mat.diffuseTexture = this._3DCanvasTexture;
|
|
|
+ mat.disableLighting = true;
|
|
|
+ mat.emissiveColor = Color3.White();
|
|
|
+ this._3DPlane.material = mat;
|
|
|
+
|
|
|
|
|
|
- this._displayTexture = new HtmlElementTexture("display", this._displayCanvas, {engine: this._engine, scene: this._scene});
|
|
|
- this._displayTexture.updateSamplingMode(Engine.TEXTURE_NEAREST_LINEAR);
|
|
|
this.grabOriginalTexture();
|
|
|
|
|
|
- NodeMaterial.ParseFromSnippetAsync("#TPSEV2#4", this._scene)
|
|
|
- .then((material) => {
|
|
|
- this._planeMaterial = material;
|
|
|
- this._planeMaterial.getTextureBlocks()[0].texture = this._displayTexture;
|
|
|
- this._plane.material = this._planeMaterial;
|
|
|
- this._UICanvas.focus();
|
|
|
- });
|
|
|
+
|
|
|
+ this._planeMaterial = new ShaderMaterial(
|
|
|
+ 'shader',
|
|
|
+ this._scene,
|
|
|
+ {
|
|
|
+ vertexSource: `
|
|
|
+ precision highp float;
|
|
|
+
|
|
|
+ attribute vec3 position;
|
|
|
+ attribute vec2 uv;
|
|
|
+
|
|
|
+ uniform mat4 worldViewProjection;
|
|
|
+
|
|
|
+ varying vec2 vUV;
|
|
|
+
|
|
|
+ void main(void) {
|
|
|
+ gl_Position = worldViewProjection * vec4(position, 1.0);
|
|
|
+ vUV = uv;
|
|
|
+ }
|
|
|
+ `,
|
|
|
+ fragmentSource: `
|
|
|
+ precision highp float;
|
|
|
+
|
|
|
+ uniform sampler2D textureSampler;
|
|
|
+
|
|
|
+ uniform bool r;
|
|
|
+ uniform bool g;
|
|
|
+ uniform bool b;
|
|
|
+ uniform bool a;
|
|
|
+
|
|
|
+ varying vec2 vUV;
|
|
|
+
|
|
|
+ void main(void) {
|
|
|
+ float size = 20.0;
|
|
|
+ vec2 pos2 = vec2(gl_FragCoord.x, gl_FragCoord.y);
|
|
|
+ vec2 pos = floor(pos2 * 0.05);
|
|
|
+ float pattern = mod(pos.x + pos.y, 2.0);
|
|
|
+ if (pattern == 0.0) {
|
|
|
+ pattern = 0.7;
|
|
|
+ }
|
|
|
+ vec4 bg = vec4(pattern, pattern, pattern, 1.0);
|
|
|
+ vec4 col = texture(textureSampler, vUV);
|
|
|
+ if (!r && !g && !b) {
|
|
|
+ if (a) {
|
|
|
+ col = vec4(col.a, col.a, col.a, 1.0);
|
|
|
+ } else {
|
|
|
+ col = vec4(0.0,0.0,0.0,0.0);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!r) {
|
|
|
+ col.r = 0.0;
|
|
|
+ if (!b) {
|
|
|
+ col.r = col.g;
|
|
|
+ }
|
|
|
+ else if (!g) {
|
|
|
+ col.r = col.b;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!g) {
|
|
|
+ col.g = 0.0;
|
|
|
+ if (!b) {
|
|
|
+ col.g = col.r;
|
|
|
+ }
|
|
|
+ else if (!r) {
|
|
|
+ col.g = col.b;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!b) {
|
|
|
+ col.b = 0.0;
|
|
|
+ if (!r) {
|
|
|
+ col.b = col.g;
|
|
|
+ } else if (!g) {
|
|
|
+ col.b = col.r;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!a) {
|
|
|
+ col.a = 1.0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ gl_FragColor = col;
|
|
|
+ gl_FragColor = col * (col.a) + bg * (1.0 - col.a);
|
|
|
+ }`
|
|
|
+ },
|
|
|
+ {
|
|
|
+ attributes: ['position', 'uv'],
|
|
|
+ uniforms: ['worldViewProjection', 'textureSampler', 'r', 'g', 'b', 'a']
|
|
|
+ });
|
|
|
+
|
|
|
+ this._planeMaterial.setTexture('textureSampler', this._channelsTexture);
|
|
|
+ this._planeMaterial.setFloat('r', 1.0);
|
|
|
+ this._planeMaterial.setFloat('g', 1.0);
|
|
|
+ this._planeMaterial.setFloat('b', 1.0);
|
|
|
+ this._planeMaterial.setFloat('a', 1.0);
|
|
|
+ this._plane.material = this._planeMaterial;
|
|
|
+
|
|
|
+ const adt = AdvancedDynamicTexture.CreateFullscreenUI('gui', true, this._scene);
|
|
|
+ const style = adt.createStyle();
|
|
|
+ style.fontFamily = 'acumin-pro-condensed';
|
|
|
+ style.fontSize = '15px';
|
|
|
+
|
|
|
+ const toolWindow = new StackPanel();
|
|
|
+ toolWindow.background = '#333333';
|
|
|
+ toolWindow.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_RIGHT;
|
|
|
+ toolWindow.verticalAlignment = Control.VERTICAL_ALIGNMENT_BOTTOM;
|
|
|
+ toolWindow.left = '0px';
|
|
|
+ toolWindow.top = '-30px';
|
|
|
+ toolWindow.width = '200px';
|
|
|
+ toolWindow.isVisible = false;
|
|
|
+ toolWindow.isPointerBlocker = true;
|
|
|
+ adt.addControl(toolWindow);
|
|
|
+
|
|
|
+ this._GUI = {adt, style, toolWindow, isDragging: false, dragCoords: null};
|
|
|
+
|
|
|
+ const topBar = new Rectangle();
|
|
|
+ topBar.width = '100%';
|
|
|
+ topBar.height = '20px';
|
|
|
+ topBar.background = '#666666';
|
|
|
+ topBar.thickness = 0;
|
|
|
+ topBar.hoverCursor = 'grab';
|
|
|
+ topBar.onPointerDownObservable.add(evt => {this._GUI.isDragging = true; topBar.hoverCursor = 'grabbing';});
|
|
|
+ topBar.onPointerUpObservable.add(() => {this._GUI.isDragging = false; this._GUI.dragCoords = null; topBar.hoverCursor = 'grab';});
|
|
|
+
|
|
|
+ const title = new TextBlock();
|
|
|
+ title.text = 'Tool Settings';
|
|
|
+ title.color = 'white';
|
|
|
+ title.height = '20px';
|
|
|
+ title.style = this._GUI.style;
|
|
|
+ topBar.addControl(title);
|
|
|
+ this._GUI.toolWindow.addControl(topBar);
|
|
|
+
|
|
|
+ this._window.addEventListener('pointermove', (evt : PointerEvent) => {
|
|
|
+ if (!this._GUI.isDragging) return;
|
|
|
+ if (!this._GUI.dragCoords) {
|
|
|
+ this._GUI.dragCoords = new Vector2(evt.x, evt.y);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let x = parseInt(this._GUI.toolWindow.left.toString().replace('px', ''));
|
|
|
+ let y = parseInt(this._GUI.toolWindow.top.toString().replace('px', ''));
|
|
|
+ x += evt.x - this._GUI.dragCoords.x;
|
|
|
+ y += evt.y - this._GUI.dragCoords.y;
|
|
|
+ this._GUI.toolWindow.left = `${x}px`;
|
|
|
+ this._GUI.toolWindow.top = `${y}px`;
|
|
|
+ this._GUI.dragCoords.x = evt.x;
|
|
|
+ this._GUI.dragCoords.y = evt.y;
|
|
|
+ });
|
|
|
|
|
|
this._engine.runRenderLoop(() => {
|
|
|
this._engine.resize();
|
|
|
this._scene.render();
|
|
|
- let cursor = 'initial';
|
|
|
- if (this._keyMap[TextureCanvasManager.PAN_KEY]) {
|
|
|
- cursor = 'pointer';
|
|
|
- }
|
|
|
- this._UICanvas.parentElement!.style.cursor = cursor;
|
|
|
});
|
|
|
|
|
|
this._scale = 1.5;
|
|
@@ -167,7 +335,7 @@ export class TextureCanvasManager {
|
|
|
this._scale -= (event.deltaY * TextureCanvasManager.ZOOM_MOUSE_SPEED * this._scale);
|
|
|
break;
|
|
|
case PointerEventTypes.POINTERDOWN:
|
|
|
- if (pointerInfo.event.button === TextureCanvasManager.PAN_MOUSE_BUTTON && this._keyMap[TextureCanvasManager.PAN_KEY]) {
|
|
|
+ if (pointerInfo.event.button === TextureCanvasManager.PAN_MOUSE_BUTTON) {
|
|
|
this._isPanning = true;
|
|
|
this._mouseX = pointerInfo.event.x;
|
|
|
this._mouseY = pointerInfo.event.y;
|
|
@@ -211,67 +379,47 @@ export class TextureCanvasManager {
|
|
|
break;
|
|
|
case KeyboardEventTypes.KEYUP:
|
|
|
this._keyMap[kbInfo.event.key] = false;
|
|
|
- if (kbInfo.event.key == TextureCanvasManager.PAN_KEY) {
|
|
|
- this._isPanning = false;
|
|
|
- }
|
|
|
break;
|
|
|
}
|
|
|
- })
|
|
|
-
|
|
|
- this._scene.debugLayer.show();
|
|
|
-
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
public async updateTexture() {
|
|
|
this._didEdit = true;
|
|
|
+ const element = this._editing3D ? this._3DCanvas : this._2DCanvas;
|
|
|
+ if (this._editing3D) {
|
|
|
+ this._3DCanvasTexture.update();
|
|
|
+ this._3DScene.render();
|
|
|
+ }
|
|
|
if (this._originalTexture.isCube) {
|
|
|
// TODO: fix cube map editing
|
|
|
- let pixels : ArrayBufferView[] = [];
|
|
|
- for (let face = 0; face < 6; face++) {
|
|
|
- let textureToCopy = this._originalTexture;
|
|
|
- if (face === this._face) {
|
|
|
- // textureToCopy = this._texture;
|
|
|
- }
|
|
|
- pixels[face] = await TextureHelper.GetTextureDataAsync(textureToCopy, this._size.width, this._size.height, face, {R: true, G: true, B: true, A: true});
|
|
|
- }
|
|
|
- if (!this._target) {
|
|
|
- this._target = new RawCubeTexture(this._originalTexture.getScene()!, pixels, this._size.width, this._originalTexture.textureFormat, Engine.TEXTURETYPE_UNSIGNED_INT, false);
|
|
|
- this._target.getScene()?.removeTexture(this._target);
|
|
|
- } else {
|
|
|
- (this._target as RawCubeTexture).update(pixels, this._originalTexture.textureFormat, this._originalTexture.textureType, false);
|
|
|
- }
|
|
|
} else {
|
|
|
if (!this._target) {
|
|
|
this._target = new HtmlElementTexture(
|
|
|
"editor",
|
|
|
- this._2DCanvas,
|
|
|
+ element,
|
|
|
{
|
|
|
engine: this._originalTexture.getScene()?.getEngine()!,
|
|
|
scene: null,
|
|
|
samplingMode: (this._originalTexture as Texture).samplingMode
|
|
|
}
|
|
|
);
|
|
|
+ } else {
|
|
|
+ (this._target as HtmlElementTexture).element = element;
|
|
|
}
|
|
|
(this._target as HtmlElementTexture).update((this._originalTexture as Texture).invertY);
|
|
|
}
|
|
|
this._originalTexture._texture = this._target._texture;
|
|
|
- this.copyTextureToDisplayTexture();
|
|
|
+ this._channelsTexture.element = element;
|
|
|
+ this.updateDisplay();
|
|
|
}
|
|
|
|
|
|
- private async copyTextureToDisplayTexture() {
|
|
|
- let channelsToDisplay : TextureChannelsToDisplay = {
|
|
|
- R: true,
|
|
|
- G: true,
|
|
|
- B: true,
|
|
|
- A: true
|
|
|
- }
|
|
|
- this._channels.forEach(channel => channelsToDisplay[channel.id] = channel.visible);
|
|
|
- const pixels = await TextureHelper.GetTextureDataAsync(this._originalTexture, this._size.width, this._size.height, this._face, channelsToDisplay);
|
|
|
- TextureCanvasManager.paintPixelsOnCanvas(pixels, this._displayCanvas);
|
|
|
- this._displayTexture.update();
|
|
|
+ private updateDisplay() {
|
|
|
+ this._3DScene.render()
|
|
|
+ this._channelsTexture.update();
|
|
|
}
|
|
|
|
|
|
- public set channels(channels: Channel[]) {
|
|
|
+ public set channels(channels: IChannel[]) {
|
|
|
// Determine if we need to re-render the texture. This is an expensive operation, so we should only do it if channel visibility has changed.
|
|
|
let needsRender = false;
|
|
|
if (channels.length !== this._channels.length) {
|
|
@@ -282,13 +430,14 @@ export class TextureCanvasManager {
|
|
|
(channel,index) => {
|
|
|
if (channel.visible !== this._channels[index].visible) {
|
|
|
needsRender = true;
|
|
|
+ this._planeMaterial.setFloat(channel.id.toLowerCase(), channel.visible ? 1.0 : 0.0);
|
|
|
}
|
|
|
}
|
|
|
);
|
|
|
}
|
|
|
this._channels = channels;
|
|
|
if (needsRender) {
|
|
|
- this.copyTextureToDisplayTexture();
|
|
|
+ this.updateDisplay();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -299,10 +448,9 @@ export class TextureCanvasManager {
|
|
|
ctx.putImageData(imgData, 0, 0);
|
|
|
}
|
|
|
|
|
|
- public grabOriginalTexture() {
|
|
|
+ public grabOriginalTexture(adjustZoom = true) {
|
|
|
// Grab image data from original texture and paint it onto the context of a DynamicTexture
|
|
|
- this._size = this._originalTexture.getSize();
|
|
|
- this.updateSize();
|
|
|
+ this.setSize(this._originalTexture.getSize(), adjustZoom);
|
|
|
TextureHelper.GetTextureDataAsync(
|
|
|
this._originalTexture,
|
|
|
this._size.width,
|
|
@@ -311,11 +459,12 @@ export class TextureCanvasManager {
|
|
|
{R:true ,G:true ,B:true ,A:true}
|
|
|
).then(data => {
|
|
|
TextureCanvasManager.paintPixelsOnCanvas(data, this._2DCanvas);
|
|
|
- this.copyTextureToDisplayTexture();
|
|
|
+ this._3DCanvasTexture.update();
|
|
|
+ this.updateDisplay();
|
|
|
})
|
|
|
}
|
|
|
|
|
|
- public getMouseCoordinates(pointerInfo : PointerInfo) : Vector2 {
|
|
|
+ public getMouseCoordinates(pointerInfo : PointerInfo) {
|
|
|
if (pointerInfo.pickInfo?.hit) {
|
|
|
const x = Math.floor(pointerInfo.pickInfo.getTextureCoordinates()!.x * this._size.width);
|
|
|
const y = Math.floor((1 - pointerInfo.pickInfo.getTextureCoordinates()!.y) * this._size.height);
|
|
@@ -325,39 +474,64 @@ export class TextureCanvasManager {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public get scene() : Scene {
|
|
|
+ public get scene() {
|
|
|
return this._scene;
|
|
|
}
|
|
|
|
|
|
- public get canvas2D() : HTMLCanvasElement {
|
|
|
+ public get canvas2D() {
|
|
|
return this._2DCanvas;
|
|
|
}
|
|
|
|
|
|
- public get size() : ISize {
|
|
|
+ public get size() {
|
|
|
return this._size;
|
|
|
}
|
|
|
|
|
|
- public set tool(tool: Nullable<Tool>) {
|
|
|
+ public set tool(tool: Nullable<ITool>) {
|
|
|
if (this._tool) {
|
|
|
this._tool.instance.cleanup();
|
|
|
}
|
|
|
this._tool = tool;
|
|
|
if (this._tool) {
|
|
|
this._tool.instance.setup();
|
|
|
+ if (this._tool.usesWindow) {
|
|
|
+ this._GUI.toolWindow.isVisible = true;
|
|
|
+ } else {
|
|
|
+ this._GUI.toolWindow.isVisible = false;
|
|
|
+ }
|
|
|
+ if (this._editing3D && !this._tool.is3D) {
|
|
|
+ this._editing3D = false;
|
|
|
+ this._2DCanvas.getContext('2d')?.drawImage(this._3DCanvas, 0, 0);
|
|
|
+ }
|
|
|
+ else if (!this._editing3D && this._tool.is3D) {
|
|
|
+ this._editing3D = true;
|
|
|
+ this.updateTexture();
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public get tool(): Nullable<Tool> {
|
|
|
+ public get tool() {
|
|
|
return this._tool;
|
|
|
}
|
|
|
|
|
|
+ // BROKEN : FIX THIS
|
|
|
public set face(face: number) {
|
|
|
if (this._face !== face) {
|
|
|
this._face = face;
|
|
|
- this.copyTextureToDisplayTexture();
|
|
|
+ this.grabOriginalTexture(false);
|
|
|
+ this.updateDisplay();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /** Returns the tool GUI object, allowing tools to access the GUI */
|
|
|
+ public get GUI() {
|
|
|
+ return this._GUI;
|
|
|
+ }
|
|
|
+
|
|
|
+ /** Returns the 3D scene used for postprocesses */
|
|
|
+ public get scene3D() {
|
|
|
+ return this._3DScene;
|
|
|
+ }
|
|
|
+
|
|
|
private makePlane() {
|
|
|
const textureRatio = this._size.width / this._size.height;
|
|
|
if (this._plane) this._plane.dispose();
|
|
@@ -366,10 +540,13 @@ export class TextureCanvasManager {
|
|
|
this._plane.edgesWidth = 4.0;
|
|
|
this._plane.edgesColor = new Color4(1,1,1,1);
|
|
|
this._plane.enablePointerMoveEvents = true;
|
|
|
- if (this._planeMaterial) this._plane.material = this._planeMaterial; else this._plane.material = this._planeFallbackMaterial;
|
|
|
+ this._plane.material = this._planeMaterial;
|
|
|
}
|
|
|
|
|
|
public reset() : void {
|
|
|
+ if (this._tool && this._tool.instance.onReset) {
|
|
|
+ this._tool.instance.onReset();
|
|
|
+ }
|
|
|
this._originalTexture._texture = this._originalInternalTexture;
|
|
|
this.grabOriginalTexture();
|
|
|
this.makePlane();
|
|
@@ -378,18 +555,23 @@ export class TextureCanvasManager {
|
|
|
|
|
|
public async resize(newSize : ISize) {
|
|
|
const data = await TextureHelper.GetTextureDataAsync(this._originalTexture, newSize.width, newSize.height, this._face, {R: true,G: true,B: true,A: true});
|
|
|
- this._size = newSize;
|
|
|
- this.updateSize();
|
|
|
+ this.setSize(newSize);
|
|
|
TextureCanvasManager.paintPixelsOnCanvas(data, this._2DCanvas);
|
|
|
this.updateTexture();
|
|
|
this._didEdit = true;
|
|
|
}
|
|
|
|
|
|
- private updateSize() {
|
|
|
+ public setSize(size: ISize, adjustZoom = true) {
|
|
|
+ this._size = size;
|
|
|
this._2DCanvas.width = this._size.width;
|
|
|
this._2DCanvas.height = this._size.height;
|
|
|
- this._displayCanvas.width = this._size.width;
|
|
|
- this._displayCanvas.height = this._size.height;
|
|
|
+ this._3DCanvas.width = this._size.width;
|
|
|
+ this._3DCanvas.height = this._size.height;
|
|
|
+ if (adjustZoom) {
|
|
|
+ this._camera.position.x = 0;
|
|
|
+ this._camera.position.y = 0;
|
|
|
+ this._scale = 1.5 / (this._size.width/this._size.height);
|
|
|
+ }
|
|
|
this.makePlane();
|
|
|
}
|
|
|
|
|
@@ -429,14 +611,16 @@ export class TextureCanvasManager {
|
|
|
() => {
|
|
|
TextureHelper.GetTextureDataAsync(texture, texture.getSize().width, texture.getSize().height, 0, {R: true, G: true, B: true, A: true})
|
|
|
.then((pixels) => {
|
|
|
- this._size = texture.getSize();
|
|
|
- this.updateSize();
|
|
|
+ if (this._tool && this._tool.instance.onReset) {
|
|
|
+ this._tool.instance.onReset();
|
|
|
+ }
|
|
|
+ this.setSize(texture.getSize());
|
|
|
TextureCanvasManager.paintPixelsOnCanvas(pixels, this._2DCanvas);
|
|
|
this.updateTexture();
|
|
|
texture.dispose();
|
|
|
});
|
|
|
- });
|
|
|
-
|
|
|
+ }
|
|
|
+ );
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -444,17 +628,19 @@ export class TextureCanvasManager {
|
|
|
}
|
|
|
|
|
|
public dispose() {
|
|
|
- if (this._planeMaterial) {
|
|
|
- this._planeMaterial.dispose();
|
|
|
- }
|
|
|
if (this._didEdit) {
|
|
|
this._originalInternalTexture?.dispose();
|
|
|
}
|
|
|
if (this._tool) {
|
|
|
this._tool.instance.cleanup();
|
|
|
- }
|
|
|
- this._displayTexture.dispose();
|
|
|
+ }
|
|
|
+ this._3DPlane.dispose();
|
|
|
+ this._3DCanvasTexture.dispose();
|
|
|
+ this._3DScene.dispose();
|
|
|
+ this._3DEngine.dispose();
|
|
|
this._plane.dispose();
|
|
|
+ this._channelsTexture.dispose();
|
|
|
+ this._planeMaterial.dispose();
|
|
|
this._camera.dispose();
|
|
|
this._scene.dispose();
|
|
|
this._engine.dispose();
|