collisionCoordinator.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import { Nullable } from "../types";
  2. import { Scene } from "../scene";
  3. import { Vector3 } from "../Maths/math";
  4. import { Engine } from "../Engines/engine";
  5. import { Collider } from "./collider";
  6. import { Geometry } from "../Meshes/geometry";
  7. import { AbstractMesh } from "../Meshes/abstractMesh";
  8. /** @hidden */
  9. export interface ICollisionCoordinator {
  10. getNewPosition(position: Vector3, displacement: Vector3, collider: Collider, maximumRetry: number, excludedMesh: Nullable<AbstractMesh>, onNewPosition: (collisionIndex: number, newPosition: Vector3, collidedMesh: Nullable<AbstractMesh>) => void, collisionIndex: number): void;
  11. init(scene: Scene): void;
  12. destroy(): void;
  13. //Update meshes and geometries
  14. onMeshAdded(mesh: AbstractMesh): void;
  15. onMeshUpdated(mesh: AbstractMesh): void;
  16. onMeshRemoved(mesh: AbstractMesh): void;
  17. onGeometryAdded(geometry: Geometry): void;
  18. onGeometryUpdated(geometry: Geometry): void;
  19. onGeometryDeleted(geometry: Geometry): void;
  20. }
  21. /** @hidden */
  22. export class CollisionCoordinatorLegacy implements ICollisionCoordinator {
  23. private _scene: Scene;
  24. private _scaledPosition = Vector3.Zero();
  25. private _scaledVelocity = Vector3.Zero();
  26. private _finalPosition = Vector3.Zero();
  27. public getNewPosition(position: Vector3, displacement: Vector3, collider: Collider, maximumRetry: number, excludedMesh: AbstractMesh, onNewPosition: (collisionIndex: number, newPosition: Vector3, collidedMesh: Nullable<AbstractMesh>) => void, collisionIndex: number): void {
  28. position.divideToRef(collider._radius, this._scaledPosition);
  29. displacement.divideToRef(collider._radius, this._scaledVelocity);
  30. collider.collidedMesh = null;
  31. collider._retry = 0;
  32. collider._initialVelocity = this._scaledVelocity;
  33. collider._initialPosition = this._scaledPosition;
  34. this._collideWithWorld(this._scaledPosition, this._scaledVelocity, collider, maximumRetry, this._finalPosition, excludedMesh);
  35. this._finalPosition.multiplyInPlace(collider._radius);
  36. //run the callback
  37. onNewPosition(collisionIndex, this._finalPosition, collider.collidedMesh);
  38. }
  39. public init(scene: Scene): void {
  40. this._scene = scene;
  41. }
  42. public destroy(): void {
  43. //Legacy need no destruction method.
  44. }
  45. //No update in legacy mode
  46. public onMeshAdded(mesh: AbstractMesh) { }
  47. public onMeshUpdated(mesh: AbstractMesh) { }
  48. public onMeshRemoved(mesh: AbstractMesh) { }
  49. public onGeometryAdded(geometry: Geometry) { }
  50. public onGeometryUpdated(geometry: Geometry) { }
  51. public onGeometryDeleted(geometry: Geometry) { }
  52. private _collideWithWorld(position: Vector3, velocity: Vector3, collider: Collider, maximumRetry: number, finalPosition: Vector3, excludedMesh: Nullable<AbstractMesh> = null): void {
  53. var closeDistance = Engine.CollisionsEpsilon * 10.0;
  54. if (collider._retry >= maximumRetry) {
  55. finalPosition.copyFrom(position);
  56. return;
  57. }
  58. // Check if this is a mesh else camera or -1
  59. var collisionMask = (excludedMesh ? excludedMesh.collisionMask : collider.collisionMask);
  60. collider._initialize(position, velocity, closeDistance);
  61. // Check all meshes
  62. for (var index = 0; index < this._scene.meshes.length; index++) {
  63. var mesh = this._scene.meshes[index];
  64. if (mesh.isEnabled() && mesh.checkCollisions && mesh.subMeshes && mesh !== excludedMesh && ((collisionMask & mesh.collisionGroup) !== 0)) {
  65. mesh._checkCollision(collider);
  66. }
  67. }
  68. if (!collider.collisionFound) {
  69. position.addToRef(velocity, finalPosition);
  70. return;
  71. }
  72. if (velocity.x !== 0 || velocity.y !== 0 || velocity.z !== 0) {
  73. collider._getResponse(position, velocity);
  74. }
  75. if (velocity.length() <= closeDistance) {
  76. finalPosition.copyFrom(position);
  77. return;
  78. }
  79. collider._retry++;
  80. this._collideWithWorld(position, velocity, collider, maximumRetry, finalPosition, excludedMesh);
  81. }
  82. }