XRPlanes.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import {
  2. BoxGeometry,
  3. Matrix4,
  4. Mesh,
  5. MeshBasicMaterial,
  6. Object3D
  7. } from 'three';
  8. class XRPlanes extends Object3D {
  9. constructor( renderer ) {
  10. super();
  11. const matrix = new Matrix4();
  12. const currentPlanes = new Map();
  13. const xr = renderer.xr;
  14. xr.addEventListener( 'planesdetected', event => {
  15. const frame = event.data;
  16. const planes = frame.detectedPlanes;
  17. const referenceSpace = xr.getReferenceSpace();
  18. let planeschanged = false;
  19. for ( const [ plane, mesh ] of currentPlanes ) {
  20. if ( planes.has( plane ) === false ) {
  21. mesh.geometry.dispose();
  22. mesh.material.dispose();
  23. this.remove( mesh );
  24. currentPlanes.delete( plane );
  25. planeschanged = true;
  26. }
  27. }
  28. for ( const plane of planes ) {
  29. if ( currentPlanes.has( plane ) === false ) {
  30. const pose = frame.getPose( plane.planeSpace, referenceSpace );
  31. matrix.fromArray( pose.transform.matrix );
  32. const polygon = plane.polygon;
  33. let minX = Number.MAX_SAFE_INTEGER;
  34. let maxX = Number.MIN_SAFE_INTEGER;
  35. let minZ = Number.MAX_SAFE_INTEGER;
  36. let maxZ = Number.MIN_SAFE_INTEGER;
  37. for ( const point of polygon ) {
  38. minX = Math.min( minX, point.x );
  39. maxX = Math.max( maxX, point.x );
  40. minZ = Math.min( minZ, point.z );
  41. maxZ = Math.max( maxZ, point.z );
  42. }
  43. const width = maxX - minX;
  44. const height = maxZ - minZ;
  45. const geometry = new BoxGeometry( width, 0.01, height );
  46. const material = new MeshBasicMaterial( { color: 0xffffff * Math.random() } );
  47. const mesh = new Mesh( geometry, material );
  48. mesh.position.setFromMatrixPosition( matrix );
  49. mesh.quaternion.setFromRotationMatrix( matrix );
  50. this.add( mesh );
  51. currentPlanes.set( plane, mesh );
  52. planeschanged = true;
  53. }
  54. }
  55. if ( planeschanged ) {
  56. this.dispatchEvent( { type: 'planeschanged' } );
  57. }
  58. } );
  59. }
  60. }
  61. export { XRPlanes };