diff --git a/dist/xeokit-bim-viewer.es.js b/dist/xeokit-bim-viewer.es.js
index ced7fb73..26a36176 100644
--- a/dist/xeokit-bim-viewer.es.js
+++ b/dist/xeokit-bim-viewer.es.js
@@ -8203,7 +8203,7 @@ class Component {
}
}
-const tempVec3a$F = math.vec3();
+const tempVec3a$E = math.vec3();
/**
* Given a view matrix and a relative-to-center (RTC) coordinate origin, returns a view matrix
@@ -8283,7 +8283,7 @@ function worldToRTCPos(worldPos, rtcCenter, rtcPos) {
*/
function worldToRTCPositions(worldPositions, rtcPositions, rtcCenter, cellSize = 1000) {
- const center = math.getPositionsCenter(worldPositions, tempVec3a$F);
+ const center = math.getPositionsCenter(worldPositions, tempVec3a$E);
const rtcCenterX = Math.round(center[0] / cellSize) * cellSize;
const rtcCenterY = Math.round(center[1] / cellSize) * cellSize;
@@ -8319,7 +8319,7 @@ function worldToRTCPositions(worldPositions, rtcPositions, rtcCenter, cellSize =
*/
function getPlaneRTCPos(dist, dir, rtcCenter, rtcPlanePos) {
const rtcCenterToPlaneDist = math.dotVec3(dir, rtcCenter) + dist;
- const dirNormalized = math.normalizeVec3(dir, tempVec3a$F);
+ const dirNormalized = math.normalizeVec3(dir, tempVec3a$E);
math.mulVec3Scalar(dirNormalized, -rtcCenterToPlaneDist, rtcPlanePos);
return rtcPlanePos;
}
@@ -9150,52 +9150,6 @@ class Spinner extends Component {
}
}
-/**
- * @private
- * @type {{WEBGL: boolean, SUPPORTED_EXTENSIONS: {}}}
- */
-const WEBGL_INFO = {
- WEBGL: false,
- SUPPORTED_EXTENSIONS: {}
-};
-
-const canvas = document.createElement("canvas");
-
-if (canvas) {
-
- const gl = canvas.getContext("webgl", {antialias: true}) || canvas.getContext("experimental-webgl", {antialias: true});
-
- WEBGL_INFO.WEBGL = !!gl;
-
- if (WEBGL_INFO.WEBGL) {
- WEBGL_INFO.ANTIALIAS = gl.getContextAttributes().antialias;
- if (gl.getShaderPrecisionFormat) {
- if (gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision > 0) {
- WEBGL_INFO.FS_MAX_FLOAT_PRECISION = "highp";
- } else if (gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT).precision > 0) {
- WEBGL_INFO.FS_MAX_FLOAT_PRECISION = "mediump";
- } else {
- WEBGL_INFO.FS_MAX_FLOAT_PRECISION = "lowp";
- }
- } else {
- WEBGL_INFO.FS_MAX_FLOAT_PRECISION = "mediump";
- }
- WEBGL_INFO.DEPTH_BUFFER_BITS = gl.getParameter(gl.DEPTH_BITS);
- WEBGL_INFO.MAX_TEXTURE_SIZE = gl.getParameter(gl.MAX_TEXTURE_SIZE);
- WEBGL_INFO.MAX_CUBE_MAP_SIZE = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);
- WEBGL_INFO.MAX_RENDERBUFFER_SIZE = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE);
- WEBGL_INFO.MAX_TEXTURE_UNITS = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS);
- WEBGL_INFO.MAX_TEXTURE_IMAGE_UNITS = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
- WEBGL_INFO.MAX_VERTEX_ATTRIBS = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
- WEBGL_INFO.MAX_VERTEX_UNIFORM_VECTORS = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS);
- WEBGL_INFO.MAX_FRAGMENT_UNIFORM_VECTORS = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS);
- WEBGL_INFO.MAX_VARYING_VECTORS = gl.getParameter(gl.MAX_VARYING_VECTORS);
- gl.getSupportedExtensions().forEach(function (ext) {
- WEBGL_INFO.SUPPORTED_EXTENSIONS[ext] = true;
- });
- }
-}
-
const WEBGL_CONTEXT_NAMES = [
"webgl2",
"experimental-webgl",
@@ -9985,6 +9939,52 @@ class FrameContext {
}
}
+/**
+ * @private
+ * @type {{WEBGL: boolean, SUPPORTED_EXTENSIONS: {}}}
+ */
+const WEBGL_INFO = {
+ WEBGL: false,
+ SUPPORTED_EXTENSIONS: {}
+};
+
+const canvas = document.createElement("canvas");
+
+if (canvas) {
+
+ const gl = canvas.getContext("webgl", {antialias: true}) || canvas.getContext("experimental-webgl", {antialias: true});
+
+ WEBGL_INFO.WEBGL = !!gl;
+
+ if (WEBGL_INFO.WEBGL) {
+ WEBGL_INFO.ANTIALIAS = gl.getContextAttributes().antialias;
+ if (gl.getShaderPrecisionFormat) {
+ if (gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision > 0) {
+ WEBGL_INFO.FS_MAX_FLOAT_PRECISION = "highp";
+ } else if (gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT).precision > 0) {
+ WEBGL_INFO.FS_MAX_FLOAT_PRECISION = "mediump";
+ } else {
+ WEBGL_INFO.FS_MAX_FLOAT_PRECISION = "lowp";
+ }
+ } else {
+ WEBGL_INFO.FS_MAX_FLOAT_PRECISION = "mediump";
+ }
+ WEBGL_INFO.DEPTH_BUFFER_BITS = gl.getParameter(gl.DEPTH_BITS);
+ WEBGL_INFO.MAX_TEXTURE_SIZE = gl.getParameter(gl.MAX_TEXTURE_SIZE);
+ WEBGL_INFO.MAX_CUBE_MAP_SIZE = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);
+ WEBGL_INFO.MAX_RENDERBUFFER_SIZE = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE);
+ WEBGL_INFO.MAX_TEXTURE_UNITS = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+ WEBGL_INFO.MAX_TEXTURE_IMAGE_UNITS = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
+ WEBGL_INFO.MAX_VERTEX_ATTRIBS = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
+ WEBGL_INFO.MAX_VERTEX_UNIFORM_VECTORS = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS);
+ WEBGL_INFO.MAX_FRAGMENT_UNIFORM_VECTORS = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS);
+ WEBGL_INFO.MAX_VARYING_VECTORS = gl.getParameter(gl.MAX_VARYING_VECTORS);
+ gl.getSupportedExtensions().forEach(function (ext) {
+ WEBGL_INFO.SUPPORTED_EXTENSIONS[ext] = true;
+ });
+ }
+}
+
/**
* @desc Pick result returned by {@link Scene#pick}.
*
@@ -10036,16 +10036,16 @@ class PickResult {
this.touchInput = false;
/**
- * True when snapped to the nearest vertex position.
+ * True when snapped to nearest edge.
* @type {boolean}
*/
- this.snappedToVertex = false;
+ this.snappedToEdge = false;
/**
- * True when snapped to the nearest edge.
+ * True when snapped to nearest vertex.
* @type {boolean}
*/
- this.snappedToEdge = false;
+ this.snappedToVertex = false;
this._canvasPos = new Int16Array([0, 0]);
this._origin = new Float64Array([0, 0, 0]);
@@ -10318,8 +10318,8 @@ class PickResult {
this._gotWorldNormal = false;
this._gotUV = false;
this.touchInput = false;
- this.snappedToVertex = false;
this.snappedToEdge = false;
+ this.snappedToVertex = false;
}
}
@@ -10493,7 +10493,7 @@ class Program {
gl.attachShader(this.handle, this._fragmentShader.handle);
gl.linkProgram(this.handle);
this.linked = gl.getProgramParameter(this.handle, gl.LINK_STATUS);
- // HACK: Disable validation temporarily: https://github.com/xeolabs/xeokit/issues/5
+ // HACK: Disable validation temporarily
// Perhaps we should defer validation until render-time, when the program has values set for all inputs?
this.validated = true;
if (!this.linked || !this.validated) {
@@ -10918,7 +10918,7 @@ const MARKER_COLOR = math.vec3([1.0, 0.0, 0.0]);
const POINT_SIZE = 20;
const MARKER_SPRITE_CLIPZ_OFFSET = -0.001; // Amount that we offset sprite clip Z coords to raise them from surfaces
-const tempVec3a$D = math.vec3();
+const tempVec3a$C = math.vec3();
/**
* Manages occlusion testing. Private member of a Renderer.
@@ -11255,7 +11255,7 @@ class OcclusionTester {
gl.uniform1i(sectionPlaneUniforms.active, active ? 1 : 0);
if (active) {
const sectionPlane = sectionPlanes[sectionPlaneIndex];
- gl.uniform3fv(sectionPlaneUniforms.pos, getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a$D));
+ gl.uniform3fv(sectionPlaneUniforms.pos, getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a$C));
gl.uniform3fv(sectionPlaneUniforms.dir, sectionPlane.dir);
}
}
@@ -12189,7 +12189,7 @@ class RenderBuffer {
read(pickX, pickY, glFormat = null, glType = null, arrayType = Uint8Array, arrayMultiplier = 4) {
const x = pickX;
- const y = (this.buffer.height || this.gl.drawingBufferHeight) - pickY;
+ const y = this.buffer.height ? (this.buffer.height - pickY - 1) : (this.gl.drawingBufferHeight - pickY);
const pix = new arrayType(arrayMultiplier);
const gl = this.gl;
gl.readPixels(x, y, 1, 1, glFormat || gl.RGBA, glType || gl.UNSIGNED_BYTE, pix, 0);
@@ -13296,10 +13296,10 @@ const Renderer$1 = function (scene, options) {
* Picks an Entity.
* @private
*/
- this.pick = (function () {
+ this.pick = (function () {
const tempVec3a = math.vec3();
- const tempMat4a = math.mat4();
+ math.mat4();
const tempMat4b = math.mat4();
const randomVec3 = math.vec3();
@@ -13341,13 +13341,11 @@ const Renderer$1 = function (scene, options) {
// Picking with arbitrary World-space ray
// Align camera along ray and fire ray through center of canvas
-
- const pickFrustumMatrix = math.frustumMat4(-1, 1, -1, 1, 0.01, scene.camera.project.far, tempMat4a);
-
+
if (params.matrix) {
pickViewMatrix = params.matrix;
- pickProjMatrix = pickFrustumMatrix;
+ pickProjMatrix = scene.camera.projMatrix;
} else {
@@ -13364,7 +13362,7 @@ const Renderer$1 = function (scene, options) {
math.cross3Vec3(worldRayDir, randomVec3, up);
pickViewMatrix = math.lookAtMat4v(worldRayOrigin, look, up, tempMat4b);
- pickProjMatrix = pickFrustumMatrix;
+ pickProjMatrix = scene.camera.projMatrix;
pickResult.origin = worldRayOrigin;
pickResult.direction = worldRayDir;
@@ -13386,7 +13384,7 @@ const Renderer$1 = function (scene, options) {
}
}
- const pickBuffer = renderBufferManager.getRenderBuffer("pick");
+ const pickBuffer = renderBufferManager.getRenderBuffer("pick", { size: [1, 1] });
pickBuffer.bind();
@@ -13448,10 +13446,13 @@ const Renderer$1 = function (scene, options) {
frameCtx.pickViewMatrix = pickViewMatrix;
frameCtx.pickProjMatrix = pickProjMatrix;
frameCtx.pickInvisible = !!params.pickInvisible;
+ frameCtx.pickClipPos = [
+ getClipPosX(canvasPos[0], gl.drawingBufferWidth),
+ getClipPosY(canvasPos[1], gl.drawingBufferHeight),
+ ];
- gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
-
- gl.clearColor(0, 0, 0, 0);
+ gl.viewport(0, 0, 1, 1);
+ gl.depthMask(true);
gl.enable(gl.DEPTH_TEST);
gl.disable(gl.CULL_FACE);
gl.disable(gl.BLEND);
@@ -13484,8 +13485,7 @@ const Renderer$1 = function (scene, options) {
}
}
}
- const resolutionScale = scene.canvas.resolutionScale;
- const pix = pickBuffer.read(Math.round(canvasPos[0] * resolutionScale), Math.round(canvasPos[1] * resolutionScale));
+ const pix = pickBuffer.read(0, 0);
let pickID = pix[0] + (pix[1] * 256) + (pix[2] * 256 * 256) + (pix[3] * 256 * 256 * 256);
if (pickID < 0) {
@@ -13510,8 +13510,12 @@ const Renderer$1 = function (scene, options) {
frameCtx.pickViewMatrix = pickViewMatrix; // Can be null
frameCtx.pickProjMatrix = pickProjMatrix; // Can be null
// frameCtx.pickInvisible = !!params.pickInvisible;
+ frameCtx.pickClipPos = [
+ getClipPosX(canvasPos[0], gl.drawingBufferWidth),
+ getClipPosY(canvasPos[1], gl.drawingBufferHeight),
+ ];
- gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
+ gl.viewport(0, 0, 1, 1);
gl.clearColor(0, 0, 0, 0);
gl.enable(gl.DEPTH_TEST);
@@ -13521,8 +13525,7 @@ const Renderer$1 = function (scene, options) {
pickable.drawPickTriangles(frameCtx);
- const resolutionScale = scene.canvas.resolutionScale;
- const pix = pickBuffer.read(Math.round(canvasPos[0] * resolutionScale), Math.round(canvasPos[1] * resolutionScale));
+ const pix = pickBuffer.read(0, 0);
let primIndex = pix[0] + (pix[1] * 256) + (pix[2] * 256 * 256) + (pix[3] * 256 * 256 * 256);
@@ -13554,10 +13557,15 @@ const Renderer$1 = function (scene, options) {
frameCtx.pickZFar = nearAndFar[1];
frameCtx.pickElementsCount = pickable.pickElementsCount;
frameCtx.pickElementsOffset = pickable.pickElementsOffset;
-
- gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
+ frameCtx.pickClipPos = [
+ getClipPosX(canvasPos[0], gl.drawingBufferWidth),
+ getClipPosY(canvasPos[1], gl.drawingBufferHeight),
+ ];
+
+ gl.viewport(0, 0, 1, 1);
gl.clearColor(0, 0, 0, 0);
+ gl.depthMask(true);
gl.enable(gl.DEPTH_TEST);
gl.disable(gl.CULL_FACE);
gl.disable(gl.BLEND);
@@ -13565,8 +13573,7 @@ const Renderer$1 = function (scene, options) {
pickable.drawPickDepths(frameCtx); // Draw color-encoded fragment screen-space depths
- const resolutionScale = scene.canvas.resolutionScale;
- const pix = pickBuffer.read(Math.round(canvasPos[0] * resolutionScale), Math.round(canvasPos[1] * resolutionScale));
+ const pix = pickBuffer.read(0, 0);
const screenZ = unpackDepth(pix); // Get screen-space Z at the given canvas coords
@@ -13615,7 +13622,7 @@ const Renderer$1 = function (scene, options) {
})();
function snapInitDepthBuf(frameCtx) {
- frameCtx.snapPickLayerParams = {};
+ frameCtx.snapPickLayerParams = [];
frameCtx.snapPickLayerNumber = 0;
for (let type in drawableTypeInfo) {
const drawableInfo = drawableTypeInfo[type];
@@ -13633,8 +13640,8 @@ const Renderer$1 = function (scene, options) {
}
function snapPickDrawSnapDepths(frameCtx) {
- frameCtx.snapPickLayerParams = {};
- frameCtx.snapPickLayerNumber = 0;
+ frameCtx.snapPickLayerParams = frameCtx.snapPickLayerParams || [];
+ frameCtx.snapPickLayerNumber = frameCtx.snapPickLayerParams.length;
for (let type in drawableTypeInfo) {
const drawableInfo = drawableTypeInfo[type];
const drawableList = drawableInfo.drawableList;
@@ -13660,12 +13667,17 @@ const Renderer$1 = function (scene, options) {
/**
* @param {[number, number]} canvasPos
- * @param {number} snapRadiusInPixels
- * @param {"vertex"|"edge"} snapMode
+ * @param {number} [snapRadiusInPixels=30]
+ * @param {boolean} [snapToVertex=true]
+ * @param {boolean} [snapToEdge=true]
*
- * @returns {{worldPos:number[],snappedWorldPos:null|number[],snappedCanvasPos:null|number[]}}
+ * @returns {{worldPos:number[],snappedWorldPos:null|number[],snappedCanvasPos:null|number[], snapType:null|"vertex"|"edge"}}
*/
- this.snapPick = function (canvasPos, snapRadiusInPixels = 50, snapMode = "vertex") {
+ this.snapPick = function (canvasPos, snapRadiusInPixels = 30, snapToVertex = true, snapToEdge = true) {
+
+ if (!snapToVertex && !snapToEdge) {
+ return this.pick({canvasPos, pickSurface: true});
+ }
frameCtx.reset();
frameCtx.backfaces = true;
@@ -13691,8 +13703,6 @@ const Renderer$1 = function (scene, options) {
gl.drawingBufferHeight / (2 * snapRadiusInPixels),
];
- frameCtx.snapMode = snapMode;
-
// Bind and clear the snap render target
vertexPickBuffer.bind(gl.RGBA32I);
@@ -13729,7 +13739,26 @@ const Renderer$1 = function (scene, options) {
const layerParamsSurface = snapInitDepthBuf(frameCtx);
// b) snap-pick
- const layerParamsSnap = snapPickDrawSnapDepths(frameCtx);
+ const layerParamsSnap = [];
+ frameCtx.snapPickLayerParams = layerParamsSnap;
+
+ gl.depthMask(false);
+
+ if (snapToVertex && snapToEdge) {
+ frameCtx.snapMode = "edge";
+ snapPickDrawSnapDepths(frameCtx);
+
+ frameCtx.snapMode = "vertex";
+ frameCtx.snapPickLayerNumber++;
+
+ snapPickDrawSnapDepths(frameCtx);
+ } else {
+ frameCtx.snapMode = snapToVertex ? "vertex" : "edge";
+
+ snapPickDrawSnapDepths(frameCtx);
+ }
+
+ gl.depthMask(true);
// Read and decode the snapped coordinates
@@ -13747,7 +13776,7 @@ const Renderer$1 = function (scene, options) {
const pickResultMiddleXY = snapPickResultArray.slice(middleIndex, middleIndex + 4);
if (pickResultMiddleXY[3] !== 0) {
- const pickedLayerParmasSurface = layerParamsSurface[Math.abs(pickResultMiddleXY[3])];
+ const pickedLayerParmasSurface = layerParamsSurface[Math.abs(pickResultMiddleXY[3]) % layerParamsSurface.length];
const origin = pickedLayerParmasSurface.origin;
const scale = pickedLayerParmasSurface.coordinateScale;
worldPos = [
@@ -13765,7 +13794,6 @@ const Renderer$1 = function (scene, options) {
if (snapPickResultArray[i + 3] > 0) {
const pixelNumber = Math.floor(i / 4);
const w = vertexPickBuffer.size[0];
- vertexPickBuffer.size[1];
const x = pixelNumber % w - Math.floor(w / 2);
const y = Math.floor(pixelNumber / w) - Math.floor(w / 2);
const dist = (Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));
@@ -13773,6 +13801,7 @@ const Renderer$1 = function (scene, options) {
x,
y,
dist,
+ isVertex: snapToVertex && snapToEdge ? snapPickResultArray[i + 3] > layerParamsSnap.length / 2 : snapToVertex,
result: [
snapPickResultArray[i + 0],
snapPickResultArray[i + 1],
@@ -13784,12 +13813,19 @@ const Renderer$1 = function (scene, options) {
}
let snappedWorldPos = null;
+ let snapType = null;
if (snapPickResult.length > 0) {
+ // vertex snap first, then edge snap
snapPickResult.sort((a, b) => {
- return a.dist - b.dist
+ if (a.isVertex !== b.isVertex) {
+ return a.isVertex ? -1 : 1;
+ } else {
+ return a.dist - b.dist;
+ }
});
+ snapType = snapPickResult[0].isVertex ? "vertex" : "edge";
snapPickResult = snapPickResult[0].result;
const pickedLayerParmas = layerParamsSnap[snapPickResult[3]];
@@ -13815,6 +13851,9 @@ const Renderer$1 = function (scene, options) {
}
return {
+ snapType,
+ snappedToVertex: snapType === "vertex",
+ snappedToEdge: snapType === "edge",
worldPos,
snappedWorldPos,
snappedCanvasPos
@@ -13835,21 +13874,34 @@ const Renderer$1 = function (scene, options) {
frameCtx.pickOrigin = pickResult.origin;
frameCtx.pickViewMatrix = pickViewMatrix;
frameCtx.pickProjMatrix = pickProjMatrix;
+ frameCtx.pickClipPos = [
+ getClipPosX(canvasPos[0], gl.drawingBufferWidth),
+ getClipPosY(canvasPos[1], gl.drawingBufferHeight),
+ ];
- gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
+ const pickNormalBuffer = renderBufferManager.getRenderBuffer("pick-normal", { size: [3, 3] });
+
+ pickNormalBuffer.bind(gl.RGBA32I);
+
+ gl.viewport(0, 0, pickNormalBuffer.size[0], pickNormalBuffer.size[1]);
- gl.clearColor(0, 0, 0, 0);
gl.enable(gl.DEPTH_TEST);
gl.disable(gl.CULL_FACE);
gl.disable(gl.BLEND);
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.clear(gl.DEPTH_BUFFER_BIT);
+ gl.clearBufferiv(gl.COLOR, 0, new Int32Array([0, 0, 0, 0]));
pickable.drawPickNormals(frameCtx); // Draw color-encoded fragment World-space normals
- const resolutionScale = scene.canvas.resolutionScale;
- const pix = pickBuffer.read(Math.round(canvasPos[0] * resolutionScale), Math.round(canvasPos[1] * resolutionScale));
+ const pix = pickNormalBuffer.read(1, 1, gl.RGBA_INTEGER, gl.INT, Int32Array, 4);
+
+ pickNormalBuffer.unbind();
- const worldNormal = [(pix[0] / 256.0) - 0.5, (pix[1] / 256.0) - 0.5, (pix[2] / 256.0) - 0.5];
+ const worldNormal = [
+ pix[0] / math.MAX_INT,
+ pix[1] / math.MAX_INT,
+ pix[2] / math.MAX_INT,
+ ];
math.normalizeVec3(worldNormal);
@@ -16639,10 +16691,10 @@ class CustomProjection extends Component {
}
const tempVec3$7 = math.vec3();
-const tempVec3b$q = math.vec3();
-const tempVec3c$m = math.vec3();
-const tempVec3d$g = math.vec3();
-const tempVec3e$8 = math.vec3();
+const tempVec3b$r = math.vec3();
+const tempVec3c$n = math.vec3();
+const tempVec3d$h = math.vec3();
+const tempVec3e$4 = math.vec3();
const tempVec3f$2 = math.vec3();
const tempVec4a$d = math.vec4();
const tempVec4b$c = math.vec4();
@@ -16952,9 +17004,9 @@ class Camera extends Component {
orbitYaw(angleInc) {
let lookEyeVec = math.subVec3(this._eye, this._look, tempVec3$7);
math.rotationMat4v(angleInc * 0.0174532925, this._gimbalLock ? this._worldUp : this._up, tempMat);
- lookEyeVec = math.transformPoint3(tempMat, lookEyeVec, tempVec3b$q);
- this.eye = math.addVec3(this._look, lookEyeVec, tempVec3c$m); // Set eye position as 'look' plus 'eye' vector
- this.up = math.transformPoint3(tempMat, this._up, tempVec3d$g); // Rotate 'up' vector
+ lookEyeVec = math.transformPoint3(tempMat, lookEyeVec, tempVec3b$r);
+ this.eye = math.addVec3(this._look, lookEyeVec, tempVec3c$n); // Set eye position as 'look' plus 'eye' vector
+ this.up = math.transformPoint3(tempMat, this._up, tempVec3d$h); // Rotate 'up' vector
}
/**
@@ -16970,10 +17022,10 @@ class Camera extends Component {
}
}
let eye2 = math.subVec3(this._eye, this._look, tempVec3$7);
- const left = math.cross3Vec3(math.normalizeVec3(eye2, tempVec3b$q), math.normalizeVec3(this._up, tempVec3c$m));
+ const left = math.cross3Vec3(math.normalizeVec3(eye2, tempVec3b$r), math.normalizeVec3(this._up, tempVec3c$n));
math.rotationMat4v(angleInc * 0.0174532925, left, tempMat);
- eye2 = math.transformPoint3(tempMat, eye2, tempVec3d$g);
- this.up = math.transformPoint3(tempMat, this._up, tempVec3e$8);
+ eye2 = math.transformPoint3(tempMat, eye2, tempVec3d$h);
+ this.up = math.transformPoint3(tempMat, this._up, tempVec3e$4);
this.eye = math.addVec3(eye2, this._look, tempVec3f$2);
}
@@ -16985,10 +17037,10 @@ class Camera extends Component {
yaw(angleInc) {
let look2 = math.subVec3(this._look, this._eye, tempVec3$7);
math.rotationMat4v(angleInc * 0.0174532925, this._gimbalLock ? this._worldUp : this._up, tempMat);
- look2 = math.transformPoint3(tempMat, look2, tempVec3b$q);
- this.look = math.addVec3(look2, this._eye, tempVec3c$m);
+ look2 = math.transformPoint3(tempMat, look2, tempVec3b$r);
+ this.look = math.addVec3(look2, this._eye, tempVec3c$n);
if (this._gimbalLock) {
- this.up = math.transformPoint3(tempMat, this._up, tempVec3d$g);
+ this.up = math.transformPoint3(tempMat, this._up, tempVec3d$h);
}
}
@@ -17005,11 +17057,11 @@ class Camera extends Component {
}
}
let look2 = math.subVec3(this._look, this._eye, tempVec3$7);
- const left = math.cross3Vec3(math.normalizeVec3(look2, tempVec3b$q), math.normalizeVec3(this._up, tempVec3c$m));
+ const left = math.cross3Vec3(math.normalizeVec3(look2, tempVec3b$r), math.normalizeVec3(this._up, tempVec3c$n));
math.rotationMat4v(angleInc * 0.0174532925, left, tempMat);
this.up = math.transformPoint3(tempMat, this._up, tempVec3f$2);
- look2 = math.transformPoint3(tempMat, look2, tempVec3d$g);
- this.look = math.addVec3(look2, this._eye, tempVec3e$8);
+ look2 = math.transformPoint3(tempMat, look2, tempVec3d$h);
+ this.look = math.addVec3(look2, this._eye, tempVec3e$4);
}
/**
@@ -17022,25 +17074,25 @@ class Camera extends Component {
const vec = [0, 0, 0];
let v;
if (pan[0] !== 0) {
- const left = math.cross3Vec3(math.normalizeVec3(eye2, []), math.normalizeVec3(this._up, tempVec3b$q));
+ const left = math.cross3Vec3(math.normalizeVec3(eye2, []), math.normalizeVec3(this._up, tempVec3b$r));
v = math.mulVec3Scalar(left, pan[0]);
vec[0] += v[0];
vec[1] += v[1];
vec[2] += v[2];
}
if (pan[1] !== 0) {
- v = math.mulVec3Scalar(math.normalizeVec3(this._up, tempVec3c$m), pan[1]);
+ v = math.mulVec3Scalar(math.normalizeVec3(this._up, tempVec3c$n), pan[1]);
vec[0] += v[0];
vec[1] += v[1];
vec[2] += v[2];
}
if (pan[2] !== 0) {
- v = math.mulVec3Scalar(math.normalizeVec3(eye2, tempVec3d$g), pan[2]);
+ v = math.mulVec3Scalar(math.normalizeVec3(eye2, tempVec3d$h), pan[2]);
vec[0] += v[0];
vec[1] += v[1];
vec[2] += v[2];
}
- this.eye = math.addVec3(this._eye, vec, tempVec3e$8);
+ this.eye = math.addVec3(this._eye, vec, tempVec3e$4);
this.look = math.addVec3(this._look, vec, tempVec3f$2);
}
@@ -17051,13 +17103,13 @@ class Camera extends Component {
*/
zoom(delta) {
const vec = math.subVec3(this._eye, this._look, tempVec3$7);
- const lenLook = Math.abs(math.lenVec3(vec, tempVec3b$q));
+ const lenLook = Math.abs(math.lenVec3(vec, tempVec3b$r));
const newLenLook = Math.abs(lenLook + delta);
if (newLenLook < 0.5) {
return;
}
- const dir = math.normalizeVec3(vec, tempVec3c$m);
- this.eye = math.addVec3(this._look, math.mulVec3Scalar(dir, newLenLook), tempVec3d$g);
+ const dir = math.normalizeVec3(vec, tempVec3c$n);
+ this.eye = math.addVec3(this._look, math.mulVec3Scalar(dir, newLenLook), tempVec3d$h);
}
/**
@@ -22720,116 +22772,6 @@ class LinesMaterial extends Material {
}
}
-const tempVec3a$C = math.vec3();
-const tempVec3b$p = math.vec3();
-const tempMat4a$g = math.mat4();
-
-/**
- * @private
- */
-class FrustumPlane {
-
- constructor() {
- this.normal = math.vec3();
- this.offset = 0;
- this.testVertex = math.vec3();
- }
-
- set(nx, ny, nz, offset) {
- const s = 1.0 / Math.sqrt(nx * nx + ny * ny + nz * nz);
- this.normal[0] = nx * s;
- this.normal[1] = ny * s;
- this.normal[2] = nz * s;
- this.offset = offset * s;
- this.testVertex[0] = (this.normal[0] >= 0.0) ? 1 : 0;
- this.testVertex[1] = (this.normal[1] >= 0.0) ? 1 : 0;
- this.testVertex[2] = (this.normal[2] >= 0.0) ? 1 : 0;
- }
-}
-
-/**
- * @private
- */
-class Frustum {
- constructor() {
- this.planes = [
- new FrustumPlane(), new FrustumPlane(), new FrustumPlane(),
- new FrustumPlane(), new FrustumPlane(), new FrustumPlane()
- ];
- }
-}
-
-Frustum.INSIDE = 0;
-Frustum.INTERSECT = 1;
-Frustum.OUTSIDE = 2;
-
-/** @private */
-function setFrustum(frustum, viewMat, projMat) {
-
- const m = math.mulMat4(projMat, viewMat, tempMat4a$g);
-
- const m0 = m[0];
- const m1 = m[1];
- const m2 = m[2];
- const m3 = m[3];
- const m4 = m[4];
- const m5 = m[5];
- const m6 = m[6];
- const m7 = m[7];
- const m8 = m[8];
- const m9 = m[9];
- const m10 = m[10];
- const m11 = m[11];
- const m12 = m[12];
- const m13 = m[13];
- const m14 = m[14];
- const m15 = m[15];
-
- frustum.planes[0].set(m3 - m0, m7 - m4, m11 - m8, m15 - m12);
- frustum.planes[1].set(m3 + m0, m7 + m4, m11 + m8, m15 + m12);
- frustum.planes[2].set(m3 - m1, m7 - m5, m11 - m9, m15 - m13);
- frustum.planes[3].set(m3 + m1, m7 + m5, m11 + m9, m15 + m13);
- frustum.planes[4].set(m3 - m2, m7 - m6, m11 - m10, m15 - m14);
- frustum.planes[5].set(m3 + m2, m7 + m6, m11 + m10, m15 + m14);
-}
-
-/** @private */
-function frustumIntersectsAABB3(frustum, aabb) {
-
- let ret = Frustum.INSIDE;
-
- const min = tempVec3a$C;
- const max = tempVec3b$p;
-
- min[0] = aabb[0];
- min[1] = aabb[1];
- min[2] = aabb[2];
- max[0] = aabb[3];
- max[1] = aabb[4];
- max[2] = aabb[5];
-
- const bminmax = [min, max];
-
- for (let i = 0; i < 6; ++i) {
- const plane = frustum.planes[i];
- if (((plane.normal[0] * bminmax[plane.testVertex[0]][0]) +
- (plane.normal[1] * bminmax[plane.testVertex[1]][1]) +
- (plane.normal[2] * bminmax[plane.testVertex[2]][2]) +
- (plane.offset)) < 0.0) {
- return Frustum.OUTSIDE;
- }
-
- if (((plane.normal[0] * bminmax[1 - plane.testVertex[0]][0]) +
- (plane.normal[1] * bminmax[1 - plane.testVertex[1]][1]) +
- (plane.normal[2] * bminmax[1 - plane.testVertex[2]][2]) +
- (plane.offset)) < 0.0) {
- ret = Frustum.INTERSECT;
- }
- }
-
- return ret;
-}
-
/**
* Data structure containing pre-initialized `LOD` data.
*
@@ -22838,6 +22780,18 @@ function frustumIntersectsAABB3(frustum, aabb) {
* @private
*/
+
+const neverCullTypes = {
+ "IfcWall": true,
+ "IfcSlab": true,
+ "IfcFloor": true,
+ "IfcRoof": true,
+ "IfcSpace": true,
+ "IfcBeam": true,
+ "IfcStair": true,
+ "IfcPlate":true
+};
+
class LODState {
/**
@@ -22919,19 +22873,24 @@ class LODState {
if (entityList.length === 0) {
return;
}
+ const metaScene = sceneModel.scene.viewer.metaScene;
const entitiesInLOD = {};
const primCountInLOD = {};
+ const maxSize = 20;
+ const minComplexity = 25;
for (let i = 0, len = entityList.length; i < len; i++) {
const entity = entityList[i];
- entity.numPrimitives;
- math.getAABB3Diag(entity.aabb);
-// // const isCullable = ((minComplexity <= entityComplexity) && (entitySize <= maxSize));
-// const isCullable = ( (entitySize <= maxSize));
-//
-// if (!isCullable) {
-// continue;
-// }
+ const metaObject = metaScene.metaObjects[entity.id];
+ if (metaObject && neverCullTypes[metaObject.type]) {
+ continue;
+ }
+ const entityComplexity = entity.numPrimitives;
+ const entitySize = math.getAABB3Diag(entity.aabb);
+ const isCullable = ((minComplexity <= entityComplexity) && (entitySize <= maxSize));
+ if (!isCullable) {
+ continue;
+ }
let lodLevel = 0, len;
for (lodLevel = 0, len = this.primLODLevels.length; lodLevel < len; lodLevel++) {
if (entity.numPrimitives >= this.primLODLevels [lodLevel]) {
@@ -22976,7 +22935,6 @@ class LODCullingManager {
}
const entitiesInLOD = lodState.entitiesInLOD [lodState.primLODLevels[lodState.lodLevelIndex]] || [];
for (let i = 0, len = entitiesInLOD.length; i < len; i++) {
-
entitiesInLOD[i].culledLOD = true;
}
lodState.lodLevelIndex++;
@@ -23012,12 +22970,12 @@ class LODCullingManager {
let lodState = this.lodState;
let retVal = false;
if (currentFPS < lodState.targetFps) {
- if (++lodState.consecutiveFramesWithoutTargetFps > 0) {
+ if (++lodState.consecutiveFramesWithoutTargetFps > 5) {
lodState.consecutiveFramesWithoutTargetFps = 0;
retVal = this._increaseLODLevelIndex();
}
} else if (currentFPS > (lodState.targetFps + 4)) {
- if (++lodState.consecutiveFramesWithTargetFps > 1) {
+ if (++lodState.consecutiveFramesWithTargetFps > 5) {
lodState.consecutiveFramesWithTargetFps = 0;
retVal = this._decreaseLODLevelIndex();
}
@@ -23165,6 +23123,32 @@ class LOD extends Component {
return this._targetFPS;
}
+ /**
+ * Sets the {@link MetaObject} types that are never culled.
+ *
+ * Default value is ````[]````.
+ *
+ * @type {string[]}
+ */
+ set neverCullTypes(value) {
+ if (value === undefined || value === null) {
+ value = [];
+ }
+ this._neverCullTypes = value;
+ // this.glRedraw();
+ }
+
+ /**
+ * Gets the {@link MetaObject} types that are never culled.
+ *
+ * Default value is ````[]````.
+ *
+ * @type {string[]}
+ */
+ get neverCullTypes() {
+ return this._neverCullTypes;
+ }
+
/**
* Called within SceneModel constructors
* @private
@@ -27243,13 +27227,15 @@ class Scene extends Component {
* @param {Object} params Picking parameters.
* @param {Number[]} [params.canvasPos] Canvas-space coordinates. When ray-picking, this will override the **origin** and ** direction** parameters and will cause the ray to be fired through the canvas at this position, directly along the negative View-space Z-axis.
* @param {Number} [params.snapRadius=30] The snap radius, in canvas pixels
- * @param {"vertex"|"edge"} [params.snapMode="vertex"] Whether to snap to vertex or edge.
+ * @param {boolean} [params.snapToVertex=true] Whether to snap to vertex.
+ * @param {boolean} [params.snapToEdge=true] Whether to snap to edge.
*/
snapPick(params) {
return this._renderer.snapPick(
params.canvasPos,
params.snapRadius || 30,
- params.snapMode || "vertex"
+ params.snapToVertex,
+ params.snapToEdge,
);
}
@@ -31503,6 +31489,16 @@ function buildVertex$3(mesh) {
src.push(" mat[2][2] =1.0;");
src.push("}");
}
+
+ src.push("uniform vec2 pickClipPos;");
+
+ src.push("vec4 remapClipPos(vec4 clipPos) {");
+ src.push(" clipPos.xy /= clipPos.w;");
+ src.push(" clipPos.xy -= pickClipPos;");
+ src.push(" clipPos.xy *= clipPos.w;");
+ src.push(" return clipPos;");
+ src.push("}");
+
src.push("void main(void) {");
src.push("vec4 localPosition = vec4(position, 1.0); ");
if (quantizedGeometry) {
@@ -31529,7 +31525,7 @@ function buildVertex$3(mesh) {
src.push("vFragDepth = 1.0 + clipPos.w;");
src.push("isPerspective = float (isPerspectiveMatrix(projMatrix));");
}
- src.push("gl_Position = clipPos;");
+ src.push("gl_Position = remapClipPos(clipPos);");
src.push("}");
return src;
}
@@ -31732,6 +31728,8 @@ PickMeshRenderer.prototype.drawMesh = function (frameCtx, mesh) {
const r = pickID & 0xFF;
gl.uniform4f(this._uPickColor, r / 255, g / 255, b / 255, a / 255);
+ gl.uniform2fv(this._uPickClipPos, frameCtx.pickClipPos);
+
if (geometryState.indicesBuf) {
gl.drawElements(geometryState.primitive, geometryState.indicesBuf.numItems, geometryState.indicesBuf.itemType, 0);
frameCtx.drawElements++;
@@ -31765,6 +31763,7 @@ PickMeshRenderer.prototype._allocate = function (mesh) {
this._aPosition = program.getAttribute("position");
this._uClippable = program.getLocation("clippable");
this._uPickColor = program.getLocation("pickColor");
+ this._uPickClipPos = program.getLocation("pickClipPos");
this._uOffset = program.getLocation("offset");
if (scene.logarithmicDepthBufferEnabled ) {
this._uLogDepthBufFC = program.getLocation("logDepthBufFC");
@@ -31802,8 +31801,6 @@ function buildVertex$2(mesh) {
const scene = mesh.scene;
const clipping = scene._sectionPlanesState.sectionPlanes.length > 0;
const quantizedGeometry = !!mesh._geometry._state.compressGeometry;
- mesh._state.billboard;
- mesh._state.stationary;
const src = [];
src.push('#version 300 es');
src.push("// Surface picking vertex shader");
@@ -31825,6 +31822,16 @@ function buildVertex$2(mesh) {
src.push("}");
src.push("out float isPerspective;");
}
+
+ src.push("uniform vec2 pickClipPos;");
+
+ src.push("vec4 remapClipPos(vec4 clipPos) {");
+ src.push(" clipPos.xy /= clipPos.w;");
+ src.push(" clipPos.xy -= pickClipPos;");
+ src.push(" clipPos.xy *= clipPos.w;");
+ src.push(" return clipPos;");
+ src.push("}");
+
src.push("out vec4 vColor;");
if (quantizedGeometry) {
src.push("uniform mat4 positionsDecodeMatrix;");
@@ -31846,7 +31853,7 @@ function buildVertex$2(mesh) {
src.push("vFragDepth = 1.0 + clipPos.w;");
src.push("isPerspective = float (isPerspectiveMatrix(projMatrix));");
}
- src.push("gl_Position = clipPos;");
+ src.push("gl_Position = remapClipPos(clipPos);");
src.push("}");
return src;
}
@@ -32039,6 +32046,9 @@ PickTriangleRenderer.prototype.drawMesh = function (frameCtx, mesh) {
} else {
this._aPosition.bindArrayBuffer(positionsBuf);
}
+
+ gl.uniform2fv(this._uPickClipPos, frameCtx.pickClipPos);
+
pickColorsBuf.bind();
gl.enableVertexAttribArray(this._aColor.location);
gl.vertexAttribPointer(this._aColor.location, pickColorsBuf.itemSize, pickColorsBuf.itemType, true, 0, 0); // Normalize
@@ -32070,6 +32080,7 @@ PickTriangleRenderer.prototype._allocate = function (mesh) {
}
this._aPosition = program.getAttribute("position");
this._aColor = program.getAttribute("color");
+ this._uPickClipPos = program.getLocation("pickClipPos");
this._uClippable = program.getLocation("clippable");
this._uOffset = program.getLocation("offset");
if (scene.logarithmicDepthBufferEnabled ) {
@@ -40503,8 +40514,8 @@ class LineSet extends Component {
const tempVec3$5 = math.vec3();
const tempVec3a$v = math.vec3();
-const tempVec3b$o = math.vec3();
-const tempVec3c$l = math.vec3();
+const tempVec3b$q = math.vec3();
+const tempVec3c$m = math.vec3();
/**
* {@link Viewer} plugin that saves and loads BCF viewpoints as JSON objects.
@@ -41129,7 +41140,7 @@ class BCFViewpointsPlugin extends Plugin {
scene.clearSectionPlanes();
- if (bcfViewpoint.clipping_planes) {
+ if (bcfViewpoint.clipping_planes && bcfViewpoint.clipping_planes.length > 0) {
bcfViewpoint.clipping_planes.forEach(function (e) {
let pos = xyzObjectToArray(e.location, tempVec3$5);
let dir = xyzObjectToArray(e.direction, tempVec3$5);
@@ -41149,7 +41160,7 @@ class BCFViewpointsPlugin extends Plugin {
scene.clearLines();
- if (bcfViewpoint.lines) {
+ if (bcfViewpoint.lines && bcfViewpoint.lines.length > 0) {
const positions = [];
const indices = [];
let i = 0;
@@ -41179,13 +41190,13 @@ class BCFViewpointsPlugin extends Plugin {
scene.clearBitmaps();
- if (bcfViewpoint.bitmaps) {
+ if (bcfViewpoint.bitmaps && bcfViewpoint.bitmaps.length > 0) {
bcfViewpoint.bitmaps.forEach(function (e) {
const bitmap_type = e.bitmap_type || "jpg"; // "jpg" | "png"
const bitmap_data = e.bitmap_data; // base64
let location = xyzObjectToArray(e.location, tempVec3a$v);
- let normal = xyzObjectToArray(e.normal, tempVec3b$o);
- let up = xyzObjectToArray(e.up, tempVec3c$l);
+ let normal = xyzObjectToArray(e.normal, tempVec3b$q);
+ let up = xyzObjectToArray(e.up, tempVec3c$m);
let height = e.height || 1;
if (!bitmap_type) {
return;
@@ -41448,6 +41459,428 @@ function colorizeToRGB(color) {
math.vec3();
+/**
+ * {@link Viewer} plugin that makes interaction smoother with large models, by temporarily switching
+ * the Viewer to faster, lower-quality rendering modes whenever we interact.
+ *
+ * [](https://xeokit.github.io/xeokit-sdk/examples/#performance_FastNavPlugin)
+ *
+ * FastNavPlugin works by hiding specified Viewer rendering features, and optionally scaling the Viewer's canvas
+ * resolution, whenever we interact with the Viewer. Then, once we've finished interacting, FastNavPlugin restores those
+ * rendering features and the original canvas scale, after a configured delay.
+ *
+ * Depending on how we configure FastNavPlugin, we essentially switch to a smooth-rendering low-quality view while
+ * interacting, then return to the normal higher-quality view after we stop, following an optional delay.
+ *
+ * Down-scaling the canvas resolution gives particularly good results. For example, scaling by ````0.5```` means that
+ * we're rendering a quarter of the pixels while interacting, which can make the Viewer noticeably smoother with big models.
+ *
+ * The screen capture above shows FastNavPlugin in action. In this example, whenever we move the Camera or resize the Canvas,
+ * FastNavPlugin switches off enhanced edges and ambient shadows (SAO), and down-scales the canvas, making it slightly
+ * blurry. When ````0.5```` seconds passes with no interaction, the plugin shows edges and SAO again, and restores the
+ * original canvas scale.
+ *
+ * # Usage
+ *
+ * In the example below, we'll create a {@link Viewer}, add a {@link FastNavPlugin}, then use an {@link XKTLoaderPlugin} to load a model.
+ *
+ * Whenever we interact with the Viewer, our FastNavPlugin will:
+ *
+ * * hide edges,
+ * * hide ambient shadows (SAO),
+ * * hide physically-based materials (switching to non-PBR),
+ * * hide transparent objects, and
+ * * scale the canvas resolution by 0.5, causing the GPU to render 75% less pixels.
+ *
+ *
+ * We'll also configure a 0.5 second delay before we transition back to high-quality each time we stop ineracting, so that we're
+ * not continually flipping between low and high quality as we interact. Since we're only rendering ambient shadows when not interacting, we'll also treat ourselves
+ * to expensive, high-quality SAO settings, that we wouldn't normally configure for an interactive SAO effect.
+ *
+ * * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/#performance_FastNavPlugin)]
+ *
+ * ````javascript
+ * import {Viewer, XKTLoaderPlugin, FastNavPlugin} from "xeokit-sdk.es.js";
+ *
+ * // Create a Viewer with PBR and SAO enabled
+ *
+ * const viewer = new Viewer({
+ * canvasId: "myCanvas",
+ * transparent: true,
+ * pbr: true, // Enable physically-based rendering for Viewer
+ * sao: true // Enable ambient shadows for Viewer
+ * });
+ *
+ * viewer.scene.camera.eye = [-66.26, 105.84, -281.92];
+ * viewer.scene.camera.look = [42.45, 49.62, -43.59];
+ * viewer.scene.camera.up = [0.05, 0.95, 0.15];
+ *
+ * // Higher-quality SAO settings
+ *
+ * viewer.scene.sao.enabled = true;
+ * viewer.scene.sao.numSamples = 60;
+ * viewer.scene.sao.kernelRadius = 170;
+ *
+ * // Install a FastNavPlugin
+ *
+ * new FastNavPlugin(viewer, {
+ * hideEdges: true, // Don't show edges while we interact (default is true)
+ * hideSAO: true, // Don't show ambient shadows while we interact (default is true)
+ * hideColorTexture: true, // No color textures while we interact (default is true)
+ * hidePBR: true, // No physically-based rendering while we interact (default is true)
+ * hideTransparentObjects: true, // Hide transparent objects while we interact (default is false)
+ * scaleCanvasResolution: true, // Scale canvas resolution while we interact (default is false)
+ * scaleCanvasResolutionFactor: 0.5, // Factor by which we scale canvas resolution when we interact (default is 0.6)
+ * delayBeforeRestore: true, // When we stop interacting, delay before restoring normal render (default is true)
+ * delayBeforeRestoreSeconds: 0.5 // The delay duration, in seconds (default is 0.5)
+ * });
+ *
+ * // Load a BIM model from XKT
+ *
+ * const xktLoader = new XKTLoaderPlugin(viewer);
+ *
+ * const model = xktLoader.load({
+ * id: "myModel",
+ * src: "./models/xkt/HolterTower.xkt",
+ * sao: true, // Enable ambient shadows for this model
+ * pbr: true // Enable physically-based rendering for this model
+ * });
+ * ````
+ *
+ * @class FastNavPlugin
+ */
+class FastNavPlugin extends Plugin {
+
+ /**
+ * @constructor
+ * @param {Viewer} viewer The Viewer.
+ * @param {Object} cfg FastNavPlugin configuration.
+ * @param {String} [cfg.id="FastNav"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.
+ * @param {Boolean} [cfg.hideColorTexture=true] Whether to temporarily hide color textures whenever we interact with the Viewer.
+ * @param {Boolean} [cfg.hidePBR=true] Whether to temporarily hide physically-based rendering (PBR) whenever we interact with the Viewer.
+ * @param {Boolean} [cfg.hideSAO=true] Whether to temporarily hide scalable ambient occlusion (SAO) whenever we interact with the Viewer.
+ * @param {Boolean} [cfg.hideEdges=true] Whether to temporarily hide edges whenever we interact with the Viewer.
+ * @param {Boolean} [cfg.hideTransparentObjects=false] Whether to temporarily hide transparent objects whenever we interact with the Viewer.
+ * @param {Number} [cfg.scaleCanvasResolution=false] Whether to temporarily down-scale the canvas resolution whenever we interact with the Viewer.
+ * @param {Number} [cfg.scaleCanvasResolutionFactor=0.6] The factor by which we downscale the canvas resolution whenever we interact with the Viewer.
+ * @param {Boolean} [cfg.delayBeforeRestore=true] Whether to temporarily have a delay before restoring normal rendering after we stop interacting with the Viewer.
+ * @param {Number} [cfg.delayBeforeRestoreSeconds=0.5] Delay in seconds before restoring normal rendering after we stop interacting with the Viewer.
+ */
+ constructor(viewer, cfg = {}) {
+
+ super("FastNav", viewer);
+
+ this._hideColorTexture = cfg.hideColorTexture !== false;
+ this._hidePBR = cfg.hidePBR !== false;
+ this._hideSAO = cfg.hideSAO !== false;
+ this._hideEdges = cfg.hideEdges !== false;
+ this._hideTransparentObjects = !!cfg.hideTransparentObjects;
+ this._scaleCanvasResolution = !!cfg.scaleCanvasResolution;
+ this._scaleCanvasResolutionFactor = cfg.scaleCanvasResolutionFactor || 0.6;
+ this._delayBeforeRestore = (cfg.delayBeforeRestore !== false);
+ this._delayBeforeRestoreSeconds = cfg.delayBeforeRestoreSeconds || 0.5;
+
+ let timer = this._delayBeforeRestoreSeconds * 1000;
+ let fastMode = false;
+
+ const switchToLowQuality = () => {
+ timer = (this._delayBeforeRestoreSeconds * 1000);
+ if (!fastMode) {
+ viewer.scene._renderer.setColorTextureEnabled(!this._hideColorTexture);
+ viewer.scene._renderer.setPBREnabled(!this._hidePBR);
+ viewer.scene._renderer.setSAOEnabled(!this._hideSAO);
+ viewer.scene._renderer.setTransparentEnabled(!this._hideTransparentObjects);
+ viewer.scene._renderer.setEdgesEnabled(!this._hideEdges);
+ if (this._scaleCanvasResolution) {
+ viewer.scene.canvas.resolutionScale = this._scaleCanvasResolutionFactor;
+ } else {
+ viewer.scene.canvas.resolutionScale = 1;
+ }
+ fastMode = true;
+ }
+ };
+
+ const switchToHighQuality = () => {
+ viewer.scene.canvas.resolutionScale = 1;
+ viewer.scene._renderer.setEdgesEnabled(true);
+ viewer.scene._renderer.setColorTextureEnabled(true);
+ viewer.scene._renderer.setPBREnabled(true);
+ viewer.scene._renderer.setSAOEnabled(true);
+ viewer.scene._renderer.setTransparentEnabled(true);
+ fastMode = false;
+ };
+
+ this._onCanvasBoundary = viewer.scene.canvas.on("boundary", switchToLowQuality);
+ this._onCameraMatrix = viewer.scene.camera.on("matrix", switchToLowQuality);
+
+ this._onSceneTick = viewer.scene.on("tick", (tickEvent) => {
+ if (!fastMode) {
+ return;
+ }
+ timer -= tickEvent.deltaTime;
+ if ((!this._delayBeforeRestore) || timer <= 0) {
+ switchToHighQuality();
+ }
+ });
+
+ let down = false;
+
+ this._onSceneMouseDown = viewer.scene.input.on("mousedown", () => {
+ down = true;
+ });
+
+ this._onSceneMouseUp = viewer.scene.input.on("mouseup", () => {
+ down = false;
+ });
+
+ this._onSceneMouseMove = viewer.scene.input.on("mousemove", () => {
+ if (!down) {
+ return;
+ }
+ switchToLowQuality();
+ });
+ }
+
+ /**
+ * Gets whether to temporarily hide color textures whenever we interact with the Viewer.
+ *
+ * Default is ````true````.
+ *
+ * @return {Boolean} ````true```` if hiding color textures.
+ */
+ get hideColorTexture() {
+ return this._hideColorTexture;
+ }
+
+ /**
+ * Sets whether to temporarily hide color textures whenever we interact with the Viewer.
+ *
+ * Default is ````true````.
+ *
+ * @param {Boolean} hideColorTexture ````true```` to hide color textures.
+ */
+ set hideColorTexture(hideColorTexture) {
+ this._hideColorTexture = hideColorTexture;
+ }
+
+ /**
+ * Gets whether to temporarily hide physically-based rendering (PBR) whenever we interact with the Viewer.
+ *
+ * Default is ````true````.
+ *
+ * @return {Boolean} ````true```` if hiding PBR.
+ */
+ get hidePBR() {
+ return this._hidePBR;
+ }
+
+ /**
+ * Sets whether to temporarily hide physically-based rendering (PBR) whenever we interact with the Viewer.
+ *
+ * Default is ````true````.
+ *
+ * @param {Boolean} hidePBR ````true```` to hide PBR.
+ */
+ set hidePBR(hidePBR) {
+ this._hidePBR = hidePBR;
+ }
+
+ /**
+ * Gets whether to temporarily hide scalable ambient shadows (SAO) whenever we interact with the Viewer.
+ *
+ * Default is ````true````.
+ *
+ * @return {Boolean} ````true```` if hiding SAO.
+ */
+ get hideSAO() {
+ return this._hideSAO;
+ }
+
+ /**
+ * Sets whether to temporarily hide scalable ambient shadows (SAO) whenever we interact with the Viewer.
+ *
+ * Default is ````true````.
+ *
+ * @param {Boolean} hideSAO ````true```` to hide SAO.
+ */
+ set hideSAO(hideSAO) {
+ this._hideSAO = hideSAO;
+ }
+
+ /**
+ * Gets whether to temporarily hide edges whenever we interact with the Viewer.
+ *
+ * Default is ````true````.
+ *
+ * @return {Boolean} ````true```` if hiding edges.
+ */
+ get hideEdges() {
+ return this._hideEdges;
+ }
+
+ /**
+ * Sets whether to temporarily hide edges whenever we interact with the Viewer.
+ *
+ * Default is ````true````.
+ *
+ * @param {Boolean} hideEdges ````true```` to hide edges.
+ */
+ set hideEdges(hideEdges) {
+ this._hideEdges = hideEdges;
+ }
+
+ /**
+ * Gets whether to temporarily hide transparent objects whenever we interact with the Viewer.
+ *
+ * Does not hide X-rayed, selected, highlighted objects.
+ *
+ * Default is ````false````.
+ *
+ * @return {Boolean} ````true```` if hiding transparent objects.
+ */
+ get hideTransparentObjects() {
+ return this._hideTransparentObjects
+ }
+
+ /**
+ * Sets whether to temporarily hide transparent objects whenever we interact with the Viewer.
+ *
+ * Does not hide X-rayed, selected, highlighted objects.
+ *
+ * Default is ````false````.
+ *
+ * @param {Boolean} hideTransparentObjects ````true```` to hide transparent objects.
+ */
+ set hideTransparentObjects(hideTransparentObjects) {
+ this._hideTransparentObjects = (hideTransparentObjects !== false);
+ }
+
+ /**
+ * Gets whether to temporarily scale the canvas resolution whenever we interact with the Viewer.
+ *
+ * Default is ````false````.
+ *
+ * The scaling factor is configured via {@link FastNavPlugin#scaleCanvasResolutionFactor}.
+ *
+ * @return {Boolean} ````true```` if scaling the canvas resolution.
+ */
+ get scaleCanvasResolution() {
+ return this._scaleCanvasResolution;
+ }
+
+ /**
+ * Sets whether to temporarily scale the canvas resolution whenever we interact with the Viewer.
+ *
+ * Default is ````false````.
+ *
+ * The scaling factor is configured via {@link FastNavPlugin#scaleCanvasResolutionFactor}.
+ *
+ * @param {Boolean} scaleCanvasResolution ````true```` to scale the canvas resolution.
+ */
+ set scaleCanvasResolution(scaleCanvasResolution) {
+ this._scaleCanvasResolution = scaleCanvasResolution;
+ }
+
+ /**
+ * Gets the factor by which we temporarily scale the canvas resolution when we interact with the viewer.
+ *
+ * Default is ````0.6````.
+ *
+ * Enable canvas resolution scaling by setting {@link FastNavPlugin#scaleCanvasResolution} ````true````.
+ *
+ * @return {Number} Factor by which we scale the canvas resolution.
+ */
+ get scaleCanvasResolutionFactor() {
+ return this._scaleCanvasResolutionFactor;
+ }
+
+ /**
+ * Sets the factor by which we temporarily scale the canvas resolution when we interact with the viewer.
+ *
+ * Accepted range is ````[0.0 .. 1.0]````.
+ *
+ * Default is ````0.6````.
+ *
+ * Enable canvas resolution scaling by setting {@link FastNavPlugin#scaleCanvasResolution} ````true````.
+ *
+ * @param {Number} scaleCanvasResolutionFactor Factor by which we scale the canvas resolution.
+ */
+ set scaleCanvasResolutionFactor(scaleCanvasResolutionFactor) {
+ this._scaleCanvasResolutionFactor = scaleCanvasResolutionFactor || 0.6;
+ }
+
+ /**
+ * Gets whether to have a delay before restoring normal rendering after we stop interacting with the Viewer.
+ *
+ * The delay duration is configured via {@link FastNavPlugin#delayBeforeRestoreSeconds}.
+ *
+ * Default is ````true````.
+ *
+ * @return {Boolean} Whether to have a delay.
+ */
+ get delayBeforeRestore() {
+ return this._delayBeforeRestore;
+ }
+
+ /**
+ * Sets whether to have a delay before restoring normal rendering after we stop interacting with the Viewer.
+ *
+ * The delay duration is configured via {@link FastNavPlugin#delayBeforeRestoreSeconds}.
+ *
+ * Default is ````true````.
+ *
+ * @param {Boolean} delayBeforeRestore Whether to have a delay.
+ */
+ set delayBeforeRestore(delayBeforeRestore) {
+ this._delayBeforeRestore = delayBeforeRestore;
+ }
+
+ /**
+ * Gets the delay before restoring normal rendering after we stop interacting with the Viewer.
+ *
+ * The delay is enabled when {@link FastNavPlugin#delayBeforeRestore} is ````true````.
+ *
+ * Default is ````0.5```` seconds.
+ *
+ * @return {Number} Delay in seconds.
+ */
+ get delayBeforeRestoreSeconds() {
+ return this._delayBeforeRestoreSeconds;
+ }
+
+ /**
+ * Sets the delay before restoring normal rendering after we stop interacting with the Viewer.
+ *
+ * The delay is enabled when {@link FastNavPlugin#delayBeforeRestore} is ````true````.
+ *
+ * Default is ````0.5```` seconds.
+ *
+ * @param {Number} delayBeforeRestoreSeconds Delay in seconds.
+ */
+ set delayBeforeRestoreSeconds(delayBeforeRestoreSeconds) {
+ this._delayBeforeRestoreSeconds = delayBeforeRestoreSeconds !== null && delayBeforeRestoreSeconds !== undefined ? delayBeforeRestoreSeconds : 0.5;
+ }
+
+ /**
+ * @private
+ */
+ send(name, value) {
+ }
+
+ /**
+ * Destroys this plugin.
+ */
+ destroy() {
+ this.viewer.scene.camera.off(this._onCameraMatrix);
+ this.viewer.scene.canvas.off(this._onCanvasBoundary);
+ this.viewer.scene.input.off(this._onSceneMouseDown);
+ this.viewer.scene.input.off(this._onSceneMouseUp);
+ this.viewer.scene.input.off(this._onSceneMouseMove);
+ this.viewer.scene.off(this._onSceneTick);
+ super.destroy();
+ }
+}
+
/**
* @desc Localization service for a {@link Viewer}.
*
@@ -42911,6 +43344,116 @@ math.vec3();
math.vec3([0, -1, 0]);
math.vec4([0, 0, 0, 1]);
+const tempVec3a$t = math.vec3();
+const tempVec3b$o = math.vec3();
+const tempMat4a$h = math.mat4();
+
+/**
+ * @private
+ */
+class FrustumPlane {
+
+ constructor() {
+ this.normal = math.vec3();
+ this.offset = 0;
+ this.testVertex = math.vec3();
+ }
+
+ set(nx, ny, nz, offset) {
+ const s = 1.0 / Math.sqrt(nx * nx + ny * ny + nz * nz);
+ this.normal[0] = nx * s;
+ this.normal[1] = ny * s;
+ this.normal[2] = nz * s;
+ this.offset = offset * s;
+ this.testVertex[0] = (this.normal[0] >= 0.0) ? 1 : 0;
+ this.testVertex[1] = (this.normal[1] >= 0.0) ? 1 : 0;
+ this.testVertex[2] = (this.normal[2] >= 0.0) ? 1 : 0;
+ }
+}
+
+/**
+ * @private
+ */
+class Frustum {
+ constructor() {
+ this.planes = [
+ new FrustumPlane(), new FrustumPlane(), new FrustumPlane(),
+ new FrustumPlane(), new FrustumPlane(), new FrustumPlane()
+ ];
+ }
+}
+
+Frustum.INSIDE = 0;
+Frustum.INTERSECT = 1;
+Frustum.OUTSIDE = 2;
+
+/** @private */
+function setFrustum(frustum, viewMat, projMat) {
+
+ const m = math.mulMat4(projMat, viewMat, tempMat4a$h);
+
+ const m0 = m[0];
+ const m1 = m[1];
+ const m2 = m[2];
+ const m3 = m[3];
+ const m4 = m[4];
+ const m5 = m[5];
+ const m6 = m[6];
+ const m7 = m[7];
+ const m8 = m[8];
+ const m9 = m[9];
+ const m10 = m[10];
+ const m11 = m[11];
+ const m12 = m[12];
+ const m13 = m[13];
+ const m14 = m[14];
+ const m15 = m[15];
+
+ frustum.planes[0].set(m3 - m0, m7 - m4, m11 - m8, m15 - m12);
+ frustum.planes[1].set(m3 + m0, m7 + m4, m11 + m8, m15 + m12);
+ frustum.planes[2].set(m3 - m1, m7 - m5, m11 - m9, m15 - m13);
+ frustum.planes[3].set(m3 + m1, m7 + m5, m11 + m9, m15 + m13);
+ frustum.planes[4].set(m3 - m2, m7 - m6, m11 - m10, m15 - m14);
+ frustum.planes[5].set(m3 + m2, m7 + m6, m11 + m10, m15 + m14);
+}
+
+/** @private */
+function frustumIntersectsAABB3(frustum, aabb) {
+
+ let ret = Frustum.INSIDE;
+
+ const min = tempVec3a$t;
+ const max = tempVec3b$o;
+
+ min[0] = aabb[0];
+ min[1] = aabb[1];
+ min[2] = aabb[2];
+ max[0] = aabb[3];
+ max[1] = aabb[4];
+ max[2] = aabb[5];
+
+ const bminmax = [min, max];
+
+ for (let i = 0; i < 6; ++i) {
+ const plane = frustum.planes[i];
+ if (((plane.normal[0] * bminmax[plane.testVertex[0]][0]) +
+ (plane.normal[1] * bminmax[plane.testVertex[1]][1]) +
+ (plane.normal[2] * bminmax[plane.testVertex[2]][2]) +
+ (plane.offset)) < 0.0) {
+ return Frustum.OUTSIDE;
+ }
+
+ if (((plane.normal[0] * bminmax[1 - plane.testVertex[0]][0]) +
+ (plane.normal[1] * bminmax[1 - plane.testVertex[1]][1]) +
+ (plane.normal[2] * bminmax[1 - plane.testVertex[2]][2]) +
+ (plane.offset)) < 0.0) {
+ ret = Frustum.INTERSECT;
+ }
+ }
+
+ return ret;
+}
+
const color$3 = math.vec3();
/**
@@ -43431,10 +43974,9 @@ const defaultColor$2 = new Float32Array([1, 1, 1, 1]);
const edgesDefaultColor = new Float32Array([0, 0, 0, 1]);
const tempVec4 = math.vec4();
-const tempVec3a$t = math.vec3();
-math.vec3();
-const tempVec3c$k = math.vec3();
-const tempMat4a$f = math.mat4();
+const tempVec3a$s = math.vec3();
+const tempVec3c$l = math.vec3();
+const tempMat4a$g = math.mat4();
class VBOSceneModelRenderer {
constructor(scene, withSAO = false, {instancing = false, edges = false} = {}) {
@@ -43505,6 +44047,23 @@ class VBOSceneModelRenderer {
return src;
}
+ _addRemapClipPosLines(src, viewportSize = 1) {
+ src.push("uniform vec2 drawingBufferSize;");
+ src.push("uniform vec2 pickClipPos;");
+
+ src.push("vec4 remapClipPos(vec4 clipPos) {");
+ src.push(" clipPos.xy /= clipPos.w;");
+ if (viewportSize === 1) {
+ src.push(" clipPos.xy = (clipPos.xy - pickClipPos) * drawingBufferSize;");
+ } else {
+ src.push(` clipPos.xy = (clipPos.xy - pickClipPos) * (drawingBufferSize / float(${viewportSize}));`);
+ }
+ src.push(" clipPos.xy *= clipPos.w;");
+ src.push(" return clipPos;");
+ src.push("}");
+ return src;
+ }
+
getValid() {
return this._hash === this._getHash();
}
@@ -43528,7 +44087,7 @@ class VBOSceneModelRenderer {
const sectionPlane = sectionPlanes[sectionPlaneIndex];
const origin = layer._state.origin;
if (origin) {
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a$t);
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a$s);
gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
} else {
gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -43638,6 +44197,8 @@ class VBOSceneModelRenderer {
this._aPickColor = program.getAttribute("pickColor");
this._uPickZNear = program.getLocation("pickZNear");
this._uPickZFar = program.getLocation("pickZFar");
+ this._uPickClipPos = program.getLocation("pickClipPos");
+ this._uDrawingBufferSize = program.getLocation("drawingBufferSize");
this._uColorMap = "uColorMap";
this._uMetallicRoughMap = "uMetallicRoughMap";
@@ -43678,7 +44239,6 @@ class VBOSceneModelRenderer {
const program = this._program;
const lightsState = scene._lightsState;
const lights = lightsState.lights;
- const project = scene.camera.project;
program.bind();
@@ -43688,6 +44248,10 @@ class VBOSceneModelRenderer {
gl.uniform4fv(this._uLightAmbient, lightsState.getAmbientColorAndIntensity());
}
+ if (this._uGammaFactor) {
+ gl.uniform1f(this._uGammaFactor, scene.gammaFactor);
+ }
+
for (let i = 0, len = lights.length; i < len; i++) {
const light = lights[i];
@@ -43705,43 +44269,6 @@ class VBOSceneModelRenderer {
gl.uniform3fv(this._uLightDir[i], light.dir);
}
}
-
- if (this._withSAO) {
- const sao = scene.sao;
- const saoEnabled = sao.possible;
- if (saoEnabled) {
- const viewportWidth = gl.drawingBufferWidth;
- const viewportHeight = gl.drawingBufferHeight;
- tempVec4[0] = viewportWidth;
- tempVec4[1] = viewportHeight;
- tempVec4[2] = sao.blendCutoff;
- tempVec4[3] = sao.blendFactor;
- gl.uniform4fv(this._uSAOParams, tempVec4);
- this._program.bindTexture(this._uOcclusionTexture, frameCtx.occlusionTexture, 0);
- }
- }
-
- if (scene.logarithmicDepthBufferEnabled) {
- const logDepthBufFC = 2.0 / (Math.log(project.far + 1.0) / Math.LN2);
- gl.uniform1f(this._uLogDepthBufFC, logDepthBufFC);
- }
-
- if (this._uGammaFactor) {
- gl.uniform1f(this._uGammaFactor, scene.gammaFactor);
- }
-
- if (this._uPickInvisible) {
- gl.uniform1i(this._uPickInvisible, frameCtx.pickInvisible);
- }
-
-
- if (this._uShadowViewMatrix) {
- gl.uniformMatrix4fv(this._uShadowViewMatrix, false, frameCtx.shadowViewMatrix);
- }
-
- if (this._uShadowProjMatrix) {
- gl.uniformMatrix4fv(this._uShadowProjMatrix, false, frameCtx.shadowProjMatrix);
- }
}
_makeVAO(state) {
@@ -43773,14 +44300,14 @@ class VBOSceneModelRenderer {
}
- this._aPosition.bindArrayBuffer(this._instancing ? state.positionsBuf : state.positionsBuf);
+ this._aPosition.bindArrayBuffer(state.positionsBuf);
if (this._aUV) {
- this._aUV.bindArrayBuffer(this._instancing ? state.uvBuf : state.uvBuf);
+ this._aUV.bindArrayBuffer(state.uvBuf);
}
if (this._aNormal) {
- this._aNormal.bindArrayBuffer(this._instancing ? state.normalsBuf : state.normalsBuf);
+ this._aNormal.bindArrayBuffer(state.normalsBuf);
}
if (this._aMetallicRoughness) {
@@ -43791,7 +44318,7 @@ class VBOSceneModelRenderer {
}
if (this._aColor) {
- this._aColor.bindArrayBuffer(state.colorsBuf ? state.colorsBuf : state.colorsBuf);
+ this._aColor.bindArrayBuffer(state.colorsBuf);
if (this._instancing && state.colorsBuf) {
gl.vertexAttribDivisor(this._aColor.location, 1);
}
@@ -43879,9 +44406,9 @@ class VBOSceneModelRenderer {
const gotOrigin = (origin[0] !== 0 || origin[1] !== 0 || origin[2] !== 0);
const gotPosition = (position[0] !== 0 || position[1] !== 0 || position[2] !== 0);
if (gotOrigin || gotPosition) {
- const rtcOrigin = tempVec3a$t;
+ const rtcOrigin = tempVec3a$s;
if (gotOrigin) {
- const rotatedOrigin = math.transformPoint3(rotationMatrix, origin, tempVec3c$k);
+ const rotatedOrigin = math.transformPoint3(rotationMatrix, origin, tempVec3c$l);
rtcOrigin[0] = rotatedOrigin[0];
rtcOrigin[1] = rotatedOrigin[1];
rtcOrigin[2] = rotatedOrigin[2];
@@ -43893,7 +44420,7 @@ class VBOSceneModelRenderer {
rtcOrigin[0] += position[0];
rtcOrigin[1] += position[1];
rtcOrigin[2] += position[2];
- this._matricesUniformBlockBufferData.set(createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$f), offset += mat4Size);
+ this._matricesUniformBlockBufferData.set(createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$g), offset += mat4Size);
} else {
this._matricesUniformBlockBufferData.set(viewMatrix, offset += mat4Size);
}
@@ -43938,12 +44465,16 @@ class VBOSceneModelRenderer {
gl.uniform1f(this._uPickZFar, frameCtx.pickZFar);
}
- if (this._uPositionsDecodeMatrix) {
- gl.uniformMatrix4fv(this._uPositionsDecodeMatrix, false, state.positionsDecodeMatrix);
+ if (this._uPickClipPos) {
+ gl.uniform2fv(this._uPickClipPos, frameCtx.pickClipPos);
+ }
+
+ if (this._uDrawingBufferSize) {
+ gl.uniform2f(this._uDrawingBufferSize, gl.drawingBufferWidth, gl.drawingBufferHeight);
}
if (this._uUVDecodeMatrix) {
- gl.uniformMatrix3fv(this._uUVDecodeMatrix, false, this._instancing ? state.uvDecodeMatrix : state.uvDecodeMatrix);
+ gl.uniformMatrix3fv(this._uUVDecodeMatrix, false, state.uvDecodeMatrix);
}
if (this._uIntensityRange && pointsMaterial.filterIntensity) {
@@ -44104,7 +44635,7 @@ class VBOSceneModelTriangleBatchingEdgesRenderer extends VBOSceneModelTriangleBa
class VBOSceneModelTriangleInstancingRenderer extends VBOSceneModelRenderer {
- constructor(scene, withSAO, {edges = false} = {}) {
+ constructor(scene, withSAO, { edges = false} = {}) {
super(scene, withSAO, {instancing: true, edges});
}
@@ -45117,6 +45648,8 @@ class TrianglesBatchingPickMeshRenderer extends VBOSceneModelTriangleBatchingRen
src.push("out float vFlags;");
}
+ this._addRemapClipPosLines(src);
+
src.push("out vec4 vPickColor;");
src.push("void main(void) {");
@@ -45144,7 +45677,7 @@ class TrianglesBatchingPickMeshRenderer extends VBOSceneModelTriangleBatchingRen
src.push("vFragDepth = 1.0 + clipPos.w;");
src.push("isPerspective = float (isPerspectiveMatrix(projMatrix));");
}
- src.push("gl_Position = clipPos;");
+ src.push("gl_Position = remapClipPos(clipPos);");
src.push(" }");
src.push("}");
return src;
@@ -45243,6 +45776,9 @@ class TrianglesBatchingPickDepthRenderer extends VBOSceneModelTriangleBatchingRe
src.push("out vec4 vWorldPosition;");
src.push("out float vFlags;");
}
+
+ this._addRemapClipPosLines(src);
+
src.push("out vec4 vViewPosition;");
src.push("void main(void) {");
@@ -45268,7 +45804,7 @@ class TrianglesBatchingPickDepthRenderer extends VBOSceneModelTriangleBatchingRe
src.push("vFragDepth = 1.0 + clipPos.w;");
src.push("isPerspective = float (isPerspectiveMatrix(projMatrix));");
}
- src.push("gl_Position = clipPos;");
+ src.push("gl_Position = remapClipPos(clipPos);");
src.push(" }");
src.push("}");
return src;
@@ -45366,6 +45902,8 @@ class TrianglesBatchingPickNormalsRenderer extends VBOSceneModelTriangleBatching
this._addMatricesUniformBlockLines(src);
+ this._addRemapClipPosLines(src, 3);
+
if (scene.logarithmicDepthBufferEnabled) {
src.push("uniform float logDepthBufFC;");
src.push("out float vFragDepth;");
@@ -45410,7 +45948,7 @@ class TrianglesBatchingPickNormalsRenderer extends VBOSceneModelTriangleBatching
src.push("vFragDepth = 1.0 + clipPos.w;");
src.push("isPerspective = float (isPerspectiveMatrix(projMatrix));");
}
- src.push("gl_Position = clipPos;");
+ src.push("gl_Position = remapClipPos(clipPos);");
src.push(" }");
src.push("}");
return src;
@@ -45446,7 +45984,7 @@ class TrianglesBatchingPickNormalsRenderer extends VBOSceneModelTriangleBatching
}
}
src.push("in vec3 vWorldNormal;");
- src.push("out vec4 outColor;");
+ src.push("out highp ivec4 outNormal;");
src.push("void main(void) {");
if (clipping) {
src.push(" bool clippable = (int(vFlags) >> 16 & 0xF) == 1;");
@@ -45463,7 +46001,7 @@ class TrianglesBatchingPickNormalsRenderer extends VBOSceneModelTriangleBatching
if (scene.logarithmicDepthBufferEnabled) {
src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
}
- src.push(" outColor = vec4((vWorldNormal * 0.5) + 0.5, 1.0);");
+ src.push(` outNormal = ivec4(vWorldNormal * float(${math.MAX_INT}), 1.0);`);
src.push("}");
return src;
}
@@ -46513,6 +47051,8 @@ class TrianglesBatchingPickNormalsFlatRenderer extends VBOSceneModelTriangleBatc
this._addMatricesUniformBlockLines(src);
+ this._addRemapClipPosLines(src, 3);
+
if (scene.logarithmicDepthBufferEnabled) {
src.push("uniform float logDepthBufFC;");
src.push("out float vFragDepth;");
@@ -46546,7 +47086,7 @@ class TrianglesBatchingPickNormalsFlatRenderer extends VBOSceneModelTriangleBatc
src.push("vFragDepth = 1.0 + clipPos.w;");
src.push("isPerspective = float (isPerspectiveMatrix(projMatrix));");
}
- src.push("gl_Position = clipPos;");
+ src.push("gl_Position = remapClipPos(clipPos);");
src.push(" }");
src.push("}");
return src;
@@ -46581,7 +47121,7 @@ class TrianglesBatchingPickNormalsFlatRenderer extends VBOSceneModelTriangleBatc
src.push("uniform vec3 sectionPlaneDir" + i + ";");
}
}
- src.push("out vec4 outColor;");
+ src.push("out highp ivec4 outNormal;");
src.push("void main(void) {");
if (clipping) {
src.push(" bool clippable = (int(vFlags) >> 16 & 0xF) == 1;");
@@ -46601,7 +47141,7 @@ class TrianglesBatchingPickNormalsFlatRenderer extends VBOSceneModelTriangleBatc
src.push(" vec3 xTangent = dFdx( vWorldPosition.xyz );");
src.push(" vec3 yTangent = dFdy( vWorldPosition.xyz );");
src.push(" vec3 worldNormal = normalize( cross( xTangent, yTangent ) );");
- src.push(" outColor = vec4((worldNormal * 0.5) + 0.5, 1.0);");
+ src.push(` outNormal = ivec4(worldNormal * float(${math.MAX_INT}), 1.0);`);
src.push("}");
return src;
}
@@ -46844,6 +47384,7 @@ class TrianglesBatchingColorTextureRenderer extends VBOSceneModelTriangleBatchin
src.push("vec4 colorTexel = color * sRGBToLinear(texture(uColorMap, vUV));");
} else {
src.push("vec4 colorTexel = color * texture(uColorMap, vUV);");
+
}
src.push("float opacity = color.a;");
@@ -46963,6 +47504,23 @@ class TrianglesBatchingRenderers {
}
}
+ eagerCreateRenders() {
+
+ // Pre-initialize certain renderers that would otherwise be lazy-initialised
+ // on user interaction, such as picking or emphasis, so that there is no delay
+ // when user first begins interacting with the viewer.
+
+ if (!this._silhouetteRenderer) { // Used for highlighting and selection
+ this._silhouetteRenderer = new TrianglesBatchingSilhouetteRenderer(this._scene);
+ }
+ if (!this._pickMeshRenderer) {
+ this._pickMeshRenderer = new TrianglesBatchingPickMeshRenderer(this._scene);
+ }
+ if (!this._pickDepthRenderer) {
+ this._pickDepthRenderer = new TrianglesBatchingPickDepthRenderer(this._scene);
+ }
+ }
+
get colorRenderer() {
if (!this._colorRenderer) {
this._colorRenderer = new TrianglesBatchingColorRenderer(this._scene, false);
@@ -47169,8 +47727,10 @@ function getBatchingRenderers$1(scene) {
batchingRenderers = new TrianglesBatchingRenderers(scene);
cachdRenderers$1[sceneId] = batchingRenderers;
batchingRenderers._compile();
+ batchingRenderers.eagerCreateRenders();
scene.on("compile", () => {
batchingRenderers._compile();
+ batchingRenderers.eagerCreateRenders();
});
scene.on("destroyed", () => {
delete cachdRenderers$1[sceneId];
@@ -47356,32 +47916,16 @@ function octDecodeVec2(oct) { // Decode an oct-encoded normal
];
}
-const tempVec3a$s = math.vec3();
-const tempVec3b$m = math.vec3();
-const tempVec3c$j = math.vec3();
-const tempVec3d$f = math.vec3();
-const tempVec3e$7 = math.vec3();
-const tempMat4a$e = math.mat4();
+const tempVec3a$r = math.vec3();
+const tempVec3b$n = math.vec3();
+const tempVec3c$k = math.vec3();
+const tempVec3d$g = math.vec3();
+const tempMat4a$f = math.mat4();
/**
* @private
*/
-class SnapBatchingDepthBufInitRenderer {
-
- constructor(scene) {
- this._scene = scene;
- this._hash = this._getHash();
- this._allocate();
- }
-
- getValid() {
- return this._hash === this._getHash();
- };
-
- _getHash() {
- return this._scene._sectionPlanesState.getHash();
- }
-
+class SnapBatchingDepthBufInitRenderer extends VBOSceneModelRenderer {
drawLayer(frameCtx, batchingLayer, renderPass) {
if (!this._program) {
@@ -47406,7 +47950,13 @@ class SnapBatchingDepthBufInitRenderer {
const aabb = batchingLayer.aabb;
const viewMatrix = frameCtx.pickViewMatrix || camera.viewMatrix;
- const coordinateScaler = tempVec3a$s;
+ if (this._vaoCache.has(batchingLayer)) {
+ gl.bindVertexArray(this._vaoCache.get(batchingLayer));
+ } else {
+ this._vaoCache.set(batchingLayer, this._makeVAO(state));
+ }
+
+ const coordinateScaler = tempVec3a$r;
coordinateScaler[0] = math.safeInv(aabb[3] - aabb[0]) * math.MAX_INT;
coordinateScaler[1] = math.safeInv(aabb[4] - aabb[1]) * math.MAX_INT;
coordinateScaler[2] = math.safeInv(aabb[5] - aabb[2]) * math.MAX_INT;
@@ -47419,9 +47969,9 @@ class SnapBatchingDepthBufInitRenderer {
let rtcCameraEye;
if (origin || position[0] !== 0 || position[1] !== 0 || position[2] !== 0) {
- const rtcOrigin = tempVec3b$m;
+ const rtcOrigin = tempVec3b$n;
if (origin) {
- const rotatedOrigin = tempVec3c$j;
+ const rotatedOrigin = tempVec3c$k;
math.transformPoint3(rotationMatrix, origin, rotatedOrigin);
rtcOrigin[0] = rotatedOrigin[0];
rtcOrigin[1] = rotatedOrigin[1];
@@ -47434,8 +47984,8 @@ class SnapBatchingDepthBufInitRenderer {
rtcOrigin[0] += position[0];
rtcOrigin[1] += position[1];
rtcOrigin[2] += position[2];
- rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$e);
- rtcCameraEye = tempVec3d$f;
+ rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$f);
+ rtcCameraEye = tempVec3d$g;
rtcCameraEye[0] = camera.eye[0] - rtcOrigin[0];
rtcCameraEye[1] = camera.eye[1] - rtcOrigin[1];
rtcCameraEye[2] = camera.eye[2] - rtcOrigin[2];
@@ -47457,80 +48007,43 @@ class SnapBatchingDepthBufInitRenderer {
gl.uniform3fv(this._uCoordinateScaler, coordinateScaler);
gl.uniform1i(this._uRenderPass, renderPass);
gl.uniform1i(this._uPickInvisible, frameCtx.pickInvisible);
- gl.uniform1i(this._uSolid, batchingLayer.solid);
- gl.uniformMatrix4fv(this._uWorldMatrix, false, rotationMatrixConjugate);
- gl.uniformMatrix4fv(this._uViewMatrix, false, rtcViewMatrix);
- gl.uniformMatrix4fv(this._uProjMatrix, false, camera.projMatrix);
+
+ let offset = 0;
+ const mat4Size = 4 * 4;
+
+ this._matricesUniformBlockBufferData.set(rotationMatrixConjugate, 0);
+ this._matricesUniformBlockBufferData.set(rtcViewMatrix, offset += mat4Size);
+ this._matricesUniformBlockBufferData.set(camera.projMatrix, offset += mat4Size);
+ this._matricesUniformBlockBufferData.set(state.positionsDecodeMatrix, offset += mat4Size);
+
+ gl.bindBuffer(gl.UNIFORM_BUFFER, this._matricesUniformBlockBuffer);
+ gl.bufferData(gl.UNIFORM_BUFFER, this._matricesUniformBlockBufferData, gl.DYNAMIC_DRAW);
+
+ gl.bindBufferBase(
+ gl.UNIFORM_BUFFER,
+ this._matricesUniformBlockBufferBindingPoint,
+ this._matricesUniformBlockBuffer);
+
{
const logDepthBufFC = 2.0 / (Math.log(frameCtx.pickZFar + 1.0) / Math.LN2); // TODO: Far from pick project matrix?
gl.uniform1f(this._uLogDepthBufFC, logDepthBufFC);
}
- const numSectionPlanes = scene._sectionPlanesState.sectionPlanes.length;
- if (numSectionPlanes > 0) {
- const sectionPlanes = scene._sectionPlanesState.sectionPlanes;
- const baseIndex = batchingLayer.layerIndex * numSectionPlanes;
- const renderFlags = model.renderFlags;
- for (let sectionPlaneIndex = 0; sectionPlaneIndex < numSectionPlanes; sectionPlaneIndex++) {
- const sectionPlaneUniforms = this._uSectionPlanes[sectionPlaneIndex];
- if (sectionPlaneUniforms) {
- const active = renderFlags.sectionPlanesActivePerLayer[baseIndex + sectionPlaneIndex];
- gl.uniform1i(sectionPlaneUniforms.active, active ? 1 : 0);
- if (active) {
- const sectionPlane = sectionPlanes[sectionPlaneIndex];
- if (origin) {
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3e$7);
- gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
- } else {
- gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
- }
- gl.uniform3fv(sectionPlaneUniforms.dir, sectionPlane.dir);
- }
- }
- }
- }
+
+ this.setSectionPlanesStateUniforms(batchingLayer);
//=============================================================
// TODO: Use drawElements count and offset to draw only one entity
//=============================================================
- gl.uniformMatrix4fv(this._uPositionsDecodeMatrix, false, batchingLayer._state.positionsDecodeMatrix);
- this._aPosition.bindArrayBuffer(state.positionsBuf);
- if (this._aOffset) {
- this._aOffset.bindArrayBuffer(state.offsetsBuf);
- }
- if (this._aFlags) {
- this._aFlags.bindArrayBuffer(state.flagsBuf);
- }
+
state.indicesBuf.bind();
gl.drawElements(gl.TRIANGLES, state.indicesBuf.numItems, state.indicesBuf.itemType, 0);
state.indicesBuf.unbind();
}
_allocate() {
- const scene = this._scene;
- const gl = scene.canvas.gl;
- this._program = new Program(gl, this._buildShader());
- if (this._program.errors) {
- this.errors = this._program.errors;
- return;
- }
+ super._allocate();
+
const program = this._program;
- this._uRenderPass = program.getLocation("renderPass");
- this._uPickInvisible = program.getLocation("pickInvisible");
- this._uSolid = program.getLocation("solid");
- this._uPositionsDecodeMatrix = program.getLocation("positionsDecodeMatrix");
- this._uWorldMatrix = program.getLocation("worldMatrix");
- this._uViewMatrix = program.getLocation("viewMatrix");
- this._uProjMatrix = program.getLocation("projMatrix");
- this._uSectionPlanes = [];
- for (let i = 0, len = scene._sectionPlanesState.sectionPlanes.length; i < len; i++) {
- this._uSectionPlanes.push({
- active: program.getLocation("sectionPlaneActive" + i),
- pos: program.getLocation("sectionPlanePos" + i),
- dir: program.getLocation("sectionPlaneDir" + i)
- });
- }
- this._aPosition = program.getAttribute("position");
- this._aOffset = program.getAttribute("offset");
- this._aFlags = program.getAttribute("flags");
+
{
this._uLogDepthBufFC = program.getLocation("logDepthBufFC");
}
@@ -47545,13 +48058,6 @@ class SnapBatchingDepthBufInitRenderer {
this._program.bind();
}
- _buildShader() {
- return {
- vertex: this._buildVertexShader(),
- fragment: this._buildFragmentShader()
- };
- }
-
_buildVertexShader() {
const scene = this._scene;
const clipping = scene._sectionPlanesState.sectionPlanes.length > 0;
@@ -47578,11 +48084,9 @@ class SnapBatchingDepthBufInitRenderer {
}
src.push("in float flags;");
src.push("uniform bool pickInvisible;");
- src.push("uniform bool solid;");
- src.push("uniform mat4 worldMatrix;");
- src.push("uniform mat4 viewMatrix;");
- src.push("uniform mat4 projMatrix;");
- src.push("uniform mat4 positionsDecodeMatrix;");
+
+ this._addMatricesUniformBlockLines(src);
+
src.push("uniform vec3 uCameraEyeRtc;");
src.push("uniform vec2 snapVectorA;");
src.push("uniform vec2 snapInvVectorAB;");
@@ -47702,28 +48206,16 @@ class SnapBatchingDepthBufInitRenderer {
}
}
-const tempVec3a$r = math.vec3();
-const tempVec3b$l = math.vec3();
-const tempVec3c$i = math.vec3();
-const tempVec3d$e = math.vec3();
-const tempVec3e$6 = math.vec3();
-const tempMat4a$d = math.mat4();
+const tempVec3a$q = math.vec3();
+const tempVec3b$m = math.vec3();
+const tempVec3c$j = math.vec3();
+const tempVec3d$f = math.vec3();
+const tempMat4a$e = math.mat4();
/**
* @private
*/
-class SnapBatchingDepthRenderer {
-
- constructor(scene) {
- this._scene = scene;
- this._hash = this._getHash();
- this._allocate();
- }
-
- getValid() {
- return this._hash === this._getHash();
- };
-
+class SnapBatchingDepthRenderer extends VBOSceneModelRenderer{
_getHash() {
return this._scene._sectionPlanesState.getHash() + (this._scene.pointsMaterial.hash);
}
@@ -47752,7 +48244,13 @@ class SnapBatchingDepthRenderer {
const aabb = batchingLayer.aabb;
const viewMatrix = frameCtx.pickViewMatrix || camera.viewMatrix;
- const coordinateScaler = tempVec3a$r;
+ if (this._vaoCache.has(batchingLayer)) {
+ gl.bindVertexArray(this._vaoCache.get(batchingLayer));
+ } else {
+ this._vaoCache.set(batchingLayer, this._makeVAO(state));
+ }
+
+ const coordinateScaler = tempVec3a$q;
coordinateScaler[0] = math.safeInv(aabb[3] - aabb[0]) * math.MAX_INT;
coordinateScaler[1] = math.safeInv(aabb[4] - aabb[1]) * math.MAX_INT;
coordinateScaler[2] = math.safeInv(aabb[5] - aabb[2]) * math.MAX_INT;
@@ -47765,9 +48263,9 @@ class SnapBatchingDepthRenderer {
let rtcCameraEye;
if (origin || position[0] !== 0 || position[1] !== 0 || position[2] !== 0) {
- const rtcOrigin = tempVec3b$l;
+ const rtcOrigin = tempVec3b$m;
if (origin) {
- const rotatedOrigin = tempVec3c$i;
+ const rotatedOrigin = tempVec3c$j;
math.transformPoint3(rotationMatrix, origin, rotatedOrigin);
rtcOrigin[0] = rotatedOrigin[0];
rtcOrigin[1] = rotatedOrigin[1];
@@ -47780,8 +48278,8 @@ class SnapBatchingDepthRenderer {
rtcOrigin[0] += position[0];
rtcOrigin[1] += position[1];
rtcOrigin[2] += position[2];
- rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$d);
- rtcCameraEye = tempVec3d$e;
+ rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$e);
+ rtcCameraEye = tempVec3d$f;
rtcCameraEye[0] = camera.eye[0] - rtcOrigin[0];
rtcCameraEye[1] = camera.eye[1] - rtcOrigin[1];
rtcCameraEye[2] = camera.eye[2] - rtcOrigin[2];
@@ -47803,47 +48301,34 @@ class SnapBatchingDepthRenderer {
gl.uniform3fv(this._uCoordinateScaler, coordinateScaler);
gl.uniform1i(this._uRenderPass, renderPass);
gl.uniform1i(this._uPickInvisible, frameCtx.pickInvisible);
- gl.uniformMatrix4fv(this._uWorldMatrix, false, rotationMatrixConjugate);
- gl.uniformMatrix4fv(this._uViewMatrix, false, rtcViewMatrix);
- gl.uniformMatrix4fv(this._uProjMatrix, false, camera.projMatrix);
+
+ let offset = 0;
+ const mat4Size = 4 * 4;
+
+ this._matricesUniformBlockBufferData.set(rotationMatrixConjugate, 0);
+ this._matricesUniformBlockBufferData.set(rtcViewMatrix, offset += mat4Size);
+ this._matricesUniformBlockBufferData.set(camera.projMatrix, offset += mat4Size);
+ this._matricesUniformBlockBufferData.set(state.positionsDecodeMatrix, offset += mat4Size);
+
+ gl.bindBuffer(gl.UNIFORM_BUFFER, this._matricesUniformBlockBuffer);
+ gl.bufferData(gl.UNIFORM_BUFFER, this._matricesUniformBlockBufferData, gl.DYNAMIC_DRAW);
+
+ gl.bindBufferBase(
+ gl.UNIFORM_BUFFER,
+ this._matricesUniformBlockBufferBindingPoint,
+ this._matricesUniformBlockBuffer);
+
{
const logDepthBufFC = 2.0 / (Math.log(frameCtx.pickZFar + 1.0) / Math.LN2); // TODO: Far from pick project matrix?
gl.uniform1f(this._uLogDepthBufFC, logDepthBufFC);
}
- const numSectionPlanes = scene._sectionPlanesState.sectionPlanes.length;
- if (numSectionPlanes > 0) {
- const sectionPlanes = scene._sectionPlanesState.sectionPlanes;
- const baseIndex = batchingLayer.layerIndex * numSectionPlanes;
- const renderFlags = model.renderFlags;
- for (let sectionPlaneIndex = 0; sectionPlaneIndex < numSectionPlanes; sectionPlaneIndex++) {
- const sectionPlaneUniforms = this._uSectionPlanes[sectionPlaneIndex];
- if (sectionPlaneUniforms) {
- const active = renderFlags.sectionPlanesActivePerLayer[baseIndex + sectionPlaneIndex];
- gl.uniform1i(sectionPlaneUniforms.active, active ? 1 : 0);
- if (active) {
- const sectionPlane = sectionPlanes[sectionPlaneIndex];
- if (origin) {
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3e$6);
- gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
- } else {
- gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
- }
- gl.uniform3fv(sectionPlaneUniforms.dir, sectionPlane.dir);
- }
- }
- }
- }
+
+ this.setSectionPlanesStateUniforms(batchingLayer);
+
//=============================================================
// TODO: Use drawElements count and offset to draw only one entity
//=============================================================
- gl.uniformMatrix4fv(this._uPositionsDecodeMatrix, false, batchingLayer._state.positionsDecodeMatrix);
- this._aPosition.bindArrayBuffer(state.positionsBuf);
- if (this._aOffset) {
- this._aOffset.bindArrayBuffer(state.offsetsBuf);
- }
- if (this._aFlags) {
- this._aFlags.bindArrayBuffer(state.flagsBuf);
- }
+
if (frameCtx.snapMode === "edge") {
state.edgeIndicesBuf.bind();
gl.drawElements(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0);
@@ -47854,39 +48339,10 @@ class SnapBatchingDepthRenderer {
}
_allocate() {
-
- const scene = this._scene;
- const gl = scene.canvas.gl;
-
- this._program = new Program(gl, this._buildShader());
-
- if (this._program.errors) {
- this.errors = this._program.errors;
- return;
- }
+ super._allocate();
const program = this._program;
- this._uRenderPass = program.getLocation("renderPass");
- this._uPickInvisible = program.getLocation("pickInvisible");
- this._uPositionsDecodeMatrix = program.getLocation("positionsDecodeMatrix");
- this._uWorldMatrix = program.getLocation("worldMatrix");
- this._uViewMatrix = program.getLocation("viewMatrix");
- this._uProjMatrix = program.getLocation("projMatrix");
- this._uSectionPlanes = [];
-
- for (let i = 0, len = scene._sectionPlanesState.sectionPlanes.length; i < len; i++) {
- this._uSectionPlanes.push({
- active: program.getLocation("sectionPlaneActive" + i),
- pos: program.getLocation("sectionPlanePos" + i),
- dir: program.getLocation("sectionPlaneDir" + i)
- });
- }
-
- this._aPosition = program.getAttribute("position");
- this._aOffset = program.getAttribute("offset");
- this._aFlags = program.getAttribute("flags");
-
{
this._uLogDepthBufFC = program.getLocation("logDepthBufFC");
}
@@ -47902,13 +48358,6 @@ class SnapBatchingDepthRenderer {
this._program.bind();
}
- _buildShader() {
- return {
- vertex: this._buildVertexShader(),
- fragment: this._buildFragmentShader()
- };
- }
-
_buildVertexShader() {
const scene = this._scene;
const clipping = scene._sectionPlanesState.sectionPlanes.length > 0;
@@ -47936,10 +48385,9 @@ class SnapBatchingDepthRenderer {
}
src.push("in float flags;");
src.push("uniform bool pickInvisible;");
- src.push("uniform mat4 worldMatrix;");
- src.push("uniform mat4 viewMatrix;");
- src.push("uniform mat4 projMatrix;");
- src.push("uniform mat4 positionsDecodeMatrix;");
+
+ this._addMatricesUniformBlockLines(src);
+
src.push("uniform vec3 uCameraEyeRtc;");
src.push("uniform vec2 snapVectorA;");
src.push("uniform vec2 snapInvVectorAB;");
@@ -48081,6 +48529,20 @@ class SnapBatchingRenderers {
}
}
+ eagerCreateRenders() {
+
+ // Pre-initialize renderers that would otherwise be lazy-initialised
+ // on user interaction, such as picking or emphasis, so that there is no delay
+ // when user first begins interacting with the viewer.
+
+ if (!this._snapDepthBufInitRenderer) {
+ this._snapDepthBufInitRenderer = new SnapBatchingDepthBufInitRenderer(this._scene, false);
+ }
+ if (!this._snapDepthRenderer) {
+ this._snapDepthRenderer = new SnapBatchingDepthRenderer(this._scene);
+ }
+ }
+
get snapDepthBufInitRenderer() {
if (!this._snapDepthBufInitRenderer) {
this._snapDepthBufInitRenderer = new SnapBatchingDepthBufInitRenderer(this._scene, false);
@@ -48117,8 +48579,10 @@ function getSnapBatchingRenderers(scene) {
batchingRenderers = new SnapBatchingRenderers(scene);
cachedRenderers$6[sceneId] = batchingRenderers;
batchingRenderers._compile();
+ batchingRenderers.eagerCreateRenders();
scene.on("compile", () => {
batchingRenderers._compile();
+ batchingRenderers.eagerCreateRenders();
});
scene.on("destroyed", () => {
delete cachedRenderers$6[sceneId];
@@ -48135,11 +48599,11 @@ const tempVec4b$b = math.vec4([0, 0, 0, 1]);
math.vec4([0, 0, 0, 1]);
math.OBB3();
-const tempVec3a$q = math.vec3();
-const tempVec3b$k = math.vec3();
-const tempVec3c$h = math.vec3();
-const tempVec3d$d = math.vec3();
-const tempVec3e$5 = math.vec3();
+const tempVec3a$p = math.vec3();
+const tempVec3b$l = math.vec3();
+const tempVec3c$i = math.vec3();
+const tempVec3d$e = math.vec3();
+const tempVec3e$3 = math.vec3();
const tempVec3f$1 = math.vec3();
const tempVec3g$1 = math.vec3();
@@ -49318,10 +49782,10 @@ class TrianglesBatchingLayer {
const origin = state.origin;
const offset = portion.offset;
- const rtcRayOrigin = tempVec3a$q;
- const rtcRayDir = tempVec3b$k;
+ const rtcRayOrigin = tempVec3a$p;
+ const rtcRayDir = tempVec3b$l;
- rtcRayOrigin.set(origin ? math.subVec3(worldRayOrigin, origin, tempVec3c$h) : worldRayOrigin); // World -> RTC
+ rtcRayOrigin.set(origin ? math.subVec3(worldRayOrigin, origin, tempVec3c$i) : worldRayOrigin); // World -> RTC
rtcRayDir.set(worldRayDir);
if (offset) {
@@ -49330,8 +49794,8 @@ class TrianglesBatchingLayer {
math.transformRay(this.model.worldNormalMatrix, rtcRayOrigin, rtcRayDir, rtcRayOrigin, rtcRayDir); // RTC -> local
- const a = tempVec3d$d;
- const b = tempVec3e$5;
+ const a = tempVec3d$e;
+ const b = tempVec3e$3;
const c = tempVec3f$1;
let gotIntersect = false;
@@ -50354,6 +50818,8 @@ class TrianglesInstancingPickMeshRenderer extends VBOSceneModelTriangleInstancin
this._addMatricesUniformBlockLines(src);
+ this._addRemapClipPosLines(src);
+
if (scene.logarithmicDepthBufferEnabled) {
src.push("uniform float logDepthBufFC;");
src.push("out float vFragDepth;");
@@ -50398,7 +50864,7 @@ class TrianglesInstancingPickMeshRenderer extends VBOSceneModelTriangleInstancin
src.push("vFragDepth = 1.0 + clipPos.w;");
src.push("isPerspective = float (isPerspectiveMatrix(projMatrix));");
}
- src.push("gl_Position = clipPos;");
+ src.push("gl_Position = remapClipPos(clipPos);");
src.push("}");
src.push("}");
return src;
@@ -50488,6 +50954,8 @@ class TrianglesInstancingPickDepthRenderer extends VBOSceneModelTriangleInstanci
this._addMatricesUniformBlockLines(src);
+ this._addRemapClipPosLines(src);
+
if (scene.logarithmicDepthBufferEnabled) {
src.push("uniform float logDepthBufFC;");
src.push("out float vFragDepth;");
@@ -50530,7 +50998,7 @@ class TrianglesInstancingPickDepthRenderer extends VBOSceneModelTriangleInstanci
src.push("vFragDepth = 1.0 + clipPos.w;");
src.push("isPerspective = float (isPerspectiveMatrix(projMatrix));");
}
- src.push("gl_Position = clipPos;");
+ src.push("gl_Position = remapClipPos(clipPos);");
src.push("}");
src.push("}");
return src;
@@ -50633,6 +51101,8 @@ class TrianglesInstancingPickNormalsRenderer extends VBOSceneModelTriangleInstan
this._addMatricesUniformBlockLines(src);
+ this._addRemapClipPosLines(src, 3);
+
if (scene.logarithmicDepthBufferEnabled) {
src.push("uniform float logDepthBufFC;");
src.push("out float vFragDepth;");
@@ -50681,7 +51151,7 @@ class TrianglesInstancingPickNormalsRenderer extends VBOSceneModelTriangleInstan
src.push("vFragDepth = 1.0 + clipPos.w;");
src.push("isPerspective = float (isPerspectiveMatrix(projMatrix));");
}
- src.push("gl_Position = clipPos;");
+ src.push("gl_Position = remapClipPos(clipPos);");
src.push("}");
src.push("}");
return src;
@@ -50721,7 +51191,7 @@ class TrianglesInstancingPickNormalsRenderer extends VBOSceneModelTriangleInstan
}
}
src.push("in vec3 vWorldNormal;");
- src.push("out vec4 outColor;");
+ src.push("out highp ivec4 outNormal;");
src.push("void main(void) {");
if (clipping) {
src.push(" bool clippable = (int(vFlags) >> 16 & 0xF) == 1;");
@@ -50738,7 +51208,7 @@ class TrianglesInstancingPickNormalsRenderer extends VBOSceneModelTriangleInstan
if (scene.logarithmicDepthBufferEnabled) {
src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
}
- src.push(" outColor = vec4((vWorldNormal * 0.5) + 0.5, 1.0);");
+ src.push(` outNormal = ivec4(vWorldNormal * float(${math.MAX_INT}), 1.0);`);
src.push("}");
return src;
}
@@ -51799,6 +52269,8 @@ class TrianglesInstancingPickNormalsFlatRenderer extends VBOSceneModelTriangleIn
this._addMatricesUniformBlockLines(src);
+ this._addRemapClipPosLines(src, 3);
+
if (scene.logarithmicDepthBufferEnabled) {
src.push("uniform float logDepthBufFC;");
src.push("out float vFragDepth;");
@@ -51837,7 +52309,7 @@ class TrianglesInstancingPickNormalsFlatRenderer extends VBOSceneModelTriangleIn
src.push("vFlags = flags;");
}
- src.push("gl_Position = clipPos;");
+ src.push("gl_Position = remapClipPos(clipPos);");
src.push("}");
src.push("}");
return src;
@@ -51873,8 +52345,7 @@ class TrianglesInstancingPickNormalsFlatRenderer extends VBOSceneModelTriangleIn
src.push("uniform vec3 sectionPlaneDir" + i + ";");
}
}
- src.push("in vec3 vWorldNormal;");
- src.push("out vec4 outColor;");
+ src.push("out highp ivec4 outNormal;");
src.push("void main(void) {");
if (clipping) {
src.push(" bool clippable = (int(vFlags) >> 16 & 0xF) == 1;");
@@ -51894,7 +52365,7 @@ class TrianglesInstancingPickNormalsFlatRenderer extends VBOSceneModelTriangleIn
src.push(" vec3 xTangent = dFdx( vWorldPosition.xyz );");
src.push(" vec3 yTangent = dFdy( vWorldPosition.xyz );");
src.push(" vec3 worldNormal = normalize( cross( xTangent, yTangent ) );");
- src.push(" outColor = vec4((worldNormal * 0.5) + 0.5, 1.0);");
+ src.push(` outNormal = ivec4(worldNormal * float(${math.MAX_INT}), 1.0);`);
src.push("}");
return src;
}
@@ -52263,6 +52734,23 @@ class TrianglesInstancingRenderers {
}
}
+ eagerCreateRenders() {
+
+ // Pre-initialize certain renderers that would otherwise be lazy-initialised
+ // on user interaction, such as picking or emphasis, so that there is no delay
+ // when user first begins interacting with the viewer.
+
+ if (!this._silhouetteRenderer) { // Used for highlighting and selection
+ this._silhouetteRenderer = new TrianglesInstancingSilhouetteRenderer(this._scene);
+ }
+ if (!this._pickMeshRenderer) {
+ this._pickMeshRenderer = new TrianglesInstancingPickMeshRenderer(this._scene);
+ }
+ if (!this._pickDepthRenderer) {
+ this._pickDepthRenderer = new TrianglesInstancingPickDepthRenderer(this._scene);
+ }
+ }
+
get colorRenderer() {
if (!this._colorRenderer) {
this._colorRenderer = new TrianglesInstancingColorRenderer(this._scene, false);
@@ -52469,8 +52957,10 @@ function getInstancingRenderers$1(scene) {
instancingRenderers = new TrianglesInstancingRenderers(scene);
cachedRenderers$5[sceneId] = instancingRenderers;
instancingRenderers._compile();
+ instancingRenderers.eagerCreateRenders();
scene.on("compile", () => {
instancingRenderers._compile();
+ instancingRenderers.eagerCreateRenders();
});
scene.on("destroyed", () => {
delete cachedRenderers$5[sceneId];
@@ -52480,30 +52970,19 @@ function getInstancingRenderers$1(scene) {
return instancingRenderers;
}
-const tempVec3a$p = math.vec3();
-const tempVec3b$j = math.vec3();
-const tempVec3c$g = math.vec3();
-const tempVec3d$c = math.vec3();
-const tempVec3e$4 = math.vec3();
-const tempMat4a$c = math.mat4();
+const tempVec3a$o = math.vec3();
+const tempVec3b$k = math.vec3();
+const tempVec3c$h = math.vec3();
+const tempVec3d$d = math.vec3();
+const tempMat4a$d = math.mat4();
/**
* @private
*/
-class SnapInstancingDepthBufInitRenderer {
+class SnapInstancingDepthBufInitRenderer extends VBOSceneModelRenderer {
constructor(scene) {
- this._scene = scene;
- this._hash = this._getHash();
- this._allocate();
- }
-
- getValid() {
- return this._hash === this._getHash();
- };
-
- _getHash() {
- return this._scene._sectionPlanesState.getHash();
+ super(scene, false, { instancing: true });
}
drawLayer(frameCtx, instancingLayer, renderPass) {
@@ -52530,7 +53009,13 @@ class SnapInstancingDepthBufInitRenderer {
const aabb = instancingLayer.aabb;
const viewMatrix = frameCtx.pickViewMatrix || camera.viewMatrix;
- const coordinateScaler = tempVec3a$p;
+ if (this._vaoCache.has(instancingLayer)) {
+ gl.bindVertexArray(this._vaoCache.get(instancingLayer));
+ } else {
+ this._vaoCache.set(instancingLayer, this._makeVAO(state));
+ }
+
+ const coordinateScaler = tempVec3a$o;
coordinateScaler[0] = math.safeInv(aabb[3] - aabb[0]) * math.MAX_INT;
coordinateScaler[1] = math.safeInv(aabb[4] - aabb[1]) * math.MAX_INT;
coordinateScaler[2] = math.safeInv(aabb[5] - aabb[2]) * math.MAX_INT;
@@ -52542,9 +53027,9 @@ class SnapInstancingDepthBufInitRenderer {
let rtcViewMatrix;
let rtcCameraEye;
if (origin || position[0] !== 0 || position[1] !== 0 || position[2] !== 0) {
- const rtcOrigin = tempVec3b$j;
+ const rtcOrigin = tempVec3b$k;
if (origin) {
- const rotatedOrigin = math.transformPoint3(rotationMatrix, origin, tempVec3c$g);
+ const rotatedOrigin = math.transformPoint3(rotationMatrix, origin, tempVec3c$h);
rtcOrigin[0] = rotatedOrigin[0];
rtcOrigin[1] = rotatedOrigin[1];
rtcOrigin[2] = rotatedOrigin[2];
@@ -52556,8 +53041,8 @@ class SnapInstancingDepthBufInitRenderer {
rtcOrigin[0] += position[0];
rtcOrigin[1] += position[1];
rtcOrigin[2] += position[2];
- rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$c);
- rtcCameraEye = tempVec3d$c;
+ rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$d);
+ rtcCameraEye = tempVec3d$d;
rtcCameraEye[0] = camera.eye[0] - rtcOrigin[0];
rtcCameraEye[1] = camera.eye[1] - rtcOrigin[1];
rtcCameraEye[2] = camera.eye[2] - rtcOrigin[2];
@@ -52579,40 +53064,30 @@ class SnapInstancingDepthBufInitRenderer {
gl.uniform3fv(this._uCoordinateScaler, coordinateScaler);
gl.uniform1i(this._uRenderPass, renderPass);
gl.uniform1i(this._uPickInvisible, frameCtx.pickInvisible);
- gl.uniformMatrix4fv(this._uWorldMatrix, false, rotationMatrixConjugate);
- gl.uniformMatrix4fv(this._uViewMatrix, false, rtcViewMatrix);
- gl.uniformMatrix4fv(this._uProjMatrix, false, camera.projMatrix);
+
+ let offset = 0;
+ const mat4Size = 4 * 4;
+
+ this._matricesUniformBlockBufferData.set(rotationMatrixConjugate, 0);
+ this._matricesUniformBlockBufferData.set(rtcViewMatrix, offset += mat4Size);
+ this._matricesUniformBlockBufferData.set(camera.projMatrix, offset += mat4Size);
+ this._matricesUniformBlockBufferData.set(state.positionsDecodeMatrix, offset += mat4Size);
+
+ gl.bindBuffer(gl.UNIFORM_BUFFER, this._matricesUniformBlockBuffer);
+ gl.bufferData(gl.UNIFORM_BUFFER, this._matricesUniformBlockBufferData, gl.DYNAMIC_DRAW);
+
+ gl.bindBufferBase(
+ gl.UNIFORM_BUFFER,
+ this._matricesUniformBlockBufferBindingPoint,
+ this._matricesUniformBlockBuffer);
+
{
const logDepthBufFC = 2.0 / (Math.log(frameCtx.pickZFar + 1.0) / Math.LN2);
gl.uniform1f(this._uLogDepthBufFC, logDepthBufFC);
}
- const numSectionPlanes = scene._sectionPlanesState.sectionPlanes.length;
- if (numSectionPlanes > 0) {
- const sectionPlanes = scene._sectionPlanesState.sectionPlanes;
- const baseIndex = instancingLayer.layerIndex * numSectionPlanes;
- const renderFlags = model.renderFlags;
- for (let sectionPlaneIndex = 0; sectionPlaneIndex < numSectionPlanes; sectionPlaneIndex++) {
- const sectionPlaneUniforms = this._uSectionPlanes[sectionPlaneIndex];
- if (sectionPlaneUniforms) {
- const active = renderFlags.sectionPlanesActivePerLayer[baseIndex + sectionPlaneIndex];
- gl.uniform1i(sectionPlaneUniforms.active, active ? 1 : 0);
- if (active) {
- const sectionPlane = sectionPlanes[sectionPlaneIndex];
- if (origin) {
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3e$4);
- gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
- } else {
- gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
- }
- gl.uniform3fv(sectionPlaneUniforms.dir, sectionPlane.dir);
- }
- }
- }
- }
-
- gl.uniformMatrix4fv(this._uPositionsDecodeMatrix, false, state.positionsDecodeMatrix);
+ this.setSectionPlanesStateUniforms(instancingLayer);
this._aModelMatrixCol0.bindArrayBuffer(state.modelMatrixCol0Buf);
this._aModelMatrixCol1.bindArrayBuffer(state.modelMatrixCol1Buf);
@@ -52622,16 +53097,11 @@ class SnapInstancingDepthBufInitRenderer {
gl.vertexAttribDivisor(this._aModelMatrixCol1.location, 1);
gl.vertexAttribDivisor(this._aModelMatrixCol2.location, 1);
- this._aPosition.bindArrayBuffer(state.positionsBuf);
if (this._aFlags) {
this._aFlags.bindArrayBuffer(state.flagsBuf);
gl.vertexAttribDivisor(this._aFlags.location, 1);
}
- if (this._aOffset) {
- this._aOffset.bindArrayBuffer(state.offsetsBuf);
- gl.vertexAttribDivisor(this._aOffset.location, 1);
- }
state.indicesBuf.bind();
gl.drawElementsInstanced(gl.TRIANGLES, state.indicesBuf.numItems, state.indicesBuf.itemType, 0, state.numInstances);
@@ -52650,34 +53120,10 @@ class SnapInstancingDepthBufInitRenderer {
}
_allocate() {
- const scene = this._scene;
- const gl = scene.canvas.gl;
- this._program = new Program(gl, this._buildShader());
- if (this._program.errors) {
- this.errors = this._program.errors;
- return;
- }
+ super._allocate();
+
const program = this._program;
- this._uRenderPass = program.getLocation("renderPass");
- this._uPickInvisible = program.getLocation("pickInvisible");
- this._uPositionsDecodeMatrix = program.getLocation("positionsDecodeMatrix");
- this._uWorldMatrix = program.getLocation("worldMatrix");
- this._uViewMatrix = program.getLocation("viewMatrix");
- this._uProjMatrix = program.getLocation("projMatrix");
- this._uSectionPlanes = [];
- for (let i = 0, len = scene._sectionPlanesState.sectionPlanes.length; i < len; i++) {
- this._uSectionPlanes.push({
- active: program.getLocation("sectionPlaneActive" + i),
- pos: program.getLocation("sectionPlanePos" + i),
- dir: program.getLocation("sectionPlaneDir" + i)
- });
- }
- this._aPosition = program.getAttribute("position");
- this._aOffset = program.getAttribute("offset");
- this._aFlags = program.getAttribute("flags");
- this._aModelMatrixCol0 = program.getAttribute("modelMatrixCol0");
- this._aModelMatrixCol1 = program.getAttribute("modelMatrixCol1");
- this._aModelMatrixCol2 = program.getAttribute("modelMatrixCol2");
+
{
this._uLogDepthBufFC = program.getLocation("logDepthBufFC");
}
@@ -52693,13 +53139,6 @@ class SnapInstancingDepthBufInitRenderer {
}
- _buildShader() {
- return {
- vertex: this._buildVertexShader(),
- fragment: this._buildFragmentShader()
- };
- }
-
_buildVertexShader() {
const scene = this._scene;
const sectionPlanesState = scene._sectionPlanesState;
@@ -52730,10 +53169,9 @@ class SnapInstancingDepthBufInitRenderer {
src.push("in vec4 modelMatrixCol1;");
src.push("in vec4 modelMatrixCol2;");
src.push("uniform bool pickInvisible;");
- src.push("uniform mat4 worldMatrix;");
- src.push("uniform mat4 viewMatrix;");
- src.push("uniform mat4 projMatrix;");
- src.push("uniform mat4 positionsDecodeMatrix;");
+
+ this._addMatricesUniformBlockLines(src);
+
src.push("uniform vec3 uCameraEyeRtc;");
src.push("uniform vec2 snapVectorA;");
src.push("uniform vec2 snapInvVectorAB;");
@@ -52854,30 +53292,19 @@ class SnapInstancingDepthBufInitRenderer {
}
}
-const tempVec3a$o = math.vec3();
-const tempVec3b$i = math.vec3();
-const tempVec3c$f = math.vec3();
-const tempVec3d$b = math.vec3();
-const tempVec3e$3 = math.vec3();
-const tempMat4a$b = math.mat4();
+const tempVec3a$n = math.vec3();
+const tempVec3b$j = math.vec3();
+const tempVec3c$g = math.vec3();
+const tempVec3d$c = math.vec3();
+const tempMat4a$c = math.mat4();
/**
* @private
*/
-class SnapInstancingDepthRenderer {
+class SnapInstancingDepthRenderer extends VBOSceneModelRenderer {
constructor(scene) {
- this._scene = scene;
- this._hash = this._getHash();
- this._allocate();
- }
-
- getValid() {
- return this._hash === this._getHash();
- };
-
- _getHash() {
- return this._scene._sectionPlanesState.getHash();
+ super(scene, false, { instancing: true });
}
drawLayer(frameCtx, instancingLayer, renderPass) {
@@ -52904,7 +53331,13 @@ class SnapInstancingDepthRenderer {
const aabb = instancingLayer.aabb;
const viewMatrix = frameCtx.pickViewMatrix || camera.viewMatrix;
- const coordinateScaler = tempVec3a$o;
+ if (this._vaoCache.has(instancingLayer)) {
+ gl.bindVertexArray(this._vaoCache.get(instancingLayer));
+ } else {
+ this._vaoCache.set(instancingLayer, this._makeVAO(state));
+ }
+
+ const coordinateScaler = tempVec3a$n;
coordinateScaler[0] = math.safeInv(aabb[3] - aabb[0]) * math.MAX_INT;
coordinateScaler[1] = math.safeInv(aabb[4] - aabb[1]) * math.MAX_INT;
coordinateScaler[2] = math.safeInv(aabb[5] - aabb[2]) * math.MAX_INT;
@@ -52917,9 +53350,9 @@ class SnapInstancingDepthRenderer {
let rtcCameraEye;
if (origin || position[0] !== 0 || position[1] !== 0 || position[2] !== 0) {
- const rtcOrigin = tempVec3b$i;
+ const rtcOrigin = tempVec3b$j;
if (origin) {
- const rotatedOrigin = math.transformPoint3(rotationMatrix, origin, tempVec3c$f);
+ const rotatedOrigin = math.transformPoint3(rotationMatrix, origin, tempVec3c$g);
rtcOrigin[0] = rotatedOrigin[0];
rtcOrigin[1] = rotatedOrigin[1];
rtcOrigin[2] = rotatedOrigin[2];
@@ -52931,8 +53364,8 @@ class SnapInstancingDepthRenderer {
rtcOrigin[0] += position[0];
rtcOrigin[1] += position[1];
rtcOrigin[2] += position[2];
- rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$b);
- rtcCameraEye = tempVec3d$b;
+ rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$c);
+ rtcCameraEye = tempVec3d$c;
rtcCameraEye[0] = camera.eye[0] - rtcOrigin[0];
rtcCameraEye[1] = camera.eye[1] - rtcOrigin[1];
rtcCameraEye[2] = camera.eye[2] - rtcOrigin[2];
@@ -52954,51 +53387,41 @@ class SnapInstancingDepthRenderer {
gl.uniform3fv(this._uCoordinateScaler, coordinateScaler);
gl.uniform1i(this._uRenderPass, renderPass);
gl.uniform1i(this._uPickInvisible, frameCtx.pickInvisible);
- gl.uniformMatrix4fv(this._uViewMatrix, false, rtcViewMatrix);
- gl.uniformMatrix4fv(this._uWorldMatrix, false, rotationMatrixConjugate);
- gl.uniformMatrix4fv(this._uProjMatrix, false, camera.projMatrix);
+
+ let offset = 0;
+ const mat4Size = 4 * 4;
+
+ this._matricesUniformBlockBufferData.set(rotationMatrixConjugate, 0);
+ this._matricesUniformBlockBufferData.set(rtcViewMatrix, offset += mat4Size);
+ this._matricesUniformBlockBufferData.set(camera.projMatrix, offset += mat4Size);
+ this._matricesUniformBlockBufferData.set(state.positionsDecodeMatrix, offset += mat4Size);
+
+ gl.bindBuffer(gl.UNIFORM_BUFFER, this._matricesUniformBlockBuffer);
+ gl.bufferData(gl.UNIFORM_BUFFER, this._matricesUniformBlockBufferData, gl.DYNAMIC_DRAW);
+
+ gl.bindBufferBase(
+ gl.UNIFORM_BUFFER,
+ this._matricesUniformBlockBufferBindingPoint,
+ this._matricesUniformBlockBuffer);
+
{
const logDepthBufFC = 2.0 / (Math.log(frameCtx.pickZFar + 1.0) / Math.LN2); // TODO: Far from pick project matrix
gl.uniform1f(this._uLogDepthBufFC, logDepthBufFC);
}
- const numSectionPlanes = scene._sectionPlanesState.sectionPlanes.length;
- if (numSectionPlanes > 0) {
- const sectionPlanes = scene._sectionPlanesState.sectionPlanes;
- const baseIndex = instancingLayer.layerIndex * numSectionPlanes;
- const renderFlags = model.renderFlags;
- for (let sectionPlaneIndex = 0; sectionPlaneIndex < numSectionPlanes; sectionPlaneIndex++) {
- const sectionPlaneUniforms = this._uSectionPlanes[sectionPlaneIndex];
- if (sectionPlaneUniforms) {
- const active = renderFlags.sectionPlanesActivePerLayer[baseIndex + sectionPlaneIndex];
- gl.uniform1i(sectionPlaneUniforms.active, active ? 1 : 0);
- if (active) {
- const sectionPlane = sectionPlanes[sectionPlaneIndex];
- if (origin) {
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3e$3);
- gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
- } else {
- gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
- }
- gl.uniform3fv(sectionPlaneUniforms.dir, sectionPlane.dir);
- }
- }
- }
- }
- gl.uniformMatrix4fv(this._uPositionsDecodeMatrix, false, state.positionsDecodeMatrix);
+ this.setSectionPlanesStateUniforms(instancingLayer);
+
+
this._aModelMatrixCol0.bindArrayBuffer(state.modelMatrixCol0Buf);
this._aModelMatrixCol1.bindArrayBuffer(state.modelMatrixCol1Buf);
this._aModelMatrixCol2.bindArrayBuffer(state.modelMatrixCol2Buf);
gl.vertexAttribDivisor(this._aModelMatrixCol0.location, 1);
gl.vertexAttribDivisor(this._aModelMatrixCol1.location, 1);
gl.vertexAttribDivisor(this._aModelMatrixCol2.location, 1);
- this._aPosition.bindArrayBuffer(state.positionsBuf);
+
this._aFlags.bindArrayBuffer(state.flagsBuf);
gl.vertexAttribDivisor(this._aFlags.location, 1);
- if (this._aOffset) {
- this._aOffset.bindArrayBuffer(state.offsetsBuf);
- gl.vertexAttribDivisor(this._aOffset.location, 1);
- }
+
if (frameCtx.snapMode === "edge") {
state.edgeIndicesBuf.bind();
gl.drawElementsInstanced(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0, state.numInstances);
@@ -53017,34 +53440,10 @@ class SnapInstancingDepthRenderer {
}
_allocate() {
- const scene = this._scene;
- const gl = scene.canvas.gl;
- this._program = new Program(gl, this._buildShader());
- if (this._program.errors) {
- this.errors = this._program.errors;
- return;
- }
+ super._allocate();
+
const program = this._program;
- this._uRenderPass = program.getLocation("renderPass");
- this._uPickInvisible = program.getLocation("pickInvisible");
- this._uPositionsDecodeMatrix = program.getLocation("positionsDecodeMatrix");
- this._uWorldMatrix = program.getLocation("worldMatrix");
- this._uViewMatrix = program.getLocation("viewMatrix");
- this._uProjMatrix = program.getLocation("projMatrix");
- this._uSectionPlanes = [];
- for (let i = 0, len = scene._sectionPlanesState.sectionPlanes.length; i < len; i++) {
- this._uSectionPlanes.push({
- active: program.getLocation("sectionPlaneActive" + i),
- pos: program.getLocation("sectionPlanePos" + i),
- dir: program.getLocation("sectionPlaneDir" + i)
- });
- }
- this._aPosition = program.getAttribute("position");
- this._aOffset = program.getAttribute("offset");
- this._aFlags = program.getAttribute("flags");
- this._aModelMatrixCol0 = program.getAttribute("modelMatrixCol0");
- this._aModelMatrixCol1 = program.getAttribute("modelMatrixCol1");
- this._aModelMatrixCol2 = program.getAttribute("modelMatrixCol2");
+
{
this._uLogDepthBufFC = program.getLocation("logDepthBufFC");
}
@@ -53060,13 +53459,6 @@ class SnapInstancingDepthRenderer {
}
- _buildShader() {
- return {
- vertex: this._buildVertexShader(),
- fragment: this._buildFragmentShader()
- };
- }
-
_buildVertexShader() {
const scene = this._scene;
const sectionPlanesState = scene._sectionPlanesState;
@@ -53097,10 +53489,9 @@ class SnapInstancingDepthRenderer {
src.push("in vec4 modelMatrixCol1;");
src.push("in vec4 modelMatrixCol2;");
src.push("uniform bool pickInvisible;");
- src.push("uniform mat4 worldMatrix;");
- src.push("uniform mat4 viewMatrix;");
- src.push("uniform mat4 projMatrix;");
- src.push("uniform mat4 positionsDecodeMatrix;");
+
+ this._addMatricesUniformBlockLines(src);
+
src.push("uniform vec3 uCameraEyeRtc;");
src.push("uniform vec2 snapVectorA;");
src.push("uniform vec2 snapInvVectorAB;");
@@ -53241,6 +53632,20 @@ class SnapInstancingRenderers {
}
}
+ eagerCreateRenders() {
+
+ // Pre-initialize renderers that would otherwise be lazy-initialised
+ // on user interaction, such as picking or emphasis, so that there is no delay
+ // when user first begins interacting with the viewer.
+
+ if (!this._snapDepthBufInitRenderer) {
+ this._snapDepthBufInitRenderer = new SnapInstancingDepthBufInitRenderer(this._scene, false);
+ }
+ if (!this._snapDepthRenderer) {
+ this._snapDepthRenderer = new SnapInstancingDepthRenderer(this._scene);
+ }
+ }
+
get snapDepthBufInitRenderer() {
if (!this._snapDepthBufInitRenderer) {
this._snapDepthBufInitRenderer = new SnapInstancingDepthBufInitRenderer(this._scene, false);
@@ -53277,8 +53682,10 @@ function getSnapInstancingRenderers(scene) {
instancingRenderers = new SnapInstancingRenderers(scene);
cachedRenderers$4[sceneId] = instancingRenderers;
instancingRenderers._compile();
+ instancingRenderers.eagerCreateRenders();
scene.on("compile", () => {
instancingRenderers._compile();
+ instancingRenderers.eagerCreateRenders();
});
scene.on("destroyed", () => {
delete cachedRenderers$4[sceneId];
@@ -53295,10 +53702,10 @@ const tempVec4b$a = math.vec4([0, 0, 0, 1]);
math.vec4([0, 0, 0, 1]);
const tempVec3fa$2 = new Float32Array(3);
-const tempVec3a$n = math.vec3();
-const tempVec3b$h = math.vec3();
-const tempVec3c$e = math.vec3();
-const tempVec3d$a = math.vec3();
+const tempVec3a$m = math.vec3();
+const tempVec3b$i = math.vec3();
+const tempVec3c$f = math.vec3();
+const tempVec3d$b = math.vec3();
const tempVec3e$2 = math.vec3();
const tempVec3f = math.vec3();
const tempVec3g = math.vec3();
@@ -54312,10 +54719,10 @@ class TrianglesInstancingLayer {
const origin = state.origin;
const offset = portion.offset;
- const rtcRayOrigin = tempVec3a$n;
- const rtcRayDir = tempVec3b$h;
+ const rtcRayOrigin = tempVec3a$m;
+ const rtcRayDir = tempVec3b$i;
- rtcRayOrigin.set(origin ? math.subVec3(worldRayOrigin, origin, tempVec3c$e) : worldRayOrigin); // World -> RTC
+ rtcRayOrigin.set(origin ? math.subVec3(worldRayOrigin, origin, tempVec3c$f) : worldRayOrigin); // World -> RTC
rtcRayDir.set(worldRayDir);
if (offset) {
@@ -54326,7 +54733,7 @@ class TrianglesInstancingLayer {
math.transformRay(portion.inverseMatrix, rtcRayOrigin, rtcRayDir, rtcRayOrigin, rtcRayDir);
- const a = tempVec3d$a;
+ const a = tempVec3d$b;
const b = tempVec3e$2;
const c = tempVec3f;
@@ -56821,6 +57228,8 @@ class PointsBatchingPickMeshRenderer extends VBOSceneModelPointBatchingRenderer
this._addMatricesUniformBlockLines(src);
+ this._addRemapClipPosLines(src);
+
src.push("uniform float pointSize;");
if (pointsMaterial.perspectivePoints) {
src.push("uniform float nearPlaneHeight;");
@@ -56862,7 +57271,7 @@ class PointsBatchingPickMeshRenderer extends VBOSceneModelPointBatchingRenderer
if (scene.logarithmicDepthBufferEnabled) {
src.push("vFragDepth = 1.0 + clipPos.w;");
}
- src.push("gl_Position = clipPos;");
+ src.push("gl_Position = remapClipPos(clipPos);");
if (pointsMaterial.perspectivePoints) {
src.push("gl_PointSize = (nearPlaneHeight * pointSize) / clipPos.w;");
src.push("gl_PointSize = max(gl_PointSize, " + Math.floor(pointsMaterial.minPerspectivePointSize) + ".0);");
@@ -56961,6 +57370,8 @@ class PointsBatchingPickDepthRenderer extends VBOSceneModelPointBatchingRenderer
this._addMatricesUniformBlockLines(src);
+ this._addRemapClipPosLines(src);
+
src.push("uniform float pointSize;");
if (pointsMaterial.perspectivePoints) {
src.push("uniform float nearPlaneHeight;");
@@ -56999,7 +57410,7 @@ class PointsBatchingPickDepthRenderer extends VBOSceneModelPointBatchingRenderer
if (scene.logarithmicDepthBufferEnabled) {
src.push("vFragDepth = 1.0 + clipPos.w;");
}
- src.push("gl_Position = clipPos;");
+ src.push("gl_Position = remapClipPos(clipPos);");
if (pointsMaterial.perspectivePoints) {
src.push("gl_PointSize = (nearPlaneHeight * pointSize) / clipPos.w;");
src.push("gl_PointSize = max(gl_PointSize, " + Math.floor(pointsMaterial.minPerspectivePointSize) + ".0);");
@@ -57347,8 +57758,8 @@ class PointsBatchingBuffer {
}
}
-const tempVec3a$m = math.vec4();
-const tempVec3b$g = math.vec4();
+const tempVec3a$l = math.vec4();
+const tempVec3b$h = math.vec4();
const tempVec4a$8 = math.vec4([0, 0, 0, 1]);
const tempVec4b$7 = math.vec4([0, 0, 0, 1]);
math.vec4([0, 0, 0, 1]);
@@ -57497,8 +57908,8 @@ class PointsBatchingLayer {
const bounds = geometryCompressionUtils.getPositionsBounds(positionsCompressed);
- const min = geometryCompressionUtils.decompressPosition(bounds.min, this._state.positionsDecodeMatrix, tempVec3a$m);
- const max = geometryCompressionUtils.decompressPosition(bounds.max, this._state.positionsDecodeMatrix, tempVec3b$g);
+ const min = geometryCompressionUtils.decompressPosition(bounds.min, this._state.positionsDecodeMatrix, tempVec3a$l);
+ const max = geometryCompressionUtils.decompressPosition(bounds.max, this._state.positionsDecodeMatrix, tempVec3b$h);
worldAABB[0] = min[0];
worldAABB[1] = min[1];
@@ -58444,6 +58855,8 @@ class PointsInstancingPickMeshRenderer extends VBOSceneModelPointInstancingRende
this._addMatricesUniformBlockLines(src);
+ this._addRemapClipPosLines(src);
+
src.push("uniform float pointSize;");
if (pointsMaterial.perspectivePoints) {
src.push("uniform float nearPlaneHeight;");
@@ -58485,6 +58898,7 @@ class PointsInstancingPickMeshRenderer extends VBOSceneModelPointInstancingRende
src.push(" vFlags = flags;");
}
src.push("vec4 clipPos = projMatrix * viewPosition;");
+ src.push("gl_Position = remapClipPos(clipPos);");
if (scene.logarithmicDepthBufferEnabled) {
src.push("vFragDepth = 1.0 + clipPos.w;");
}
@@ -58595,6 +59009,8 @@ class PointsInstancingPickDepthRenderer extends VBOSceneModelPointInstancingRend
this._addMatricesUniformBlockLines(src);
+ this._addRemapClipPosLines(src);
+
src.push("uniform float pointSize;");
if (pointsMaterial.perspectivePoints) {
src.push("uniform float nearPlaneHeight;");
@@ -58634,10 +59050,11 @@ class PointsInstancingPickDepthRenderer extends VBOSceneModelPointInstancingRend
}
src.push(" vViewPosition = viewPosition;");
src.push("vec4 clipPos = projMatrix * viewPosition;");
+ src.push("gl_Position = remapClipPos(clipPos);");
if (scene.logarithmicDepthBufferEnabled) {
src.push("vFragDepth = 1.0 + clipPos.w;");
}
- src.push("gl_Position = clipPos;");
+ src.push("gl_Position = remapClipPos(clipPos);");
if (pointsMaterial.perspectivePoints) {
src.push("gl_PointSize = (nearPlaneHeight * pointSize) / clipPos.w;");
src.push("gl_PointSize = max(gl_PointSize, " + Math.floor(pointsMaterial.minPerspectivePointSize) + ".0);");
@@ -59334,6 +59751,7 @@ class PointsInstancingLayer {
numInstances: 0,
origin: cfg.origin ? math.vec3(cfg.origin) : null,
geometry: cfg.geometry,
+ positionsDecodeMatrix: cfg.geometry.positionsDecodeMatrix, // So we can null the geometry for GC
colorsBuf: null,
flagsBuf: null,
offsetsBuf: null,
@@ -59472,34 +59890,46 @@ class PointsInstancingLayer {
}
const gl = this.model.scene.canvas.gl;
const flagsLength = this._pickColors.length / 4;
+ const state = this._state;
+ const geometry = state.geometry;
if (flagsLength > 0) {
// Because we only build flags arrays here,
// get their length from the colors array
let notNormalized = false;
- this._state.flagsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(flagsLength), flagsLength, 1, gl.DYNAMIC_DRAW, notNormalized);
+ state.flagsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(flagsLength), flagsLength, 1, gl.DYNAMIC_DRAW, notNormalized);
}
if (this.model.scene.entityOffsetsEnabled) {
if (this._offsets.length > 0) {
const notNormalized = false;
- this._state.offsetsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(this._offsets), this._offsets.length, 3, gl.DYNAMIC_DRAW, notNormalized);
+ state.offsetsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(this._offsets), this._offsets.length, 3, gl.DYNAMIC_DRAW, notNormalized);
this._offsets = []; // Release memory
}
}
+ if (geometry.positionsCompressed && geometry.positionsCompressed.length > 0) {
+ const normalized = false;
+ state.positionsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, geometry.positionsCompressed, geometry.positionsCompressed.length, 3, gl.STATIC_DRAW, normalized);
+ state.positionsDecodeMatrix = math.mat4(geometry.positionsDecodeMatrix);
+ }
+ if (geometry.colorsCompressed && geometry.colorsCompressed.length > 0) {
+ const colorsCompressed = new Uint8Array(geometry.colorsCompressed);
+ const notNormalized = false;
+ state.colorsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, colorsCompressed, colorsCompressed.length, 4, gl.STATIC_DRAW, notNormalized);
+ }
if (this._modelMatrixCol0.length > 0) {
const normalized = false;
- this._state.modelMatrixCol0Buf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(this._modelMatrixCol0), this._modelMatrixCol0.length, 4, gl.STATIC_DRAW, normalized);
- this._state.modelMatrixCol1Buf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(this._modelMatrixCol1), this._modelMatrixCol1.length, 4, gl.STATIC_DRAW, normalized);
- this._state.modelMatrixCol2Buf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(this._modelMatrixCol2), this._modelMatrixCol2.length, 4, gl.STATIC_DRAW, normalized);
+ state.modelMatrixCol0Buf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(this._modelMatrixCol0), this._modelMatrixCol0.length, 4, gl.STATIC_DRAW, normalized);
+ state.modelMatrixCol1Buf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(this._modelMatrixCol1), this._modelMatrixCol1.length, 4, gl.STATIC_DRAW, normalized);
+ state.modelMatrixCol2Buf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Float32Array(this._modelMatrixCol2), this._modelMatrixCol2.length, 4, gl.STATIC_DRAW, normalized);
this._modelMatrixCol0 = [];
this._modelMatrixCol1 = [];
this._modelMatrixCol2 = [];
}
if (this._pickColors.length > 0) {
const normalized = false;
- this._state.pickColorsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Uint8Array(this._pickColors), this._pickColors.length, 4, gl.STATIC_DRAW, normalized);
+ state.pickColorsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, new Uint8Array(this._pickColors), this._pickColors.length, 4, gl.STATIC_DRAW, normalized);
this._pickColors = []; // Release memory
}
- this._state.geometry = null;
+ state.geometry = null;
this._finalized = true;
}
@@ -61461,14 +61891,14 @@ function doCheckResult(buckets, mesh) {
}
}
-const tempVec3a$l = math.vec3();
-const tempVec3b$f = math.vec3();
-const tempVec3c$d = math.vec3();
-const tempVec3d$9 = math.vec3();
+const tempVec3a$k = math.vec3();
+const tempVec3b$g = math.vec3();
+const tempVec3c$e = math.vec3();
+const tempVec3d$a = math.vec3();
const tempVec4a$6 = math.vec4();
-const tempMat4a$a = math.mat4();
+const tempMat4a$b = math.mat4();
/**
* @private
@@ -61529,9 +61959,9 @@ class TrianglesDataTextureColorRenderer {
const gotOrigin = (origin[0] !== 0 || origin[1] !== 0 || origin[2] !== 0);
const gotPosition = (position[0] !== 0 || position[1] !== 0 || position[2] !== 0);
if (gotOrigin || gotPosition) {
- const rtcOrigin = tempVec3a$l;
+ const rtcOrigin = tempVec3a$k;
if (gotOrigin) {
- const rotatedOrigin = math.transformPoint3(rotationMatrix, origin, tempVec3b$f);
+ const rotatedOrigin = math.transformPoint3(rotationMatrix, origin, tempVec3b$g);
rtcOrigin[0] = rotatedOrigin[0];
rtcOrigin[1] = rotatedOrigin[1];
rtcOrigin[2] = rotatedOrigin[2];
@@ -61543,8 +61973,8 @@ class TrianglesDataTextureColorRenderer {
rtcOrigin[0] += position[0];
rtcOrigin[1] += position[1];
rtcOrigin[2] += position[2];
- rtcViewMatrix = createRTCViewMat(camera.viewMatrix, rtcOrigin, tempMat4a$a);
- rtcCameraEye = tempVec3c$d;
+ rtcViewMatrix = createRTCViewMat(camera.viewMatrix, rtcOrigin, tempMat4a$b);
+ rtcCameraEye = tempVec3c$e;
rtcCameraEye[0] = camera.eye[0] - rtcOrigin[0];
rtcCameraEye[1] = camera.eye[1] - rtcOrigin[1];
rtcCameraEye[2] = camera.eye[2] - rtcOrigin[2];
@@ -61577,7 +62007,7 @@ class TrianglesDataTextureColorRenderer {
if (active) {
const sectionPlane = sectionPlanes[sectionPlaneIndex];
if (origin) {
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3d$9);
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3d$a);
gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
} else {
gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -61869,9 +62299,6 @@ class TrianglesDataTextureColorRenderer {
src.push(" return;"); // Cull vertex
src.push("} else {");
- // model matrices
- src.push ("mat4 worldMatrix = sceneModelWorldMatrix * mat4 (texelFetch (uTextureModelMatrices, ivec2(0, 0), 0), texelFetch (uTextureModelMatrices, ivec2(1, 0), 0), texelFetch (uTextureModelMatrices, ivec2(2, 0), 0), texelFetch (uTextureModelMatrices, ivec2(3, 0), 0));");
-
// get vertex base
src.push("ivec4 packedVertexBase = ivec4(texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+4, objectIndexCoords.y), 0));");
@@ -61916,7 +62343,7 @@ class TrianglesDataTextureColorRenderer {
// when the geometry is not solid, if needed, flip the triangle winding
src.push("if (solid != 1u) {");
src.push("if (isPerspectiveMatrix(projMatrix)) {");
- src.push("vec3 uCameraEyeRtcInQuantizedSpace = (inverse(worldMatrix * positionsDecodeMatrix) * vec4(uCameraEyeRtc, 1)).xyz;");
+ src.push("vec3 uCameraEyeRtcInQuantizedSpace = (inverse(sceneModelWorldMatrix * positionsDecodeMatrix) * vec4(uCameraEyeRtc, 1)).xyz;");
// src.push("vColor = vec4(vec3(1, -1, 0)*dot(normalize(position.xyz - uCameraEyeRtcInQuantizedSpace), normal), 1);")
src.push("if (dot(position.xyz - uCameraEyeRtcInQuantizedSpace, normal) < 0.0) {");
src.push("position = positions[2 - (gl_VertexID % 3)];");
@@ -61931,7 +62358,7 @@ class TrianglesDataTextureColorRenderer {
src.push("}");
src.push("}");
- src.push("vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
+ src.push("vec4 worldPosition = sceneModelWorldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
// get XYZ offset
src.push("vec4 offset = vec4(texelFetch (uTexturePerObjectIdOffsets, objectIndexCoords, 0).rgb, 0.0);");
@@ -62093,11 +62520,11 @@ class TrianglesDataTextureColorRenderer {
const defaultColor$1 = new Float32Array([1, 1, 1]);
-const tempVec3a$k = math.vec3();
-const tempVec3b$e = math.vec3();
-const tempVec3c$c = math.vec3();
-const tempVec3d$8 = math.vec3();
-const tempMat4a$9 = math.mat4();
+const tempVec3a$j = math.vec3();
+const tempVec3b$f = math.vec3();
+const tempVec3c$d = math.vec3();
+const tempVec3d$9 = math.vec3();
+const tempMat4a$a = math.mat4();
/**
* @private
@@ -62156,9 +62583,9 @@ class TrianglesDataTextureSilhouetteRenderer {
let rtcCameraEye;
if (origin || position[0] !== 0 || position[1] !== 0 || position[2] !== 0) {
- const rtcOrigin = tempVec3a$k;
+ const rtcOrigin = tempVec3a$j;
if (origin) {
- const rotatedOrigin = tempVec3b$e;
+ const rotatedOrigin = tempVec3b$f;
math.transformPoint3(rotationMatrix, origin, rotatedOrigin);
rtcOrigin[0] = rotatedOrigin[0];
rtcOrigin[1] = rotatedOrigin[1];
@@ -62171,8 +62598,8 @@ class TrianglesDataTextureSilhouetteRenderer {
rtcOrigin[0] += position[0];
rtcOrigin[1] += position[1];
rtcOrigin[2] += position[2];
- rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$9);
- rtcCameraEye = tempVec3c$c;
+ rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$a);
+ rtcCameraEye = tempVec3c$d;
rtcCameraEye[0] = camera.eye[0] - rtcOrigin[0];
rtcCameraEye[1] = camera.eye[1] - rtcOrigin[1];
rtcCameraEye[2] = camera.eye[2] - rtcOrigin[2];
@@ -62225,7 +62652,7 @@ class TrianglesDataTextureSilhouetteRenderer {
if (active) {
const sectionPlane = sectionPlanes[sectionPlaneIndex];
if (origin) {
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3d$8);
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3d$9);
gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
} else {
gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -62558,11 +62985,11 @@ class TrianglesDataTextureSilhouetteRenderer {
const defaultColor = new Float32Array([0, 0, 0, 1]);
-const tempVec3a$j = math.vec3();
-const tempVec3b$d = math.vec3();
+const tempVec3a$i = math.vec3();
+const tempVec3b$e = math.vec3();
math.vec3();
-const tempVec3d$7 = math.vec3();
-const tempMat4a$8 = math.mat4();
+const tempVec3d$8 = math.vec3();
+const tempMat4a$9 = math.mat4();
/**
* @private
@@ -62621,9 +63048,9 @@ class TrianglesDataTextureEdgesRenderer {
const gotOrigin = (origin[0] !== 0 || origin[1] !== 0 || origin[2] !== 0);
const gotPosition = (position[0] !== 0 || position[1] !== 0 || position[2] !== 0);
if (gotOrigin || gotPosition) {
- const rtcOrigin = tempVec3a$j;
+ const rtcOrigin = tempVec3a$i;
if (gotOrigin) {
- const rotatedOrigin = tempVec3b$d;
+ const rotatedOrigin = tempVec3b$e;
math.transformPoint3(rotationMatrix, origin, rotatedOrigin);
rtcOrigin[0] = rotatedOrigin[0];
rtcOrigin[1] = rotatedOrigin[1];
@@ -62636,7 +63063,7 @@ class TrianglesDataTextureEdgesRenderer {
rtcOrigin[0] += position[0];
rtcOrigin[1] += position[1];
rtcOrigin[2] += position[2];
- rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$8);
+ rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$9);
} else {
rtcViewMatrix = viewMatrix;
}
@@ -62681,7 +63108,7 @@ class TrianglesDataTextureEdgesRenderer {
if (active) {
const sectionPlane = sectionPlanes[sectionPlaneIndex];
if (origin) {
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3d$7);
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3d$8);
gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
} else {
gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -62863,8 +63290,6 @@ class TrianglesDataTextureEdgesRenderer {
src.push(" return;"); // Cull vertex
src.push("} else {");
- src.push("mat4 worldMatrix = sceneModelWorldMatrix * mat4 (texelFetch (uTextureModelMatrices, ivec2(0, 0), 0), texelFetch (uTextureModelMatrices, ivec2(1, 0), 0), texelFetch (uTextureModelMatrices, ivec2(2, 0), 0), texelFetch (uTextureModelMatrices, ivec2(3, 0), 0));");
-
// get vertex base
src.push("ivec4 packedVertexBase = ivec4(texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+4, objectIndexCoords.y), 0));");
@@ -62890,7 +63315,7 @@ class TrianglesDataTextureEdgesRenderer {
// get position
src.push("vec3 position = vec3(texelFetch(uTexturePerVertexIdCoordinates, ivec2(indexPositionH, indexPositionV), 0));");
- src.push(" vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
+ src.push("vec4 worldPosition = sceneModelWorldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
// get XYZ offset
src.push("vec4 offset = vec4(texelFetch (uTexturePerObjectIdOffsets, objectIndexCoords, 0).rgb, 0.0);");
@@ -62982,10 +63407,10 @@ class TrianglesDataTextureEdgesRenderer {
}
}
-const tempVec3a$i = math.vec3();
-const tempVec3b$c = math.vec3();
-const tempVec3c$b = math.vec3();
-const tempMat4a$7 = math.mat4();
+const tempVec3a$h = math.vec3();
+const tempVec3b$d = math.vec3();
+const tempVec3c$c = math.vec3();
+const tempMat4a$8 = math.mat4();
/**
* @private
@@ -63043,9 +63468,9 @@ class TrianglesDataTextureEdgesColorRenderer {
const gotOrigin = (origin[0] !== 0 || origin[1] !== 0 || origin[2] !== 0);
const gotPosition = (position[0] !== 0 || position[1] !== 0 || position[2] !== 0);
if (gotOrigin || gotPosition) {
- const rtcOrigin = tempVec3a$i;
+ const rtcOrigin = tempVec3a$h;
if (gotOrigin) {
- const rotatedOrigin = tempVec3b$c;
+ const rotatedOrigin = tempVec3b$d;
math.transformPoint3(rotationMatrix, origin, rotatedOrigin);
rtcOrigin[0] = rotatedOrigin[0];
rtcOrigin[1] = rotatedOrigin[1];
@@ -63058,7 +63483,7 @@ class TrianglesDataTextureEdgesColorRenderer {
rtcOrigin[0] += position[0];
rtcOrigin[1] += position[1];
rtcOrigin[2] += position[2];
- rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$7);
+ rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$8);
} else {
rtcViewMatrix = viewMatrix;
}
@@ -63081,7 +63506,7 @@ class TrianglesDataTextureEdgesColorRenderer {
if (active) {
const sectionPlane = sectionPlanes[sectionPlaneIndex];
if (origin) {
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3c$b);
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3c$c);
gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
} else {
gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -63253,9 +63678,6 @@ class TrianglesDataTextureEdgesColorRenderer {
src.push("void main(void) {");
- // model matrices
- src.push("mat4 worldMatrix = sceneModelWorldMatrix * mat4 (texelFetch (uTextureModelMatrices, ivec2(0, 0), 0), texelFetch (uTextureModelMatrices, ivec2(1, 0), 0), texelFetch (uTextureModelMatrices, ivec2(2, 0), 0), texelFetch (uTextureModelMatrices, ivec2(3, 0), 0));");
-
// constants
src.push("int edgeIndex = gl_VertexID / 2;");
@@ -63311,7 +63733,7 @@ class TrianglesDataTextureEdgesColorRenderer {
src.push(" return;");
src.push("};");
- src.push(" vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
+ src.push(" vec4 worldPosition = sceneModelWorldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
// get XYZ offset
src.push("vec4 offset = vec4(texelFetch (uTexturePerObjectIdOffsets, objectIndexCoords, 0).rgb, 0.0);");
@@ -63403,10 +63825,10 @@ class TrianglesDataTextureEdgesColorRenderer {
}
}
-const tempVec3a$h = math.vec3();
-const tempVec3b$b = math.vec3();
-const tempVec3c$a = math.vec3();
-const tempMat4a$6 = math.mat4();
+const tempVec3a$g = math.vec3();
+const tempVec3b$c = math.vec3();
+const tempVec3c$b = math.vec3();
+const tempMat4a$7 = math.mat4();
/**
* @private
@@ -63421,7 +63843,7 @@ class TrianglesDataTexturePickMeshRenderer {
getValid() {
return this._hash === this._getHash();
- };
+ }
_getHash() {
return this._scene._sectionPlanesState.getHash();
@@ -63459,9 +63881,9 @@ class TrianglesDataTexturePickMeshRenderer {
const gotOrigin = (origin[0] !== 0 || origin[1] !== 0 || origin[2] !== 0);
const gotPosition = (position[0] !== 0 || position[1] !== 0 || position[2] !== 0);
if (gotOrigin || gotPosition) {
- const rtcOrigin = tempVec3a$h;
+ const rtcOrigin = tempVec3a$g;
if (gotOrigin) {
- const rotatedOrigin = math.transformPoint3(rotationMatrix, origin, tempVec3b$b);
+ const rotatedOrigin = math.transformPoint3(rotationMatrix, origin, tempVec3b$c);
rtcOrigin[0] = rotatedOrigin[0];
rtcOrigin[1] = rotatedOrigin[1];
rtcOrigin[2] = rotatedOrigin[2];
@@ -63473,8 +63895,8 @@ class TrianglesDataTexturePickMeshRenderer {
rtcOrigin[0] += position[0];
rtcOrigin[1] += position[1];
rtcOrigin[2] += position[2];
- rtcViewMatrix = createRTCViewMat(camera.viewMatrix, rtcOrigin, tempMat4a$6);
- rtcCameraEye = tempVec3c$a;
+ rtcViewMatrix = createRTCViewMat(camera.viewMatrix, rtcOrigin, tempMat4a$7);
+ rtcCameraEye = tempVec3c$b;
rtcCameraEye[0] = camera.eye[0] - rtcOrigin[0];
rtcCameraEye[1] = camera.eye[1] - rtcOrigin[1];
rtcCameraEye[2] = camera.eye[2] - rtcOrigin[2];
@@ -63482,6 +63904,8 @@ class TrianglesDataTexturePickMeshRenderer {
rtcViewMatrix = camera.viewMatrix;
rtcCameraEye = camera.eye;
}
+ gl.uniform2fv(this._uPickClipPos, frameCtx.pickClipPos);
+ gl.uniform2f(this._uDrawingBufferSize, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.uniformMatrix4fv(this._uSceneModelWorldMatrix, false, rotationMatrixConjugate);
gl.uniformMatrix4fv(this._uViewMatrix, false, rtcViewMatrix);
gl.uniformMatrix4fv(this._uProjMatrix, false, camera.projMatrix);
@@ -63504,7 +63928,7 @@ class TrianglesDataTexturePickMeshRenderer {
if (active) {
const sectionPlane = sectionPlanes[sectionPlaneIndex];
if (origin) {
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a$h);
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a$g);
gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
} else {
gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -63555,6 +63979,8 @@ class TrianglesDataTexturePickMeshRenderer {
const program = this._program;
this._uRenderPass = program.getLocation("renderPass");
this._uPickInvisible = program.getLocation("pickInvisible");
+ this._uPickClipPos = program.getLocation("pickClipPos");
+ this._uDrawingBufferSize = program.getLocation("drawingBufferSize");
this._uSceneModelWorldMatrix = program.getLocation("sceneModelWorldMatrix");
this._uViewMatrix = program.getLocation("viewMatrix");
this._uProjMatrix = program.getLocation("projMatrix");
@@ -63566,10 +63992,6 @@ class TrianglesDataTexturePickMeshRenderer {
dir: program.getLocation("sectionPlaneDir" + i)
});
}
- if (this._withSAO) {
- this._uOcclusionTexture = "uOcclusionTexture";
- this._uSAOParams = program.getLocation("uSAOParams");
- }
if (scene.logarithmicDepthBufferEnabled) {
this._uLogDepthBufFC = program.getLocation("logDepthBufFC");
}
@@ -63585,12 +64007,9 @@ class TrianglesDataTexturePickMeshRenderer {
}
_bindProgram(frameCtx) {
-
const scene = this._scene;
const gl = scene.canvas.gl;
-
this._program.bind();
-
gl.uniform1i(this._uPickInvisible, frameCtx.pickInvisible);
}
@@ -63652,6 +64071,16 @@ class TrianglesDataTexturePickMeshRenderer {
src.push("out float isPerspective;");
}
+ src.push("uniform vec2 pickClipPos;");
+ src.push("uniform vec2 drawingBufferSize;");
+
+ src.push("vec4 remapClipPos(vec4 clipPos) {");
+ src.push(" clipPos.xy /= clipPos.w;");
+ src.push(` clipPos.xy = (clipPos.xy - pickClipPos) * drawingBufferSize;`);
+ src.push(" clipPos.xy *= clipPos.w;");
+ src.push(" return clipPos;");
+ src.push("}");
+
src.push("bool isPerspectiveMatrix(mat4 m) {");
src.push(" return (m[2][3] == - 1.0);");
src.push("}");
@@ -63665,10 +64094,6 @@ class TrianglesDataTexturePickMeshRenderer {
src.push("void main(void) {");
- // model matrices
- src.push ("mat4 worldMatrix = sceneModelWorldMatrix * mat4 (texelFetch (uTextureModelMatrices, ivec2(0, 0), 0), texelFetch (uTextureModelMatrices, ivec2(1, 0), 0), texelFetch (uTextureModelMatrices, ivec2(2, 0), 0), texelFetch (uTextureModelMatrices, ivec2(3, 0), 0));");
-
- // constants
src.push("int polygonIndex = gl_VertexID / 3;");
// get packed object-id
@@ -63735,7 +64160,7 @@ class TrianglesDataTexturePickMeshRenderer {
// when the geometry is not solid, if needed, flip the triangle winding
src.push("if (solid != 1u) {");
src.push("if (isPerspectiveMatrix(projMatrix)) {");
- src.push("vec3 uCameraEyeRtcInQuantizedSpace = (inverse(worldMatrix * positionsDecodeMatrix) * vec4(uCameraEyeRtc, 1)).xyz;");
+ src.push("vec3 uCameraEyeRtcInQuantizedSpace = (inverse(sceneModelWorldMatrix * positionsDecodeMatrix) * vec4(uCameraEyeRtc, 1)).xyz;");
src.push("if (dot(position.xyz - uCameraEyeRtcInQuantizedSpace, normal) < 0.0) {");
src.push("position = positions[2 - (gl_VertexID % 3)];");
src.push("}");
@@ -63747,7 +64172,7 @@ class TrianglesDataTexturePickMeshRenderer {
src.push("}");
src.push("}");
- src.push("vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
+ src.push("vec4 worldPosition = sceneModelWorldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
// get XYZ offset
src.push("vec4 offset = vec4(texelFetch (uTexturePerObjectIdOffsets, objectIndexCoords, 0).rgb, 0.0);");
@@ -63766,7 +64191,7 @@ class TrianglesDataTexturePickMeshRenderer {
src.push("vFragDepth = 1.0 + clipPos.w;");
src.push("isPerspective = float (isPerspectiveMatrix(projMatrix));");
}
- src.push("gl_Position = clipPos;");
+ src.push("gl_Position = remapClipPos(clipPos);");
src.push(" }");
src.push("}");
return src;
@@ -63836,11 +64261,11 @@ class TrianglesDataTexturePickMeshRenderer {
}
}
-const tempVec3a$g = math.vec3();
-const tempVec3b$a = math.vec3();
-const tempVec3c$9 = math.vec3();
-const tempVec3d$6 = math.vec3();
-const tempMat4a$5 = math.mat4();
+const tempVec3a$f = math.vec3();
+const tempVec3b$b = math.vec3();
+const tempVec3c$a = math.vec3();
+const tempVec3d$7 = math.vec3();
+const tempMat4a$6 = math.mat4();
/**
* @private
@@ -63855,7 +64280,7 @@ class TrianglesDataTexturePickDepthRenderer {
getValid() {
return this._hash === this._getHash();
- };
+ }
_getHash() {
return this._scene._sectionPlanesState.getHash();
@@ -63895,9 +64320,9 @@ class TrianglesDataTexturePickDepthRenderer {
let rtcCameraEye;
if (origin || position[0] !== 0 || position[1] !== 0 || position[2] !== 0) {
- const rtcOrigin = tempVec3a$g;
+ const rtcOrigin = tempVec3a$f;
if (origin) {
- const rotatedOrigin = tempVec3b$a;
+ const rotatedOrigin = tempVec3b$b;
math.transformPoint3(rotationMatrix, origin, rotatedOrigin);
rtcOrigin[0] = rotatedOrigin[0];
rtcOrigin[1] = rotatedOrigin[1];
@@ -63910,8 +64335,8 @@ class TrianglesDataTexturePickDepthRenderer {
rtcOrigin[0] += position[0];
rtcOrigin[1] += position[1];
rtcOrigin[2] += position[2];
- rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$5);
- rtcCameraEye = tempVec3c$9;
+ rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$6);
+ rtcCameraEye = tempVec3c$a;
rtcCameraEye[0] = camera.eye[0] - rtcOrigin[0];
rtcCameraEye[1] = camera.eye[1] - rtcOrigin[1];
rtcCameraEye[2] = camera.eye[2] - rtcOrigin[2];
@@ -63929,6 +64354,8 @@ class TrianglesDataTexturePickDepthRenderer {
gl.uniform3fv(this._uCameraEyeRtc, rtcCameraEye);
gl.uniform1i(this._uRenderPass, renderPass);
gl.uniform1i(this._uPickInvisible, frameCtx.pickInvisible);
+ gl.uniform2fv(this._uPickClipPos, frameCtx.pickClipPos);
+ gl.uniform2f(this._uDrawingBufferSize, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.uniform1f(this._uPickZNear, frameCtx.pickZNear);
gl.uniform1f(this._uPickZFar, frameCtx.pickZFar);
gl.uniformMatrix4fv(this._uWorldMatrix, false, rotationMatrixConjugate);
@@ -63952,7 +64379,7 @@ class TrianglesDataTexturePickDepthRenderer {
if (active) {
const sectionPlane = sectionPlanes[sectionPlaneIndex];
if (origin) {
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3d$6);
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3d$7);
gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
} else {
gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -64003,6 +64430,8 @@ class TrianglesDataTexturePickDepthRenderer {
const program = this._program;
this._uRenderPass = program.getLocation("renderPass");
this._uPickInvisible = program.getLocation("pickInvisible");
+ this._uPickClipPos = program.getLocation("pickClipPos");
+ this._uDrawingBufferSize = program.getLocation("drawingBufferSize");
this._uWorldMatrix = program.getLocation("worldMatrix");
this._uViewMatrix = program.getLocation("viewMatrix");
this._uProjMatrix = program.getLocation("projMatrix");
@@ -64092,6 +64521,16 @@ class TrianglesDataTexturePickDepthRenderer {
src.push("out float isPerspective;");
}
+ src.push("uniform vec2 pickClipPos;");
+ src.push("uniform vec2 drawingBufferSize;");
+
+ src.push("vec4 remapClipPos(vec4 clipPos) {");
+ src.push(" clipPos.xy /= clipPos.w;");
+ src.push(` clipPos.xy = (clipPos.xy - pickClipPos) * drawingBufferSize;`);
+ src.push(" clipPos.xy *= clipPos.w;");
+ src.push(" return clipPos;");
+ src.push("}");
+
src.push("bool isPerspectiveMatrix(mat4 m) {");
src.push(" return (m[2][3] == - 1.0);");
src.push("}");
@@ -64198,7 +64637,7 @@ class TrianglesDataTexturePickDepthRenderer {
src.push("vFragDepth = 1.0 + clipPos.w;");
src.push("isPerspective = float (isPerspectiveMatrix(projMatrix));");
}
- src.push("gl_Position = clipPos;");
+ src.push("gl_Position = remapClipPos(clipPos);");
src.push(" }");
src.push("}");
return src;
@@ -64283,12 +64722,12 @@ class TrianglesDataTexturePickDepthRenderer {
}
}
-const tempVec3a$f = math.vec3();
-const tempVec3b$9 = math.vec3();
-const tempVec3c$8 = math.vec3();
-const tempVec3d$5 = math.vec3();
+const tempVec3a$e = math.vec3();
+const tempVec3b$a = math.vec3();
+const tempVec3c$9 = math.vec3();
+const tempVec3d$6 = math.vec3();
const tempVec3e$1 = math.vec3();
-const tempMat4a$4 = math.mat4();
+const tempMat4a$5 = math.mat4();
/**
* @private
@@ -64334,7 +64773,7 @@ class TrianglesDataTextureSnapDepthRenderer {
const aabb = dataTextureLayer.aabb;
const viewMatrix = frameCtx.pickViewMatrix || camera.viewMatrix;
- const coordinateScaler = tempVec3a$f;
+ const coordinateScaler = tempVec3a$e;
coordinateScaler[0] = math.safeInv(aabb[3] - aabb[0]) * math.MAX_INT;
coordinateScaler[1] = math.safeInv(aabb[4] - aabb[1]) * math.MAX_INT;
coordinateScaler[2] = math.safeInv(aabb[5] - aabb[2]) * math.MAX_INT;
@@ -64358,9 +64797,9 @@ class TrianglesDataTextureSnapDepthRenderer {
const gotOrigin = (origin[0] !== 0 || origin[1] !== 0 || origin[2] !== 0);
const gotPosition = (position[0] !== 0 || position[1] !== 0 || position[2] !== 0);
if (gotOrigin || gotPosition) {
- const rtcOrigin = tempVec3b$9;
+ const rtcOrigin = tempVec3b$a;
if (gotOrigin) {
- const rotatedOrigin = math.transformPoint3(rotationMatrix, origin, tempVec3c$8);
+ const rotatedOrigin = math.transformPoint3(rotationMatrix, origin, tempVec3c$9);
rtcOrigin[0] = rotatedOrigin[0];
rtcOrigin[1] = rotatedOrigin[1];
rtcOrigin[2] = rotatedOrigin[2];
@@ -64372,8 +64811,8 @@ class TrianglesDataTextureSnapDepthRenderer {
rtcOrigin[0] += position[0];
rtcOrigin[1] += position[1];
rtcOrigin[2] += position[2];
- rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$4);
- rtcCameraEye = tempVec3d$5;
+ rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$5);
+ rtcCameraEye = tempVec3d$6;
rtcCameraEye[0] = camera.eye[0] - rtcOrigin[0];
rtcCameraEye[1] = camera.eye[1] - rtcOrigin[1];
rtcCameraEye[2] = camera.eye[2] - rtcOrigin[2];
@@ -64590,8 +65029,6 @@ class TrianglesDataTextureSnapDepthRenderer {
src.push("{");
- src.push ("mat4 worldMatrix = sceneModelWorldMatrix * mat4 (texelFetch (uTextureModelMatrices, ivec2(0, 0), 0), texelFetch (uTextureModelMatrices, ivec2(1, 0), 0), texelFetch (uTextureModelMatrices, ivec2(2, 0), 0), texelFetch (uTextureModelMatrices, ivec2(3, 0), 0));");
-
// get vertex base
src.push("ivec4 packedVertexBase = ivec4(texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+4, objectIndexCoords.y), 0));");
src.push("ivec4 packedEdgeIndexBaseOffset = ivec4(texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+6, objectIndexCoords.y), 0));");
@@ -64608,7 +65045,7 @@ class TrianglesDataTextureSnapDepthRenderer {
src.push("uvec4 flags2 = texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+3, objectIndexCoords.y), 0);");
// get position
src.push("vec3 position = vec3(texelFetch(uTexturePerVertexIdCoordinates, ivec2(indexPositionH, indexPositionV), 0));");
- src.push(" vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
+ src.push("vec4 worldPosition = sceneModelWorldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
// get XYZ offset
src.push("vec4 offset = vec4(texelFetch (uTexturePerObjectIdOffsets, objectIndexCoords, 0).rgb, 0.0);");
src.push("worldPosition.xyz = worldPosition.xyz + offset.xyz;");
@@ -64702,12 +65139,12 @@ class TrianglesDataTextureSnapDepthRenderer {
}
}
-const tempVec3a$e = math.vec3();
-const tempVec3b$8 = math.vec3();
-const tempVec3c$7 = math.vec3();
-const tempVec3d$4 = math.vec3();
+const tempVec3a$d = math.vec3();
+const tempVec3b$9 = math.vec3();
+const tempVec3c$8 = math.vec3();
+const tempVec3d$5 = math.vec3();
const tempVec3e = math.vec3();
-const tempMat4a$3 = math.mat4();
+const tempMat4a$4 = math.mat4();
/**
* @private
*/
@@ -64749,7 +65186,7 @@ class TrianglesDataTextureSnapDepthBufInitRenderer {
const aabb = dataTextureLayer.aabb;
const viewMatrix = frameCtx.pickViewMatrix || camera.viewMatrix;
- const coordinateScaler = tempVec3a$e;
+ const coordinateScaler = tempVec3a$d;
coordinateScaler[0] = math.safeInv(aabb[3] - aabb[0]) * math.MAX_INT;
coordinateScaler[1] = math.safeInv(aabb[4] - aabb[1]) * math.MAX_INT;
coordinateScaler[2] = math.safeInv(aabb[5] - aabb[2]) * math.MAX_INT;
@@ -64770,9 +65207,9 @@ class TrianglesDataTextureSnapDepthBufInitRenderer {
const gotOrigin = (origin[0] !== 0 || origin[1] !== 0 || origin[2] !== 0);
const gotPosition = (position[0] !== 0 || position[1] !== 0 || position[2] !== 0);
if (gotOrigin || gotPosition) {
- const rtcOrigin = tempVec3b$8;
+ const rtcOrigin = tempVec3b$9;
if (gotOrigin) {
- const rotatedOrigin = tempVec3c$7;
+ const rotatedOrigin = tempVec3c$8;
math.transformPoint3(rotationMatrix, origin, rotatedOrigin);
rtcOrigin[0] = rotatedOrigin[0];
rtcOrigin[1] = rotatedOrigin[1];
@@ -64785,8 +65222,8 @@ class TrianglesDataTextureSnapDepthBufInitRenderer {
rtcOrigin[0] += position[0];
rtcOrigin[1] += position[1];
rtcOrigin[2] += position[2];
- rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$3);
- rtcCameraEye = tempVec3d$4;
+ rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$4);
+ rtcCameraEye = tempVec3d$5;
rtcCameraEye[0] = camera.eye[0] - rtcOrigin[0];
rtcCameraEye[1] = camera.eye[1] - rtcOrigin[1];
rtcCameraEye[2] = camera.eye[2] - rtcOrigin[2];
@@ -65001,8 +65438,6 @@ class TrianglesDataTextureSnapDepthBufInitRenderer {
src.push("{");
- src.push("mat4 worldMatrix = sceneModelWorldMatrix * mat4 (texelFetch (uTextureModelMatrices, ivec2(0, 0), 0), texelFetch (uTextureModelMatrices, ivec2(1, 0), 0), texelFetch (uTextureModelMatrices, ivec2(2, 0), 0), texelFetch (uTextureModelMatrices, ivec2(3, 0), 0));");
-
// get color
src.push("uvec4 color = texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+0, objectIndexCoords.y), 0);");
@@ -65044,7 +65479,7 @@ class TrianglesDataTextureSnapDepthBufInitRenderer {
// when the geometry is not solid, if needed, flip the triangle winding
src.push("if (solid != 1u) {");
src.push(" if (isPerspectiveMatrix(projMatrix)) {");
- src.push(" vec3 uCameraEyeRtcInQuantizedSpace = (inverse(worldMatrix * positionsDecodeMatrix) * vec4(uCameraEyeRtc, 1)).xyz;");
+ src.push(" vec3 uCameraEyeRtcInQuantizedSpace = (inverse(sceneModelWorldMatrix * positionsDecodeMatrix) * vec4(uCameraEyeRtc, 1)).xyz;");
src.push(" if (dot(position.xyz - uCameraEyeRtcInQuantizedSpace, normal) < 0.0) {");
src.push(" position = positions[2 - (gl_VertexID % 3)];");
src.push(" viewNormal = -viewNormal;");
@@ -65057,7 +65492,7 @@ class TrianglesDataTextureSnapDepthBufInitRenderer {
src.push(" }");
src.push("}");
- src.push("vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
+ src.push("vec4 worldPosition = sceneModelWorldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
src.push("vec4 offset = vec4(texelFetch (uTexturePerObjectIdOffsets, objectIndexCoords, 0).rgb, 0.0);");
src.push("worldPosition.xyz = worldPosition.xyz + offset.xyz;");
src.push("relativeToOriginPosition = worldPosition.xyz;");
@@ -65148,12 +65583,16 @@ class TrianglesDataTextureSnapDepthBufInitRenderer {
}
}
-const tempVec3a$d = math.vec3();
+const tempVec3a$c = math.vec3();
+const tempVec3b$8 = math.vec3();
+const tempVec3c$7 = math.vec3();
+const tempVec3d$4 = math.vec3();
+const tempMat4a$3 = math.mat4();
/**
* @private
*/
-class TrianglesDataTexturePickNormalsRenderer {
+class TrianglesDataTextureOcclusionRenderer {
constructor(scene) {
this._scene = scene;
@@ -65178,9 +65617,14 @@ class TrianglesDataTexturePickNormalsRenderer {
const state = dataTextureLayer._state;
const textureState = state.textureState;
const origin = dataTextureLayer._state.origin;
+ const {position, rotationMatrix, rotationMatrixConjugate} = model;
+ const viewMatrix = frameCtx.pickViewMatrix || camera.viewMatrix;
if (!this._program) {
this._allocate(dataTextureLayer);
+ if (this.errors) {
+ return;
+ }
}
if (frameCtx.lastProgramId !== this._program.id) {
@@ -65193,39 +65637,45 @@ class TrianglesDataTexturePickNormalsRenderer {
this._uTexturePerObjectIdPositionsDecodeMatrix,
this._uTexturePerVertexIdCoordinates,
this._uTexturePerObjectIdColorsAndFlags,
- this._uTextureCameraMatrices,
this._uTextureModelMatrices,
this._uTexturePerObjectIdOffsets
);
- let cameraEye = camera.eye;
+ let rtcViewMatrix;
+ let rtcCameraEye;
- if (frameCtx.pickViewMatrix) {
- textureState.bindPickCameraTexture(
- this._program,
- this._uTextureCameraMatrices
- );
- cameraEye = frameCtx.pickOrigin || cameraEye;
+ if (origin || position[0] !== 0 || position[1] !== 0 || position[2] !== 0) {
+ const rtcOrigin = tempVec3a$c;
+ if (origin) {
+ const rotatedOrigin = tempVec3b$8;
+ math.transformPoint3(rotationMatrix, origin, rotatedOrigin);
+ rtcOrigin[0] = rotatedOrigin[0];
+ rtcOrigin[1] = rotatedOrigin[1];
+ rtcOrigin[2] = rotatedOrigin[2];
+ } else {
+ rtcOrigin[0] = 0;
+ rtcOrigin[1] = 0;
+ rtcOrigin[2] = 0;
+ }
+ rtcOrigin[0] += position[0];
+ rtcOrigin[1] += position[1];
+ rtcOrigin[2] += position[2];
+ rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$3);
+ rtcCameraEye = tempVec3c$7;
+ rtcCameraEye[0] = camera.eye[0] - rtcOrigin[0];
+ rtcCameraEye[1] = camera.eye[1] - rtcOrigin[1];
+ rtcCameraEye[2] = camera.eye[2] - rtcOrigin[2];
+ } else {
+ rtcViewMatrix = viewMatrix;
+ rtcCameraEye = camera.eye;
}
- const originCameraEye = [
- cameraEye[0] - origin[0],
- cameraEye[1] - origin[1],
- cameraEye[2] - origin[2],
- ];
-
- gl.uniform3fv(this._uCameraEyeRtc, originCameraEye);
-
+ gl.uniform3fv(this._uCameraEyeRtc, rtcCameraEye);
gl.uniform1i(this._uRenderPass, renderPass);
+ gl.uniformMatrix4fv(this._uWorldMatrix, false, rotationMatrixConjugate);
+ gl.uniformMatrix4fv(this._uViewMatrix, false, rtcViewMatrix);
- gl.uniform3fv(this._uCameraEyeRtc, originCameraEye);
-
- gl.uniform1i(this._uPickInvisible, frameCtx.pickInvisible);
-
- if (scene.logarithmicDepthBufferEnabled) {
- const logDepthBufFC = 2.0 / (Math.log(camera.project.far + 1.0) / Math.LN2); // TODO: Far should be from projection matrix?
- gl.uniform1f(this._uLogDepthBufFC, logDepthBufFC);
- }
+ gl.uniformMatrix4fv(this._uProjMatrix, false, camera.projMatrix);
const numSectionPlanes = scene._sectionPlanesState.sectionPlanes.length;
if (numSectionPlanes > 0) {
@@ -65240,7 +65690,7 @@ class TrianglesDataTexturePickNormalsRenderer {
if (active) {
const sectionPlane = sectionPlanes[sectionPlaneIndex];
if (origin) {
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a$d);
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3d$4);
gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
} else {
gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -65258,10 +65708,8 @@ class TrianglesDataTexturePickNormalsRenderer {
this._uTexturePerPolygonIdIndices,
8 // 8 bits indices
);
-
gl.drawArrays(gl.TRIANGLES, 0, state.numIndices8Bits);
}
-
if (state.numIndices16Bits > 0) {
textureState.bindTriangleIndicesTextures(
this._program,
@@ -65269,10 +65717,8 @@ class TrianglesDataTexturePickNormalsRenderer {
this._uTexturePerPolygonIdIndices,
16 // 16 bits indices
);
-
gl.drawArrays(gl.TRIANGLES, 0, state.numIndices16Bits);
}
-
if (state.numIndices32Bits > 0) {
textureState.bindTriangleIndicesTextures(
this._program,
@@ -65280,32 +65726,26 @@ class TrianglesDataTexturePickNormalsRenderer {
this._uTexturePerPolygonIdIndices,
32 // 32 bits indices
);
-
gl.drawArrays(gl.TRIANGLES, 0, state.numIndices32Bits);
}
-
frameCtx.drawElements++;
}
_allocate() {
-
const scene = this._scene;
const gl = scene.canvas.gl;
-
this._program = new Program(gl, this._buildShader());
-
if (this._program.errors) {
this.errors = this._program.errors;
return;
}
-
const program = this._program;
-
this._uRenderPass = program.getLocation("renderPass");
this._uPickInvisible = program.getLocation("pickInvisible");
-
+ this._uWorldMatrix = program.getLocation("sceneModelWorldMatrix");
+ this._uViewMatrix = program.getLocation("viewMatrix");
+ this._uProjMatrix = program.getLocation("projMatrix");
this._uSectionPlanes = [];
-
for (let i = 0, len = scene._sectionPlanesState.sectionPlanes.length; i < len; i++) {
this._uSectionPlanes.push({
active: program.getLocation("sectionPlaneActive" + i),
@@ -65313,11 +65753,11 @@ class TrianglesDataTexturePickNormalsRenderer {
dir: program.getLocation("sectionPlaneDir" + i)
});
}
-
+ this._uPickZNear = program.getLocation("pickZNear");
+ this._uPickZFar = program.getLocation("pickZFar");
if (scene.logarithmicDepthBufferEnabled) {
this._uLogDepthBufFC = program.getLocation("logDepthBufFC");
}
-
this._uTexturePerObjectIdPositionsDecodeMatrix = "uTexturePerObjectIdPositionsDecodeMatrix";
this._uTexturePerObjectIdColorsAndFlags = "uTexturePerObjectIdColorsAndFlags";
this._uTexturePerVertexIdCoordinates = "uTexturePerVertexIdCoordinates";
@@ -65331,6 +65771,11 @@ class TrianglesDataTexturePickNormalsRenderer {
}
_bindProgram() {
+
+ const scene = this._scene;
+ scene.canvas.gl;
+ scene.camera.project;
+
this._program.bind();
}
@@ -65346,7 +65791,7 @@ class TrianglesDataTexturePickNormalsRenderer {
const clipping = scene._sectionPlanesState.sectionPlanes.length > 0;
const src = [];
src.push("#version 300 es");
- src.push("// Triangles dataTexture pick normals vertex shader");
+ src.push("// TrianglesDataTextureColorRenderer vertex shader");
src.push("#ifdef GL_FRAGMENT_PRECISION_HIGH");
src.push("precision highp float;");
@@ -65368,45 +65813,29 @@ class TrianglesDataTexturePickNormalsRenderer {
src.push("in vec3 offset;");
}
- src.push("uniform bool pickInvisible;");
+ src.push("uniform mat4 sceneModelWorldMatrix;");
+ src.push("uniform mat4 viewMatrix;");
+ src.push("uniform mat4 projMatrix;");
+
src.push("uniform highp sampler2D uTexturePerObjectIdPositionsDecodeMatrix;");
src.push("uniform lowp usampler2D uTexturePerObjectIdColorsAndFlags;");
src.push("uniform highp sampler2D uTexturePerObjectIdOffsets;");
src.push("uniform mediump usampler2D uTexturePerVertexIdCoordinates;");
src.push("uniform highp usampler2D uTexturePerPolygonIdIndices;");
src.push("uniform mediump usampler2D uTexturePerPolygonIdPortionIds;");
- src.push("uniform highp sampler2D uTextureCameraMatrices;");
src.push("uniform highp sampler2D uTextureModelMatrices;");
src.push("uniform vec3 uCameraEyeRtc;");
src.push("vec3 positions[3];");
-
- if (scene.logarithmicDepthBufferEnabled) {
- src.push("uniform float logDepthBufFC;");
- src.push("out float vFragDepth;");
- src.push("out float isPerspective;");
- }
-
src.push("bool isPerspectiveMatrix(mat4 m) {");
src.push(" return (m[2][3] == - 1.0);");
src.push("}");
-
if (clipping) {
src.push("out vec4 vWorldPosition;");
- src.push("flat out uint vFlags2;");
+ src.push("out vec4 vFlags2;");
}
-
- src.push("out vec3 vWorldNormal;");
-
src.push("void main(void) {");
- // camera matrices
- src.push("mat4 viewMatrix = mat4 (texelFetch (uTextureCameraMatrices, ivec2(0, 0), 0), texelFetch (uTextureCameraMatrices, ivec2(1, 0), 0), texelFetch (uTextureCameraMatrices, ivec2(2, 0), 0), texelFetch (uTextureCameraMatrices, ivec2(3, 0), 0));");
- src.push("mat4 projMatrix = mat4 (texelFetch (uTextureCameraMatrices, ivec2(0, 2), 0), texelFetch (uTextureCameraMatrices, ivec2(1, 2), 0), texelFetch (uTextureCameraMatrices, ivec2(2, 2), 0), texelFetch (uTextureCameraMatrices, ivec2(3, 2), 0));");
-
- // model matrices
- src.push("mat4 worldMatrix = mat4 (texelFetch (uTextureModelMatrices, ivec2(0, 0), 0), texelFetch (uTextureModelMatrices, ivec2(1, 0), 0), texelFetch (uTextureModelMatrices, ivec2(2, 0), 0), texelFetch (uTextureModelMatrices, ivec2(3, 0), 0));");
-
// constants
src.push("int polygonIndex = gl_VertexID / 3;");
@@ -65421,13 +65850,14 @@ class TrianglesDataTexturePickNormalsRenderer {
src.push("uvec4 flags = texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+2, objectIndexCoords.y), 0);");
src.push("uvec4 flags2 = texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+3, objectIndexCoords.y), 0);");
- // flags.w = NOT_RENDERED | PICK
- // renderPass = PICK
+ // flags.x = NOT_RENDERED | COLOR_OPAQUE | COLOR_TRANSPARENT
+ // renderPass = COLOR_OPAQUE
+ // Only opaque objects can be occluders
- src.push(`if (int(flags.w) != renderPass) {`);
- src.push(" gl_Position = vec4(3.0, 3.0, 3.0, 1.0);"); // Cull vertex
- src.push(" return;"); // Cull vertex
- src.push("} else {");
+ src.push(`if (int(flags.x) != renderPass) {`);
+ src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex
+
+ src.push(" } else {");
// get vertex base
src.push("ivec4 packedVertexBase = ivec4(texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+4, objectIndexCoords.y), 0));");
@@ -65454,58 +65884,51 @@ class TrianglesDataTexturePickNormalsRenderer {
src.push("positions[1] = vec3(texelFetch(uTexturePerVertexIdCoordinates, ivec2(indexPositionH.g, indexPositionV.g), 0));");
src.push("positions[2] = vec3(texelFetch(uTexturePerVertexIdCoordinates, ivec2(indexPositionH.b, indexPositionV.b), 0));");
- // get normal
- src.push("vec3 normal = normalize(cross(positions[2] - positions[0], positions[1] - positions[0]));");
+ // get color
+ src.push("uvec4 color = texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+0, objectIndexCoords.y), 0);");
+ src.push(`if (color.a == 0u) {`);
+ src.push(" gl_Position = vec4(3.0, 3.0, 3.0, 1.0);"); // Cull vertex
+ src.push(" return;");
+ src.push("};");
+ src.push("vec3 normal = normalize(cross(positions[2] - positions[0], positions[1] - positions[0]));");
src.push("vec3 position;");
src.push("position = positions[gl_VertexID % 3];");
// when the geometry is not solid, if needed, flip the triangle winding
src.push("if (solid != 1u) {");
- src.push("if (isPerspectiveMatrix(projMatrix)) {");
- src.push("vec3 uCameraEyeRtcInQuantizedSpace = (inverse(worldMatrix * positionsDecodeMatrix) * vec4(uCameraEyeRtc, 1)).xyz;");
- src.push("if (dot(position.xyz - uCameraEyeRtcInQuantizedSpace, normal) < 0.0) {");
- src.push("position = positions[2 - (gl_VertexID % 3)];");
- src.push("normal = -normal;");
- src.push("}");
- src.push("} else {");
- src.push("vec3 viewNormal = -normalize((transpose(inverse(viewMatrix*positionsDecodeMatrix)) * vec4(normal,1)).xyz);");
- src.push("if (viewNormal.z < 0.0) {");
- src.push("position = positions[2 - (gl_VertexID % 3)];");
- src.push("normal = -normal;");
- src.push("}");
- src.push("}");
+ src.push(" if (isPerspectiveMatrix(projMatrix)) {");
+ src.push(" vec3 uCameraEyeRtcInQuantizedSpace = (inverse(sceneModelWorldMatrix; * positionsDecodeMatrix) * vec4(uCameraEyeRtc, 1)).xyz;");
+ src.push(" if (dot(position.xyz - uCameraEyeRtcInQuantizedSpace, normal) < 0.0) {");
+ src.push(" position = positions[2 - (gl_VertexID % 3)];");
+ src.push(" }");
+ src.push(" } else {");
+ src.push(" vec3 viewNormal = -normalize((transpose(inverse(viewMatrix*positionsDecodeMatrix)) * vec4(normal,1)).xyz);");
+ src.push(" if (viewNormal.z < 0.0) {");
+ src.push(" position = positions[2 - (gl_VertexID % 3)];");
+ src.push(" }");
+ src.push(" }");
src.push("}");
- src.push("normal = -normal;");
-
- src.push("vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
+ src.push("vec4 worldPosition = sceneModelWorldMatrix; * (positionsDecodeMatrix * vec4(position, 1.0)); ");
// get XYZ offset
src.push("vec4 offset = vec4(texelFetch (uTexturePerObjectIdOffsets, objectIndexCoords, 0).rgb, 0.0);");
-
src.push("worldPosition.xyz = worldPosition.xyz + offset.xyz;");
-
src.push("vec4 viewPosition = viewMatrix * worldPosition; ");
-
- src.push("vWorldNormal = normal.xyz;");
-
- src.push("vec4 clipPos = projMatrix * viewPosition;");
-
- if (scene.logarithmicDepthBufferEnabled) {
- src.push("vFragDepth = 1.0 + clipPos.w;");
- src.push("isPerspective = float (isPerspectiveMatrix(projMatrix));");
- }
if (clipping) {
src.push(" vWorldPosition = worldPosition;");
- src.push(" vFlags2 = flags2.w;");
+ src.push(" vFlags2 = flags2;");
+ }
+ src.push("vec4 clipPos = projMatrix * viewPosition;");
+ if (clipping) {
+ src.push("vWorldPosition = worldPosition;");
+ src.push("vFlags2 = flags2.r;");
}
src.push("gl_Position = clipPos;");
+ src.push(" }");
src.push("}");
-
- src.push("}");
-
return src;
}
@@ -65515,7 +65938,7 @@ class TrianglesDataTexturePickNormalsRenderer {
const clipping = sectionPlanesState.sectionPlanes.length > 0;
const src = [];
src.push('#version 300 es');
- src.push("// Triangles dataTexture pick normals fragment shader");
+ src.push("// TrianglesDataTextureColorRenderer fragment shader");
src.push("#ifdef GL_FRAGMENT_PRECISION_HIGH");
src.push("precision highp float;");
src.push("precision highp int;");
@@ -65523,29 +65946,22 @@ class TrianglesDataTexturePickNormalsRenderer {
src.push("precision mediump float;");
src.push("precision mediump int;");
src.push("#endif");
-
- if (scene.logarithmicDepthBufferEnabled) {
- src.push("in float isPerspective;");
- src.push("uniform float logDepthBufFC;");
- src.push("in float vFragDepth;");
- }
if (clipping) {
src.push("in vec4 vWorldPosition;");
- src.push("flat in uint vFlags2;");
- for (var i = 0; i < sectionPlanesState.sectionPlanes.length; i++) {
+ src.push("in vec4 vFlags2;");
+ for (let i = 0; i < sectionPlanesState.sectionPlanes.length; i++) {
src.push("uniform bool sectionPlaneActive" + i + ";");
src.push("uniform vec3 sectionPlanePos" + i + ";");
src.push("uniform vec3 sectionPlaneDir" + i + ";");
}
}
- src.push("in vec3 vWorldNormal;");
- src.push("out vec4 outNormal;");
+ src.push("out vec4 outColor;");
src.push("void main(void) {");
if (clipping) {
- src.push(" bool clippable = vFlags2 > 0u;");
+ src.push(" bool clippable = (float(vFlags2.x) > 0.0);");
src.push(" if (clippable) {");
src.push(" float dist = 0.0;");
- for (var i = 0; i < sectionPlanesState.sectionPlanes.length; i++) {
+ for (let i = 0; i < sectionPlanesState.sectionPlanes.length; i++) {
src.push(" if (sectionPlaneActive" + i + ") {");
src.push(" dist += clamp(dot(-sectionPlaneDir" + i + ".xyz, vWorldPosition.xyz - sectionPlanePos" + i + ".xyz), 0.0, 1000.0);");
src.push(" }");
@@ -65553,12 +65969,7 @@ class TrianglesDataTexturePickNormalsRenderer {
src.push(" if (dist > 0.0) { discard; }");
src.push(" }");
}
-
- if (scene.logarithmicDepthBufferEnabled) {
- // src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
- src.push(" gl_FragDepth = log2( vFragDepth ) * logDepthBufFC * 0.5;");
- }
- src.push(" outNormal = vec4((vWorldNormal * 0.5) + 0.5, 1.0);");
+ src.push(" outColor = vec4(0.0, 0.0, 1.0, 1.0); "); // Occluders are blue
src.push("}");
return src;
}
@@ -65575,7 +65986,7 @@ class TrianglesDataTexturePickNormalsRenderer {
}
}
-const tempVec3a$c = math.vec3();
+const tempVec3a$b = math.vec3();
const tempVec3b$7 = math.vec3();
const tempVec3c$6 = math.vec3();
const tempVec3d$3 = math.vec3();
@@ -65584,12 +65995,12 @@ const tempMat4a$2 = math.mat4();
/**
* @private
*/
-class TrianglesDataTextureOcclusionRenderer {
+class TrianglesDataTextureDepthRenderer {
constructor(scene) {
this._scene = scene;
- this._hash = this._getHash();
this._allocate();
+ this._hash = this._getHash();
}
getValid() {
@@ -65602,18 +66013,17 @@ class TrianglesDataTextureOcclusionRenderer {
drawLayer(frameCtx, dataTextureLayer, renderPass) {
- const model = dataTextureLayer.model;
- const scene = model.scene;
+ const scene = this._scene;
const camera = scene.camera;
+ const model = dataTextureLayer.model;
const gl = scene.canvas.gl;
const state = dataTextureLayer._state;
const textureState = state.textureState;
const origin = dataTextureLayer._state.origin;
const {position, rotationMatrix, rotationMatrixConjugate} = model;
- const viewMatrix = frameCtx.pickViewMatrix || camera.viewMatrix;
if (!this._program) {
- this._allocate(dataTextureLayer);
+ this._allocate();
if (this.errors) {
return;
}
@@ -65621,7 +66031,7 @@ class TrianglesDataTextureOcclusionRenderer {
if (frameCtx.lastProgramId !== this._program.id) {
frameCtx.lastProgramId = this._program.id;
- this._bindProgram();
+ this._bindProgram(frameCtx, state);
}
textureState.bindCommonTextures(
@@ -65636,11 +66046,12 @@ class TrianglesDataTextureOcclusionRenderer {
let rtcViewMatrix;
let rtcCameraEye;
- if (origin || position[0] !== 0 || position[1] !== 0 || position[2] !== 0) {
- const rtcOrigin = tempVec3a$c;
- if (origin) {
- const rotatedOrigin = tempVec3b$7;
- math.transformPoint3(rotationMatrix, origin, rotatedOrigin);
+ const gotOrigin = (origin[0] !== 0 || origin[1] !== 0 || origin[2] !== 0);
+ const gotPosition = (position[0] !== 0 || position[1] !== 0 || position[2] !== 0);
+ if (gotOrigin || gotPosition) {
+ const rtcOrigin = tempVec3a$b;
+ if (gotOrigin) {
+ const rotatedOrigin = math.transformPoint3(rotationMatrix, origin, tempVec3b$7);
rtcOrigin[0] = rotatedOrigin[0];
rtcOrigin[1] = rotatedOrigin[1];
rtcOrigin[2] = rotatedOrigin[2];
@@ -65652,22 +66063,26 @@ class TrianglesDataTextureOcclusionRenderer {
rtcOrigin[0] += position[0];
rtcOrigin[1] += position[1];
rtcOrigin[2] += position[2];
- rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$2);
+ rtcViewMatrix = createRTCViewMat(camera.viewMatrix, rtcOrigin, tempMat4a$2);
rtcCameraEye = tempVec3c$6;
rtcCameraEye[0] = camera.eye[0] - rtcOrigin[0];
rtcCameraEye[1] = camera.eye[1] - rtcOrigin[1];
rtcCameraEye[2] = camera.eye[2] - rtcOrigin[2];
} else {
- rtcViewMatrix = viewMatrix;
+ rtcViewMatrix = camera.viewMatrix;
rtcCameraEye = camera.eye;
}
+ gl.uniformMatrix4fv(this._uSceneModelWorldMatrix, false, rotationMatrixConjugate);
+ gl.uniformMatrix4fv(this._uViewMatrix, false, rtcViewMatrix);
+ gl.uniformMatrix4fv(this._uProjMatrix, false, camera.projMatrix);
gl.uniform3fv(this._uCameraEyeRtc, rtcCameraEye);
gl.uniform1i(this._uRenderPass, renderPass);
- gl.uniformMatrix4fv(this._uWorldMatrix, false, rotationMatrixConjugate);
- gl.uniformMatrix4fv(this._uViewMatrix, false, rtcViewMatrix);
- gl.uniformMatrix4fv(this._uProjMatrix, false, camera.projMatrix);
+ if (scene.logarithmicDepthBufferEnabled) {
+ const logDepthBufFC = 2.0 / (Math.log(frameCtx.pickZFar + 1.0) / Math.LN2);
+ gl.uniform1f(this._uLogDepthBufFC, logDepthBufFC);
+ }
const numSectionPlanes = scene._sectionPlanesState.sectionPlanes.length;
if (numSectionPlanes > 0) {
@@ -65693,415 +66108,6 @@ class TrianglesDataTextureOcclusionRenderer {
}
}
- if (state.numIndices8Bits > 0) {
- textureState.bindTriangleIndicesTextures(
- this._program,
- this._uTexturePerPolygonIdPortionIds,
- this._uTexturePerPolygonIdIndices,
- 8 // 8 bits indices
- );
- gl.drawArrays(gl.TRIANGLES, 0, state.numIndices8Bits);
- }
- if (state.numIndices16Bits > 0) {
- textureState.bindTriangleIndicesTextures(
- this._program,
- this._uTexturePerPolygonIdPortionIds,
- this._uTexturePerPolygonIdIndices,
- 16 // 16 bits indices
- );
- gl.drawArrays(gl.TRIANGLES, 0, state.numIndices16Bits);
- }
- if (state.numIndices32Bits > 0) {
- textureState.bindTriangleIndicesTextures(
- this._program,
- this._uTexturePerPolygonIdPortionIds,
- this._uTexturePerPolygonIdIndices,
- 32 // 32 bits indices
- );
- gl.drawArrays(gl.TRIANGLES, 0, state.numIndices32Bits);
- }
- frameCtx.drawElements++;
- }
-
- _allocate() {
- const scene = this._scene;
- const gl = scene.canvas.gl;
- this._program = new Program(gl, this._buildShader());
- if (this._program.errors) {
- this.errors = this._program.errors;
- return;
- }
- const program = this._program;
- this._uRenderPass = program.getLocation("renderPass");
- this._uPickInvisible = program.getLocation("pickInvisible");
- this._uWorldMatrix = program.getLocation("sceneModelWorldMatrix");
- this._uViewMatrix = program.getLocation("viewMatrix");
- this._uProjMatrix = program.getLocation("projMatrix");
- this._uSectionPlanes = [];
- for (let i = 0, len = scene._sectionPlanesState.sectionPlanes.length; i < len; i++) {
- this._uSectionPlanes.push({
- active: program.getLocation("sectionPlaneActive" + i),
- pos: program.getLocation("sectionPlanePos" + i),
- dir: program.getLocation("sectionPlaneDir" + i)
- });
- }
- this._uPickZNear = program.getLocation("pickZNear");
- this._uPickZFar = program.getLocation("pickZFar");
- if (scene.logarithmicDepthBufferEnabled) {
- this._uLogDepthBufFC = program.getLocation("logDepthBufFC");
- }
- this._uTexturePerObjectIdPositionsDecodeMatrix = "uTexturePerObjectIdPositionsDecodeMatrix";
- this._uTexturePerObjectIdColorsAndFlags = "uTexturePerObjectIdColorsAndFlags";
- this._uTexturePerVertexIdCoordinates = "uTexturePerVertexIdCoordinates";
- this._uTexturePerPolygonIdNormals = "uTexturePerPolygonIdNormals";
- this._uTexturePerPolygonIdIndices = "uTexturePerPolygonIdIndices";
- this._uTexturePerPolygonIdPortionIds = "uTexturePerPolygonIdPortionIds";
- this._uTextureCameraMatrices = "uTextureCameraMatrices";
- this._uTextureModelMatrices = "uTextureModelMatrices";
- this._uTexturePerObjectIdOffsets = "uTexturePerObjectIdOffsets";
- this._uCameraEyeRtc = program.getLocation("uCameraEyeRtc");
- }
-
- _bindProgram() {
-
- const scene = this._scene;
- scene.canvas.gl;
- scene.camera.project;
-
- this._program.bind();
- }
-
- _buildShader() {
- return {
- vertex: this._buildVertexShader(),
- fragment: this._buildFragmentShader()
- };
- }
-
- _buildVertexShader() {
- const scene = this._scene;
- const clipping = scene._sectionPlanesState.sectionPlanes.length > 0;
- const src = [];
- src.push("#version 300 es");
- src.push("// TrianglesDataTextureColorRenderer vertex shader");
-
- src.push("#ifdef GL_FRAGMENT_PRECISION_HIGH");
- src.push("precision highp float;");
- src.push("precision highp int;");
- src.push("precision highp usampler2D;");
- src.push("precision highp isampler2D;");
- src.push("precision highp sampler2D;");
- src.push("#else");
- src.push("precision mediump float;");
- src.push("precision mediump int;");
- src.push("precision mediump usampler2D;");
- src.push("precision mediump isampler2D;");
- src.push("precision mediump sampler2D;");
- src.push("#endif");
-
- src.push("uniform int renderPass;");
-
- if (scene.entityOffsetsEnabled) {
- src.push("in vec3 offset;");
- }
-
- src.push("uniform mat4 sceneModelWorldMatrix;");
- src.push("uniform mat4 viewMatrix;");
- src.push("uniform mat4 projMatrix;");
-
- src.push("uniform highp sampler2D uTexturePerObjectIdPositionsDecodeMatrix;");
- src.push("uniform lowp usampler2D uTexturePerObjectIdColorsAndFlags;");
- src.push("uniform highp sampler2D uTexturePerObjectIdOffsets;");
- src.push("uniform mediump usampler2D uTexturePerVertexIdCoordinates;");
- src.push("uniform highp usampler2D uTexturePerPolygonIdIndices;");
- src.push("uniform mediump usampler2D uTexturePerPolygonIdPortionIds;");
- src.push("uniform highp sampler2D uTextureModelMatrices;");
- src.push("uniform vec3 uCameraEyeRtc;");
-
- src.push("vec3 positions[3];");
- src.push("bool isPerspectiveMatrix(mat4 m) {");
- src.push(" return (m[2][3] == - 1.0);");
- src.push("}");
- if (clipping) {
- src.push("out vec4 vWorldPosition;");
- src.push("out vec4 vFlags2;");
- }
- src.push("void main(void) {");
-
- // constants
- src.push("int polygonIndex = gl_VertexID / 3;");
-
- // get packed object-id
- src.push("int h_packed_object_id_index = (polygonIndex >> 3) & 4095;");
- src.push("int v_packed_object_id_index = (polygonIndex >> 3) >> 12;");
-
- src.push("int objectIndex = int(texelFetch(uTexturePerPolygonIdPortionIds, ivec2(h_packed_object_id_index, v_packed_object_id_index), 0).r);");
- src.push("ivec2 objectIndexCoords = ivec2(objectIndex % 512, objectIndex / 512);");
-
- // get flags & flags2
- src.push("uvec4 flags = texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+2, objectIndexCoords.y), 0);");
- src.push("uvec4 flags2 = texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+3, objectIndexCoords.y), 0);");
-
- // flags.x = NOT_RENDERED | COLOR_OPAQUE | COLOR_TRANSPARENT
- // renderPass = COLOR_OPAQUE
- // Only opaque objects can be occluders
-
- src.push(`if (int(flags.x) != renderPass) {`);
- src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex
-
- src.push(" } else {");
- // model matrices
- src.push ("mat4 worldMatrix = sceneModelWorldMatrix * mat4 (texelFetch (uTextureModelMatrices, ivec2(0, 0), 0), texelFetch (uTextureModelMatrices, ivec2(1, 0), 0), texelFetch (uTextureModelMatrices, ivec2(2, 0), 0), texelFetch (uTextureModelMatrices, ivec2(3, 0), 0));");
-
- // get vertex base
- src.push("ivec4 packedVertexBase = ivec4(texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+4, objectIndexCoords.y), 0));");
-
- src.push("ivec4 packedIndexBaseOffset = ivec4(texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+5, objectIndexCoords.y), 0));");
-
- src.push("int indexBaseOffset = (packedIndexBaseOffset.r << 24) + (packedIndexBaseOffset.g << 16) + (packedIndexBaseOffset.b << 8) + packedIndexBaseOffset.a;");
-
- src.push("int h_index = (polygonIndex - indexBaseOffset) & 4095;");
- src.push("int v_index = (polygonIndex - indexBaseOffset) >> 12;");
-
- src.push("ivec3 vertexIndices = ivec3(texelFetch(uTexturePerPolygonIdIndices, ivec2(h_index, v_index), 0));");
- src.push("ivec3 uniqueVertexIndexes = vertexIndices + (packedVertexBase.r << 24) + (packedVertexBase.g << 16) + (packedVertexBase.b << 8) + packedVertexBase.a;");
-
- src.push("ivec3 indexPositionH = uniqueVertexIndexes & 4095;");
- src.push("ivec3 indexPositionV = uniqueVertexIndexes >> 12;");
-
- src.push("mat4 positionsDecodeMatrix = mat4 (texelFetch (uTexturePerObjectIdPositionsDecodeMatrix, ivec2(objectIndexCoords.x*4+0, objectIndexCoords.y), 0), texelFetch (uTexturePerObjectIdPositionsDecodeMatrix, ivec2(objectIndexCoords.x*4+1, objectIndexCoords.y), 0), texelFetch (uTexturePerObjectIdPositionsDecodeMatrix, ivec2(objectIndexCoords.x*4+2, objectIndexCoords.y), 0), texelFetch (uTexturePerObjectIdPositionsDecodeMatrix, ivec2(objectIndexCoords.x*4+3, objectIndexCoords.y), 0));");
-
- src.push("uint solid = texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+7, objectIndexCoords.y), 0).r;");
-
- // get position
- src.push("positions[0] = vec3(texelFetch(uTexturePerVertexIdCoordinates, ivec2(indexPositionH.r, indexPositionV.r), 0));");
- src.push("positions[1] = vec3(texelFetch(uTexturePerVertexIdCoordinates, ivec2(indexPositionH.g, indexPositionV.g), 0));");
- src.push("positions[2] = vec3(texelFetch(uTexturePerVertexIdCoordinates, ivec2(indexPositionH.b, indexPositionV.b), 0));");
-
- // get color
- src.push("uvec4 color = texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+0, objectIndexCoords.y), 0);");
-
- src.push(`if (color.a == 0u) {`);
- src.push(" gl_Position = vec4(3.0, 3.0, 3.0, 1.0);"); // Cull vertex
- src.push(" return;");
- src.push("};");
-
- src.push("vec3 normal = normalize(cross(positions[2] - positions[0], positions[1] - positions[0]));");
- src.push("vec3 position;");
- src.push("position = positions[gl_VertexID % 3];");
-
- // when the geometry is not solid, if needed, flip the triangle winding
- src.push("if (solid != 1u) {");
- src.push(" if (isPerspectiveMatrix(projMatrix)) {");
- src.push(" vec3 uCameraEyeRtcInQuantizedSpace = (inverse(worldMatrix * positionsDecodeMatrix) * vec4(uCameraEyeRtc, 1)).xyz;");
- src.push(" if (dot(position.xyz - uCameraEyeRtcInQuantizedSpace, normal) < 0.0) {");
- src.push(" position = positions[2 - (gl_VertexID % 3)];");
- src.push(" }");
- src.push(" } else {");
- src.push(" vec3 viewNormal = -normalize((transpose(inverse(viewMatrix*positionsDecodeMatrix)) * vec4(normal,1)).xyz);");
- src.push(" if (viewNormal.z < 0.0) {");
- src.push(" position = positions[2 - (gl_VertexID % 3)];");
- src.push(" }");
- src.push(" }");
- src.push("}");
-
- src.push("vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
-
- // get XYZ offset
- src.push("vec4 offset = vec4(texelFetch (uTexturePerObjectIdOffsets, objectIndexCoords, 0).rgb, 0.0);");
- src.push("worldPosition.xyz = worldPosition.xyz + offset.xyz;");
- src.push("vec4 viewPosition = viewMatrix * worldPosition; ");
- if (clipping) {
- src.push(" vWorldPosition = worldPosition;");
- src.push(" vFlags2 = flags2;");
- }
- src.push("vec4 clipPos = projMatrix * viewPosition;");
- if (clipping) {
- src.push("vWorldPosition = worldPosition;");
- src.push("vFlags2 = flags2.r;");
- }
- src.push("gl_Position = clipPos;");
- src.push(" }");
- src.push("}");
- return src;
- }
-
- _buildFragmentShader() {
- const scene = this._scene;
- const sectionPlanesState = scene._sectionPlanesState;
- const clipping = sectionPlanesState.sectionPlanes.length > 0;
- const src = [];
- src.push('#version 300 es');
- src.push("// TrianglesDataTextureColorRenderer fragment shader");
- src.push("#ifdef GL_FRAGMENT_PRECISION_HIGH");
- src.push("precision highp float;");
- src.push("precision highp int;");
- src.push("#else");
- src.push("precision mediump float;");
- src.push("precision mediump int;");
- src.push("#endif");
- if (clipping) {
- src.push("in vec4 vWorldPosition;");
- src.push("in vec4 vFlags2;");
- for (let i = 0; i < sectionPlanesState.sectionPlanes.length; i++) {
- src.push("uniform bool sectionPlaneActive" + i + ";");
- src.push("uniform vec3 sectionPlanePos" + i + ";");
- src.push("uniform vec3 sectionPlaneDir" + i + ";");
- }
- }
- src.push("out vec4 outColor;");
- src.push("void main(void) {");
- if (clipping) {
- src.push(" bool clippable = (float(vFlags2.x) > 0.0);");
- src.push(" if (clippable) {");
- src.push(" float dist = 0.0;");
- for (let i = 0; i < sectionPlanesState.sectionPlanes.length; i++) {
- src.push(" if (sectionPlaneActive" + i + ") {");
- src.push(" dist += clamp(dot(-sectionPlaneDir" + i + ".xyz, vWorldPosition.xyz - sectionPlanePos" + i + ".xyz), 0.0, 1000.0);");
- src.push(" }");
- }
- src.push(" if (dist > 0.0) { discard; }");
- src.push(" }");
- }
- src.push(" outColor = vec4(0.0, 0.0, 1.0, 1.0); "); // Occluders are blue
- src.push("}");
- return src;
- }
-
- webglContextRestored() {
- this._program = null;
- }
-
- destroy() {
- if (this._program) {
- this._program.destroy();
- }
- this._program = null;
- }
-}
-
-const tempVec3a$b = math.vec3();
-const tempVec3b$6 = math.vec3();
-const tempVec3c$5 = math.vec3();
-const tempVec3d$2 = math.vec3();
-const tempMat4a$1 = math.mat4();
-
-/**
- * @private
- */
-class TrianglesDataTextureDepthRenderer {
-
- constructor(scene) {
- this._scene = scene;
- this._allocate();
- this._hash = this._getHash();
- }
-
- getValid() {
- return this._hash === this._getHash();
- };
-
- _getHash() {
- return this._scene._sectionPlanesState.getHash();
- }
-
- drawLayer(frameCtx, dataTextureLayer, renderPass) {
-
- const scene = this._scene;
- const camera = scene.camera;
- const model = dataTextureLayer.model;
- const gl = scene.canvas.gl;
- const state = dataTextureLayer._state;
- const textureState = state.textureState;
- const origin = dataTextureLayer._state.origin;
- const {position, rotationMatrix, rotationMatrixConjugate} = model;
-
- if (!this._program) {
- this._allocate();
- if (this.errors) {
- return;
- }
- }
-
- if (frameCtx.lastProgramId !== this._program.id) {
- frameCtx.lastProgramId = this._program.id;
- this._bindProgram(frameCtx, state);
- }
-
- textureState.bindCommonTextures(
- this._program,
- this._uTexturePerObjectIdPositionsDecodeMatrix,
- this._uTexturePerVertexIdCoordinates,
- this._uTexturePerObjectIdColorsAndFlags,
- this._uTextureModelMatrices,
- this._uTexturePerObjectIdOffsets
- );
-
- let rtcViewMatrix;
- let rtcCameraEye;
-
- const gotOrigin = (origin[0] !== 0 || origin[1] !== 0 || origin[2] !== 0);
- const gotPosition = (position[0] !== 0 || position[1] !== 0 || position[2] !== 0);
- if (gotOrigin || gotPosition) {
- const rtcOrigin = tempVec3a$b;
- if (gotOrigin) {
- const rotatedOrigin = math.transformPoint3(rotationMatrix, origin, tempVec3b$6);
- rtcOrigin[0] = rotatedOrigin[0];
- rtcOrigin[1] = rotatedOrigin[1];
- rtcOrigin[2] = rotatedOrigin[2];
- } else {
- rtcOrigin[0] = 0;
- rtcOrigin[1] = 0;
- rtcOrigin[2] = 0;
- }
- rtcOrigin[0] += position[0];
- rtcOrigin[1] += position[1];
- rtcOrigin[2] += position[2];
- rtcViewMatrix = createRTCViewMat(camera.viewMatrix, rtcOrigin, tempMat4a$1);
- rtcCameraEye = tempVec3c$5;
- rtcCameraEye[0] = camera.eye[0] - rtcOrigin[0];
- rtcCameraEye[1] = camera.eye[1] - rtcOrigin[1];
- rtcCameraEye[2] = camera.eye[2] - rtcOrigin[2];
- } else {
- rtcViewMatrix = camera.viewMatrix;
- rtcCameraEye = camera.eye;
- }
-
- gl.uniformMatrix4fv(this._uSceneModelWorldMatrix, false, rotationMatrixConjugate);
- gl.uniformMatrix4fv(this._uViewMatrix, false, rtcViewMatrix);
- gl.uniformMatrix4fv(this._uProjMatrix, false, camera.projMatrix);
- gl.uniform3fv(this._uCameraEyeRtc, rtcCameraEye);
- gl.uniform1i(this._uRenderPass, renderPass);
-
- if (scene.logarithmicDepthBufferEnabled) {
- const logDepthBufFC = 2.0 / (Math.log(frameCtx.pickZFar + 1.0) / Math.LN2);
- gl.uniform1f(this._uLogDepthBufFC, logDepthBufFC);
- }
-
- const numSectionPlanes = scene._sectionPlanesState.sectionPlanes.length;
- if (numSectionPlanes > 0) {
- const sectionPlanes = scene._sectionPlanesState.sectionPlanes;
- const baseIndex = dataTextureLayer.layerIndex * numSectionPlanes;
- const renderFlags = model.renderFlags;
- for (let sectionPlaneIndex = 0; sectionPlaneIndex < numSectionPlanes; sectionPlaneIndex++) {
- const sectionPlaneUniforms = this._uSectionPlanes[sectionPlaneIndex];
- if (sectionPlaneUniforms) {
- const active = renderFlags.sectionPlanesActivePerLayer[baseIndex + sectionPlaneIndex];
- gl.uniform1i(sectionPlaneUniforms.active, active ? 1 : 0);
- if (active) {
- const sectionPlane = sectionPlanes[sectionPlaneIndex];
- if (origin) {
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3d$2);
- gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
- } else {
- gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
- }
- gl.uniform3fv(sectionPlaneUniforms.dir, sectionPlane.dir);
- }
- }
- }
- }
-
if (state.numIndices8Bits > 0) {
textureState.bindTriangleIndicesTextures(
this._program,
@@ -66155,7 +66161,6 @@ class TrianglesDataTextureDepthRenderer {
this._uRenderPass = program.getLocation("renderPass");
this._uPositionsDecodeMatrix = program.getLocation("positionsDecodeMatrix");
this._uSceneModelWorldMatrix = program.getLocation("sceneModelWorldMatrix");
- this._uWorldMatrix = program.getLocation("worldMatrix");
this._uViewMatrix = program.getLocation("viewMatrix");
this._uProjMatrix = program.getLocation("projMatrix");
this._uSectionPlanes = [];
@@ -66292,9 +66297,6 @@ class TrianglesDataTextureDepthRenderer {
src.push(" return;"); // Cull vertex
src.push("} else {");
- // model matrices
- src.push("mat4 worldMatrix = sceneModelWorldMatrix * mat4 (texelFetch (uTextureModelMatrices, ivec2(0, 0), 0), texelFetch (uTextureModelMatrices, ivec2(1, 0), 0), texelFetch (uTextureModelMatrices, ivec2(2, 0), 0), texelFetch (uTextureModelMatrices, ivec2(3, 0), 0));");
-
// get vertex base
src.push("ivec4 packedVertexBase = ivec4(texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+4, objectIndexCoords.y), 0));");
@@ -66339,7 +66341,7 @@ class TrianglesDataTextureDepthRenderer {
// when the geometry is not solid, if needed, flip the triangle winding
src.push("if (solid != 1u) {");
src.push("if (isPerspectiveMatrix(projMatrix)) {");
- src.push("vec3 uCameraEyeRtcInQuantizedSpace = (inverse(worldMatrix * positionsDecodeMatrix) * vec4(uCameraEyeRtc, 1)).xyz;");
+ src.push("vec3 uCameraEyeRtcInQuantizedSpace = (inverse(sceneModelWorldMatrix * positionsDecodeMatrix) * vec4(uCameraEyeRtc, 1)).xyz;");
src.push("if (dot(position.xyz - uCameraEyeRtcInQuantizedSpace, normal) < 0.0) {");
src.push("position = positions[2 - (gl_VertexID % 3)];");
src.push("viewNormal = -viewNormal;");
@@ -66352,7 +66354,7 @@ class TrianglesDataTextureDepthRenderer {
src.push("}");
src.push("}");
- src.push("vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
+ src.push("vec4 worldPosition = sceneModelWorldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
// get XYZ offset
src.push("vec4 offset = vec4(texelFetch (uTexturePerObjectIdOffsets, objectIndexCoords, 0).rgb, 0.0);");
@@ -66451,10 +66453,10 @@ class TrianglesDataTextureDepthRenderer {
}
const tempVec3a$a = math.vec3();
-const tempVec3b$5 = math.vec3();
-const tempVec3c$4 = math.vec3();
-const tempVec3d$1 = math.vec3();
-const tempMat4a = math.mat4();
+const tempVec3b$6 = math.vec3();
+const tempVec3c$5 = math.vec3();
+const tempVec3d$2 = math.vec3();
+const tempMat4a$1 = math.mat4();
/**
* @private
@@ -66506,7 +66508,7 @@ class TrianglesDataTextureNormalsRenderer {
if (gotOrigin || gotPosition) {
const rtcOrigin = tempVec3a$a;
if (gotOrigin) {
- const rotatedOrigin = tempVec3b$5;
+ const rotatedOrigin = tempVec3b$6;
math.transformPoint3(rotationMatrix, origin, rotatedOrigin);
rtcOrigin[0] = rotatedOrigin[0];
rtcOrigin[1] = rotatedOrigin[1];
@@ -66519,8 +66521,8 @@ class TrianglesDataTextureNormalsRenderer {
rtcOrigin[0] += position[0];
rtcOrigin[1] += position[1];
rtcOrigin[2] += position[2];
- rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a);
- rtcCameraEye = tempVec3c$4;
+ rtcViewMatrix = createRTCViewMat(viewMatrix, rtcOrigin, tempMat4a$1);
+ rtcCameraEye = tempVec3c$5;
rtcCameraEye[0] = camera.eye[0] - rtcOrigin[0];
rtcCameraEye[1] = camera.eye[1] - rtcOrigin[1];
rtcCameraEye[2] = camera.eye[2] - rtcOrigin[2];
@@ -66551,7 +66553,7 @@ class TrianglesDataTextureNormalsRenderer {
if (active) {
const sectionPlane = sectionPlanes[sectionPlaneIndex];
if (origin) {
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3d$1);
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3d$2);
gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
} else {
gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -66788,14 +66790,22 @@ class TrianglesDataTextureNormalsRenderer {
}
const tempVec3a$9 = math.vec3();
+const tempVec3b$5 = math.vec3();
+const tempVec3c$4 = math.vec3();
+const tempVec3d$1 = math.vec3();
+
+math.vec4();
+
+const tempMat4a = math.mat4();
/**
* @private
*/
class TrianglesDataTexturePickNormalsFlatRenderer {
- constructor(scene) {
+ constructor(scene, withSAO) {
this._scene = scene;
+ this._withSAO = withSAO;
this._hash = this._getHash();
this._allocate();
}
@@ -66805,90 +66815,82 @@ class TrianglesDataTexturePickNormalsFlatRenderer {
};
_getHash() {
- return this._scene._sectionPlanesState.getHash();
+ const scene = this._scene;
+ return [scene._lightsState.getHash(), scene._sectionPlanesState.getHash(), (this._withSAO ? "sao" : "nosao")].join(";");
}
drawLayer(frameCtx, dataTextureLayer, renderPass) {
- const model = dataTextureLayer.model;
- const scene = model.scene;
+
+ const scene = this._scene;
const camera = scene.camera;
+ const model = dataTextureLayer.model;
const gl = scene.canvas.gl;
const state = dataTextureLayer._state;
+ const textureState = state.textureState;
const origin = dataTextureLayer._state.origin;
+ const {position, rotationMatrix, rotationMatrixConjugate} = model;
if (!this._program) {
- this._allocate(dataTextureLayer);
+ this._allocate();
+ if (this.errors) {
+ return;
+ }
}
if (frameCtx.lastProgramId !== this._program.id) {
frameCtx.lastProgramId = this._program.id;
- this._bindProgram();
+ this._bindProgram(frameCtx, state);
}
- this._program.bindTexture(
- this._uTexturePerObjectIdPositionsDecodeMatrix,
- {
- bind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, state.texturePerObjectIdPositionsDecodeMatrix);
- return true;
- },
- unbind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, null);
- }
- },
- 1
- );
-
- this._program.bindTexture(
- this._uTexturePerVertexIdCoordinates,
- {
- bind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, state.texturePerVertexIdCoordinates);
- return true;
- },
- unbind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, null);
- }
- },
- 2
- );
-
- this._program.bindTexture(
+ textureState.bindCommonTextures(
+ this._program,
+ this._uTexturePerObjectIdPositionsDecodeMatrix,
+ this._uTexturePerVertexIdCoordinates,
this._uTexturePerObjectIdColorsAndFlags,
- {
- bind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, state.texturePerObjectIdColorsAndFlags);
- return true;
- },
- unbind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, null);
- }
- },
- 3
- );
-
- gl.uniform1i(this._uRenderPass, renderPass);
- gl.uniform1i(this._uPickInvisible, frameCtx.pickInvisible);
-
- gl.uniformMatrix4fv(this._uWorldMatrix, false, model.worldMatrix);
-
- const pickViewMatrix = frameCtx.pickViewMatrix || camera.viewMatrix;
- const viewMatrix = origin ? createRTCViewMat(pickViewMatrix, origin) : pickViewMatrix;
+ this._uTextureModelMatrices,
+ this._uTexturePerObjectIdOffsets
+ );
- gl.uniformMatrix4fv(this._uViewMatrix, false, viewMatrix);
- gl.uniformMatrix4fv(this._uProjMatrix, false, frameCtx.pickProjMatrix);
+ let rtcViewMatrix;
+ let rtcCameraEye;
+ const gotOrigin = (origin[0] !== 0 || origin[1] !== 0 || origin[2] !== 0);
+ const gotPosition = (position[0] !== 0 || position[1] !== 0 || position[2] !== 0);
+ if (gotOrigin || gotPosition) {
+ const rtcOrigin = tempVec3a$9;
+ if (gotOrigin) {
+ const rotatedOrigin = math.transformPoint3(rotationMatrix, origin, tempVec3b$5);
+ rtcOrigin[0] = rotatedOrigin[0];
+ rtcOrigin[1] = rotatedOrigin[1];
+ rtcOrigin[2] = rotatedOrigin[2];
+ } else {
+ rtcOrigin[0] = 0;
+ rtcOrigin[1] = 0;
+ rtcOrigin[2] = 0;
+ }
+ rtcOrigin[0] += position[0];
+ rtcOrigin[1] += position[1];
+ rtcOrigin[2] += position[2];
+ rtcViewMatrix = createRTCViewMat(camera.viewMatrix, rtcOrigin, tempMat4a);
+ rtcCameraEye = tempVec3c$4;
+ rtcCameraEye[0] = camera.eye[0] - rtcOrigin[0];
+ rtcCameraEye[1] = camera.eye[1] - rtcOrigin[1];
+ rtcCameraEye[2] = camera.eye[2] - rtcOrigin[2];
+ } else {
+ rtcViewMatrix = camera.viewMatrix; // TODO: make pickMatrix
+ rtcCameraEye = camera.eye;
+ }
+ gl.uniform2fv(this._uPickClipPos, frameCtx.pickClipPos);
+ gl.uniform2f(this._uDrawingBufferSize, gl.drawingBufferWidth, gl.drawingBufferHeight);
+ gl.uniformMatrix4fv(this._uSceneModelWorldMatrix, false, rotationMatrixConjugate);
+ gl.uniformMatrix4fv(this._uViewMatrix, false, rtcViewMatrix);
+ gl.uniformMatrix4fv(this._uProjMatrix, false, camera.projMatrix); // TODO: pickProjMatrix
+ gl.uniform3fv(this._uCameraEyeRtc, rtcCameraEye);
+ gl.uniform1i(this._uRenderPass, renderPass);
if (scene.logarithmicDepthBufferEnabled) {
- const logDepthBufFC = 2.0 / (Math.log(camera.project.far + 1.0) / Math.LN2); // TODO: Far should be from projection matrix?
+ const logDepthBufFC = 2.0 / (Math.log(frameCtx.pickZFar + 1.0) / Math.LN2);
gl.uniform1f(this._uLogDepthBufFC, logDepthBufFC);
}
-
const numSectionPlanes = scene._sectionPlanesState.sectionPlanes.length;
if (numSectionPlanes > 0) {
const sectionPlanes = scene._sectionPlanesState.sectionPlanes;
@@ -66896,159 +66898,73 @@ class TrianglesDataTexturePickNormalsFlatRenderer {
const renderFlags = model.renderFlags;
for (let sectionPlaneIndex = 0; sectionPlaneIndex < numSectionPlanes; sectionPlaneIndex++) {
const sectionPlaneUniforms = this._uSectionPlanes[sectionPlaneIndex];
- const active = renderFlags.sectionPlanesActivePerLayer[baseIndex + sectionPlaneIndex];
- gl.uniform1i(sectionPlaneUniforms.active, active ? 1 : 0);
- if (active) {
- const sectionPlane = sectionPlanes[sectionPlaneIndex];
- if (origin) {
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a$9);
- gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
- } else {
- gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
+ if (sectionPlaneUniforms) {
+ const active = renderFlags.sectionPlanesActivePerLayer[baseIndex + sectionPlaneIndex];
+ gl.uniform1i(sectionPlaneUniforms.active, active ? 1 : 0);
+ if (active) {
+ const sectionPlane = sectionPlanes[sectionPlaneIndex];
+ if (origin) {
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3d$1);
+ gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
+ } else {
+ gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
+ }
+ gl.uniform3fv(sectionPlaneUniforms.dir, sectionPlane.dir);
}
- gl.uniform3fv(sectionPlaneUniforms.dir, sectionPlane.dir);
}
}
}
- //=============================================================
- // TODO: Use drawElements count and offset to draw only one entity
- //=============================================================
-
if (state.numIndices8Bits > 0) {
- this._program.bindTexture(
- this._uTexturePerPolygonIdPortionIds,
- {
- bind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, state.texturePerPolygonIdPortionIds8Bits);
- return true;
- },
- unbind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, null);
- }
- },
- 4
- );
-
- this._program.bindTexture(
- this._uTexturePerPolygonIdIndices,
- {
- bind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, state.texturePerPolygonIdIndices8Bits);
- return true;
- },
- unbind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, null);
- }
- },
- 5
- );
-
+ textureState.bindTriangleIndicesTextures(
+ this._program,
+ this._uTexturePerPolygonIdPortionIds,
+ this._uTexturePerPolygonIdIndices,
+ 8 // 8 bits indices
+ );
gl.drawArrays(gl.TRIANGLES, 0, state.numIndices8Bits);
}
if (state.numIndices16Bits > 0) {
- this._program.bindTexture(
- this._uTexturePerPolygonIdPortionIds,
- {
- bind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, state.texturePerPolygonIdPortionIds16Bits);
- return true;
- },
- unbind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, null);
- }
- },
- 4
- );
-
- this._program.bindTexture(
- this._uTexturePerPolygonIdIndices,
- {
- bind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, state.texturePerPolygonIdIndices16Bits);
- return true;
- },
- unbind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, null);
- }
- },
- 5
- );
-
+ textureState.bindTriangleIndicesTextures(
+ this._program,
+ this._uTexturePerPolygonIdPortionIds,
+ this._uTexturePerPolygonIdIndices,
+ 16 // 16 bits indices
+ );
gl.drawArrays(gl.TRIANGLES, 0, state.numIndices16Bits);
}
if (state.numIndices32Bits > 0) {
- this._program.bindTexture(
- this._uTexturePerPolygonIdPortionIds,
- {
- bind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, state.texturePerPolygonIdPortionIds32Bits);
- return true;
- },
- unbind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, null);
- }
- },
- 4
- );
-
- this._program.bindTexture(
- this._uTexturePerPolygonIdIndices,
- {
- bind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, state.texturePerPolygonIdIndices32Bits);
- return true;
- },
- unbind: function (unit) {
- gl.activeTexture(gl["TEXTURE" + unit]);
- gl.bindTexture(gl.TEXTURE_2D, null);
- }
- },
- 5
- );
-
+ textureState.bindTriangleIndicesTextures(
+ this._program,
+ this._uTexturePerPolygonIdPortionIds,
+ this._uTexturePerPolygonIdIndices,
+ 32 // 32 bits indices
+ );
gl.drawArrays(gl.TRIANGLES, 0, state.numIndices32Bits);
}
-
frameCtx.drawElements++;
}
_allocate() {
-
const scene = this._scene;
const gl = scene.canvas.gl;
-
this._program = new Program(gl, this._buildShader());
-
if (this._program.errors) {
this.errors = this._program.errors;
return;
}
-
const program = this._program;
-
this._uRenderPass = program.getLocation("renderPass");
this._uPickInvisible = program.getLocation("pickInvisible");
- this._uPositionsDecodeMatrix = program.getLocation("positionsDecodeMatrix");
- this._uWorldMatrix = program.getLocation("worldMatrix");
+ this._uPickClipPos = program.getLocation("pickClipPos");
+ this._uDrawingBufferSize = program.getLocation("drawingBufferSize");
+ this._uSceneModelWorldMatrix = program.getLocation("sceneModelWorldMatrix");
this._uViewMatrix = program.getLocation("viewMatrix");
this._uProjMatrix = program.getLocation("projMatrix");
this._uSectionPlanes = [];
-
for (let i = 0, len = scene._sectionPlanesState.sectionPlanes.length; i < len; i++) {
this._uSectionPlanes.push({
active: program.getLocation("sectionPlaneActive" + i),
@@ -67056,24 +66972,30 @@ class TrianglesDataTexturePickNormalsFlatRenderer {
dir: program.getLocation("sectionPlaneDir" + i)
});
}
-
- this._aPackedVertexId = program.getAttribute("packedVertexId");
-
-
if (scene.logarithmicDepthBufferEnabled) {
this._uLogDepthBufFC = program.getLocation("logDepthBufFC");
}
-
- this._uTexturePerObjectIdPositionsDecodeMatrix = "uTexturePerObjectIdPositionsDecodeMatrix";
- this._uTexturePerObjectIdColorsAndFlags = "uTexturePerObjectIdColorsAndFlags";
- this._uTexturePerVertexIdCoordinates = "uTexturePerVertexIdCoordinates";
- this._uTexturePerPolygonIdNormals = "uTexturePerPolygonIdNormals";
- this._uTexturePerPolygonIdIndices = "uTexturePerPolygonIdIndices";
- this._uTexturePerPolygonIdPortionIds = "uTexturePerPolygonIdPortionIds";
+ this._uTexturePerObjectIdPositionsDecodeMatrix = "uTexturePerObjectIdPositionsDecodeMatrix";
+ this._uTexturePerObjectIdColorsAndFlags = "uTexturePerObjectIdColorsAndFlags";
+ this._uTexturePerVertexIdCoordinates = "uTexturePerVertexIdCoordinates";
+ this._uTexturePerPolygonIdNormals = "uTexturePerPolygonIdNormals";
+ this._uTexturePerPolygonIdIndices = "uTexturePerPolygonIdIndices";
+ this._uTexturePerPolygonIdPortionIds = "uTexturePerPolygonIdPortionIds";
+ this._uTextureModelMatrices = "uTextureModelMatrices";
+ this._uTexturePerObjectIdOffsets = "uTexturePerObjectIdOffsets";
+ this._uCameraEyeRtc = program.getLocation("uCameraEyeRtc");
}
- _bindProgram() {
- this._program.bind();
+ _bindProgram(frameCtx) {
+ const scene = this._scene;
+ const gl = scene.canvas.gl;
+ const program = this._program;
+ const project = scene.camera.project;
+ program.bind();
+ if (scene.logarithmicDepthBufferEnabled) {
+ const logDepthBufFC = 2.0 / (Math.log(project.far + 1.0) / Math.LN2);
+ gl.uniform1f(this._uLogDepthBufFC, logDepthBufFC);
+ }
}
_buildShader() {
@@ -67085,10 +67007,12 @@ class TrianglesDataTexturePickNormalsFlatRenderer {
_buildVertexShader() {
const scene = this._scene;
- const clipping = scene._sectionPlanesState.sectionPlanes.length > 0;
+ const sectionPlanesState = scene._sectionPlanesState;
+ scene._lightsState;
+ const clipping = sectionPlanesState.sectionPlanes.length > 0;
const src = [];
src.push("#version 300 es");
- src.push("// Triangles dataTexture pick flat normals vertex shader");
+ src.push("// trianglesDatatextureNormalsRenderer vertex shader");
src.push("#ifdef GL_FRAGMENT_PRECISION_HIGH");
src.push("precision highp float;");
@@ -67106,112 +67030,147 @@ class TrianglesDataTexturePickNormalsFlatRenderer {
src.push("uniform int renderPass;");
- src.push("in uvec3 packedVertexId;");
-
if (scene.entityOffsetsEnabled) {
src.push("in vec3 offset;");
}
- src.push("uniform bool pickInvisible;");
- src.push("uniform mat4 worldMatrix;");
+ src.push("uniform mat4 sceneModelWorldMatrix;");
src.push("uniform mat4 viewMatrix;");
src.push("uniform mat4 projMatrix;");
- // src.push("uniform sampler2D uOcclusionTexture;");
- src.push("uniform sampler2D uTexturePerObjectIdPositionsDecodeMatrix;");
- src.push("uniform usampler2D uTexturePerObjectIdColorsAndFlags;");
- src.push("uniform usampler2D uTexturePerVertexIdCoordinates;");
- src.push("uniform usampler2D uTexturePerPolygonIdIndices;");
- src.push("uniform isampler2D uTexturePerPolygonIdNormals;");
- src.push("uniform usampler2D uTexturePerPolygonIdPortionIds;");
+
+ src.push("uniform highp sampler2D uTexturePerObjectIdPositionsDecodeMatrix;");
+ src.push("uniform lowp usampler2D uTexturePerObjectIdColorsAndFlags;");
+ src.push("uniform highp sampler2D uTexturePerObjectIdOffsets;");
+ src.push("uniform mediump usampler2D uTexturePerVertexIdCoordinates;");
+ src.push("uniform highp usampler2D uTexturePerPolygonIdIndices;");
+ src.push("uniform mediump usampler2D uTexturePerPolygonIdPortionIds;");
+ src.push("uniform highp sampler2D uTextureModelMatrices;");
+ src.push("uniform vec3 uCameraEyeRtc;");
+
+ src.push("vec3 positions[3];");
if (scene.logarithmicDepthBufferEnabled) {
src.push("uniform float logDepthBufFC;");
src.push("out float vFragDepth;");
- src.push("bool isPerspectiveMatrix(mat4 m) {");
- src.push(" return (m[2][3] == - 1.0);");
- src.push("}");
src.push("out float isPerspective;");
}
+
+ src.push("uniform vec2 pickClipPos;");
+ src.push("uniform vec2 drawingBufferSize;");
+
+ src.push("vec4 remapClipPos(vec4 clipPos) {");
+ src.push(" clipPos.xy /= clipPos.w;");
+ src.push(` clipPos.xy = (clipPos.xy - pickClipPos) * drawingBufferSize;`);
+ src.push(" clipPos.xy *= clipPos.w;");
+ src.push(" return clipPos;");
+ src.push("}");
+
+ src.push("bool isPerspectiveMatrix(mat4 m) {");
+ src.push(" return (m[2][3] == - 1.0);");
+ src.push("}");
+
src.push("out vec4 vWorldPosition;");
+
if (clipping) {
- src.push("out int vFlags2;");
+ src.push("flat out uint vFlags2;");
}
+
src.push("void main(void) {");
// constants
- // src.push("int objectIndex = int(packedVertexId.g) & 4095;");
src.push("int polygonIndex = gl_VertexID / 3;");
- src.push("int h_normal_index = polygonIndex & 4095;");
- src.push("int v_normal_index = polygonIndex >> 12;");
-
// get packed object-id
- src.push("int h_packed_object_id_index = ((polygonIndex >> 3) / 2) & 4095;");
- src.push("int v_packed_object_id_index = ((polygonIndex >> 3) / 2) >> 12;");
-
- src.push("ivec3 packedObjectId = ivec3(texelFetch(uTexturePerPolygonIdPortionIds, ivec2(h_packed_object_id_index, v_packed_object_id_index), 0).rgb);");
+ src.push("int h_packed_object_id_index = (polygonIndex >> 3) & 4095;");
+ src.push("int v_packed_object_id_index = (polygonIndex >> 3) >> 12;");
- src.push("int objectIndex;");
- src.push("if (((polygonIndex >> 3) % 2) == 0) {");
- src.push(" objectIndex = (packedObjectId.r << 4) + (packedObjectId.g >> 4);");
- src.push("} else {");
- src.push(" objectIndex = ((packedObjectId.g & 15) << 8) + packedObjectId.b;");
- src.push("}");
+ src.push("int objectIndex = int(texelFetch(uTexturePerPolygonIdPortionIds, ivec2(h_packed_object_id_index, v_packed_object_id_index), 0).r);");
src.push("ivec2 objectIndexCoords = ivec2(objectIndex % 512, objectIndex / 512);");
- // get vertex base
- src.push("ivec4 packedVertexBase = ivec4(texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+4, objectIndexCoords.y), 0));");
+ // get flags & flags2
+ src.push("uvec4 flags = texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+2, objectIndexCoords.y), 0);");
+ src.push("uvec4 flags2 = texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+3, objectIndexCoords.y), 0);"); // pickFlag = NOT_RENDERED | PICK
- src.push("int h_index = polygonIndex & 4095;");
- src.push("int v_index = polygonIndex >> 12;");
+ // renderPass = PICK
+ src.push(`if (int(flags.w) != renderPass) {`);
+ src.push(" gl_Position = vec4(3.0, 3.0, 3.0, 1.0);"); // Cull vertex
+ src.push(" return;"); // Cull vertex
+ src.push("} else {");
+ // get vertex base
+ src.push("ivec4 packedVertexBase = ivec4(texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+4, objectIndexCoords.y), 0));");
+ src.push("ivec4 packedIndexBaseOffset = ivec4(texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+5, objectIndexCoords.y), 0));");
+ src.push("int indexBaseOffset = (packedIndexBaseOffset.r << 24) + (packedIndexBaseOffset.g << 16) + (packedIndexBaseOffset.b << 8) + packedIndexBaseOffset.a;");
+ src.push("int h_index = (polygonIndex - indexBaseOffset) & 4095;");
+ src.push("int v_index = (polygonIndex - indexBaseOffset) >> 12;");
src.push("ivec3 vertexIndices = ivec3(texelFetch(uTexturePerPolygonIdIndices, ivec2(h_index, v_index), 0));");
src.push("ivec3 uniqueVertexIndexes = vertexIndices + (packedVertexBase.r << 24) + (packedVertexBase.g << 16) + (packedVertexBase.b << 8) + packedVertexBase.a;");
-
src.push("ivec3 indexPositionH = uniqueVertexIndexes & 4095;");
src.push("ivec3 indexPositionV = uniqueVertexIndexes >> 12;");
-
src.push("mat4 positionsDecodeMatrix = mat4 (texelFetch (uTexturePerObjectIdPositionsDecodeMatrix, ivec2(objectIndexCoords.x*4+0, objectIndexCoords.y), 0), texelFetch (uTexturePerObjectIdPositionsDecodeMatrix, ivec2(objectIndexCoords.x*4+1, objectIndexCoords.y), 0), texelFetch (uTexturePerObjectIdPositionsDecodeMatrix, ivec2(objectIndexCoords.x*4+2, objectIndexCoords.y), 0), texelFetch (uTexturePerObjectIdPositionsDecodeMatrix, ivec2(objectIndexCoords.x*4+3, objectIndexCoords.y), 0));");
-
- // get flags & flags2
- src.push("uvec4 flags = texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+2, objectIndexCoords.y), 0);");
- src.push("uvec4 flags2 = texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+3, objectIndexCoords.y), 0);");
-
+ src.push("uint solid = texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+7, objectIndexCoords.y), 0).r;");
// get position
- src.push("vec3 position1 = vec3(texelFetch(uTexturePerVertexIdCoordinates, ivec2(indexPositionH.r, indexPositionV.r), 0));");
- src.push("vec3 position2 = vec3(texelFetch(uTexturePerVertexIdCoordinates, ivec2(indexPositionH.g, indexPositionV.g), 0));");
- src.push("vec3 position3 = vec3(texelFetch(uTexturePerVertexIdCoordinates, ivec2(indexPositionH.b, indexPositionV.b), 0));");
+ src.push("positions[0] = vec3(texelFetch(uTexturePerVertexIdCoordinates, ivec2(indexPositionH.r, indexPositionV.r), 0));");
+ src.push("positions[1] = vec3(texelFetch(uTexturePerVertexIdCoordinates, ivec2(indexPositionH.g, indexPositionV.g), 0));");
+ src.push("positions[2] = vec3(texelFetch(uTexturePerVertexIdCoordinates, ivec2(indexPositionH.b, indexPositionV.b), 0));");
+
+ // get color
+ src.push("uvec4 color = texelFetch (uTexturePerObjectIdColorsAndFlags, ivec2(objectIndexCoords.x*8+0, objectIndexCoords.y), 0);");
+
+ src.push(`if (color.a == 0u) {`);
+ src.push(" gl_Position = vec4(3.0, 3.0, 3.0, 1.0);"); // Cull vertex
+ src.push(" return;");
+ src.push("};");
// get normal
- src.push("vec3 normal = normalize(cross(position3 - position1, position2 - position1));");
- src.push("int vertexNumber = gl_VertexID % 3;");
+ src.push("vec3 normal = normalize(cross(positions[2] - positions[0], positions[1] - positions[0]));");
+
src.push("vec3 position;");
- src.push("if (vertexNumber == 0) position = position1;");
- src.push("else if (vertexNumber == 1) position = position2;");
- src.push("else position = position3;");
+ src.push("position = positions[gl_VertexID % 3];");
+
+ src.push("vec3 viewNormal = -normalize((transpose(inverse(viewMatrix*positionsDecodeMatrix)) * vec4(normal,1)).xyz);");
+
+ // when the geometry is not solid, if needed, flip the triangle winding
+ src.push("if (solid != 1u) {");
+ src.push("if (isPerspectiveMatrix(projMatrix)) {");
+ src.push("vec3 uCameraEyeRtcInQuantizedSpace = (inverse(sceneModelWorldMatrix * positionsDecodeMatrix) * vec4(uCameraEyeRtc, 1)).xyz;");
+ // src.push("vColor = vec4(vec3(1, -1, 0)*dot(normalize(position.xyz - uCameraEyeRtcInQuantizedSpace), normal), 1);")
+ src.push("if (dot(position.xyz - uCameraEyeRtcInQuantizedSpace, normal) < 0.0) {");
+ src.push("position = positions[2 - (gl_VertexID % 3)];");
+ src.push("viewNormal = -viewNormal;");
+ src.push("}");
+ src.push("} else {");
+ src.push("vec3 viewNormal = -normalize((transpose(inverse(viewMatrix*positionsDecodeMatrix)) * vec4(normal,1)).xyz);");
+ src.push("if (viewNormal.z < 0.0) {");
+ src.push("position = positions[2 - (gl_VertexID % 3)];");
+ src.push("}");
+ src.push("}");
+ src.push("}");
+
+ src.push("vec4 worldPosition = sceneModelWorldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
+
+ // get XYZ offset
+ src.push("vec4 offset = vec4(texelFetch (uTexturePerObjectIdOffsets, objectIndexCoords, 0).rgb, 0.0);");
+
+ src.push("worldPosition.xyz = worldPosition.xyz + offset.xyz;");
+
+ src.push("vec4 viewPosition = viewMatrix * worldPosition; ");
- // flags.w = NOT_RENDERED | PICK
- // renderPass = PICK
- src.push(`if (int(flags.w) != renderPass) {`);
- src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex
- src.push(" } else {");
- src.push(" vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
- if (scene.entityOffsetsEnabled) {
- src.push(" worldPosition.xyz = worldPosition.xyz + offset;");
- }
- src.push(" vec4 viewPosition = viewMatrix * worldPosition; ");
- src.push(" vWorldPosition = worldPosition;");
- if (clipping) {
- src.push(" vFlags2 = flags2.r;");
- }
src.push("vec4 clipPos = projMatrix * viewPosition;");
+
if (scene.logarithmicDepthBufferEnabled) {
src.push("vFragDepth = 1.0 + clipPos.w;");
src.push("isPerspective = float (isPerspectiveMatrix(projMatrix));");
}
- src.push("gl_Position = clipPos;");
- src.push(" }");
+
+ src.push("vWorldPosition = worldPosition;");
+
+ if (clipping) {
+ src.push("vFlags2 = flags2.r;");
+ }
+ src.push("gl_Position = remapClipPos(clipPos);");
+ src.push("}");
src.push("}");
return src;
}
@@ -67221,12 +67180,8 @@ class TrianglesDataTexturePickNormalsFlatRenderer {
const sectionPlanesState = scene._sectionPlanesState;
const clipping = sectionPlanesState.sectionPlanes.length > 0;
const src = [];
- src.push ('#version 300 es');
- src.push("// Triangles dataTexture pick flat normals fragment shader");
- src.push("#extension GL_OES_standard_derivatives : enable");
- if (scene.logarithmicDepthBufferEnabled) {
- src.push("#extension GL_EXT_frag_depth : enable");
- }
+ src.push('#version 300 es');
+ src.push("// TrianglesDataTexturePickNormalsRenderer fragment shader");
src.push("#ifdef GL_FRAGMENT_PRECISION_HIGH");
src.push("precision highp float;");
src.push("precision highp int;");
@@ -67241,26 +67196,28 @@ class TrianglesDataTexturePickNormalsFlatRenderer {
}
src.push("in vec4 vWorldPosition;");
if (clipping) {
- src.push("in int vFlags2;");
- for (var i = 0; i < sectionPlanesState.sectionPlanes.length; i++) {
+ src.push("flat in uint vFlags2;");
+ for (let i = 0, len = sectionPlanesState.sectionPlanes.length; i < len; i++) {
src.push("uniform bool sectionPlaneActive" + i + ";");
src.push("uniform vec3 sectionPlanePos" + i + ";");
src.push("uniform vec3 sectionPlaneDir" + i + ";");
}
}
- src.push("out vec4 outNormal;");
+ src.push("out highp ivec4 outNormal;");
src.push("void main(void) {");
if (clipping) {
- src.push(" bool clippable = vFlags2 > 0;");
+ src.push(" bool clippable = vFlags2 > 0u;");
src.push(" if (clippable) {");
- src.push(" float dist = 0.0;");
- for (var i = 0; i < sectionPlanesState.sectionPlanes.length; i++) {
- src.push(" if (sectionPlaneActive" + i + ") {");
- src.push(" dist += clamp(dot(-sectionPlaneDir" + i + ".xyz, vWorldPosition.xyz - sectionPlanePos" + i + ".xyz), 0.0, 1000.0);");
- src.push(" }");
+ src.push(" float dist = 0.0;");
+ for (let i = 0, len = sectionPlanesState.sectionPlanes.length; i < len; i++) {
+ src.push("if (sectionPlaneActive" + i + ") {");
+ src.push(" dist += clamp(dot(-sectionPlaneDir" + i + ".xyz, vWorldPosition.xyz - sectionPlanePos" + i + ".xyz), 0.0, 1000.0);");
+ src.push("}");
}
- src.push(" if (dist > 0.0) { discard; }");
+ src.push(" if (dist > 0.0) { ");
+ src.push(" discard;");
src.push(" }");
+ src.push("}");
}
if (scene.logarithmicDepthBufferEnabled) {
src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
@@ -67268,7 +67225,7 @@ class TrianglesDataTexturePickNormalsFlatRenderer {
src.push(" vec3 xTangent = dFdx( vWorldPosition.xyz );");
src.push(" vec3 yTangent = dFdy( vWorldPosition.xyz );");
src.push(" vec3 worldNormal = normalize( cross( xTangent, yTangent ) );");
- src.push(" outNormal = vec4((worldNormal * 0.5) + 0.5, 1.0);");
+ src.push(` outNormal = ivec4(worldNormal * float(${math.MAX_INT}), 1.0);`);
src.push("}");
return src;
}
@@ -67365,6 +67322,33 @@ class TrianglesDataTextureRenderers {
}
}
+ eagerCreateRenders() {
+
+ // Pre-initialize certain renderers that would otherwise be lazy-initialised
+ // on user interaction, such as picking or emphasis, so that there is no delay
+ // when user first begins interacting with the viewer.
+
+ if (!this._silhouetteRenderer) { // Used for highlighting and selection
+ this._silhouetteRenderer = new TrianglesDataTextureSilhouetteRenderer(this._scene);
+ }
+ if (!this._pickMeshRenderer) {
+ this._pickMeshRenderer = new TrianglesDataTexturePickMeshRenderer(this._scene);
+ }
+ if (!this._pickDepthRenderer) {
+ this._pickDepthRenderer = new TrianglesDataTexturePickDepthRenderer(this._scene);
+ }
+ if (!this._pickNormalsRenderer) {
+ this._pickNormalsRenderer = new TrianglesDataTexturePickNormalsFlatRenderer(this._scene);
+ }
+ if (!this._vertexDepthRenderer) {
+ this._vertexDepthRenderer = new TrianglesDataTextureSnapDepthRenderer(this._scene);
+ }
+ if (!this._snapDepthBufInitRenderer) {
+ this._snapDepthBufInitRenderer = new TrianglesDataTextureSnapDepthBufInitRenderer(this._scene);
+ }
+ }
+
+
get colorRenderer() {
if (!this._colorRenderer) {
this._colorRenderer = new TrianglesDataTextureColorRenderer(this._scene, false);
@@ -67380,9 +67364,9 @@ class TrianglesDataTextureRenderers {
}
get colorQualityRendererWithSAO() {
- if (!this._colorQualityRendererWithSAO) {
- this._colorQualityRendererWithSAO = new TrianglesDataTextureColorQualityRenderer(this._scene, true);
- }
+ // if (!this._colorQualityRendererWithSAO) {
+ // this._colorQualityRendererWithSAO = new TrianglesDataTextureColorQualityRenderer(this._scene, true);
+ // }
return this._colorQualityRendererWithSAO;
}
@@ -67430,7 +67414,7 @@ class TrianglesDataTextureRenderers {
get pickNormalsRenderer() {
if (!this._pickNormalsRenderer) {
- this._pickNormalsRenderer = new TrianglesDataTexturePickNormalsRenderer(this._scene);
+ this._pickNormalsRenderer = new TrianglesDataTexturePickNormalsFlatRenderer(this._scene);
}
return this._pickNormalsRenderer;
}
@@ -67537,8 +67521,10 @@ function getDataTextureRenderers(scene) {
dataTextureRenderers = new TrianglesDataTextureRenderers(scene);
cachdRenderers[sceneId] = dataTextureRenderers;
dataTextureRenderers._compile();
+ dataTextureRenderers.eagerCreateRenders();
scene.on("compile", () => {
dataTextureRenderers._compile();
+ dataTextureRenderers.eagerCreateRenders();
});
scene.on("destroyed", () => {
delete cachdRenderers[sceneId];
@@ -67788,32 +67774,13 @@ class DataTextureState {
3 // webgl texture unit
);
- this.textureModelMatrices.bindTexture(
- glProgram,
- modelMatricesShaderName,
- 4 // webgl texture unit
- );
-
this.texturePerObjectIdOffsets.bindTexture(
glProgram,
objectOffsetsShaderName,
- 5 // webgl texture unit
+ 4 // webgl texture unit
);
}
- /**
- *
- * @param {Program} glProgram
- * @param {string} cameraMatricesShaderName
- */
- bindPickCameraTexture(glProgram, cameraMatricesShaderName) {
- // this.texturePickCameraMatrices.bindTexture(
- // glProgram,
- // cameraMatricesShaderName,
- // 4 // webgl texture unit
- // );
- }
-
/**
*
* @param {Program} glProgram
@@ -67830,13 +67797,13 @@ class DataTextureState {
this.indicesPortionIdsPerBitnessTextures[textureBitness].bindTexture(
glProgram,
portionIdsShaderName,
- 6 // webgl texture unit
+ 5 // webgl texture unit
);
this.indicesPerBitnessTextures[textureBitness].bindTexture(
glProgram,
polygonIndicesShaderName,
- 7 // webgl texture unit
+ 6 // webgl texture unit
);
}
@@ -67856,13 +67823,13 @@ class DataTextureState {
this.edgeIndicesPortionIdsPerBitnessTextures[textureBitness].bindTexture(
glProgram,
edgePortionIdsShaderName,
- 6 // webgl texture unit
+ 5 // webgl texture unit
);
this.edgeIndicesPerBitnessTextures[textureBitness].bindTexture(
glProgram,
edgeIndicesShaderName,
- 7 // webgl texture unit
+ 6 // webgl texture unit
);
}
}
@@ -67972,188 +67939,6 @@ class DataTextureGenerator {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
}
- /**
- * Generate and return a `camera data texture`.
- *
- * The texture will automatically update its contents before each render when the camera matrix is dirty,
- * and to do so will use the following events:
- *
- * - `scene.rendering` event will be used to know that the camera texture should be updated
- * - `camera.matrix` event will be used to know that the camera matices changed
- *
- * @param {WebGL2RenderingContext} gl
- * @param {Camera} camera
- * @param {Scene} scene
- * @param {null|number[3]} origin
- * @returns {BindableDataTexture}
- */
- generateCameraDataTexture(gl, camera, scene, origin) {
- const textureWidth = 4;
- const textureHeight = 3; // space for 3 matrices
- const texture = gl.createTexture();
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, textureWidth, textureHeight);
- this.disableBindedTextureFiltering(gl);
- gl.bindTexture(gl.TEXTURE_2D, null);
- const cameraTexture = new BindableDataTexture(gl, texture, textureWidth, textureHeight);
- let cameraDirty = true;
- cameraTexture.updateViewMatrix = (viewMatrix, projMatrix) => {
- gl.bindTexture(gl.TEXTURE_2D, cameraTexture._texture);
- // Camera's "view matrix"
- gl.texSubImage2D(
- gl.TEXTURE_2D,
- 0,
- 0,
- 0, // 1st matrix: camera view matrix
- 4,
- 1,
- gl.RGBA,
- gl.FLOAT,
- new Float32Array((origin) ? createRTCViewMat(viewMatrix, origin) : viewMatrix)
- );
-
- // Camera's "view normal matrix"
- gl.texSubImage2D(
- gl.TEXTURE_2D,
- 0,
- 0,
- 1, // 2nd matrix: camera view normal matrix
- 4,
- 1,
- gl.RGBA,
- gl.FLOAT,
- new Float32Array(camera.viewNormalMatrix)
- );
-
- // Camera's "project matrix"
- gl.texSubImage2D(
- gl.TEXTURE_2D,
- 0,
- 0,
- 2, // 3rd matrix: camera project matrix
- 4,
- 1,
- gl.RGBA,
- gl.FLOAT,
- new Float32Array(projMatrix)
- );
- };
- const onCameraMatrix = () => {
- if (!cameraDirty) {
- return;
- }
- cameraDirty = false;
- cameraTexture.updateViewMatrix(camera.viewMatrix, camera.project.matrix);
- };
- camera.on("matrix", () => cameraDirty = true);
- scene.on("rendering", onCameraMatrix);
- onCameraMatrix();
- return cameraTexture;
- }
-
- /**
- * Generate and return a texture containing camera view and projection
- * matrices for picking, relative to the given RTC coordinate system origin.
- *
- * @param {WebGL2RenderingContext} gl
- * @param {Camera} camera
- * @param {null|number[3]} origin
- * @returns {BindableDataTexture}
- */
- generatePickCameraDataTexture(gl, camera, origin) {
- const textureWidth = 4;
- const textureHeight = 3; // space for 3 matrices
- const texture = gl.createTexture();
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, textureWidth, textureHeight);
- this.disableBindedTextureFiltering(gl);
- gl.bindTexture(gl.TEXTURE_2D, null);
- const cameraTexture = new BindableDataTexture(gl, texture, textureWidth, textureHeight);
- cameraTexture.updateViewMatrix = (viewMatrix, projMatrix) => {
- gl.bindTexture(gl.TEXTURE_2D, cameraTexture._texture);
- // Camera's "view matrix"
- gl.texSubImage2D(
- gl.TEXTURE_2D,
- 0,
- 0,
- 0, // 1st matrix: pick camera view matrix
- 4,
- 1,
- gl.RGBA,
- gl.FLOAT,
- new Float32Array((origin) ? createRTCViewMat(viewMatrix, origin) : viewMatrix)
- );
-
- // Camera's "view normal matrix"
- gl.texSubImage2D(
- gl.TEXTURE_2D,
- 0,
- 0,
- 1, // 2nd matrix: pick camera view normal matrix
- 4,
- 1,
- gl.RGBA,
- gl.FLOAT,
- new Float32Array(camera.viewNormalMatrix)
- );
-
- // Camera's "project matrix"
- gl.texSubImage2D(
- gl.TEXTURE_2D,
- 0,
- 0,
- 2, // 3rd matrix: pick camera project matrix
- 4,
- 1,
- gl.RGBA,
- gl.FLOAT,
- new Float32Array(projMatrix)
- );
- };
- return cameraTexture;
- }
-
- /**
- * Generate and return a `model data texture`.
- *
- * @param {WebGL2RenderingContext} gl
- * @param {DataTextureSceneModel} model
- *
- * @returns {BindableDataTexture}
- */
- generateModelTexture(gl, model) {
- const textureWidth = 4;
- const textureHeight = 2; // space for 2 matrices
- const texture = gl.createTexture();
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, textureWidth, textureHeight);
- gl.texSubImage2D(
- gl.TEXTURE_2D,
- 0,
- 0, // x-offset
- 0, // y-offset (model world matrix)
- 4, // data width (4x4 values)
- 1, // data height (1 matrix)
- gl.RGBA,
- gl.FLOAT,
- new Float32Array(model.worldMatrix)
- );
- gl.texSubImage2D(
- gl.TEXTURE_2D,
- 0,
- 0, // x-offset
- 1, // y-offset (model normal matrix)
- 4, // data width (4x4 values)
- 1, // data height (1 matrix)
- gl.RGBA,
- gl.FLOAT,
- new Float32Array(model.worldNormalMatrix)
- );
- this.disableBindedTextureFiltering(gl);
- gl.bindTexture(gl.TEXTURE_2D, null);
- return new BindableDataTexture(gl, texture, textureWidth, textureHeight);
- }
-
/**
* This will generate an RGBA texture for:
* - colors
@@ -69128,34 +68913,6 @@ class TrianglesDataTextureLayer {
buffer.edgeIndices32Bits);
}
- // if (buffer.metallicRoughness.length > 0) {
- // const metallicRoughness = new Uint8Array(buffer.metallicRoughness);
- // let normalized = false;
- // state.metallicRoughnessBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, metallicRoughness, buffer.metallicRoughness.length, 2, gl.STATIC_DRAW, normalized);
- // }
-
- // Model matrices texture
- if (!this.model._modelMatricesTexture) {
- this.model._modelMatricesTexture = this._dataTextureGenerator.generateModelTexture(gl, this.model);
- }
-
- textureState.textureModelMatrices = this.model._modelMatricesTexture;
-
- // Camera textures
-
- textureState.cameraTexture = this._dataTextureGenerator.generateCameraDataTexture(
- this.model.scene.canvas.gl,
- this.model.scene.camera,
- this.model.scene,
- this._state.origin.slice());
-
- textureState.textureCameraMatrices = textureState.cameraTexture;
-
- textureState.texturePickCameraMatrices = this._dataTextureGenerator.generatePickCameraDataTexture(
- this.model.scene.canvas.gl,
- this.model.scene.camera,
- this._state.origin.slice());
-
textureState.finalize();
// Free up memory
@@ -69537,14 +69294,12 @@ class TrianglesDataTextureLayer {
// object flags
textureState.texturePerObjectIdColorsAndFlags._textureData.set(tempUint8Array4, subPortionId * 32 + 8);
if (this._deferredSetFlagsActive || deferred) {
- console.info("_subPortionSetFlags set flags defer");
this._deferredSetFlagsDirty = true;
return;
}
if (++this._numUpdatesInFrame >= MAX_OBJECT_UPDATES_IN_FRAME_WITHOUT_BATCHED_UPDATE) {
this._beginDeferredFlags(); // Subsequent flags updates now deferred
}
- console.info("_subPortionSetFlags set flags write through");
gl.bindTexture(gl.TEXTURE_2D, textureState.texturePerObjectIdColorsAndFlags._texture);
gl.texSubImage2D(
gl.TEXTURE_2D,
@@ -69591,7 +69346,6 @@ class TrianglesDataTextureLayer {
if (++this._numUpdatesInFrame >= MAX_OBJECT_UPDATES_IN_FRAME_WITHOUT_BATCHED_UPDATE) {
this._beginDeferredFlags(); // Subsequent flags updates now deferred
}
- console.info("_subPortionSetFlags2 set flags write through");
gl.bindTexture(gl.TEXTURE_2D, textureState.texturePerObjectIdColorsAndFlags._texture);
gl.texSubImage2D(
gl.TEXTURE_2D,
@@ -69830,10 +69584,10 @@ class TrianglesDataTextureLayer {
//---- PICKING ----------------------------------------------------------------------------------------------------
setPickMatrices(pickViewMatrix, pickProjMatrix) {
- if (this._numVisibleLayerPortions === 0) {
- return;
- }
- this._dataTextureState.texturePickCameraMatrices.updateViewMatrix(pickViewMatrix, pickProjMatrix);
+ // if (this._numVisibleLayerPortions === 0) {
+ // return;
+ // }
+ // this._dataTextureState.texturePickCameraMatrices.updateViewMatrix(pickViewMatrix, pickProjMatrix);
}
drawPickMesh(renderFlags, frameCtx) {
@@ -72508,6 +72262,10 @@ class SceneModel extends Component {
return null;
}
+ if (cfg.normals) { // HACK
+ cfg.normals = null;
+ }
+
const useDTX = (!!this._dtxEnabled && (cfg.primitive === "triangles" || cfg.primitive === "solid" || cfg.primitive === "surface"));
cfg.origin = cfg.origin ? math.addVec3(this._origin, cfg.origin, math.vec3()) : this._origin;
@@ -72780,7 +72538,8 @@ class SceneModel extends Component {
countIndices += cfg.positions ? cfg.positions.length : cfg.positionsCompressed.length;
break;
case VBO_INSTANCED:
- countIndices += cfg.positions ? cfg.positions.length : cfg.positionsCompressed.length;
+ const geometry = cfg.geometry;
+ countIndices += geometry.positions ? geometry.positions.length : geometry.positionsCompressed.length;
break;
}
return Math.round(countIndices);
@@ -74257,7 +74016,8 @@ class PickController {
const snapPickResult = this._scene.snapPick({
canvasPos: this.pickCursorPos,
snapRadius: this._configs.snapRadius,
- snapMode: this._configs.snapMode,
+ snapToVertex: this._configs.snapToVertex,
+ snapToEdge: this._configs.snapToEdge,
});
if (snapPickResult && snapPickResult.snappedWorldPos) {
this.snapPickResult = snapPickResult;
@@ -74348,20 +74108,19 @@ class PickController {
if (this.hoveredSnappedOrSurfaceOff) {
this._cameraControl.fire("hoverSnapOrSurfaceOff", {
- canvasPos: this.pickCursorPos
+ canvasPos: this.pickCursorPos,
+ cursorPos : this.pickCursorPos
}, true);
}
if (this.snappedOrPicked) {
if (this.snapPickResult) {
const pickResult = new PickResult();
+ pickResult.snappedToVertex = this.snapPickResult.snappedToVertex;
+ pickResult.snappedToEdge = this.snapPickResult.snappedToEdge;
pickResult.worldPos = this.snapPickResult.snappedWorldPos;
+ pickResult.cursorPos = this.pickCursorPos;
pickResult.canvasPos = this.snapPickResult.snappedCanvasPos;
- if (this._configs.snapMode === "vertex") {
- pickResult.snappedToVertex = true;
- } else {
- pickResult.snappedToEdge = true;
- }
this._cameraControl.fire("hoverSnapOrSurface", pickResult, true);
this.snapPickResult = null;
} else {
@@ -74424,7 +74183,7 @@ class PickController {
const canvasPos = math.vec2();
-const getCanvasPosFromEvent$4 = function (event, canvasPos) {
+const getCanvasPosFromEvent$3 = function (event, canvasPos) {
if (!event) {
event = window.event;
canvasPos[0] = event.x;
@@ -74673,7 +74432,7 @@ class MousePanRotateDollyHandler {
}
switch (e.which) {
case 3: // Right button
- getCanvasPosFromEvent$4(e, canvasPos);
+ getCanvasPosFromEvent$3(e, canvasPos);
const x = canvasPos[0];
const y = canvasPos[1];
if (Math.abs(x - lastXDown) < 3 && Math.abs(y - lastYDown) < 3) {
@@ -75744,14 +75503,14 @@ class MouseMiscHandler {
});
document.addEventListener("mousemove", this._mouseMoveHandler = (e) => {
- getCanvasPosFromEvent$3(e, canvas, states.pointerCanvasPos);
+ getCanvasPosFromEvent$2(e, canvas, states.pointerCanvasPos);
});
canvas.addEventListener("mousedown", this._mouseDownHandler = (e) => {
if (!(configs.active && configs.pointerEnabled)) {
return;
}
- getCanvasPosFromEvent$3(e, canvas, states.pointerCanvasPos);
+ getCanvasPosFromEvent$2(e, canvas, states.pointerCanvasPos);
states.mouseover = true;
});
@@ -75777,7 +75536,7 @@ class MouseMiscHandler {
}
}
-function getCanvasPosFromEvent$3(event, canvas, canvasPos) {
+function getCanvasPosFromEvent$2(event, canvas, canvasPos) {
if (!event) {
event = window.event;
canvasPos[0] = event.x;
@@ -75790,7 +75549,7 @@ function getCanvasPosFromEvent$3(event, canvas, canvasPos) {
return canvasPos;
}
-const getCanvasPosFromEvent$2 = function (event, canvasPos) {
+const getCanvasPosFromEvent$1 = function (event, canvasPos) {
if (!event) {
event = window.event;
canvasPos[0] = event.x;
@@ -75852,7 +75611,7 @@ class TouchPanRotateAndDollyHandler {
if (touches.length === 1 && changedTouches.length === 1) {
- getCanvasPosFromEvent$2(touches[0], tapStartCanvasPos);
+ getCanvasPosFromEvent$1(touches[0], tapStartCanvasPos);
if (configs.followPointer) {
@@ -75892,7 +75651,7 @@ class TouchPanRotateAndDollyHandler {
}
for (let i = 0, len = touches.length; i < len; ++i) {
- getCanvasPosFromEvent$2(touches[i], lastCanvasTouchPosList[i]);
+ getCanvasPosFromEvent$1(touches[i], lastCanvasTouchPosList[i]);
}
numTouches = touches.length;
@@ -75936,7 +75695,7 @@ class TouchPanRotateAndDollyHandler {
if (numTouches === 1) {
- getCanvasPosFromEvent$2(touches[0], tapCanvasPos0);
+ getCanvasPosFromEvent$1(touches[0], tapCanvasPos0);
//-----------------------------------------------------------------------------------------------
// Drag rotation
@@ -75973,8 +75732,20 @@ class TouchPanRotateAndDollyHandler {
}
} else {
- updates.rotateDeltaY -= (xPanDelta / canvasWidth) * (configs.dragRotationRate * 1.0); // Full horizontal rotation
- updates.rotateDeltaX += (yPanDelta / canvasHeight) * (configs.dragRotationRate * 1.5); // Half vertical rotation
+ // if (!absorbTinyFirstDrag) {
+ updates.rotateDeltaY -= (xPanDelta / canvasWidth) * (configs.dragRotationRate * 1.0); // Full horizontal rotation
+ updates.rotateDeltaX += (yPanDelta / canvasHeight) * (configs.dragRotationRate * 1.5); // Half vertical rotation
+ // } else {
+ // firstDragDeltaY -= (xPanDelta / canvasWidth) * (configs.dragRotationRate * 1.0); // Full horizontal rotation
+ // firstDragDeltaX += (yPanDelta / canvasHeight) * (configs.dragRotationRate * 1.5); // Half vertical rotation
+ // if (Math.abs(firstDragDeltaX) > 5 || Math.abs(firstDragDeltaY) > 5) {
+ // updates.rotateDeltaX += firstDragDeltaX;
+ // updates.rotateDeltaY += firstDragDeltaY;
+ // firstDragDeltaX = 0;
+ // firstDragDeltaY = 0;
+ // absorbTinyFirstDrag = false;
+ // }
+ // }
}
} else if (numTouches === 2) {
@@ -75982,8 +75753,8 @@ class TouchPanRotateAndDollyHandler {
const touch0 = touches[0];
const touch1 = touches[1];
- getCanvasPosFromEvent$2(touch0, tapCanvasPos0);
- getCanvasPosFromEvent$2(touch1, tapCanvasPos1);
+ getCanvasPosFromEvent$1(touch0, tapCanvasPos0);
+ getCanvasPosFromEvent$1(touch1, tapCanvasPos1);
const lastMiddleTouch = math.geometricMeanVec2(lastCanvasTouchPosList[0], lastCanvasTouchPosList[1]);
const currentMiddleTouch = math.geometricMeanVec2(tapCanvasPos0, tapCanvasPos1);
@@ -76031,7 +75802,7 @@ class TouchPanRotateAndDollyHandler {
}
for (let i = 0; i < numTouches; ++i) {
- getCanvasPosFromEvent$2(touches[i], lastCanvasTouchPosList[i]);
+ getCanvasPosFromEvent$1(touches[i], lastCanvasTouchPosList[i]);
}
});
}
@@ -76052,7 +75823,7 @@ const TAP_INTERVAL = 150;
const DBL_TAP_INTERVAL = 325;
const TAP_DISTANCE_THRESHOLD = 4;
-const getCanvasPosFromEvent$1 = function (event, canvasPos) {
+const getCanvasPosFromEvent = function (event, canvasPos) {
if (!event) {
event = window.event;
canvasPos[0] = event.x;
@@ -76131,7 +75902,7 @@ class TouchPickHandler {
if (touches.length === 1 && changedTouches.length === 1) {
tapStartTime = touchStartTime;
- getCanvasPosFromEvent$1(touches[0], tapStartPos);
+ getCanvasPosFromEvent(touches[0], tapStartPos);
const rightClickClientX = tapStartPos[0];
const rightClickClientY = tapStartPos[1];
@@ -76158,7 +75929,7 @@ class TouchPickHandler {
}
for (let i = 0, len = touches.length; i < len; ++i) {
- getCanvasPosFromEvent$1(touches[i], activeTouches[i]);
+ getCanvasPosFromEvent(touches[i], activeTouches[i]);
}
activeTouches.length = touches.length;
@@ -76193,7 +75964,7 @@ class TouchPickHandler {
// Double-tap
- getCanvasPosFromEvent$1(changedTouches[0], pickController.pickCursorPos);
+ getCanvasPosFromEvent(changedTouches[0], pickController.pickCursorPos);
pickController.schedulePickEntity = true;
pickController.schedulePickSurface = pickedSurfaceSubs;
@@ -76225,7 +75996,7 @@ class TouchPickHandler {
// Single-tap
- getCanvasPosFromEvent$1(changedTouches[0], pickController.pickCursorPos);
+ getCanvasPosFromEvent(changedTouches[0], pickController.pickCursorPos);
pickController.schedulePickEntity = true;
pickController.schedulePickSurface = pickedSurfaceSubs;
@@ -76280,6 +76051,8 @@ class TouchPickHandler {
}
const DEFAULT_SNAP_PICK_RADIUS = 30;
+const DEFAULT_SNAP_VERTEX = true;
+const DEFAULT_SNAP_EDGE = true;
/**
* @desc Controls the {@link Camera} with user input, and fires events when the user interacts with pickable {@link Entity}s.
@@ -76907,7 +76680,8 @@ class CameraControl extends Component {
smartPivot: false,
doubleClickTimeFrame: 250,
- snapMode: "vertex",
+ snapToVertex: DEFAULT_SNAP_VERTEX,
+ snapToEdge: DEFAULT_SNAP_EDGE,
snapRadius: DEFAULT_SNAP_PICK_RADIUS,
// Rotation
@@ -77144,7 +76918,10 @@ class CameraControl extends Component {
* @param {Boolean} value Set ````true```` to activate this ````CameraControl````.
*/
set active(value) {
- this._configs.active = value !== false;
+ value = value !== false;
+ this._configs.active = value;
+ this._handlers[1]._active = value;
+ this._handlers[5]._active = value;
}
/**
@@ -77161,32 +76938,39 @@ class CameraControl extends Component {
}
/**
- * Sets the current snap mode for "hoverSnapOrSurface" events, to specify whether the pointer
- * snaps to the nearest vertex or the nearest edge.
+ * Sets whether the pointer snap to vertex.
*
- * Accepted values are:
+ * @param {boolean} snapToVertex
+ */
+ set snapToVertex(snapToVertex) {
+ this._configs.snapToVertex = !!snapToVertex;
+ }
+
+ /**
+ * Gets whether the pointer snap to vertex.
*
- * * "vertex" - (default) snap to the nearest vertex, or
- * * "edge" - snap to the nearest edge.
+ * @returns {boolean}
+ */
+ get snapToVertex() {
+ return this._configs.snapToVertex;
+ }
+
+ /**
+ * Sets whether the pointer snap to edge.
*
- * @param {String} snapMode The snap mode: "vertex" or "edge".
+ * @param {boolean} snapToEdge
*/
- set snapMode(snapMode) {
- snapMode = snapMode || "vertex";
- if (snapMode !== "vertex" && snapMode !== "edge") {
- this.error("Unsupported value for snapMode: " + snapMode + " - supported values are 'vertex' and 'edge' - defaulting to 'vertex'");
- snapMode = "vertex";
- }
- this._configs.snapMode = snapMode;
+ set snapToEdge(snapToEdge) {
+ this._configs.snapToEdge = !!snapToEdge;
}
/**
- * Gets the current snap mode.
+ * Gets whether the pointer snap to edge.
*
- * @returns {String} The snap mode: "vertex" or "edge".
+ * @returns {boolean}
*/
- get snapMode() {
- return this._configs.snapMode;
+ get snapToEdge() {
+ return this._configs.snapToEdge;
}
/**
@@ -87401,428 +87185,6 @@ class Viewer {
}
}
-/**
- * {@link Viewer} plugin that makes interaction smoother with large models, by temporarily switching
- * the Viewer to faster, lower-quality rendering modes whenever we interact.
- *
- * [](https://xeokit.github.io/xeokit-sdk/examples/#performance_FastNavPlugin)
- *
- * FastNavPlugin works by hiding specified Viewer rendering features, and optionally scaling the Viewer's canvas
- * resolution, whenever we interact with the Viewer. Then, once we've finished interacting, FastNavPlugin restores those
- * rendering features and the original canvas scale, after a configured delay.
- *
- * Depending on how we configure FastNavPlugin, we essentially switch to a smooth-rendering low-quality view while
- * interacting, then return to the normal higher-quality view after we stop, following an optional delay.
- *
- * Down-scaling the canvas resolution gives particularly good results. For example, scaling by ````0.5```` means that
- * we're rendering a quarter of the pixels while interacting, which can make the Viewer noticeably smoother with big models.
- *
- * The screen capture above shows FastNavPlugin in action. In this example, whenever we move the Camera or resize the Canvas,
- * FastNavPlugin switches off enhanced edges and ambient shadows (SAO), and down-scales the canvas, making it slightly
- * blurry. When ````0.5```` seconds passes with no interaction, the plugin shows edges and SAO again, and restores the
- * original canvas scale.
- *
- * # Usage
- *
- * In the example below, we'll create a {@link Viewer}, add a {@link FastNavPlugin}, then use an {@link XKTLoaderPlugin} to load a model.
- *
- * Whenever we interact with the Viewer, our FastNavPlugin will:
- *
- * * hide edges,
- * * hide ambient shadows (SAO),
- * * hide physically-based materials (switching to non-PBR),
- * * hide transparent objects, and
- * * scale the canvas resolution by 0.5, causing the GPU to render 75% less pixels.
- *
- *
- * We'll also configure a 0.5 second delay before we transition back to high-quality each time we stop ineracting, so that we're
- * not continually flipping between low and high quality as we interact. Since we're only rendering ambient shadows when not interacting, we'll also treat ourselves
- * to expensive, high-quality SAO settings, that we wouldn't normally configure for an interactive SAO effect.
- *
- * * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/#performance_FastNavPlugin)]
- *
- * ````javascript
- * import {Viewer, XKTLoaderPlugin, FastNavPlugin} from "xeokit-sdk.es.js";
- *
- * // Create a Viewer with PBR and SAO enabled
- *
- * const viewer = new Viewer({
- * canvasId: "myCanvas",
- * transparent: true,
- * pbr: true, // Enable physically-based rendering for Viewer
- * sao: true // Enable ambient shadows for Viewer
- * });
- *
- * viewer.scene.camera.eye = [-66.26, 105.84, -281.92];
- * viewer.scene.camera.look = [42.45, 49.62, -43.59];
- * viewer.scene.camera.up = [0.05, 0.95, 0.15];
- *
- * // Higher-quality SAO settings
- *
- * viewer.scene.sao.enabled = true;
- * viewer.scene.sao.numSamples = 60;
- * viewer.scene.sao.kernelRadius = 170;
- *
- * // Install a FastNavPlugin
- *
- * new FastNavPlugin(viewer, {
- * hideEdges: true, // Don't show edges while we interact (default is true)
- * hideSAO: true, // Don't show ambient shadows while we interact (default is true)
- * hideColorTexture: true, // No color textures while we interact (default is true)
- * hidePBR: true, // No physically-based rendering while we interact (default is true)
- * hideTransparentObjects: true, // Hide transparent objects while we interact (default is false)
- * scaleCanvasResolution: true, // Scale canvas resolution while we interact (default is false)
- * scaleCanvasResolutionFactor: 0.5, // Factor by which we scale canvas resolution when we interact (default is 0.6)
- * delayBeforeRestore: true, // When we stop interacting, delay before restoring normal render (default is true)
- * delayBeforeRestoreSeconds: 0.5 // The delay duration, in seconds (default is 0.5)
- * });
- *
- * // Load a BIM model from XKT
- *
- * const xktLoader = new XKTLoaderPlugin(viewer);
- *
- * const model = xktLoader.load({
- * id: "myModel",
- * src: "./models/xkt/HolterTower.xkt",
- * sao: true, // Enable ambient shadows for this model
- * pbr: true // Enable physically-based rendering for this model
- * });
- * ````
- *
- * @class FastNavPlugin
- */
-class FastNavPlugin extends Plugin {
-
- /**
- * @constructor
- * @param {Viewer} viewer The Viewer.
- * @param {Object} cfg FastNavPlugin configuration.
- * @param {String} [cfg.id="FastNav"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.
- * @param {Boolean} [cfg.hideColorTexture=true] Whether to temporarily hide color textures whenever we interact with the Viewer.
- * @param {Boolean} [cfg.hidePBR=true] Whether to temporarily hide physically-based rendering (PBR) whenever we interact with the Viewer.
- * @param {Boolean} [cfg.hideSAO=true] Whether to temporarily hide scalable ambient occlusion (SAO) whenever we interact with the Viewer.
- * @param {Boolean} [cfg.hideEdges=true] Whether to temporarily hide edges whenever we interact with the Viewer.
- * @param {Boolean} [cfg.hideTransparentObjects=false] Whether to temporarily hide transparent objects whenever we interact with the Viewer.
- * @param {Number} [cfg.scaleCanvasResolution=false] Whether to temporarily down-scale the canvas resolution whenever we interact with the Viewer.
- * @param {Number} [cfg.scaleCanvasResolutionFactor=0.6] The factor by which we downscale the canvas resolution whenever we interact with the Viewer.
- * @param {Boolean} [cfg.delayBeforeRestore=true] Whether to temporarily have a delay before restoring normal rendering after we stop interacting with the Viewer.
- * @param {Number} [cfg.delayBeforeRestoreSeconds=0.5] Delay in seconds before restoring normal rendering after we stop interacting with the Viewer.
- */
- constructor(viewer, cfg = {}) {
-
- super("FastNav", viewer);
-
- this._hideColorTexture = cfg.hideColorTexture !== false;
- this._hidePBR = cfg.hidePBR !== false;
- this._hideSAO = cfg.hideSAO !== false;
- this._hideEdges = cfg.hideEdges !== false;
- this._hideTransparentObjects = !!cfg.hideTransparentObjects;
- this._scaleCanvasResolution = !!cfg.scaleCanvasResolution;
- this._scaleCanvasResolutionFactor = cfg.scaleCanvasResolutionFactor || 0.6;
- this._delayBeforeRestore = (cfg.delayBeforeRestore !== false);
- this._delayBeforeRestoreSeconds = cfg.delayBeforeRestoreSeconds || 0.5;
-
- let timer = this._delayBeforeRestoreSeconds * 1000;
- let fastMode = false;
-
- const switchToLowQuality = () => {
- timer = (this._delayBeforeRestoreSeconds * 1000);
- if (!fastMode) {
- viewer.scene._renderer.setColorTextureEnabled(!this._hideColorTexture);
- viewer.scene._renderer.setPBREnabled(!this._hidePBR);
- viewer.scene._renderer.setSAOEnabled(!this._hideSAO);
- viewer.scene._renderer.setTransparentEnabled(!this._hideTransparentObjects);
- viewer.scene._renderer.setEdgesEnabled(!this._hideEdges);
- if (this._scaleCanvasResolution) {
- viewer.scene.canvas.resolutionScale = this._scaleCanvasResolutionFactor;
- } else {
- viewer.scene.canvas.resolutionScale = 1;
- }
- fastMode = true;
- }
- };
-
- const switchToHighQuality = () => {
- viewer.scene.canvas.resolutionScale = 1;
- viewer.scene._renderer.setEdgesEnabled(true);
- viewer.scene._renderer.setColorTextureEnabled(true);
- viewer.scene._renderer.setPBREnabled(true);
- viewer.scene._renderer.setSAOEnabled(true);
- viewer.scene._renderer.setTransparentEnabled(true);
- fastMode = false;
- };
-
- this._onCanvasBoundary = viewer.scene.canvas.on("boundary", switchToLowQuality);
- this._onCameraMatrix = viewer.scene.camera.on("matrix", switchToLowQuality);
-
- this._onSceneTick = viewer.scene.on("tick", (tickEvent) => {
- if (!fastMode) {
- return;
- }
- timer -= tickEvent.deltaTime;
- if ((!this._delayBeforeRestore) || timer <= 0) {
- switchToHighQuality();
- }
- });
-
- let down = false;
-
- this._onSceneMouseDown = viewer.scene.input.on("mousedown", () => {
- down = true;
- });
-
- this._onSceneMouseUp = viewer.scene.input.on("mouseup", () => {
- down = false;
- });
-
- this._onSceneMouseMove = viewer.scene.input.on("mousemove", () => {
- if (!down) {
- return;
- }
- switchToLowQuality();
- });
- }
-
- /**
- * Gets whether to temporarily hide color textures whenever we interact with the Viewer.
- *
- * Default is ````true````.
- *
- * @return {Boolean} ````true```` if hiding color textures.
- */
- get hideColorTexture() {
- return this._hideColorTexture;
- }
-
- /**
- * Sets whether to temporarily hide color textures whenever we interact with the Viewer.
- *
- * Default is ````true````.
- *
- * @param {Boolean} hideColorTexture ````true```` to hide color textures.
- */
- set hideColorTexture(hideColorTexture) {
- this._hideColorTexture = hideColorTexture;
- }
-
- /**
- * Gets whether to temporarily hide physically-based rendering (PBR) whenever we interact with the Viewer.
- *
- * Default is ````true````.
- *
- * @return {Boolean} ````true```` if hiding PBR.
- */
- get hidePBR() {
- return this._hidePBR;
- }
-
- /**
- * Sets whether to temporarily hide physically-based rendering (PBR) whenever we interact with the Viewer.
- *
- * Default is ````true````.
- *
- * @param {Boolean} hidePBR ````true```` to hide PBR.
- */
- set hidePBR(hidePBR) {
- this._hidePBR = hidePBR;
- }
-
- /**
- * Gets whether to temporarily hide scalable ambient shadows (SAO) whenever we interact with the Viewer.
- *
- * Default is ````true````.
- *
- * @return {Boolean} ````true```` if hiding SAO.
- */
- get hideSAO() {
- return this._hideSAO;
- }
-
- /**
- * Sets whether to temporarily hide scalable ambient shadows (SAO) whenever we interact with the Viewer.
- *
- * Default is ````true````.
- *
- * @param {Boolean} hideSAO ````true```` to hide SAO.
- */
- set hideSAO(hideSAO) {
- this._hideSAO = hideSAO;
- }
-
- /**
- * Gets whether to temporarily hide edges whenever we interact with the Viewer.
- *
- * Default is ````true````.
- *
- * @return {Boolean} ````true```` if hiding edges.
- */
- get hideEdges() {
- return this._hideEdges;
- }
-
- /**
- * Sets whether to temporarily hide edges whenever we interact with the Viewer.
- *
- * Default is ````true````.
- *
- * @param {Boolean} hideEdges ````true```` to hide edges.
- */
- set hideEdges(hideEdges) {
- this._hideEdges = hideEdges;
- }
-
- /**
- * Gets whether to temporarily hide transparent objects whenever we interact with the Viewer.
- *
- * Does not hide X-rayed, selected, highlighted objects.
- *
- * Default is ````false````.
- *
- * @return {Boolean} ````true```` if hiding transparent objects.
- */
- get hideTransparentObjects() {
- return this._hideTransparentObjects
- }
-
- /**
- * Sets whether to temporarily hide transparent objects whenever we interact with the Viewer.
- *
- * Does not hide X-rayed, selected, highlighted objects.
- *
- * Default is ````false````.
- *
- * @param {Boolean} hideTransparentObjects ````true```` to hide transparent objects.
- */
- set hideTransparentObjects(hideTransparentObjects) {
- this._hideTransparentObjects = (hideTransparentObjects !== false);
- }
-
- /**
- * Gets whether to temporarily scale the canvas resolution whenever we interact with the Viewer.
- *
- * Default is ````false````.
- *
- * The scaling factor is configured via {@link FastNavPlugin#scaleCanvasResolutionFactor}.
- *
- * @return {Boolean} ````true```` if scaling the canvas resolution.
- */
- get scaleCanvasResolution() {
- return this._scaleCanvasResolution;
- }
-
- /**
- * Sets whether to temporarily scale the canvas resolution whenever we interact with the Viewer.
- *
- * Default is ````false````.
- *
- * The scaling factor is configured via {@link FastNavPlugin#scaleCanvasResolutionFactor}.
- *
- * @param {Boolean} scaleCanvasResolution ````true```` to scale the canvas resolution.
- */
- set scaleCanvasResolution(scaleCanvasResolution) {
- this._scaleCanvasResolution = scaleCanvasResolution;
- }
-
- /**
- * Gets the factor by which we temporarily scale the canvas resolution when we interact with the viewer.
- *
- * Default is ````0.6````.
- *
- * Enable canvas resolution scaling by setting {@link FastNavPlugin#scaleCanvasResolution} ````true````.
- *
- * @return {Number} Factor by which we scale the canvas resolution.
- */
- get scaleCanvasResolutionFactor() {
- return this._scaleCanvasResolutionFactor;
- }
-
- /**
- * Sets the factor by which we temporarily scale the canvas resolution when we interact with the viewer.
- *
- * Accepted range is ````[0.0 .. 1.0]````.
- *
- * Default is ````0.6````.
- *
- * Enable canvas resolution scaling by setting {@link FastNavPlugin#scaleCanvasResolution} ````true````.
- *
- * @param {Number} scaleCanvasResolutionFactor Factor by which we scale the canvas resolution.
- */
- set scaleCanvasResolutionFactor(scaleCanvasResolutionFactor) {
- this._scaleCanvasResolutionFactor = scaleCanvasResolutionFactor || 0.6;
- }
-
- /**
- * Gets whether to have a delay before restoring normal rendering after we stop interacting with the Viewer.
- *
- * The delay duration is configured via {@link FastNavPlugin#delayBeforeRestoreSeconds}.
- *
- * Default is ````true````.
- *
- * @return {Boolean} Whether to have a delay.
- */
- get delayBeforeRestore() {
- return this._delayBeforeRestore;
- }
-
- /**
- * Sets whether to have a delay before restoring normal rendering after we stop interacting with the Viewer.
- *
- * The delay duration is configured via {@link FastNavPlugin#delayBeforeRestoreSeconds}.
- *
- * Default is ````true````.
- *
- * @param {Boolean} delayBeforeRestore Whether to have a delay.
- */
- set delayBeforeRestore(delayBeforeRestore) {
- this._delayBeforeRestore = delayBeforeRestore;
- }
-
- /**
- * Gets the delay before restoring normal rendering after we stop interacting with the Viewer.
- *
- * The delay is enabled when {@link FastNavPlugin#delayBeforeRestore} is ````true````.
- *
- * Default is ````0.5```` seconds.
- *
- * @return {Number} Delay in seconds.
- */
- get delayBeforeRestoreSeconds() {
- return this._delayBeforeRestoreSeconds;
- }
-
- /**
- * Sets the delay before restoring normal rendering after we stop interacting with the Viewer.
- *
- * The delay is enabled when {@link FastNavPlugin#delayBeforeRestore} is ````true````.
- *
- * Default is ````0.5```` seconds.
- *
- * @param {Number} delayBeforeRestoreSeconds Delay in seconds.
- */
- set delayBeforeRestoreSeconds(delayBeforeRestoreSeconds) {
- this._delayBeforeRestoreSeconds = delayBeforeRestoreSeconds !== null && delayBeforeRestoreSeconds !== undefined ? delayBeforeRestoreSeconds : 0.5;
- }
-
- /**
- * @private
- */
- send(name, value) {
- }
-
- /**
- * Destroys this plugin.
- */
- destroy() {
- this.viewer.scene.camera.off(this._onCameraMatrix);
- this.viewer.scene.canvas.off(this._onCanvasBoundary);
- this.viewer.scene.input.off(this._onSceneMouseDown);
- this.viewer.scene.input.off(this._onSceneMouseUp);
- this.viewer.scene.input.off(this._onSceneMouseMove);
- this.viewer.scene.off(this._onSceneTick);
- super.destroy();
- }
-}
-
const isBrowser$4 = Boolean(typeof process !== 'object' || String(process) !== '[object process]' || process.browser);
const matches$1 = typeof process !== 'undefined' && process.version && /v([0-9]*)/.exec(process.version);
matches$1 && parseFloat(matches$1[1]) || 0;
diff --git a/dist/xeokit-bim-viewer.min.es.js b/dist/xeokit-bim-viewer.min.es.js
index 484ae9b7..13e4e8fc 100644
--- a/dist/xeokit-bim-viewer.min.es.js
+++ b/dist/xeokit-bim-viewer.min.es.js
@@ -1,4 +1,4 @@
-class e{constructor(e,t){this.items=e||[],this._lastUniqueId=(t||0)+1}addItem(){let e;if(2===arguments.length){const t=arguments[0];if(e=arguments[1],this.items[t])throw"ID clash: '"+t+"'";return this.items[t]=e,t}for(e=arguments[0]||{};;){const t=this._lastUniqueId++;if(!this.items[t])return this.items[t]=e,t}}removeItem(e){const t=this.items[e];return delete this.items[e],t}}const t=new e;class s{constructor(e){this.id=e,this.parentItem=null,this.groups=[],this.menuElement=null,this.shown=!1,this.mouseOver=0}}class i{constructor(){this.items=[]}}class r{constructor(e,t,s,i,r){this.id=e,this.getTitle=t,this.doAction=s,this.getEnabled=i,this.getShown=r,this.itemElement=null,this.subMenu=null,this.enabled=!0}}class o{constructor(e={}){this._id=t.addItem(),this._context=null,this._enabled=!1,this._itemsCfg=[],this._rootMenu=null,this._menuList=[],this._menuMap={},this._itemList=[],this._itemMap={},this._shown=!1,this._nextId=0,this._eventSubs={},!1!==e.hideOnMouseDown&&(document.addEventListener("mousedown",(e=>{e.target.classList.contains("xeokit-context-menu-item")||this.hide()})),document.addEventListener("touchstart",this._canvasTouchStartHandler=e=>{e.target.classList.contains("xeokit-context-menu-item")||this.hide()})),e.items&&(this.items=e.items),this._hideOnAction=!1!==e.hideOnAction,this.context=e.context,this.enabled=!1!==e.enabled,this.hide()}on(e,t){let s=this._eventSubs[e];s||(s=[],this._eventSubs[e]=s),s.push(t)}fire(e,t){const s=this._eventSubs[e];if(s)for(let e=0,i=s.length;e{const o=this._getNextId(),n=new s(o);for(let s=0,o=e.length;s0,h=this._getNextId(),c=s.getTitle||(()=>s.title||""),A=s.doAction||s.callback||(()=>{}),u=s.getEnabled||(()=>!0),p=s.getShown||(()=>!0),d=new r(h,c,A,u,p);if(d.parentMenu=n,a.items.push(d),l){const e=t(i);d.subMenu=e,e.parentItem=d}this._itemList.push(d),this._itemMap[d.id]=d}}return this._menuList.push(n),this._menuMap[n.id]=n,n};this._rootMenu=t(e)}_getNextId(){return"ContextMenu_"+this._id+"_"+this._nextId++}_createUI(){const e=t=>{this._createMenuUI(t);const s=t.groups;for(let t=0,i=s.length;t