XRPlanes.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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 geometry = new BoxGeometry();
  12. const matrix = new Matrix4();
  13. const currentPlanes = new Map();
  14. const xr = renderer.xr;
  15. xr.addEventListener( 'planesdetected', event => {
  16. const frame = event.data;
  17. const planes = frame.detectedPlanes;
  18. const referenceSpace = xr.getReferenceSpace();
  19. for ( const [ plane, mesh ] of currentPlanes ) {
  20. if ( planes.has( plane ) === false ) {
  21. mesh.material.dispose();
  22. this.remove( mesh );
  23. currentPlanes.delete( plane );
  24. }
  25. }
  26. for ( const plane of planes ) {
  27. if ( currentPlanes.has( plane ) === false ) {
  28. const pose = frame.getPose( plane.planeSpace, referenceSpace );
  29. matrix.fromArray( pose.transform.matrix );
  30. const polygon = plane.polygon;
  31. let minX = Number.MAX_SAFE_INTEGER;
  32. let maxX = Number.MIN_SAFE_INTEGER;
  33. let minZ = Number.MAX_SAFE_INTEGER;
  34. let maxZ = Number.MIN_SAFE_INTEGER;
  35. for ( const point of polygon ) {
  36. minX = Math.min( minX, point.x );
  37. maxX = Math.max( maxX, point.x );
  38. minZ = Math.min( minZ, point.z );
  39. maxZ = Math.max( maxZ, point.z );
  40. }
  41. const width = maxX - minX;
  42. const height = maxZ - minZ;
  43. const material = new MeshBasicMaterial( { color: 0xffffff * Math.random() } );
  44. const mesh = new Mesh( geometry, material );
  45. mesh.position.setFromMatrixPosition( matrix );
  46. mesh.quaternion.setFromRotationMatrix( matrix );
  47. mesh.scale.set( width, 0.01, height );
  48. this.add( mesh );
  49. currentPlanes.set( plane, mesh );
  50. }
  51. }
  52. } );
  53. }
  54. }
  55. export { XRPlanes };