body.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. // Copyright 2016 The G3N Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package object
  5. import (
  6. "github.com/g3n/engine/graphic"
  7. "github.com/g3n/engine/math32"
  8. "github.com/g3n/engine/material"
  9. "github.com/g3n/engine/experimental/collision/shape"
  10. )
  11. // Body represents a physics-driven body.
  12. type Body struct {
  13. *graphic.Graphic // TODO future - embed core.Node instead and calculate properties recursively
  14. material *material.Material // Physics material specifying friction and restitution
  15. index int
  16. name string
  17. // Mass properties
  18. mass float32 // Total mass
  19. invMass float32
  20. invMassEff float32 // Effective inverse mass
  21. // Rotational inertia and related properties
  22. rotInertia *math32.Matrix3 // Angular mass i.e. moment of inertia in local coordinates
  23. invRotInertia *math32.Matrix3 // Inverse rotational inertia in local coordinates
  24. invRotInertiaEff *math32.Matrix3 // Effective inverse rotational inertia in local coordinates
  25. invRotInertiaWorld *math32.Matrix3 // Inverse rotational inertia in world coordinates
  26. invRotInertiaWorldEff *math32.Matrix3 // Effective rotational inertia in world coordinates
  27. fixedRotation bool // Set to true if you don't want the body to rotate. Make sure to run .updateMassProperties() after changing this.
  28. // Position
  29. position *math32.Vector3 // World position of the center of gravity (World space position of the body.)
  30. initPosition *math32.Vector3 // Initial position of the body.
  31. prevPosition *math32.Vector3 // Previous position
  32. interpPosition *math32.Vector3 // Interpolated position of the body.
  33. // Rotation
  34. quaternion *math32.Quaternion // World space orientation of the body.
  35. initQuaternion *math32.Quaternion
  36. prevQuaternion *math32.Quaternion
  37. interpQuaternion *math32.Quaternion // Interpolated orientation of the body.
  38. // Linear and angular velocities
  39. velocity *math32.Vector3 // Linear velocity (World space velocity of the body.)
  40. initVelocity *math32.Vector3 // Initial linear velocity (World space velocity of the body.)
  41. angularVelocity *math32.Vector3 // Angular velocity of the body, in world space. Think of the angular velocity as a vector, which the body rotates around. The length of this vector determines how fast (in radians per second) the body rotates.
  42. initAngularVelocity *math32.Vector3
  43. // Force and torque
  44. force *math32.Vector3 // Linear force on the body in world space.
  45. torque *math32.Vector3 // World space rotational force on the body, around center of mass.
  46. // Damping and factors
  47. linearDamping float32
  48. angularDamping float32
  49. linearFactor *math32.Vector3 // Use this property to limit the motion along any world axis. (1,1,1) will allow motion along all axes while (0,0,0) allows none.
  50. angularFactor *math32.Vector3 // Use this property to limit the rotational motion along any world axis. (1,1,1) will allow rotation along all axes while (0,0,0) allows none.
  51. // Body type and sleep settings
  52. bodyType BodyType
  53. sleepState BodySleepState // Current sleep state.
  54. allowSleep bool // If true, the body will automatically fall to sleep.
  55. sleepSpeedLimit float32 // If the speed (the norm of the velocity) is smaller than this value, the body is considered sleepy.
  56. sleepTimeLimit float32 // If the body has been sleepy for this sleepTimeLimit seconds, it is considered sleeping.
  57. timeLastSleepy float32
  58. wakeUpAfterNarrowphase bool
  59. // Collision settings
  60. colFilterGroup int // Collision filter group
  61. colFilterMask int // Collision filter mask
  62. colResponse bool // Whether to produce contact forces when in contact with other bodies. Note that contacts will be generated, but they will be disabled.
  63. aabb *math32.Box3 // World space bounding box of the body and its shapes.
  64. aabbNeedsUpdate bool // Indicates if the AABB needs to be updated before use.
  65. boundingRadius float32 // Total bounding radius of the body (TODO including its shapes, relative to body.position.)
  66. // Cached geometry properties
  67. faces [][3]math32.Vector3
  68. faceNormals []math32.Vector3
  69. worldFaceNormals []math32.Vector3
  70. uniqueEdges []math32.Vector3
  71. worldUniqueEdges []math32.Vector3
  72. shape shape.IShape
  73. // TODO future (for now a body is a single graphic with a single geometry)
  74. // shapes []*Shape
  75. // shapeOffsets []float32 // Position of each Shape in the body, given in local Body space.
  76. // shapeOrientations [] ?
  77. }
  78. // BodyType specifies how the body is affected during the simulation.
  79. type BodyType int
  80. const (
  81. // A static body does not move during simulation and behaves as if it has infinite mass.
  82. // Static bodies can be moved manually by setting the position of the body.
  83. // The velocity of a static body is always zero.
  84. // Static bodies do not collide with other static or kinematic bodies.
  85. Static = BodyType(iota)
  86. // A kinematic body moves under simulation according to its velocity.
  87. // They do not respond to forces.
  88. // They can be moved manually, but normally a kinematic body is moved by setting its velocity.
  89. // A kinematic body behaves as if it has infinite mass.
  90. // Kinematic bodies do not collide with other static or kinematic bodies.
  91. Kinematic
  92. // A dynamic body is fully simulated.
  93. // Can be moved manually by the user, but normally they move according to forces.
  94. // A dynamic body can collide with all body types.
  95. // A dynamic body always has finite, non-zero mass.
  96. Dynamic
  97. )
  98. // TODO Update simulation checks for BodyType to use bitwise operators ?
  99. // BodyStatus specifies
  100. type BodySleepState int
  101. const (
  102. Awake = BodySleepState(iota)
  103. Sleepy
  104. Sleeping
  105. )
  106. // Events
  107. const (
  108. SleepyEvent = "physics.SleepyEvent" // Dispatched after a body has gone in to the sleepy state.
  109. SleepEvent = "physics.SleepEvent" // Dispatched after a body has fallen asleep.
  110. WakeUpEvent = "physics.WakeUpEvent" // Dispatched after a sleeping body has woken up.
  111. CollideEvent = "physics.CollideEvent" // Dispatched after two bodies collide. This event is dispatched on each of the two bodies involved in the collision.
  112. )
  113. // TODO
  114. type HullType int
  115. const (
  116. Sphere = HullType(iota)
  117. Capsule
  118. Mesh // use mesh itself
  119. )
  120. // NewBody creates and returns a pointer to a new RigidBody.
  121. // The igraphic's geometry *must* be convex.
  122. func NewBody(igraphic graphic.IGraphic) *Body {
  123. b := new(Body)
  124. b.Graphic = igraphic.GetGraphic()
  125. b.bodyType = Dynamic
  126. // Rotational inertia and related properties
  127. b.rotInertia = math32.NewMatrix3()
  128. b.invRotInertia = math32.NewMatrix3()
  129. b.invRotInertiaEff = math32.NewMatrix3()
  130. b.invRotInertiaWorld = math32.NewMatrix3()
  131. b.invRotInertiaWorldEff = math32.NewMatrix3()
  132. // Position
  133. pos := b.GetNode().Position()
  134. b.position = pos.Clone()
  135. b.prevPosition = pos.Clone()
  136. b.interpPosition = pos.Clone()
  137. b.initPosition = pos.Clone()
  138. // Rotation
  139. quat := b.GetNode().Quaternion()
  140. b.quaternion = quat.Clone()
  141. b.prevQuaternion = quat.Clone()
  142. b.interpQuaternion = quat.Clone()
  143. b.initQuaternion = quat.Clone()
  144. // Linear and angular velocities
  145. b.velocity = math32.NewVec3()
  146. b.initVelocity = math32.NewVec3()
  147. b.angularVelocity = math32.NewVec3()
  148. b.initAngularVelocity = math32.NewVec3()
  149. // Force and torque
  150. b.force = math32.NewVec3()
  151. b.torque = math32.NewVec3()
  152. // Damping and factors
  153. b.linearDamping = 0.01
  154. b.angularDamping = 0.01
  155. b.linearFactor = math32.NewVector3(1, 1, 1)
  156. b.angularFactor = math32.NewVector3(1, 1, 1)
  157. // Sleep settings
  158. b.allowSleep = true
  159. b.sleepState = Awake
  160. b.sleepSpeedLimit = 0.1
  161. b.sleepTimeLimit = 1
  162. b.timeLastSleepy = 0
  163. // Collision filtering
  164. b.colFilterGroup = 1
  165. b.colFilterMask = -1
  166. //b.fixedRotation = true
  167. b.wakeUpAfterNarrowphase = false
  168. b.SetShape(shape.NewConvexHull(b.GetGeometry()))
  169. b.SetMass(1)
  170. b.UpdateMassProperties()
  171. b.UpdateEffectiveMassProperties()
  172. return b
  173. }
  174. // TODO future: modify this to be "AddShape" and keep track of list of shapes, their positions and orientations
  175. // For now each body can only be a single shape or a single geometry
  176. func (b *Body) SetShape(shape shape.IShape) {
  177. b.shape = shape
  178. }
  179. func (b *Body) Shape() shape.IShape {
  180. return b.shape
  181. }
  182. func (b *Body) BoundingBox() math32.Box3 {
  183. // TODO future allow multiple shapes
  184. mat4 := math32.NewMatrix4().Compose(b.position, b.quaternion, math32.NewVector3(1,1,1))
  185. localBB := b.shape.BoundingBox()
  186. worldBB := localBB.ApplyMatrix4(mat4)
  187. return *worldBB
  188. }
  189. func (b *Body) SetMass(mass float32) {
  190. // Do nothing if current mass is already the specified mass
  191. if mass == b.mass {
  192. return
  193. }
  194. // Set mass and update inverse mass
  195. b.mass = mass
  196. if b.mass > 0 {
  197. b.invMass = 1.0 / b.mass
  198. } else {
  199. // Body mass is zero - this means that the body is static
  200. b.invMass = 0
  201. b.bodyType = Static
  202. }
  203. b.UpdateMassProperties()
  204. }
  205. func (b *Body) SetIndex(i int) {
  206. b.index = i
  207. }
  208. func (b *Body) SetName(name string) {
  209. b.name = name
  210. }
  211. func (b *Body) Name() string {
  212. return b.name
  213. }
  214. func (b *Body) Index() int {
  215. return b.index
  216. }
  217. func (b *Body) Material() *material.Material {
  218. return b.material
  219. }
  220. func (b *Body) SetAllowSleep(state bool) {
  221. b.allowSleep = state
  222. }
  223. func (b *Body) AllowSleep() bool {
  224. return b.allowSleep
  225. }
  226. func (b *Body) SleepSpeedLimit() float32 {
  227. return b.sleepSpeedLimit
  228. }
  229. func (b *Body) SleepState() BodySleepState {
  230. return b.sleepState
  231. }
  232. // SetBodyType sets the body type.
  233. func (b *Body) SetBodyType(bodyType BodyType) {
  234. // Do nothing if body is already of the specified bodyType
  235. if b.bodyType == bodyType {
  236. return
  237. }
  238. // If we want the body to be static we need to zero its mass
  239. if bodyType == Static {
  240. b.mass = 0
  241. }
  242. // Temporarily save original body type and update current body type
  243. origBodyType := b.bodyType
  244. b.bodyType = bodyType
  245. // If changed body type to or from Static then we need to update mass properties
  246. if origBodyType == Static || b.bodyType == Static {
  247. b.UpdateMassProperties()
  248. }
  249. }
  250. func (b *Body) BodyType() BodyType {
  251. return b. bodyType
  252. }
  253. func (b *Body) SetWakeUpAfterNarrowphase(state bool) {
  254. b.wakeUpAfterNarrowphase = state
  255. }
  256. func (b *Body) WakeUpAfterNarrowphase() bool {
  257. return b.wakeUpAfterNarrowphase
  258. }
  259. // ApplyVelocityDeltas adds the specified deltas to the body's linear and angular velocities.
  260. func (b *Body) ApplyVelocityDeltas(linearD, angularD *math32.Vector3) {
  261. b.velocity.Add(linearD.Multiply(b.linearFactor))
  262. b.angularVelocity.Add(angularD.Multiply(b.angularFactor))
  263. }
  264. // ClearForces clears all forces on the body.
  265. func (b *Body) ClearForces() {
  266. b.force.Zero()
  267. b.torque.Zero()
  268. }
  269. func (b *Body) InvMassEff() float32 {
  270. return b.invMassEff
  271. }
  272. func (b *Body) InvRotInertiaWorldEff() *math32.Matrix3 {
  273. return b.invRotInertiaWorldEff
  274. }
  275. func (b *Body) Position() math32.Vector3 {
  276. return *b.position
  277. }
  278. func (b *Body) Quaternion() *math32.Quaternion {
  279. return b.quaternion.Clone()
  280. }
  281. func (b *Body) SetVelocity(vel *math32.Vector3) {
  282. b.velocity = vel
  283. }
  284. func (b *Body) Velocity() math32.Vector3 {
  285. return *b.velocity
  286. }
  287. func (b *Body) SetAngularVelocity(vel *math32.Vector3) {
  288. b.angularVelocity = vel
  289. }
  290. func (b *Body) AngularVelocity() math32.Vector3 {
  291. return *b.angularVelocity
  292. }
  293. func (b *Body) Force() math32.Vector3 {
  294. return *b.force
  295. }
  296. func (b *Body) Torque() math32.Vector3 {
  297. return *b.torque
  298. }
  299. func (b *Body) SetLinearDamping(d float32) {
  300. b.linearDamping = d
  301. }
  302. func (b *Body) LinearDamping() float32 {
  303. return b.linearDamping
  304. }
  305. func (b *Body) SetAngularDamping(d float32) {
  306. b.angularDamping = d
  307. }
  308. func (b *Body) AngularDamping() float32 {
  309. return b.angularDamping
  310. }
  311. func (b *Body) ApplyDamping(dt float32) {
  312. b.velocity.MultiplyScalar(math32.Pow(1.0 - b.linearDamping, dt))
  313. b.angularVelocity.MultiplyScalar(math32.Pow(1.0 - b.angularDamping, dt))
  314. }
  315. func (b *Body) SetLinearFactor(factor *math32.Vector3) {
  316. b.linearFactor = factor
  317. }
  318. func (b *Body) LinearFactor() math32.Vector3 {
  319. return *b.linearFactor
  320. }
  321. func (b *Body) SetAngularFactor(factor *math32.Vector3) {
  322. b.angularFactor = factor
  323. }
  324. func (b *Body) AngularFactor() math32.Vector3 {
  325. return *b.angularFactor
  326. }
  327. // SetFixedRotation specifies whether the body should rotate.
  328. func (b *Body) SetFixedRotation(state bool) {
  329. // Do nothing if the fixedRotation flag already has the specified value
  330. if b.fixedRotation == state {
  331. return
  332. }
  333. // Set the fixedRotation flag and update mass properties
  334. b.fixedRotation = state
  335. b.UpdateMassProperties()
  336. }
  337. // WakeUp wakes the body up.
  338. func (b *Body) WakeUp() {
  339. state := b.sleepState
  340. b.sleepState = Awake
  341. b.wakeUpAfterNarrowphase = false
  342. if state == Sleeping {
  343. b.Dispatch(WakeUpEvent, nil)
  344. }
  345. }
  346. // Sleep forces the body to sleep.
  347. func (b *Body) Sleep() {
  348. b.sleepState = Sleeping
  349. b.velocity.Set(0, 0, 0)
  350. b.angularVelocity.Set(0, 0, 0)
  351. b.wakeUpAfterNarrowphase = false
  352. }
  353. // Called every timestep to update internal sleep timer and change sleep state if needed.
  354. // time: The world time in seconds
  355. func (b *Body) SleepTick(time float32) {
  356. if b.allowSleep {
  357. speedSquared := b.velocity.LengthSq() + b.angularVelocity.LengthSq()
  358. speedLimitSquared := math32.Pow(b.sleepSpeedLimit, 2)
  359. if b.sleepState == Awake && speedSquared < speedLimitSquared {
  360. b.sleepState = Sleepy
  361. b.timeLastSleepy = time
  362. b.Dispatch(SleepyEvent, nil)
  363. } else if b.sleepState == Sleepy && speedSquared > speedLimitSquared {
  364. b.WakeUp() // Wake up
  365. } else if b.sleepState == Sleepy && (time-b.timeLastSleepy) > b.sleepTimeLimit {
  366. b.Sleep() // Sleeping
  367. b.Dispatch(SleepEvent, nil)
  368. }
  369. }
  370. }
  371. // If checkSleeping is true then returns false if both bodies are currently sleeping.
  372. func (b *Body) Sleeping() bool {
  373. return b.sleepState == Sleeping
  374. }
  375. // CollidableWith returns whether the body can collide with the specified body.
  376. func (b *Body) CollidableWith(other *Body) bool {
  377. if (b.colFilterGroup & other.colFilterMask == 0) ||
  378. (other.colFilterGroup & b.colFilterMask == 0) ||
  379. (b.bodyType == Static) && (other.bodyType == Static) {
  380. return false
  381. }
  382. return true
  383. }
  384. func (b *Body) CollisionResponse() bool {
  385. return b.colResponse
  386. }
  387. // PointToLocal converts a world point to local body frame. TODO maybe move to Node
  388. func (b *Body) PointToLocal(worldPoint *math32.Vector3) math32.Vector3 {
  389. return *worldPoint.Clone().Sub(b.position).ApplyQuaternion(b.quaternion.Conjugate())
  390. }
  391. // VectorToLocal converts a world vector to local body frame. TODO maybe move to Node
  392. func (b *Body) VectorToLocal(worldVector *math32.Vector3) math32.Vector3 {
  393. return *worldVector.Clone().ApplyQuaternion(b.quaternion.Conjugate())
  394. }
  395. // PointToWorld converts a local point to world frame. TODO maybe move to Node
  396. func (b *Body) PointToWorld(localPoint *math32.Vector3) math32.Vector3 {
  397. return *localPoint.Clone().ApplyQuaternion(b.quaternion).Add(b.position)
  398. }
  399. // VectorToWorld converts a local vector to world frame. TODO maybe move to Node
  400. func (b *Body) VectorToWorld(localVector *math32.Vector3) math32.Vector3 {
  401. return *localVector.Clone().ApplyQuaternion(b.quaternion)
  402. }
  403. // UpdateEffectiveMassProperties
  404. // If the body is sleeping, it should be immovable and thus have infinite mass during solve.
  405. // This is solved by having a separate "effective mass" and other "effective" properties
  406. func (b *Body) UpdateEffectiveMassProperties() {
  407. if b.sleepState == Sleeping || b.bodyType == Kinematic {
  408. b.invMassEff = 0
  409. b.invRotInertiaEff.Zero()
  410. b.invRotInertiaWorldEff.Zero()
  411. } else {
  412. b.invMassEff = b.invMass
  413. b.invRotInertiaEff.Copy(b.invRotInertia)
  414. b.invRotInertiaWorldEff.Copy(b.invRotInertiaWorld)
  415. }
  416. }
  417. // UpdateMassProperties
  418. // Should be called whenever you change the body shape or mass.
  419. func (b *Body) UpdateMassProperties() {
  420. if b.mass > 0 {
  421. b.invMass = 1.0 / b.mass
  422. } else {
  423. b.invMass = 0
  424. }
  425. if b.fixedRotation || b.bodyType == Static {
  426. b.rotInertia.Zero()
  427. b.invRotInertia.Zero()
  428. } else {
  429. *b.rotInertia = b.GetGeometry().RotationalInertia(b.mass)
  430. b.rotInertia.MultiplyScalar(10) // multiply by high density // TODO remove this ?
  431. b.invRotInertia.GetInverse(b.rotInertia) // Note: rotInertia is always positive definite and thus always invertible
  432. }
  433. b.UpdateInertiaWorld(true)
  434. }
  435. // Update .inertiaWorld and .invRotInertiaWorld
  436. func (b *Body) UpdateInertiaWorld(force bool) {
  437. iRI := b.invRotInertia
  438. // If rotational inertia M = s*I, where I is identity and s a scalar, then
  439. // R*M*R' = R*(s*I)*R' = s*R*I*R' = s*R*R' = s*I = M
  440. // where R is the rotation matrix.
  441. // In other words, we don't have to do the transformation if all diagonal entries are equal.
  442. if iRI[0] != iRI[4] || iRI[4] != iRI[8] || force {
  443. // iRIW = R * iRI * R'
  444. m1 := math32.NewMatrix3().MakeRotationFromQuaternion(b.quaternion)
  445. m2 := m1.Clone().Transpose()
  446. m2.Multiply(iRI)
  447. b.invRotInertiaWorld.MultiplyMatrices(m2, m1)
  448. }
  449. }
  450. // Forces from a force field need to be multiplied by mass.
  451. func (b *Body) ApplyForceField(force *math32.Vector3) {
  452. b.force.Add(force.MultiplyScalar(b.mass))
  453. }
  454. // Apply force to a world point.
  455. // This could for example be a point on the Body surface.
  456. // Applying force this way will add to Body.force and Body.torque.
  457. // relativePoint: A point relative to the center of mass to apply the force on.
  458. func (b *Body) ApplyForce(force, relativePoint *math32.Vector3) {
  459. if b.bodyType != Dynamic { // Needed?
  460. return
  461. }
  462. // Add linear force
  463. b.force.Add(force) // TODO shouldn't rotational momentum be subtracted from linear momentum?
  464. // Add rotational force
  465. b.torque.Add(math32.NewVec3().CrossVectors(relativePoint, force))
  466. }
  467. // Apply force to a local point in the body.
  468. // force: The force vector to apply, defined locally in the body frame.
  469. // localPoint: A local point in the body to apply the force on.
  470. func (b *Body) ApplyLocalForce(localForce, localPoint *math32.Vector3) {
  471. if b.bodyType != Dynamic {
  472. return
  473. }
  474. // Transform the force vector to world space
  475. worldForce := b.VectorToWorld(localForce)
  476. relativePointWorld := b.VectorToWorld(localPoint)
  477. b.ApplyForce(&worldForce, &relativePointWorld)
  478. }
  479. // Apply impulse to a world point.
  480. // This could for example be a point on the Body surface.
  481. // An impulse is a force added to a body during a short period of time (impulse = force * time).
  482. // Impulses will be added to Body.velocity and Body.angularVelocity.
  483. // impulse: The amount of impulse to add.
  484. // relativePoint: A point relative to the center of mass to apply the force on.
  485. func (b *Body) ApplyImpulse(impulse, relativePoint *math32.Vector3) {
  486. if b.bodyType != Dynamic {
  487. return
  488. }
  489. // Compute point position relative to the body center
  490. r := relativePoint
  491. // Compute produced central impulse velocity
  492. velo := impulse.Clone().MultiplyScalar(b.invMass)
  493. // Add linear impulse
  494. b.velocity.Add(velo)
  495. // Compute produced rotational impulse velocity
  496. rotVelo := math32.NewVec3().CrossVectors(r, impulse)
  497. rotVelo.ApplyMatrix3(b.invRotInertiaWorld)
  498. // Add rotational Impulse
  499. b.angularVelocity.Add(rotVelo)
  500. }
  501. // Apply locally-defined impulse to a local point in the body.
  502. // force: The force vector to apply, defined locally in the body frame.
  503. // localPoint: A local point in the body to apply the force on.
  504. func (b *Body) ApplyLocalImpulse(localImpulse, localPoint *math32.Vector3) {
  505. if b.bodyType != Dynamic {
  506. return
  507. }
  508. // Transform the force vector to world space
  509. worldImpulse := b.VectorToWorld(localImpulse)
  510. relativePointWorld := b.VectorToWorld(localPoint)
  511. b.ApplyImpulse(&worldImpulse, &relativePointWorld)
  512. }
  513. // Get world velocity of a point in the body.
  514. func (b *Body) GetVelocityAtWorldPoint(worldPoint *math32.Vector3) *math32.Vector3 {
  515. r := math32.NewVec3().SubVectors(worldPoint, b.position)
  516. r.CrossVectors(b.angularVelocity, r)
  517. r.Add(b.velocity)
  518. return r
  519. }
  520. // Move the body forward in time.
  521. // dt: Time step
  522. // quatNormalize: Set to true to normalize the body quaternion
  523. // quatNormalizeFast: If the quaternion should be normalized using "fast" quaternion normalization
  524. func (b *Body) Integrate(dt float32, quatNormalize, quatNormalizeFast bool) {
  525. // Save previous position and rotation
  526. b.prevPosition.Copy(b.position)
  527. b.prevQuaternion.Copy(b.quaternion)
  528. // If static or sleeping - skip
  529. if !(b.bodyType == Dynamic || b.bodyType == Kinematic) || b.sleepState == Sleeping {
  530. return
  531. }
  532. // Integrate force over mass (acceleration) to obtain estimate for instantaneous velocities
  533. iMdt := b.invMass * dt
  534. b.velocity.X += b.force.X * iMdt * b.linearFactor.X
  535. b.velocity.Y += b.force.Y * iMdt * b.linearFactor.Y
  536. b.velocity.Z += b.force.Z * iMdt * b.linearFactor.Z
  537. // Integrate inverse angular mass times torque to obtain estimate for instantaneous angular velocities
  538. e := b.invRotInertiaWorld
  539. tx := b.torque.X * b.angularFactor.X
  540. ty := b.torque.Y * b.angularFactor.Y
  541. tz := b.torque.Z * b.angularFactor.Z
  542. b.angularVelocity.X += dt * (e[0]*tx + e[3]*ty + e[6]*tz)
  543. b.angularVelocity.Y += dt * (e[1]*tx + e[4]*ty + e[7]*tz)
  544. b.angularVelocity.Z += dt * (e[2]*tx + e[5]*ty + e[8]*tz)
  545. // Integrate velocity to obtain estimate for position
  546. b.position.X += b.velocity.X * dt
  547. b.position.Y += b.velocity.Y * dt
  548. b.position.Z += b.velocity.Z * dt
  549. // Integrate angular velocity to obtain estimate for rotation
  550. ax := b.angularVelocity.X * b.angularFactor.X
  551. ay := b.angularVelocity.Y * b.angularFactor.Y
  552. az := b.angularVelocity.Z * b.angularFactor.Z
  553. bx := b.quaternion.X
  554. by := b.quaternion.Y
  555. bz := b.quaternion.Z
  556. bw := b.quaternion.W
  557. halfDt := dt * 0.5
  558. b.quaternion.X += halfDt * (ax*bw + ay*bz - az*by)
  559. b.quaternion.Y += halfDt * (ay*bw + az*bx - ax*bz)
  560. b.quaternion.Z += halfDt * (az*bw + ax*by - ay*bx)
  561. b.quaternion.W += halfDt * (-ax*bx - ay*by - az*bz)
  562. // Normalize quaternion
  563. b.quaternion.Normalize()
  564. //if quatNormalize { // TODO future
  565. // if quatNormalizeFast {
  566. // b.quaternion.NormalizeFast()
  567. // } else {
  568. // b.quaternion.Normalize()
  569. // }
  570. //}
  571. // Update position and rotation of Node (containing visual representation of the body)
  572. b.GetNode().SetPositionVec(b.position)
  573. b.GetNode().SetRotationQuat(b.quaternion)
  574. b.aabbNeedsUpdate = true
  575. // Update world inertia
  576. b.UpdateInertiaWorld(false)
  577. }