3d-tiles-renderer
Version:
https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/specification
95 lines (64 loc) • 2.42 kB
JavaScript
import { Matrix4, Ray, Vector3 } from 'three';
const _matrix = /* @__PURE__ */ new Matrix4();
const _vec = /* @__PURE__ */ new Vector3();
// helper function for constructing a matrix for rotating around a point
export function makeRotateAroundPoint( point, quat, target ) {
target.makeTranslation( - point.x, - point.y, - point.z );
_matrix.makeRotationFromQuaternion( quat );
target.premultiply( _matrix );
_matrix.makeTranslation( point.x, point.y, point.z );
target.premultiply( _matrix );
return target;
}
// get the three.js pointer coords from an event
export function mouseToCoords( clientX, clientY, element, target ) {
target.x = ( ( clientX - element.offsetLeft ) / element.clientWidth ) * 2 - 1;
target.y = - ( ( clientY - element.offsetTop ) / element.clientHeight ) * 2 + 1;
if ( target.isVector3 ) {
target.z = 0;
}
}
// find the closest ray on the horizon when the ray passes above the sphere
export function closestRaySpherePointFromRotation( ray, radius, target ) {
const hypotenuse = ray.origin.length();
// angle inside the sphere
const theta = Math.acos( radius / hypotenuse );
// the direction to the camera
target
.copy( ray.origin )
.multiplyScalar( - 1 )
.normalize();
// get the normal of the plane the ray and origin lie in
const rotationVec = _vec
.crossVectors( target, ray.direction )
.normalize();
// rotate the camera direction by angle and scale it to the surface
target
.multiplyScalar( - 1 )
.applyAxisAngle( rotationVec, - theta )
.normalize()
.multiplyScalar( radius );
}
// custom version of set raycaster from camera that relies on the underlying matrices
// so the ray origin is position at the camera near clip.
export function setRaycasterFromCamera( raycaster, coords, camera ) {
const ray = raycaster instanceof Ray ? raycaster : raycaster.ray;
const { origin, direction } = ray;
// get the origin and direction of the frustum ray
origin
.set( coords.x, coords.y, - 1 )
.unproject( camera );
direction
.set( coords.x, coords.y, 1 )
.unproject( camera )
.sub( origin );
if ( ! raycaster.isRay ) {
// compute the far value based on the distance from point on the near
// plane and point on the far plane. Then normalize the direction.
raycaster.near = 0;
raycaster.far = direction.length();
raycaster.camera = camera;
}
// normalize the ray direction
direction.normalize();
}