spherePanel.ts 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import { VolumeBasedPanel } from "./volumeBasedPanel";
  2. import { float, Tools, Vector3, Matrix, Tmp, Axis, Space } from "babylonjs";
  3. import { Control3D } from "./control3D";
  4. import { Container3D } from "./container3D";
  5. /**
  6. * Class used to create a container panel deployed on the surface of a sphere
  7. */
  8. export class SpherePanel extends VolumeBasedPanel {
  9. private _radius = 5.0;
  10. /**
  11. * Gets or sets the radius of the sphere where to project controls (5 by default)
  12. */
  13. public get radius(): float {
  14. return this._radius;
  15. }
  16. public set radius(value: float) {
  17. if (this._radius === value) {
  18. return;
  19. }
  20. this._radius = value;
  21. Tools.SetImmediate(() => {
  22. this._arrangeChildren();
  23. });
  24. }
  25. protected _mapGridNode(control: Control3D, nodePosition: Vector3) {
  26. let mesh = control.mesh;
  27. if (!mesh) {
  28. return;
  29. }
  30. let newPos = this._sphericalMapping(nodePosition);
  31. control.position = newPos;
  32. switch (this.orientation) {
  33. case Container3D.FACEORIGIN_ORIENTATION:
  34. mesh.lookAt(new Vector3(-newPos.x, -newPos.y, -newPos.z));
  35. break;
  36. case Container3D.FACEORIGINREVERSED_ORIENTATION:
  37. mesh.lookAt(new Vector3(2 * newPos.x, 2 * newPos.y, 2 * newPos.z));
  38. break;
  39. case Container3D.FACEFORWARD_ORIENTATION:
  40. break;
  41. case Container3D.FACEFORWARDREVERSED_ORIENTATION:
  42. mesh.rotate(Axis.Y, Math.PI, Space.LOCAL);
  43. break;
  44. }
  45. }
  46. private _sphericalMapping(source: Vector3) {
  47. let newPos = new Vector3(0, 0, this._radius);
  48. let xAngle = (source.y / this._radius);
  49. let yAngle = -(source.x / this._radius);
  50. Matrix.RotationYawPitchRollToRef(yAngle, xAngle, 0, Tmp.Matrix[0]);
  51. return Vector3.TransformNormal(newPos, Tmp.Matrix[0]);
  52. }
  53. }