Frustum.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import * as THREE from '../../../build/three.module.js';
  2. import FrustumVertex from './FrustumVertex.js';
  3. import {toRad} from './Utils.js';
  4. export default class Frustum {
  5. constructor(data) {
  6. data = data || {};
  7. this.fov = data.fov || 70;
  8. this.near = data.near || 0.1;
  9. this.far = data.far || 1000;
  10. this.aspect = data.aspect || 1;
  11. this.vertices = {
  12. near: [],
  13. far: []
  14. };
  15. }
  16. getViewSpaceVertices() {
  17. this.nearPlaneY = this.near * Math.tan(toRad(this.fov / 2));
  18. this.nearPlaneX = this.aspect * this.nearPlaneY;
  19. this.farPlaneY = this.far * Math.tan(toRad(this.fov / 2));
  20. this.farPlaneX = this.aspect * this.farPlaneY;
  21. // 3 --- 0 vertices.near/far order
  22. // | |
  23. // 2 --- 1
  24. this.vertices.near.push(
  25. new FrustumVertex(this.nearPlaneX, this.nearPlaneY, -this.near),
  26. new FrustumVertex(this.nearPlaneX, -this.nearPlaneY, -this.near),
  27. new FrustumVertex(-this.nearPlaneX, -this.nearPlaneY, -this.near),
  28. new FrustumVertex(-this.nearPlaneX, this.nearPlaneY, -this.near)
  29. );
  30. this.vertices.far.push(
  31. new FrustumVertex(this.farPlaneX, this.farPlaneY, -this.far),
  32. new FrustumVertex(this.farPlaneX, -this.farPlaneY, -this.far),
  33. new FrustumVertex(-this.farPlaneX, -this.farPlaneY, -this.far),
  34. new FrustumVertex(-this.farPlaneX, this.farPlaneY, -this.far)
  35. );
  36. return this.vertices;
  37. }
  38. split(breaks) {
  39. const result = [];
  40. for(let i = 0; i < breaks.length; i++) {
  41. const cascade = new Frustum();
  42. if(i === 0) {
  43. cascade.vertices.near = this.vertices.near;
  44. } else {
  45. for(let j = 0; j < 4; j++) {
  46. cascade.vertices.near.push(new FrustumVertex().fromLerp(this.vertices.near[j], this.vertices.far[j], breaks[i - 1]));
  47. }
  48. }
  49. if(i === breaks - 1) {
  50. cascade.vertices.far = this.vertices.far;
  51. } else {
  52. for(let j = 0; j < 4; j++) {
  53. cascade.vertices.far.push(new FrustumVertex().fromLerp(this.vertices.near[j], this.vertices.far[j], breaks[i]))
  54. }
  55. }
  56. result.push(cascade);
  57. }
  58. return result;
  59. }
  60. toSpace(cameraMatrix) {
  61. const result = new Frustum();
  62. const point = new THREE.Vector3();
  63. for(var i = 0; i < 4; i++) {
  64. point.set(this.vertices.near[i].x, this.vertices.near[i].y, this.vertices.near[i].z);
  65. point.applyMatrix4(cameraMatrix);
  66. result.vertices.near.push(new FrustumVertex(point.x, point.y, point.z));
  67. point.set(this.vertices.far[i].x, this.vertices.far[i].y, this.vertices.far[i].z);
  68. point.applyMatrix4(cameraMatrix);
  69. result.vertices.far.push(new FrustumVertex(point.x, point.y, point.z));
  70. }
  71. return result;
  72. }
  73. }