physicsConstraint.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. import { PhysicsConstraintAxis, PhysicsConstraintType } from "./IPhysicsEnginePlugin.js";
  2. /**
  3. * This is a holder class for the physics constraint created by the physics plugin
  4. * It holds a set of functions to control the underlying constraint
  5. * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine
  6. */
  7. export class PhysicsConstraint {
  8. /**
  9. * Constructs a new constraint for the physics constraint.
  10. * @param type The type of constraint to create.
  11. * @param options The options for the constraint.
  12. * @param scene The scene the constraint belongs to.
  13. *
  14. * This code is useful for creating a new constraint for the physics engine. It checks if the scene has a physics engine, and if the plugin version is correct.
  15. * If all checks pass, it initializes the constraint with the given type and options.
  16. */
  17. constructor(type, options, scene) {
  18. /**
  19. * V2 Physics plugin private data for a physics material
  20. */
  21. this._pluginData = undefined;
  22. if (!scene) {
  23. throw new Error("Missing scene parameter for constraint constructor.");
  24. }
  25. const physicsEngine = scene.getPhysicsEngine();
  26. if (!physicsEngine) {
  27. throw new Error("No Physics Engine available.");
  28. }
  29. if (physicsEngine.getPluginVersion() != 2) {
  30. throw new Error("Plugin version is incorrect. Expected version 2.");
  31. }
  32. const physicsPlugin = physicsEngine.getPhysicsPlugin();
  33. if (!physicsPlugin) {
  34. throw new Error("No Physics Plugin available.");
  35. }
  36. this._physicsPlugin = physicsPlugin;
  37. this._options = options;
  38. this._type = type;
  39. }
  40. /**
  41. * Gets the type of the constraint.
  42. *
  43. * @returns The type of the constraint.
  44. *
  45. */
  46. get type() {
  47. return this._type;
  48. }
  49. /**
  50. * Retrieves the options of the physics constraint.
  51. *
  52. * @returns The physics constraint parameters.
  53. *
  54. */
  55. get options() {
  56. return this._options;
  57. }
  58. /**
  59. * Enable/disable the constraint
  60. * @param isEnabled value for the constraint
  61. */
  62. set isEnabled(isEnabled) {
  63. this._physicsPlugin.setEnabled(this, isEnabled);
  64. }
  65. /**
  66. *
  67. * @returns true if constraint is enabled
  68. */
  69. get isEnabled() {
  70. return this._physicsPlugin.getEnabled(this);
  71. }
  72. /**
  73. * Enables or disables collisions for the physics engine.
  74. *
  75. * @param isEnabled - A boolean value indicating whether collisions should be enabled or disabled.
  76. *
  77. */
  78. set isCollisionsEnabled(isEnabled) {
  79. this._physicsPlugin.setCollisionsEnabled(this, isEnabled);
  80. }
  81. /**
  82. * Gets whether collisions are enabled for this physics object.
  83. *
  84. * @returns `true` if collisions are enabled, `false` otherwise.
  85. *
  86. */
  87. get isCollisionsEnabled() {
  88. return this._physicsPlugin.getCollisionsEnabled(this);
  89. }
  90. /**
  91. * Gets all bodies that are using this constraint
  92. * @returns
  93. */
  94. getBodiesUsingConstraint() {
  95. return this._physicsPlugin.getBodiesUsingConstraint(this);
  96. }
  97. /**
  98. * Disposes the constraint from the physics engine.
  99. *
  100. * This method is useful for cleaning up the physics engine when a body is no longer needed. Disposing the body will free up resources and prevent memory leaks.
  101. */
  102. dispose() {
  103. this._physicsPlugin.disposeConstraint(this);
  104. }
  105. }
  106. /**
  107. * This describes a single limit used by Physics6DoFConstraint
  108. */
  109. export class Physics6DoFLimit {
  110. }
  111. /**
  112. * A generic constraint, which can be used to build more complex constraints than those specified
  113. * in PhysicsConstraintType. The axis and pivot options in PhysicsConstraintParameters define the space
  114. * the constraint operates in. This constraint contains a set of limits, which restrict the
  115. * relative movement of the bodies in that coordinate system
  116. */
  117. export class Physics6DoFConstraint extends PhysicsConstraint {
  118. constructor(constraintParams, limits, scene) {
  119. super(PhysicsConstraintType.SIX_DOF, constraintParams, scene);
  120. this.limits = limits;
  121. }
  122. /**
  123. * Sets the friction of the given axis of the physics engine.
  124. * @param axis - The axis of the physics engine to set the friction for.
  125. * @param friction - The friction to set for the given axis.
  126. *
  127. */
  128. setAxisFriction(axis, friction) {
  129. this._physicsPlugin.setAxisFriction(this, axis, friction);
  130. }
  131. /**
  132. * Gets the friction of the given axis of the physics engine.
  133. * @param axis - The axis of the physics engine.
  134. * @returns The friction of the given axis, or null if the constraint hasn't been initialized yet.
  135. *
  136. */
  137. getAxisFriction(axis) {
  138. return this._physicsPlugin.getAxisFriction(this, axis);
  139. }
  140. /**
  141. * Sets the limit mode for the given axis of the constraint.
  142. * @param axis The axis to set the limit mode for.
  143. * @param limitMode The limit mode to set.
  144. *
  145. * This method is useful for setting the limit mode for a given axis of the constraint. This is important for
  146. * controlling the behavior of the physics engine when the constraint is reached. By setting the limit mode,
  147. * the engine can be configured to either stop the motion of the objects, or to allow them to continue
  148. * moving beyond the constraint.
  149. */
  150. setAxisMode(axis, limitMode) {
  151. this._physicsPlugin.setAxisMode(this, axis, limitMode);
  152. }
  153. /**
  154. * Gets the limit mode of the given axis of the constraint.
  155. *
  156. * @param axis - The axis of the constraint.
  157. * @returns The limit mode of the given axis, or null if the constraint hasn't been initialized yet.
  158. *
  159. */
  160. getAxisMode(axis) {
  161. return this._physicsPlugin.getAxisMode(this, axis);
  162. }
  163. /**
  164. * Sets the minimum limit of a given axis of a constraint.
  165. * @param axis - The axis of the constraint.
  166. * @param minLimit - The minimum limit of the axis.
  167. *
  168. */
  169. setAxisMinLimit(axis, minLimit) {
  170. this._physicsPlugin.setAxisMinLimit(this, axis, minLimit);
  171. }
  172. /**
  173. * Gets the minimum limit of the given axis of the physics engine.
  174. * @param axis - The axis of the physics engine.
  175. * @returns The minimum limit of the given axis, or null if the constraint hasn't been initialized yet.
  176. *
  177. */
  178. getAxisMinLimit(axis) {
  179. return this._physicsPlugin.getAxisMinLimit(this, axis);
  180. }
  181. /**
  182. * Sets the maximum limit of the given axis for the physics engine.
  183. * @param axis - The axis to set the limit for.
  184. * @param limit - The maximum limit of the axis.
  185. *
  186. * This method is useful for setting the maximum limit of the given axis for the physics engine,
  187. * which can be used to control the movement of the physics object. This helps to ensure that the
  188. * physics object does not move beyond the given limit.
  189. */
  190. setAxisMaxLimit(axis, limit) {
  191. this._physicsPlugin.setAxisMaxLimit(this, axis, limit);
  192. }
  193. /**
  194. * Gets the maximum limit of the given axis of the physics engine.
  195. * @param axis - The axis of the physics engine.
  196. * @returns The maximum limit of the given axis, or null if the constraint hasn't been initialized yet.
  197. *
  198. */
  199. getAxisMaxLimit(axis) {
  200. return this._physicsPlugin.getAxisMaxLimit(this, axis);
  201. }
  202. /**
  203. * Sets the motor type of the given axis of the constraint.
  204. * @param axis - The axis of the constraint.
  205. * @param motorType - The type of motor to use.
  206. */
  207. setAxisMotorType(axis, motorType) {
  208. this._physicsPlugin.setAxisMotorType(this, axis, motorType);
  209. }
  210. /**
  211. * Gets the motor type of the specified axis of the constraint.
  212. *
  213. * @param axis - The axis of the constraint.
  214. * @returns The motor type of the specified axis, or null if the constraint hasn't been initialized yet.
  215. *
  216. */
  217. getAxisMotorType(axis) {
  218. return this._physicsPlugin.getAxisMotorType(this, axis);
  219. }
  220. /**
  221. * Sets the target velocity of the motor associated with the given axis of the constraint.
  222. * @param axis - The axis of the constraint.
  223. * @param target - The target velocity of the motor.
  224. *
  225. * This method is useful for setting the target velocity of the motor associated with the given axis of the constraint.
  226. */
  227. setAxisMotorTarget(axis, target) {
  228. this._physicsPlugin.setAxisMotorTarget(this, axis, target);
  229. }
  230. /**
  231. * Gets the target velocity of the motor associated to the given constraint axis.
  232. * @param axis - The constraint axis associated to the motor.
  233. * @returns The target velocity of the motor, or null if the constraint hasn't been initialized yet.
  234. *
  235. */
  236. getAxisMotorTarget(axis) {
  237. return this._physicsPlugin.getAxisMotorTarget(this, axis);
  238. }
  239. /**
  240. * Sets the maximum force of the motor of the given axis of the constraint.
  241. * @param axis - The axis of the constraint.
  242. * @param maxForce - The maximum force of the motor.
  243. *
  244. */
  245. setAxisMotorMaxForce(axis, maxForce) {
  246. this._physicsPlugin.setAxisMotorMaxForce(this, axis, maxForce);
  247. }
  248. /**
  249. * Gets the maximum force of the motor of the given axis of the constraint.
  250. * @param axis - The axis of the constraint.
  251. * @returns The maximum force of the motor, or null if the constraint hasn't been initialized yet.
  252. *
  253. */
  254. getAxisMotorMaxForce(axis) {
  255. return this._physicsPlugin.getAxisMotorMaxForce(this, axis);
  256. }
  257. }
  258. /**
  259. * Represents a Ball and Socket Constraint, used to simulate a joint
  260. *
  261. * @param pivotA - The first pivot, defined locally in the first body frame
  262. * @param pivotB - The second pivot, defined locally in the second body frame
  263. * @param axisA - The axis of the first body
  264. * @param axisB - The axis of the second body
  265. * @param scene - The scene the constraint is applied to
  266. * @returns The Ball and Socket Constraint
  267. *
  268. * This class is useful for simulating a joint between two bodies in a physics engine.
  269. * It allows for the two bodies to move relative to each other in a way that mimics a ball and socket joint, such as a shoulder or hip joint.
  270. */
  271. export class BallAndSocketConstraint extends PhysicsConstraint {
  272. constructor(pivotA, pivotB, axisA, axisB, scene) {
  273. super(PhysicsConstraintType.BALL_AND_SOCKET, { pivotA: pivotA, pivotB: pivotB, axisA: axisA, axisB: axisB }, scene);
  274. }
  275. }
  276. /**
  277. * Creates a distance constraint.
  278. * @param maxDistance distance between bodies
  279. * @param scene The scene the constraint belongs to
  280. * @returns DistanceConstraint
  281. *
  282. * This code is useful for creating a distance constraint in a physics engine.
  283. * A distance constraint is a type of constraint that keeps two objects at a certain distance from each other.
  284. * The scene is used to add the constraint to the physics engine.
  285. */
  286. export class DistanceConstraint extends PhysicsConstraint {
  287. constructor(maxDistance, scene) {
  288. super(PhysicsConstraintType.DISTANCE, { maxDistance: maxDistance }, scene);
  289. }
  290. }
  291. /**
  292. * Creates a HingeConstraint, which is a type of PhysicsConstraint.
  293. *
  294. * @param pivotA - The first pivot point, in world space.
  295. * @param pivotB - The second pivot point, in world space.
  296. * @param scene - The scene the constraint is used in.
  297. * @returns The new HingeConstraint.
  298. *
  299. * This code is useful for creating a HingeConstraint, which is a type of PhysicsConstraint.
  300. * This constraint is used to simulate a hinge joint between two rigid bodies, allowing them to rotate around a single axis.
  301. */
  302. export class HingeConstraint extends PhysicsConstraint {
  303. constructor(pivotA, pivotB, axisA, axisB, scene) {
  304. super(PhysicsConstraintType.HINGE, { pivotA: pivotA, pivotB: pivotB, axisA: axisA, axisB: axisB }, scene);
  305. }
  306. }
  307. /**
  308. * Creates a SliderConstraint, which is a type of PhysicsConstraint.
  309. *
  310. * @param pivotA - The first pivot of the constraint, in world space.
  311. * @param pivotB - The second pivot of the constraint, in world space.
  312. * @param axisA - The first axis of the constraint, in world space.
  313. * @param axisB - The second axis of the constraint, in world space.
  314. * @param scene - The scene the constraint belongs to.
  315. * @returns The created SliderConstraint.
  316. *
  317. * This code is useful for creating a SliderConstraint, which is a type of PhysicsConstraint.
  318. * It allows the user to specify the two pivots and two axes of the constraint in world space, as well as the scene the constraint belongs to.
  319. * This is useful for creating a constraint between two rigid bodies that allows them to move along a certain axis.
  320. */
  321. export class SliderConstraint extends PhysicsConstraint {
  322. constructor(pivotA, pivotB, axisA, axisB, scene) {
  323. super(PhysicsConstraintType.SLIDER, { pivotA: pivotA, pivotB: pivotB, axisA: axisA, axisB: axisB }, scene);
  324. }
  325. }
  326. /**
  327. * Creates a LockConstraint, which is a type of PhysicsConstraint.
  328. *
  329. * @param pivotA - The first pivot of the constraint in local space.
  330. * @param pivotB - The second pivot of the constraint in local space.
  331. * @param axisA - The first axis of the constraint in local space.
  332. * @param axisB - The second axis of the constraint in local space.
  333. * @param scene - The scene the constraint belongs to.
  334. * @returns The created LockConstraint.
  335. *
  336. * This code is useful for creating a LockConstraint, which is a type of PhysicsConstraint.
  337. * It takes in two pivots and two axes in local space, as well as the scene the constraint belongs to, and creates a LockConstraint.
  338. */
  339. export class LockConstraint extends PhysicsConstraint {
  340. constructor(pivotA, pivotB, axisA, axisB, scene) {
  341. super(PhysicsConstraintType.LOCK, { pivotA: pivotA, pivotB: pivotB, axisA: axisA, axisB: axisB }, scene);
  342. }
  343. }
  344. /**
  345. * Creates a PrismaticConstraint, which is a type of PhysicsConstraint.
  346. *
  347. * @param pivotA - The first pivot of the constraint in local space.
  348. * @param pivotB - The second pivot of the constraint in local space.
  349. * @param axisA - The first axis of the constraint in local space.
  350. * @param axisB - The second axis of the constraint in local space.
  351. * @param scene - The scene the constraint belongs to.
  352. * @returns The created LockConstraint.
  353. *
  354. * This code is useful for creating a PrismaticConstraint, which is a type of PhysicsConstraint.
  355. * It takes in two pivots and two axes in local space, as well as the scene the constraint belongs to, and creates a PrismaticConstraint.
  356. */
  357. export class PrismaticConstraint extends PhysicsConstraint {
  358. constructor(pivotA, pivotB, axisA, axisB, scene) {
  359. super(PhysicsConstraintType.PRISMATIC, { pivotA: pivotA, pivotB: pivotB, axisA: axisA, axisB: axisB }, scene);
  360. }
  361. }
  362. /**
  363. * Creates a SpringConstraint, which is a type of Physics6DoFConstraint. This constraint applies a force at the ends which is proportional
  364. * to the distance between ends, and a stiffness and damping factor. The force is calculated as (stiffness * positionError) - (damping * velocity)
  365. *
  366. * @param pivotA - The first pivot of the constraint in local space.
  367. * @param pivotB - The second pivot of the constraint in local space.
  368. * @param axisA - The first axis of the constraint in local space.
  369. * @param axisB - The second axis of the constraint in local space.
  370. * @param minDistance - The minimum distance between the two pivots.
  371. * @param maxDistance - The maximum distance between the two pivots.
  372. * @param stiffness - The stiffness of the spring.
  373. * @param damping - The damping of the spring.
  374. * @param scene - The scene the constraint belongs to.
  375. * @returns The created SpringConstraint.
  376. */
  377. export class SpringConstraint extends Physics6DoFConstraint {
  378. constructor(pivotA, pivotB, axisA, axisB, minDistance, maxDistance, stiffness, damping, scene) {
  379. super({ pivotA, pivotB, axisA, axisB }, [{ axis: PhysicsConstraintAxis.LINEAR_DISTANCE, minLimit: minDistance, maxLimit: maxDistance, stiffness, damping }], scene);
  380. }
  381. }
  382. //# sourceMappingURL=physicsConstraint.js.map