return function unProject(out, a, invViewProj, viewport) { if (!vec4_0) vec4_0 = vec4.create(); let x = a[0], y = a[1], z = a[2]; vec4_0[0] = (x - viewport[0]) * 2.0 / viewport[2] - 1.0; vec4_0[1] = (y - viewport[1]) * 2.0 / viewport[3] - 1.0; vec4_0[2] = 2.0 * z - 1.0; vec4_0[3] = 1.0; vec4.transformMat4(vec4_0, vec4_0, invViewProj); if (vec4_0[3] === 0.0) { out[0] = 0; out[1] = 0; out[2] = 0; throw new Error('Perspective divide error'); } out[0] = vec4_0[0] / vec4_0[3]; out[1] = vec4_0[1] / vec4_0[3]; out[2] = vec4_0[2] / vec4_0[3]; return out; };
function _generateLinkAttributes(portal, resonator, color, resonatorPercent) { resonatorPercent = resonatorPercent === undefined ? 1 : Math.max(Math.min(resonatorPercent, 1), 0); var values = new Float32Array(_size * _chunkSize); var dist = Math.sqrt( (resonator[0] - portal[0]) * (resonator[0] - portal[0]) + (resonator[1] - portal[1]) * (resonator[1] - portal[1]) ); var f4 = (2 / 30) * dist, f5 = 0.9 + 0.1 * resonatorPercent, f6 = 0.65 + 0.35 * resonatorPercent, f8 = 0.1 + 0.3 * resonatorPercent; var cl = vec4.lerp(vec4.create(), baseColor, color, 0.1 + resonatorPercent * 0.85); cl[3] = 0.75 + 0.25 * resonatorPercent * cl[3]; var vec = vec3.fromValues(resonator[0], 0, resonator[1]); vec3.subtract(vec, vec, vec3.fromValues(portal[0], 0, portal[1])); var right = vec3.cross(vec3.create(), vec, up); vec3.normalize(right, right); var step = _len * 2; var f10 = 5.0 * ((portal[0] + portal[1]) - Math.floor(portal[0] + portal[1])); for(var i = 0; i < _len; i++) { var f11 = j[i], f12 = portal[0] + f11 * vec[0], f13 = portal[1] + f11 * vec[2], f14 = portalBaseOffset + f11 * (resonatorMidOffset - portalBaseOffset) + f5 * k[i], f15 = f6 * l[i], f16 = f11 * f4; fillChunk(values, (i * 2) + 0, f12 + f15 * right[0], f14, f13 + f15 * right[2], 0.0, f16 + f10, up, f8, cl); fillChunk(values, (i * 2) + 1, f12 - f15 * right[0], f14, f13 - f15 * right[2], 1.0, f16 + f10, up, f8, cl); fillChunk(values, step + (i * 2) + 0, f12, f14 + f15, f13, 0.0, f16 + f10, right, f8, cl); fillChunk(values, step + (i * 2) + 1, f12, f14 - f15, f13, 1.0, f16 + f10, right, f8, cl); } return values; }
pointCoordinate: function(p, targetZ) { if (targetZ === undefined) targetZ = 0; var matrix = this.coordinatePointMatrix(this.tileZoom); var inverted = mat4.invert(new Float64Array(16), matrix); if (!inverted) throw "failed to invert matrix"; // since we don't know the correct projected z value for the point, // unproject two points to get a line and then find the point on that // line with z=0 var coord0 = vec4.transformMat4([], [p.x, p.y, 0, 1], inverted); var coord1 = vec4.transformMat4([], [p.x, p.y, 1, 1], inverted); var w0 = coord0[3]; var w1 = coord1[3]; var x0 = coord0[0] / w0; var x1 = coord1[0] / w1; var y0 = coord0[1] / w0; var y1 = coord1[1] / w1; var z0 = coord0[2] / w0; var z1 = coord1[2] / w1; var t = z0 === z1 ? 0 : (targetZ - z0) / (z1 - z0); return new Coordinate( interp(x0, x1, t), interp(y0, y1, t), this.tileZoom); },
createPlacementMatrix (pos, f, scale, rotationMatrix){ var placementMatrix = mat4.create(); mat4.identity(placementMatrix); mat4.translate(placementMatrix, placementMatrix, pos); if (rotationMatrix) { mat4.multiply(placementMatrix,placementMatrix, rotationMatrix); } else { mat4.rotateZ(placementMatrix, placementMatrix, f); } mat4.scale(placementMatrix, placementMatrix, [scale , scale , scale ]); var placementInvertMatrix = mat4.create(); mat4.invert(placementInvertMatrix, placementMatrix); this.placementInvertMatrix = placementInvertMatrix; this.placementMatrix = placementMatrix; //update aabb var bb = super.getBoundingBox(); if (bb) { var a_ab = vec4.fromValues(bb.ab.x,bb.ab.y,bb.ab.z,1); var a_cd = vec4.fromValues(bb.cd.x,bb.cd.y,bb.cd.z,1); var worldAABB = mathHelper.transformAABBWithMat4(this.placementMatrix, [a_ab, a_cd]); this.diameter = vec3.distance(worldAABB[0],worldAABB[1]); this.aabb = worldAABB; } }
pointCoordinate(p: Point) { const targetZ = 0; // since we don't know the correct projected z value for the point, // unproject two points to get a line and then find the point on that // line with z=0 const coord0 = [p.x, p.y, 0, 1]; const coord1 = [p.x, p.y, 1, 1]; vec4.transformMat4(coord0, coord0, this.pixelMatrixInverse); vec4.transformMat4(coord1, coord1, this.pixelMatrixInverse); const w0 = coord0[3]; const w1 = coord1[3]; const x0 = coord0[0] / w0; const x1 = coord1[0] / w1; const y0 = coord0[1] / w0; const y1 = coord1[1] / w1; const z0 = coord0[2] / w0; const z1 = coord1[2] / w1; const t = z0 === z1 ? 0 : (targetZ - z0) / (z1 - z0); return new MercatorCoordinate( interpolate(x0, x1, t) / this.worldSize, interpolate(y0, y1, t) / this.worldSize); }
project(lngLatZ) { const [x, y] = this.projectZoom0(lngLatZ); const v = vec4.fromValues(x, y, lngLatZ[2] || 0, 1); vec4.transformMat4(v, v, this.viewMatrix); vec4.transformMat4(v, v, this.projectionMatrix); // vec4.transformMat4(v, v, this.viewportMatrix); }
updateAABB (){ var bb = super.getBoundingBox(); if (bb) { var a_ab = vec4.fromValues(bb.ab.x,bb.ab.y,bb.ab.z,1); var a_cd = vec4.fromValues(bb.cd.x,bb.cd.y,bb.cd.z,1); var worldAABB = mathHelper.transformAABBWithMat4(this.placementMatrix, [a_ab, a_cd]); this.diameter = vec3.distance(worldAABB[0], worldAABB[1]); this.aabb = worldAABB; } }
constructor(dimensions = vec2.fromValues(800, 600)) { this.dimensions = vec2.clone(dimensions); this.canvas = document.createElement('canvas'); this.canvas.width = this.dimensions[0]; this.canvas.height = this.dimensions[1]; document.body.appendChild(this.canvas); this.gl = this.canvas.getContext('webgl') || this.canvas.getContext('experimental-webgl'); this.gl.clearColor(0.0, 0.0, 0.0, 1.0); this.gl.enable(this.gl.BLEND); this.gl.blendEquation(this.gl.FUNC_ADD); this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA); this.projection = mat4.create(); mat4.ortho(this.projection, 0, this.dimensions[0], this.dimensions[1], 0, -1, 1); this.setViewport(vec4.fromValues(0, 0, this.dimensions[0], this.dimensions[1])); this.vertexBuffer = null; this.indexBuffer = null; this.shader = null; this.enabledVertexAttributeArrays = {}; this.uniformValues = new Map(); }
update (deltaTime, cameraPos) { if (!this.aabb) { var bb = super.getBoundingBox(); if (bb) { var a_ab = vec4.fromValues(bb.ab.x,bb.ab.y,bb.ab.z,1); var a_cd = vec4.fromValues(bb.cd.x,bb.cd.y,bb.cd.z,1); var worldAABB = mathHelper.transformAABBWithMat4(this.placementMatrix, [a_ab, a_cd]); this.diameter = vec3.distance(worldAABB[0],worldAABB[1]); this.aabb = worldAABB; } } if (!this.getIsRendered()) return; super.update(deltaTime, cameraPos, this.placementInvertMatrix); }
/** * Set the camera's viewport. * * @param {vec4} viewport */ viewport(viewport) { vec4.copy(this.rect, viewport); this.aspect = viewport[2] / viewport[3]; this.dirty = true; }
setViewport(viewport) { if (viewport !== this.viewport) { this.gl.viewport(viewport[0], viewport[1], viewport[2], viewport[3]); this.viewport = vec4.clone(viewport); } }
update (deltaTime, cameraPos, invPlacementMat) { if (!this.m2Geom) return; //if (!this.materialArray) return; var animation = this.currentAnimation; animation = this.checkCurrentAnimation(animation, this.currentTime + deltaTime); var animationTime = this.currentTime + deltaTime - this.currentAnimationStart; var subMeshColors = this.getSubMeshColor(animation, animationTime); this.subMeshColors = subMeshColors; var transperencies = this.getTransperencies(animation, animationTime); this.transperencies = transperencies; this.calcBones(animation, animationTime, cameraPos, invPlacementMat); this.calcAnimMatrixes(animation, animationTime); var skinData = this.skinGeom.skinFile.header; var cameraInlocalPos = vec4.create(); vec4.copy(cameraInlocalPos, cameraPos); vec4.transformMat4(cameraInlocalPos, cameraInlocalPos, invPlacementMat); this.materialArray.sort(function(a, b) { var result = a.layer - b.layer; if (result == 0) { var mesh1Pos = skinData.subMeshes[a.meshIndex].pos; var mesh2Pos = skinData.subMeshes[b.meshIndex].pos; var mesh1Vec = vec3.create(); vec3.subtract(mesh1Vec, [mesh1Pos.x, mesh1Pos.y, mesh1Pos.z], cameraInlocalPos); var mesh2Vec = vec3.create(); vec3.subtract(mesh2Vec, [mesh2Pos.x, mesh2Pos.y, mesh2Pos.z], cameraInlocalPos); var distMesh1 = vec3.length(mesh1Vec) var distMesh2 = vec3.length(mesh2Vec); result = distMesh2 - distMesh1; } return result; }); this.currentTime += deltaTime; }
function projectQueryGeometry(queryGeometry: Array<Point>, pixelPosMatrix: Float32Array, transform: Transform, z: number) { const projectedQueryGeometry = []; for (const p of queryGeometry) { const v = [p.x, p.y, z, 1]; vec4.transformMat4(v, v, pixelPosMatrix); projectedQueryGeometry.push(new Point(v[0] / v[3], v[1] / v[3])); } return projectedQueryGeometry; }
maxPitchScaleFactor() { // calcMatrices hasn't run yet if (!this.pixelMatrixInverse) return 1; const coord = this.pointCoordinate(new Point(0, 0)); const p = [coord.x * this.worldSize, coord.y * this.worldSize, 0, 1]; const topPoint = vec4.transformMat4(p, p, this.pixelMatrix); return topPoint[3] / this.cameraToCenterDistance; }
CubeGeometry.prototype._closestTile = function(view, level) { var ray = this._vec; // Compute a view ray into the central screen point. vec4.set(ray, 0, 0, 1, 1); vec4.transformMat4(ray, ray, view.inverseProjection()); var minAngle = Infinity; var closestFace = null; // Find the face whose vector makes a minimal angle with the view ray. // This is the face into which the view ray points. for (var face in faceVectors) { var vector = faceVectors[face]; // For a small angle between two normalized vectors, angle ~ 1-cos(angle). var angle = 1 - vec3.dot(vector, ray); if (angle < minAngle) { minAngle = angle; closestFace = face; } } // Project view ray onto cube, i.e., normalize the coordinate with // largest absolute value to ±0.5. var max = Math.max(Math.abs(ray[0]), Math.abs(ray[1]), Math.abs(ray[2])) / 0.5; for (var i = 0; i < 3; i++) { ray[i] = ray[i] / max; } // Rotate view ray into front face. var rot = faceRotation[closestFace]; rotateVector(ray, 0, -rot.x, -rot.y); // Get the desired zoom level. var tileZ = this.levelList.indexOf(level); var numX = level.numHorizontalTiles(); var numY = level.numVerticalTiles(); // Find the coordinates of the tile that the view ray points into. var tileX = clamp(Math.floor((0.5 + ray[0]) * numX), 0, numX - 1); var tileY = clamp(Math.floor((0.5 - ray[1]) * numY), 0, numY - 1); return new CubeTile(closestFace, tileX, tileY, tileZ, this); };
update(context, parent) { super.update(context, parent); if (this.hasChanged) { // The line should point the ground... let center = vec3.create(); vec3.transformMat4(center, center, this.globalMatrix); let point = vec3.create(); vec3.copy(point, center); point[1] = 0; // Scale the line to match the size this.guideLine.transform.scale[0] = center[1]; // Here comes the hard part... setting rotation. let hand = vec4.fromValues(0, -1, 0, 0); let inv = mat4.create(); mat4.invert(inv, this.globalMatrix); vec4.transformMat4(hand, hand, inv); vec4.normalize(hand, hand); quat.rotationTo(this.guideLine.transform.rotation, [1, 0, 0], hand); this.guideLine.transform.invalidate(); } }
checkAgainstDepthBuffer(frustumMatrix, lookAtMat4, placementMatrix, checkDepth) { var bb = this.getBoundingBox(); if (!bb) return false; var combinedMat4 = mat4.create(); mat4.multiply(combinedMat4, frustumMatrix, lookAtMat4); mat4.multiply(combinedMat4, combinedMat4, placementMatrix); var bb1 = bb.ab, bb2 = bb.cd; var bb1vec = vec4.fromValues(bb1.x, bb1.y, bb1.z, 1); var bb2vec = vec4.fromValues(bb2.x, bb2.y, bb2.z, 1); vec4.transformMat4(bb1vec, bb1vec, combinedMat4); vec4.transformMat4(bb2vec, bb2vec, combinedMat4); //Perspective divide vec4.scale(bb1vec, bb1vec, 1/bb1vec[3]); vec4.scale(bb2vec, bb2vec, 1/bb2vec[3]); var depth = Math.max(0, Math.min(bb1vec[2], bb2vec[2])); var min_x = Math.min(bb1vec[0], bb2vec[0]); min_x = Math.max(min_x, -1.0); var max_x = Math.max(bb1vec[0], bb2vec[0]); max_x = Math.min(max_x, 1.0); var min_y = Math.min(bb1vec[1], bb2vec[1]); min_y = Math.max(min_y, -1.0); var max_y = Math.max(bb1vec[1], bb2vec[1]); max_y = Math.min(max_y, 1.0); return checkDepth(min_x, max_x, min_y, max_y, depth); }
function applyToImageData(imageData, effect) { var width = imageData.width; var height = imageData.height; var data = imageData.data; for(var i = 0; i < width * height; i++) { vec4.set(tmpPixel, data[i*4+0]/255, data[i*4+1]/255, data[i*4+2]/255, data[i*4+3]/255); applyToPixel(tmpPixel, effect, tmpPixel); data[i*4+0] = tmpPixel[0]*255; data[i*4+1] = tmpPixel[1]*255; data[i*4+2] = tmpPixel[2]*255; data[i*4+3] = tmpPixel[3]*255; } }
createPlacementMatrixFromParent (parentM2, attachment, scale){ var parentM2File = parentM2.m2Geom.m2File; var attIndex = parentM2File.attachLookups[attachment]; var attachInfo = parentM2File.attachments[attIndex]; var boneId = attachInfo.bone; var parentBoneTransMat = parentM2.bones[boneId].tranformMat; var placementMatrix = mat4.create(); mat4.identity(placementMatrix); mat4.multiply(placementMatrix,placementMatrix, parentM2.placementMatrix); mat4.multiply(placementMatrix, placementMatrix, parentBoneTransMat); mat4.translate(placementMatrix, placementMatrix, [ attachInfo.pos.x, attachInfo.pos.y, attachInfo.pos.z, 0 ]); var placementInvertMatrix = mat4.create(); mat4.invert(placementInvertMatrix, placementMatrix); this.placementInvertMatrix = placementInvertMatrix; this.placementMatrix = placementMatrix; var bb = super.getBoundingBox(); if (bb) { var a_ab = vec4.fromValues(bb.ab.x,bb.ab.y,bb.ab.z,1); var a_cd = vec4.fromValues(bb.cd.x,bb.cd.y,bb.cd.z,1); var worldAABB = mathHelper.transformAABBWithMat4(this.placementMatrix, [a_ab, a_cd]); this.diameter = vec3.distance(worldAABB[0],worldAABB[1]); this.aabb = worldAABB; } }
/** * */ constructor() { // Rendered viewport. this.rect = vec4.create(); // Perspective values. this.isPerspective = true; this.fov = 0; this.aspect = 0; // Orthogonal values. this.isOrtho = false; this.leftClipPlane = 0; this.rightClipPlane = 0; this.bottomClipPlane = 0; this.topClipPlane = 0; // Shared values. this.nearClipPlane = 0; this.farClipPlane = 0; // World values. this.location = vec3.create(); this.rotation = quat.create(); // Derived values. this.inverseRotation = quat.create(); this.worldMatrix = mat4.create(); this.projectionMatrix = mat4.create(); this.worldProjectionMatrix = mat4.create(); this.inverseWorldMatrix = mat4.create(); this.inverseRotationMatrix = mat4.create(); this.inverseWorldProjectionMatrix = mat4.create(); this.directionX = vec3.create(); this.directionY = vec3.create(); this.directionZ = vec3.create(); // First four vectors are the corners of a 2x2 rectangle, the last three vectors are the unit axes this.vectors = [vec3.fromValues(-1, -1, 0), vec3.fromValues(-1, 1, 0), vec3.fromValues(1, 1, 0), vec3.fromValues(1, -1, 0), vec3.fromValues(1, 0, 0), vec3.fromValues(0, 1, 0), vec3.fromValues(0, 0, 1)]; // First four vectors are the corners of a 2x2 rectangle billboarded to the camera, the last three vectors are the unit axes billboarded this.billboardedVectors = [vec3.create(), vec3.create(), vec3.create(), vec3.create(), vec3.create(), vec3.create(), vec3.create()]; // Left, right, top, bottom, near, far this.planes = [vec4.create(), vec4.create(), vec4.create(), vec4.create(), vec4.create(), vec4.create()]; this.dirty = true; }
queryIntersectsFeature(queryGeometry: Array<Point>, feature: VectorTileFeature, featureState: FeatureState, geometry: Array<Array<Point>>, zoom: number, transform: Transform, pixelsToTileUnits: number, pixelPosMatrix: Float32Array): boolean { const translatedPolygon = translate(queryGeometry, this.paint.get('circle-translate'), this.paint.get('circle-translate-anchor'), transform.angle, pixelsToTileUnits); const radius = this.paint.get('circle-radius').evaluate(feature, featureState); const stroke = this.paint.get('circle-stroke-width').evaluate(feature, featureState); const size = radius + stroke; // For pitch-alignment: map, compare feature geometry to query geometry in the plane of the tile // // Otherwise, compare geometry in the plane of the viewport // // A circle with fixed scaling relative to the viewport gets larger in tile space as it moves into the distance // // A circle with fixed scaling relative to the map gets smaller in viewport space as it moves into the distance const alignWithMap = this.paint.get('circle-pitch-alignment') === 'map'; const transformedPolygon = alignWithMap ? translatedPolygon : projectQueryGeometry(translatedPolygon, pixelPosMatrix); const transformedSize = alignWithMap ? size * pixelsToTileUnits : size; for (const ring of geometry) { for (const point of ring) { const transformedPoint = alignWithMap ? point : projectPoint(point, pixelPosMatrix); let adjustedSize = transformedSize; const projectedCenter = vec4.transformMat4([], [point.x, point.y, 0, 1], pixelPosMatrix); if (this.paint.get('circle-pitch-scale') === 'viewport' && this.paint.get('circle-pitch-alignment') === 'map') { adjustedSize *= projectedCenter[3] / transform.cameraToCenterDistance; } else if (this.paint.get('circle-pitch-scale') === 'map' && this.paint.get('circle-pitch-alignment') === 'viewport') { adjustedSize *= transform.cameraToCenterDistance / projectedCenter[3]; } if (polygonIntersectsBufferedPoint(transformedPolygon, transformedPoint, adjustedSize)) return true; } } return false; }
/** * @class CubeGeometry * @implements Geometry * @classdesc * * A {@link Geometry} implementation suitable for tiled cube images with * multiple resolution levels. * * The following restrictions apply: * - All tiles in a level must be square and form a rectangular grid; * - The size of a level must be a multiple of the tile size; * - The size of a level must be a multiple of the parent level size; * - The number of tiles in a level must be a multiple of the number of tiles * in the parent level. * * @param {Object[]} levelPropertiesList Level description * @param {number} levelPropertiesList[].size Cube face size in pixels * @param {number} levelPropertiesList[].tileSize Tile size in pixels */ function CubeGeometry(levelPropertiesList) { if (type(levelPropertiesList) !== 'array') { throw new Error('Level list must be an array'); } this.levelList = makeLevelList(levelPropertiesList, CubeLevel); this.selectableLevelList = makeSelectableLevelList(this.levelList); for (var i = 1; i < this.levelList.length; i++) { this.levelList[i]._validateWithParentLevel(this.levelList[i-1]); } this._tileSearcher = new TileSearcher(this); this._neighborsCache = new LruMap(neighborsCacheSize); this._vec = vec4.create(); this._viewSize = {}; }
interpolateValues (currentTime, interpolType, time1, time2, value1, value2, valueType){ //Support and use only linear interpolation for now if (interpolType == 0) { return value1; } else if (interpolType >= 1) { if (valueType == 1 || valueType == 3) { var result = vec4.create(); quat.slerp(result, value1, value2, (currentTime - time1)/(time2 - time1)); } else { var diff = vec4.create(); vec4.subtract(diff, value2, value1); vec4.scale(diff, diff, (currentTime - time1)/(time2 - time1)); var result = vec4.create(); vec4.add(result, value1, diff); } return result; } }
function projectPoint(p: Point, pixelPosMatrix: Float32Array) { const point = vec4.transformMat4([], [p.x, p.y, 0, 1], pixelPosMatrix); return new Point(point[0] / point[3], point[1] / point[3]); }
// The code that utilizes Matrix4 does the same calculation as their mat4 counterparts, // has lower performance but provides error checking. // Uncomment when debugging function calculateMatrixAndOffset(_ref) { var projectionMode = _ref.projectionMode, positionOrigin = _ref.positionOrigin, viewport = _ref.viewport, modelMatrix = _ref.modelMatrix; var viewMatrixUncentered = viewport.viewMatrixUncentered, viewMatrix = viewport.viewMatrix, projectionMatrix = viewport.projectionMatrix, viewProjectionMatrix = viewport.viewProjectionMatrix; var projectionCenter = void 0; var modelViewMatrix = void 0; switch (projectionMode) { case COORDINATE_SYSTEM.IDENTITY: case COORDINATE_SYSTEM.LNGLAT: projectionCenter = ZERO_VECTOR; // modelViewMatrix = new Matrix4(viewMatrix); modelViewMatrix = mat4.copy([], viewMatrix); break; // TODO: make lighitng work for meter offset mode case COORDINATE_SYSTEM.METER_OFFSETS: // Calculate transformed projectionCenter (in 64 bit precision) // This is the key to offset mode precision (avoids doing this // addition in 32 bit precision) var positionPixels = viewport.projectFlat(positionOrigin); // projectionCenter = new Matrix4(viewProjectionMatrix) // .transformVector([positionPixels[0], positionPixels[1], 0.0, 1.0]); projectionCenter = vec4.transformMat4([], [positionPixels[0], positionPixels[1], 0.0, 1.0], viewProjectionMatrix); // Always apply uncentered projection matrix if available (shader adds center) // Zero out 4th coordinate ("after" model matrix) - avoids further translations // modelViewMatrix = new Matrix4(viewMatrixUncentered || viewMatrix) // .multiplyRight(VECTOR_TO_POINT_MATRIX); modelViewMatrix = mat4.multiply([], viewMatrixUncentered || viewMatrix, VECTOR_TO_POINT_MATRIX); break; default: throw new Error('Unknown projection mode'); } var viewMatrixInv = mat4.invert([], modelViewMatrix) || modelViewMatrix; if (modelMatrix) { // Apply model matrix if supplied // modelViewMatrix.multiplyRight(modelMatrix); mat4.multiply(modelViewMatrix, modelViewMatrix, modelMatrix); } // const modelViewProjectionMatrix = new Matrix4(projectionMatrix).multiplyRight(modelViewMatrix); var modelViewProjectionMatrix = mat4.multiply([], projectionMatrix, modelViewMatrix); var cameraPos = [viewMatrixInv[12], viewMatrixInv[13], viewMatrixInv[14]]; return { modelViewMatrix: modelViewMatrix, modelViewProjectionMatrix: modelViewProjectionMatrix, projectionCenter: projectionCenter, cameraPos: cameraPos }; }
value: function transformVector(matrix, vector) { var result = vec4.transformMat4([0, 0, 0, 0], vector, matrix); var scale = 1 / result[3]; vec4.multiply(result, result, [scale, scale, scale, scale]); return result; }
constructor(meshName, textureName) { super(PROGRAM, meshName, textureName); this.uniforms.u_color = vec4.clone(defaultColor); this.uniforms.u_rampTargetInvWidth = vec2.clone(defaultRampTargetInv); this.uniforms.u_contributionsAndAlpha = vec3.clone(defaultContributions); }
import Constants from '../constants'; import TexturedDrawable from './textured'; import { vec2, vec3, vec4 } from 'gl-matrix'; const PROGRAM = Constants.Program.ShieldEffect; // these defaults are whack. Need to find the real // functions used to update these, too // As of 1.62.0, that was in ...ingress.common.scanner.b.a.d // The baksmali is a little jacked up, though. var defaultColor = vec4.clone(Constants.teamColors.NEUTRAL); var defaultRampTargetInv = vec2.fromValues(0.5, 1.3); var defaultContributions = vec3.fromValues(0.5, 0.5, 0.5); /** * Represents the shield idle effect * * Note: This probably should actually be generalized differently... * Apparently all three shield effects use the same texture and mesh, but have * different programs and variables. * * So, perhaps a better way would be to have the base class hardcode the texture * and mesh internal names, and then the derived classes pick a program and handle * the variables. * * @param {String} meshName Mesh internal name * @param {String} textureName Texture internal name */ class ShieldEffectDrawable extends TexturedDrawable { constructor(meshName, textureName) {
/** * Apply color effects to a single pixel * * @param {vec4} pixel Values in range [0,1] * @param {Object} effect * @param {vec4} effect.colorOffset * @param {mat4} effect.colorMatrix * @param {vec4} result Object to store result * * @memberof colorEffects */ function applyToPixel(pixel, effect, result) { vec4TransformMat4Transposed(result, pixel, effect.colorMatrix); vec4.add(result, result, effect.colorOffset); }
/** * Helper functions for color transformation {@link Effects}. * * References: * * - [ColorMatrix Guide](http://docs.rainmeter.net/tips/colormatrix-guide) * - [Matrix Operations for Image Processing](http://www.graficaobscura.com/matrix/index.html) * - [WebGLImageFilter](https://github.com/phoboslab/WebGLImageFilter) * - [glfx.js](https://github.com/evanw/glfx.js) * * @namespace colorEffects */ /** * A vector and matrix corresponding to an identity transformation. * * @param {Object} result Object to store result * @param {vec4} result.colorOffset Array with zeroes. * @param {mat4} result.colorMatrix Identity matrix. * * @memberof colorEffects */ function identity(resultArg) { var result = resultArg || {}; result.colorOffset = result.colorOffset || vec4.create(); result.colorMatrix = result.colorMatrix || mat4.create(); return result; }