@openhps/core
Version:
Open Hybrid Positioning System - Core component
106 lines (102 loc) • 3.57 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.WebGLClipping = WebGLClipping;
var _Matrix = require("../../math/Matrix3.js");
var _Plane = require("../../math/Plane.js");
function WebGLClipping(properties) {
const scope = this;
let globalState = null,
numGlobalPlanes = 0,
localClippingEnabled = false,
renderingShadows = false;
const plane = new _Plane.Plane(),
viewNormalMatrix = new _Matrix.Matrix3(),
uniform = {
value: null,
needsUpdate: false
};
this.uniform = uniform;
this.numPlanes = 0;
this.numIntersection = 0;
this.init = function (planes, enableLocalClipping) {
const enabled = planes.length !== 0 || enableLocalClipping ||
// enable state of previous frame - the clipping code has to
// run another frame in order to reset the state:
numGlobalPlanes !== 0 || localClippingEnabled;
localClippingEnabled = enableLocalClipping;
numGlobalPlanes = planes.length;
return enabled;
};
this.beginShadows = function () {
renderingShadows = true;
projectPlanes(null);
};
this.endShadows = function () {
renderingShadows = false;
};
this.setGlobalState = function (planes, camera) {
globalState = projectPlanes(planes, camera, 0);
};
this.setState = function (material, camera, useCache) {
const planes = material.clippingPlanes,
clipIntersection = material.clipIntersection,
clipShadows = material.clipShadows;
const materialProperties = properties.get(material);
if (!localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && !clipShadows) {
// there's no local clipping
if (renderingShadows) {
// there's no global clipping
projectPlanes(null);
} else {
resetGlobalState();
}
} else {
const nGlobal = renderingShadows ? 0 : numGlobalPlanes,
lGlobal = nGlobal * 4;
let dstArray = materialProperties.clippingState || null;
uniform.value = dstArray; // ensure unique state
dstArray = projectPlanes(planes, camera, lGlobal, useCache);
for (let i = 0; i !== lGlobal; ++i) {
dstArray[i] = globalState[i];
}
materialProperties.clippingState = dstArray;
this.numIntersection = clipIntersection ? this.numPlanes : 0;
this.numPlanes += nGlobal;
}
};
function resetGlobalState() {
if (uniform.value !== globalState) {
uniform.value = globalState;
uniform.needsUpdate = numGlobalPlanes > 0;
}
scope.numPlanes = numGlobalPlanes;
scope.numIntersection = 0;
}
function projectPlanes(planes, camera, dstOffset, skipTransform) {
const nPlanes = planes !== null ? planes.length : 0;
let dstArray = null;
if (nPlanes !== 0) {
dstArray = uniform.value;
if (skipTransform !== true || dstArray === null) {
const flatSize = dstOffset + nPlanes * 4,
viewMatrix = camera.matrixWorldInverse;
viewNormalMatrix.getNormalMatrix(viewMatrix);
if (dstArray === null || dstArray.length < flatSize) {
dstArray = new Float32Array(flatSize);
}
for (let i = 0, i4 = dstOffset; i !== nPlanes; ++i, i4 += 4) {
plane.copy(planes[i]).applyMatrix4(viewMatrix, viewNormalMatrix);
plane.normal.toArray(dstArray, i4);
dstArray[i4 + 3] = plane.constant;
}
}
uniform.value = dstArray;
uniform.needsUpdate = true;
}
scope.numPlanes = nPlanes;
scope.numIntersection = 0;
return dstArray;
}
}