Body.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /** @format */
  2. import {Line} from './Maths'
  3. import {Dirty, cObject} from './Object'
  4. import {cShape} from './Shape'
  5. const Mat3 = cc.Mat3
  6. const Quat = cc.Quat
  7. const Vec3 = cc.Vec3
  8. const IsIdentity = function (quat: cc.Quat) {
  9. if (quat.x != 0 || quat.y != 0 || quat.z != 0 || quat.w != 1) return false
  10. return true
  11. }
  12. export class cBody {
  13. id: number = 0
  14. mask: number = 0
  15. group: number = 0
  16. shape: cShape = null
  17. object: cObject = null
  18. priority: number = 0
  19. // 碰撞体的entity
  20. entity: number
  21. //脏区更新标记
  22. isDirty: number = 1 | 2 | 4
  23. //缓存
  24. lower: number = 0
  25. upper: number = 0
  26. aabb: Array<number> = [0, 0, 0, 0, 0, 0]
  27. //状态
  28. isRemove: boolean = false
  29. isRetrieve: boolean = false
  30. isIdentity: boolean = false
  31. inCollider: boolean = false
  32. //缓存
  33. raidus: number = 0
  34. center: cc.Vec3 = new Vec3()
  35. rotMat3: cc.Mat3 = new Mat3()
  36. halfSize: cc.Vec3 = new Vec3()
  37. scale: cc.Vec3 = new Vec3(1, 1, 1)
  38. //Agent
  39. isAgent: boolean = false //Agent 开关
  40. maxNeighbors: number = 0
  41. neighborDist: number = 0 //物体半径
  42. maxVelocity: number = 0 //最大速度
  43. newVelocity: cc.Vec3 = new Vec3()
  44. prefVelocity: cc.Vec3 = new Vec3()
  45. orcaLines: Array<Line> = []
  46. constructor(obj: cObject) {
  47. this.object = obj
  48. }
  49. updateBound(force: Dirty = Dirty.NON) {
  50. let object = this.object //force 强制全局刷新
  51. let isDirty = force | object.isDirty
  52. if (this.isAgent) {
  53. let v = object.velocity
  54. this.newVelocity.x = v.x
  55. this.newVelocity.y = v.y
  56. // let pv = this.prefVelocity;
  57. // pv.x+= (v.x - pv.x)*0.75;
  58. // pv.y+= (v.y - pv.y)*0.75;
  59. }
  60. if (isDirty > 0) {
  61. let aabbChange = false
  62. const shape = this.shape
  63. if (isDirty & Dirty.S) {
  64. aabbChange = true
  65. let s = this.getScale()
  66. this.scale.x = s.x >= 0 ? s.x : -s.x
  67. this.scale.y = s.y >= 0 ? s.y : -s.y
  68. this.scale.z = s.z >= 0 ? s.z : -s.z
  69. }
  70. if (isDirty & Dirty.R) {
  71. //旋转更新aabb
  72. this.isIdentity = IsIdentity(this.getRotation())
  73. aabbChange = true
  74. }
  75. if (aabbChange) shape.updateAABB(this.getScale(), this.getRotMat3(), this.isIdentity)
  76. const AABB = this.aabb // world aabb
  77. const aabb = shape.aabb //local aabb
  78. const p = this.getPosition() //world postion
  79. AABB[0] = aabb[0] + p.x
  80. AABB[1] = aabb[1] + p.y
  81. AABB[2] = aabb[2] + p.z
  82. AABB[3] = aabb[3] + p.x
  83. AABB[4] = aabb[4] + p.y
  84. AABB[5] = aabb[5] + p.z
  85. this.isDirty = 1 | 2 | 4 //设置脏区标记
  86. object.isDirty = Dirty.NON //清除object状态
  87. return true
  88. }
  89. return false
  90. }
  91. clear() {
  92. this.id = -1
  93. this.shape = null
  94. this.object = null
  95. this.isRemove = false
  96. this.inCollider = false
  97. this.orcaLines.length = 0
  98. // this.object.body = null;
  99. }
  100. //body 坐标统一使用世界数据进行计算
  101. getScale() {
  102. return this.object.worldScale
  103. } // world scale
  104. getPosition() {
  105. return this.object.worldPosition
  106. } //wold position
  107. getRotation() {
  108. return this.object.worldRotation
  109. } //world rotation quat
  110. getRotMat3() {
  111. return this.object.worldRotatioMat3
  112. } //world rotation mat3
  113. getCenter() {
  114. if (this.isDirty & 1) {
  115. this.isDirty &= ~1
  116. const aabb = this.aabb
  117. const center = this.center
  118. center.x = (aabb[0] + aabb[3]) * 0.5
  119. center.y = (aabb[1] + aabb[4]) * 0.5
  120. center.z = (aabb[2] + aabb[5]) * 0.5
  121. }
  122. return this.center //world center
  123. }
  124. getRaidus() {
  125. if (this.isDirty & 2) {
  126. this.isDirty &= ~2
  127. const scale = this.scale
  128. const raidus = this.shape.radius
  129. this.raidus = Math.max(scale.x, scale.y, scale.z) * raidus
  130. }
  131. return this.raidus //world raidus
  132. }
  133. getHalfSize() {
  134. if (this.isDirty & 4) {
  135. this.isDirty &= ~4
  136. const scale = this.scale
  137. const size = this.shape.size
  138. const halfSize = this.halfSize
  139. halfSize.x = scale.x * size.x * 0.5
  140. halfSize.y = scale.y * size.y * 0.5
  141. halfSize.z = scale.z * size.z * 0.5
  142. }
  143. return this.halfSize //world halfsize
  144. }
  145. }