Skip to content

Commit

Permalink
Cleaned up sculptgl and scene files along with some other minor nits
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielJoyce committed Jul 6, 2024
1 parent 6b12b91 commit 1347c48
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 64 deletions.
116 changes: 99 additions & 17 deletions src/Scene.js → src/Scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,61 @@ import Rtt from './drawables/Rtt';
import ShaderLib from './render/ShaderLib';
import MeshStatic from './mesh/meshStatic/MeshStatic';
import WebGLCaps from './render/WebGLCaps';
import MeshDynamic from './mesh/dynamic/MeshDynamic';

class Scene {

protected _gl: WebGLRenderingContext; // webgl context

protected _cameraSpeed: 0.25;

// cache canvas stuffs
protected _pixelRatio: number;
protected _viewport: HTMLElement;
protected _canvas: HTMLCanvasElement;
protected _canvasWidth: number;
protected _canvasHeight: number;
protected _canvasOffsetLeft: number;
protected _canvasOffsetTop: number;

// core of the app
protected _stateManager: StateManager; // for undo-redo
protected _sculptManager: SculptManager;
protected _camera: Camera;
protected _picking: Picking; // the ray picking
protected _pickingSym: Picking; // the symmetrical picking

// TODO primitive builder
protected _meshPreview: any;
protected _torusLength: number;
protected _torusWidth: number;
protected _torusRadius: number;
protected _torusRadial: number;
protected _torusTubular: number;

protected _showContour: boolean;
protected _showGrid: boolean;
protected _grid: any;
protected _background: any;
protected _meshes: Mesh[]; // the meshes
protected _selectMeshes: Mesh[]; // multi selection
protected _mesh: Mesh; // the selected mesh

protected _rttContour: Rtt; // rtt for contour
protected _rttMerge: Rtt; // rtt decode opaque + merge transparent
protected _rttOpaque: Rtt; // rtt half float
protected _rttTransparent: Rtt; // rtt rgbm

// ui stuffs
protected _focusGui: boolean; // if the gui is being focused
protected _gui: Gui;

protected _preventRender: boolean; // prevent multiple render per frame
protected _drawFullScene: boolean; // render everything on the rtt
protected _autoMatrix: boolean; // scale and center the imported meshes
protected _vertexSRGB: boolean; // srgb vs linear colorspace for vertex color
protected _action: number;

constructor() {
this._gl = null; // webgl context

Expand All @@ -29,7 +81,7 @@ class Scene {
// cache canvas stuffs
this._pixelRatio = 1.0;
this._viewport = document.getElementById('viewport');
this._canvas = document.getElementById('canvas');
this._canvas = <HTMLCanvasElement>document.getElementById('canvas');
this._canvasWidth = 0;
this._canvasHeight = 0;
this._canvasOffsetLeft = 0;
Expand Down Expand Up @@ -100,6 +152,19 @@ class Scene {
else this.addSphere();
}

////////////////
// LOAD FILES
////////////////
getFileType(name) {
var lower = name.toLowerCase();
if (lower.endsWith('.obj')) return 'obj';
if (lower.endsWith('.sgl')) return 'sgl';
if (lower.endsWith('.stl')) return 'stl';
if (lower.endsWith('.ply')) return 'ply';
return;
}


addModelURL(url) {
var fileType = this.getFileType(url);
if (!fileType)
Expand All @@ -110,10 +175,10 @@ class Scene {

xhr.responseType = fileType === 'obj' ? 'text' : 'arraybuffer';

xhr.onload = function () {
xhr.onload = () => {
if (xhr.status === 200)
this.loadScene(xhr.response, fileType);
}.bind(this);
};

xhr.send(null);
}
Expand Down Expand Up @@ -197,7 +262,7 @@ class Scene {
grid.setFlatColor([0.04, 0.04, 0.04]);
}

setOrUnsetMesh(mesh, multiSelect) {
setOrUnsetMesh(mesh, multiSelect = false) {
if (!mesh) {
this._selectMeshes.length = 0;
} else if (!multiSelect) {
Expand Down Expand Up @@ -370,11 +435,11 @@ class Scene {
stencil: true
};

var canvas = document.getElementById('canvas');
var canvas = <HTMLCanvasElement>document.getElementById('canvas');

var gl = this._gl = <WebGLRenderingContext>(canvas.getContext('webgl', attributes)
|| canvas.getContext('experimental-webgl', attributes));

var gl = this._gl = canvas.getContext('webgl', attributes)
|| canvas.getContext('experimental-webgl', attributes);

if (!gl) {
window.alert('Could not initialise WebGL. No WebGL, no SculptGL. Sorry.');
return;
Expand Down Expand Up @@ -426,7 +491,7 @@ class Scene {
}

initAlphaTextures() {
Picking.initAlphas().then((alphaNames)=>{
Picking.initAlphas().then((alphaNames) => {
for (let alphaName of alphaNames) {
var entry = {};
entry[alphaName] = alphaName;
Expand Down Expand Up @@ -497,8 +562,8 @@ class Scene {
var mCen = mat4.create();
mat4.scale(mCen, mCen, [scale, scale, scale]);
mat4.translate(
mCen,
mCen,
mCen,
mCen,
[-(box[0] + box[3]) * 0.5, -(box[1] + box[4]) * 0.5, -(box[2] + box[5]) * 0.5]
);

Expand Down Expand Up @@ -535,11 +600,11 @@ class Scene {
addTorus(preview) {
var mesh = new Multimesh(
Primitives.createTorus(
this._gl,
this._gl,
this._torusLength,
this._torusWidth,
this._torusRadius,
this._torusRadial,
this._torusWidth,
this._torusRadius,
this._torusRadial,
this._torusTubular)
);
if (preview) {
Expand All @@ -554,7 +619,7 @@ class Scene {
this.addNewMesh(mesh);
}

subdivideClamp(mesh, linear) {
subdivideClamp(mesh, linear = false) {
Subdivision.LINEAR = !!linear;
while (mesh.getNbFaces() < 50000)
mesh.addLevel();
Expand Down Expand Up @@ -606,6 +671,23 @@ class Scene {
return newMeshes;
}

resetCameraMeshes(meshes = null) {
if (!meshes) meshes = this._meshes;

if (meshes.length > 0) {
var pivot: vec3 = [0.0, 0.0, 0.0];
var box = this.computeBoundingBoxMeshes(meshes);
var zoom = 0.8 * this.computeRadiusFromBoundingBox(box);
zoom *= this._camera.computeFrustumFit();
vec3.set(pivot, (box[0] + box[3]) * 0.5, (box[1] + box[4]) * 0.5, (box[2] + box[5]) * 0.5);
this._camera.setAndFocusOnPivot(pivot, zoom);
} else {
this._camera.resetView();
}

this.render();
}

clearScene() {
this.getStateManager().reset();
this.getMeshes().length = 0;
Expand All @@ -630,7 +712,7 @@ class Scene {
meshes.splice(this.getIndexMesh(rm[i]), 1);
}

getIndexMesh(mesh, select) {
getIndexMesh(mesh, select = false) {
var meshes = select ? this._selectMeshes : this._meshes;
var id = mesh.getID();
for (var i = 0, nbMeshes = meshes.length; i < nbMeshes; ++i) {
Expand Down
82 changes: 39 additions & 43 deletions src/SculptGL.js → src/SculptGL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Enums from './misc/Enums';
import Utils from './misc/Utils';
import Scene from './Scene';
import Multimesh from './mesh/multiresolution/Multimesh';
import MeshDynamic from './mesh/dynamic/MeshDynamic';

var MOUSE_LEFT = 1;
var MOUSE_MIDDLE = 2;
Expand All @@ -13,6 +14,33 @@ var MOUSE_RIGHT = 3;
// Manage events
class SculptGL extends Scene {


// all x and y position are canvas based

// controllers stuffs
protected _mouseX: number;
protected _mouseY: number;
protected _lastMouseX: number;
protected _lastMouseY: number;
protected _lastScale: number;

// NOTHING, MASK_EDIT, SCULPT_EDIT, CAMERA_ZOOM, CAMERA_ROTATE, CAMERA_PAN, CAMERA_PAN_ZOOM_ALT
protected _lastNbPointers: number;
protected _isWheelingIn: boolean;

// masking
protected _maskX: number;
protected _maskY: number;
protected _hammer: HammerManager;

protected _eventProxy: any;

protected _isIOS: boolean;

protected _timerResetPointer: number;
protected _timerEndWheel: number;


constructor() {
super();

Expand All @@ -37,6 +65,8 @@ class SculptGL extends Scene {

this._eventProxy = {};

this._isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);

this.initHammer();
this.addEvents();
}
Expand Down Expand Up @@ -188,19 +218,14 @@ class SculptGL extends Scene {
}
this.onDeviceMove(evProxy);

if (this._isIOS()) {
if (this._isIOS) {
window.clearTimeout(this._timerResetPointer);
this._timerResetPointer = window.setTimeout(function () {
this._timerResetPointer = window.setTimeout(() => {
this._lastNbPointers = 0;
}.bind(this), 60);
}, 60);
}
}

_isIOS() {
if (this._isIOS !== undefined) return this._isIOS;
this._isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
return this._isIOS;
}

onPanUpdateNbPointers(nbPointers) {
// called on panstart or panmove (not consistent)
Expand All @@ -215,9 +240,9 @@ class SculptGL extends Scene {
return;
this.onDeviceUp();
// we need to detect when all fingers are released
window.setTimeout(function () {
window.setTimeout(() => {
if (!e.pointers.length) this._lastNbPointers = 0;
}.bind(this), 60);
}, 60);
}

onDoubleTap(e) {
Expand All @@ -233,7 +258,7 @@ class SculptGL extends Scene {
var picking = this._picking;
var res = picking.intersectionMouseMeshes();
var cam = this._camera;
var pivot = [0.0, 0.0, 0.0];
var pivot: vec3 = [0.0, 0.0, 0.0];
if (!res) {
return this.resetCameraMeshes();
}
Expand Down Expand Up @@ -264,35 +289,6 @@ class SculptGL extends Scene {
this.onDeviceWheel(dir);
}

resetCameraMeshes(meshes) {
if (!meshes) meshes = this._meshes;

if (meshes.length > 0) {
var pivot = [0.0, 0.0, 0.0];
var box = this.computeBoundingBoxMeshes(meshes);
var zoom = 0.8 * this.computeRadiusFromBoundingBox(box);
zoom *= this._camera.computeFrustumFit();
vec3.set(pivot, (box[0] + box[3]) * 0.5, (box[1] + box[4]) * 0.5, (box[2] + box[5]) * 0.5);
this._camera.setAndFocusOnPivot(pivot, zoom);
} else {
this._camera.resetView();
}

this.render();
}

////////////////
// LOAD FILES
////////////////
getFileType(name) {
var lower = name.toLowerCase();
if (lower.endsWith('.obj')) return 'obj';
if (lower.endsWith('.sgl')) return 'sgl';
if (lower.endsWith('.stl')) return 'stl';
if (lower.endsWith('.ply')) return 'ply';
return;
}

loadFiles(event) {
event.stopPropagation();
event.preventDefault();
Expand All @@ -313,7 +309,7 @@ class SculptGL extends Scene {
var self = this;
reader.onload = function (evt) {
self.loadScene(evt.target.result, fileType);
document.getElementById('fileopen').value = '';
(<HTMLInputElement>document.getElementById('fileopen')).value = '';
};

if (fileType === 'obj')
Expand Down Expand Up @@ -494,8 +490,8 @@ class SculptGL extends Scene {

if (action === Enums.Action.SCULPT_EDIT) {
Multimesh.RENDER_HINT = Multimesh.SCULPT;
this._sculptManager.update(this);
if (this.getMesh().isDynamic)
this._sculptManager.update();
if (this.getMesh() instanceof MeshDynamic)
this._gui.updateMeshInfo();
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/math3d/Picking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class Picking {
return newAlpha;
}

constructor(main, xSym) {
constructor(main, xSym = false) {
this._main = main; // the camera
this._xSym = !!xSym;
}
Expand Down
2 changes: 1 addition & 1 deletion src/mesh/Mesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ mesh.initRender(); // only if gl has been provided
var DEF_ROUGHNESS = 0.18; // 0.18;
var DEF_METALNESS = 0.08; // 0.08;

class Mesh {
abstract class Mesh {

static OPTIMIZE = true;
static ID = 0;
Expand Down
4 changes: 2 additions & 2 deletions src/render/shaders/ShaderBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ let ShaderBase: IShaderBase = {
},

getDummyTexture(gl: WebGLRenderingContext): WebGLTexture {
if (this._dummyTex !== null)
if (this._dummyTex != null)
return this._dummyTex;
this._dummyTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this._dummyTex);
Expand All @@ -249,7 +249,7 @@ let ShaderBase: IShaderBase = {
},

getOrCreateTexture0(gl: WebGLRenderingContext, texPath: string, main): WebGLTexture | false {
if (this.texture0 !== undefined)
if (this.texture0 != null)
return this.texture0;
this.texture0 = null; // trigger loading
var tex = new Image();
Expand Down

0 comments on commit 1347c48

Please sign in to comment.