cylinderPanel.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import { VolumeBasedPanel } from "./volumeBasedPanel";
  2. import { float, Tools, Vector3, Matrix, Tmp } 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 cylinder
  7. */
  8. export class CylinderPanel extends VolumeBasedPanel {
  9. private _radius = 5.0;
  10. /**
  11. * Gets or sets the radius of the cylinder 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._cylindricalMapping(nodePosition);
  31. control.position = newPos;
  32. switch (this.orientation) {
  33. case Container3D.FACEORIGIN_ORIENTATION:
  34. mesh.lookAt(new BABYLON.Vector3(2 * newPos.x, newPos.y, 2 * newPos.z));
  35. break;
  36. case Container3D.FACEORIGINREVERSED_ORIENTATION:
  37. mesh.lookAt(new BABYLON.Vector3(-newPos.x, newPos.y, -newPos.z));
  38. break;
  39. case Container3D.FACEFORWARD_ORIENTATION:
  40. break;
  41. case Container3D.FACEFORWARDREVERSED_ORIENTATION:
  42. mesh.rotate(BABYLON.Axis.Y, Math.PI, BABYLON.Space.LOCAL);
  43. break;
  44. }
  45. }
  46. private _cylindricalMapping(source: Vector3) {
  47. let newPos = new Vector3(0, source.y, this._radius);
  48. let yAngle = (source.x / this._radius);
  49. Matrix.RotationYawPitchRollToRef(yAngle, 0, 0, Tmp.Matrix[0]);
  50. return Vector3.TransformNormal(newPos, Tmp.Matrix[0]);
  51. }
  52. }