@openhps/core
Version:
Open Hybrid Positioning System - Core component
110 lines (104 loc) • 4.87 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.WebGLMorphtargets = WebGLMorphtargets;
var _constants = require("../../constants.js");
var _DataArrayTexture = require("../../textures/DataArrayTexture.js");
var _Vector = require("../../math/Vector4.js");
var _Vector2 = require("../../math/Vector2.js");
function WebGLMorphtargets(gl, capabilities, textures) {
const morphTextures = new WeakMap();
const morph = new _Vector.Vector4();
function update(object, geometry, program) {
const objectInfluences = object.morphTargetInfluences;
// the following encodes morph targets into an array of data textures. Each layer represents a single morph target.
const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color;
const morphTargetsCount = morphAttribute !== undefined ? morphAttribute.length : 0;
let entry = morphTextures.get(geometry);
if (entry === undefined || entry.count !== morphTargetsCount) {
if (entry !== undefined) entry.texture.dispose();
const hasMorphPosition = geometry.morphAttributes.position !== undefined;
const hasMorphNormals = geometry.morphAttributes.normal !== undefined;
const hasMorphColors = geometry.morphAttributes.color !== undefined;
const morphTargets = geometry.morphAttributes.position || [];
const morphNormals = geometry.morphAttributes.normal || [];
const morphColors = geometry.morphAttributes.color || [];
let vertexDataCount = 0;
if (hasMorphPosition === true) vertexDataCount = 1;
if (hasMorphNormals === true) vertexDataCount = 2;
if (hasMorphColors === true) vertexDataCount = 3;
let width = geometry.attributes.position.count * vertexDataCount;
let height = 1;
if (width > capabilities.maxTextureSize) {
height = Math.ceil(width / capabilities.maxTextureSize);
width = capabilities.maxTextureSize;
}
const buffer = new Float32Array(width * height * 4 * morphTargetsCount);
const texture = new _DataArrayTexture.DataArrayTexture(buffer, width, height, morphTargetsCount);
texture.type = _constants.FloatType;
texture.needsUpdate = true;
// fill buffer
const vertexDataStride = vertexDataCount * 4;
for (let i = 0; i < morphTargetsCount; i++) {
const morphTarget = morphTargets[i];
const morphNormal = morphNormals[i];
const morphColor = morphColors[i];
const offset = width * height * 4 * i;
for (let j = 0; j < morphTarget.count; j++) {
const stride = j * vertexDataStride;
if (hasMorphPosition === true) {
morph.fromBufferAttribute(morphTarget, j);
buffer[offset + stride + 0] = morph.x;
buffer[offset + stride + 1] = morph.y;
buffer[offset + stride + 2] = morph.z;
buffer[offset + stride + 3] = 0;
}
if (hasMorphNormals === true) {
morph.fromBufferAttribute(morphNormal, j);
buffer[offset + stride + 4] = morph.x;
buffer[offset + stride + 5] = morph.y;
buffer[offset + stride + 6] = morph.z;
buffer[offset + stride + 7] = 0;
}
if (hasMorphColors === true) {
morph.fromBufferAttribute(morphColor, j);
buffer[offset + stride + 8] = morph.x;
buffer[offset + stride + 9] = morph.y;
buffer[offset + stride + 10] = morph.z;
buffer[offset + stride + 11] = morphColor.itemSize === 4 ? morph.w : 1;
}
}
}
entry = {
count: morphTargetsCount,
texture: texture,
size: new _Vector2.Vector2(width, height)
};
morphTextures.set(geometry, entry);
function disposeTexture() {
texture.dispose();
morphTextures.delete(geometry);
geometry.removeEventListener('dispose', disposeTexture);
}
geometry.addEventListener('dispose', disposeTexture);
}
//
if (object.isInstancedMesh === true && object.morphTexture !== null) {
program.getUniforms().setValue(gl, 'morphTexture', object.morphTexture, textures);
} else {
let morphInfluencesSum = 0;
for (let i = 0; i < objectInfluences.length; i++) {
morphInfluencesSum += objectInfluences[i];
}
const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum;
program.getUniforms().setValue(gl, 'morphTargetBaseInfluence', morphBaseInfluence);
program.getUniforms().setValue(gl, 'morphTargetInfluences', objectInfluences);
}
program.getUniforms().setValue(gl, 'morphTargetsTexture', entry.texture, textures);
program.getUniforms().setValue(gl, 'morphTargetsTextureSize', entry.size);
}
return {
update: update
};
}