starry / backend /libs /three /helpers /CameraHelper.js
k-l-lambda's picture
feat: add Python ML services (CPU mode) with model download
2b7aae2
import { Camera } from '../cameras/Camera.js';
import { Vector3 } from '../math/Vector3.js';
import { LineSegments } from '../objects/LineSegments.js';
import { Color } from '../math/Color.js';
import { LineBasicMaterial } from '../materials/LineBasicMaterial.js';
import { BufferGeometry } from '../core/BufferGeometry.js';
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
const _vector = /*@__PURE__*/ new Vector3();
const _camera = /*@__PURE__*/ new Camera();
/**
* - shows frustum, line of sight and up of the camera
* - suitable for fast updates
* - based on frustum visualization in lightgl.js shadowmap example
* https://github.com/evanw/lightgl.js/blob/master/tests/shadowmap.html
*/
class CameraHelper extends LineSegments {
constructor(camera) {
const geometry = new BufferGeometry();
const material = new LineBasicMaterial({ color: 0xffffff, vertexColors: true, toneMapped: false });
const vertices = [];
const colors = [];
const pointMap = {};
// colors
const colorFrustum = new Color(0xffaa00);
const colorCone = new Color(0xff0000);
const colorUp = new Color(0x00aaff);
const colorTarget = new Color(0xffffff);
const colorCross = new Color(0x333333);
// near
addLine('n1', 'n2', colorFrustum);
addLine('n2', 'n4', colorFrustum);
addLine('n4', 'n3', colorFrustum);
addLine('n3', 'n1', colorFrustum);
// far
addLine('f1', 'f2', colorFrustum);
addLine('f2', 'f4', colorFrustum);
addLine('f4', 'f3', colorFrustum);
addLine('f3', 'f1', colorFrustum);
// sides
addLine('n1', 'f1', colorFrustum);
addLine('n2', 'f2', colorFrustum);
addLine('n3', 'f3', colorFrustum);
addLine('n4', 'f4', colorFrustum);
// cone
addLine('p', 'n1', colorCone);
addLine('p', 'n2', colorCone);
addLine('p', 'n3', colorCone);
addLine('p', 'n4', colorCone);
// up
addLine('u1', 'u2', colorUp);
addLine('u2', 'u3', colorUp);
addLine('u3', 'u1', colorUp);
// target
addLine('c', 't', colorTarget);
addLine('p', 'c', colorCross);
// cross
addLine('cn1', 'cn2', colorCross);
addLine('cn3', 'cn4', colorCross);
addLine('cf1', 'cf2', colorCross);
addLine('cf3', 'cf4', colorCross);
function addLine(a, b, color) {
addPoint(a, color);
addPoint(b, color);
}
function addPoint(id, color) {
vertices.push(0, 0, 0);
colors.push(color.r, color.g, color.b);
if (pointMap[id] === undefined) {
pointMap[id] = [];
}
pointMap[id].push(vertices.length / 3 - 1);
}
geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
geometry.setAttribute('color', new Float32BufferAttribute(colors, 3));
super(geometry, material);
this.type = 'CameraHelper';
this.camera = camera;
if (this.camera.updateProjectionMatrix) this.camera.updateProjectionMatrix();
this.matrix = camera.matrixWorld;
this.matrixAutoUpdate = false;
this.pointMap = pointMap;
this.update();
}
update() {
const geometry = this.geometry;
const pointMap = this.pointMap;
const w = 1,
h = 1;
// we need just camera projection matrix inverse
// world matrix must be identity
_camera.projectionMatrixInverse.copy(this.camera.projectionMatrixInverse);
// center / target
setPoint('c', pointMap, geometry, _camera, 0, 0, -1);
setPoint('t', pointMap, geometry, _camera, 0, 0, 1);
// near
setPoint('n1', pointMap, geometry, _camera, -w, -h, -1);
setPoint('n2', pointMap, geometry, _camera, w, -h, -1);
setPoint('n3', pointMap, geometry, _camera, -w, h, -1);
setPoint('n4', pointMap, geometry, _camera, w, h, -1);
// far
setPoint('f1', pointMap, geometry, _camera, -w, -h, 1);
setPoint('f2', pointMap, geometry, _camera, w, -h, 1);
setPoint('f3', pointMap, geometry, _camera, -w, h, 1);
setPoint('f4', pointMap, geometry, _camera, w, h, 1);
// up
setPoint('u1', pointMap, geometry, _camera, w * 0.7, h * 1.1, -1);
setPoint('u2', pointMap, geometry, _camera, -w * 0.7, h * 1.1, -1);
setPoint('u3', pointMap, geometry, _camera, 0, h * 2, -1);
// cross
setPoint('cf1', pointMap, geometry, _camera, -w, 0, 1);
setPoint('cf2', pointMap, geometry, _camera, w, 0, 1);
setPoint('cf3', pointMap, geometry, _camera, 0, -h, 1);
setPoint('cf4', pointMap, geometry, _camera, 0, h, 1);
setPoint('cn1', pointMap, geometry, _camera, -w, 0, -1);
setPoint('cn2', pointMap, geometry, _camera, w, 0, -1);
setPoint('cn3', pointMap, geometry, _camera, 0, -h, -1);
setPoint('cn4', pointMap, geometry, _camera, 0, h, -1);
geometry.getAttribute('position').needsUpdate = true;
}
dispose() {
this.geometry.dispose();
this.material.dispose();
}
}
function setPoint(point, pointMap, geometry, camera, x, y, z) {
_vector.set(x, y, z).unproject(camera);
const points = pointMap[point];
if (points !== undefined) {
const position = geometry.getAttribute('position');
for (let i = 0, l = points.length; i < l; i++) {
position.setXYZ(points[i], _vector.x, _vector.y, _vector.z);
}
}
}
export { CameraHelper };