frustum.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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 math32
  5. type Frustum struct {
  6. planes []Plane
  7. }
  8. func NewFrustum(p0, p1, p2, p3, p4, p5 *Plane) *Frustum {
  9. this := new(Frustum)
  10. this.planes = make([]Plane, 6)
  11. if p0 != nil {
  12. this.planes[0] = *p0
  13. }
  14. if p1 != nil {
  15. this.planes[1] = *p1
  16. }
  17. if p2 != nil {
  18. this.planes[2] = *p2
  19. }
  20. if p3 != nil {
  21. this.planes[3] = *p3
  22. }
  23. if p4 != nil {
  24. this.planes[4] = *p4
  25. }
  26. if p5 != nil {
  27. this.planes[5] = *p5
  28. }
  29. return this
  30. }
  31. func (this *Frustum) Set(p0, p1, p2, p3, p4, p5 *Plane) *Frustum {
  32. if p0 != nil {
  33. this.planes[0] = *p0
  34. }
  35. if p1 != nil {
  36. this.planes[1] = *p1
  37. }
  38. if p2 != nil {
  39. this.planes[2] = *p2
  40. }
  41. if p3 != nil {
  42. this.planes[3] = *p3
  43. }
  44. if p4 != nil {
  45. this.planes[4] = *p4
  46. }
  47. if p5 != nil {
  48. this.planes[5] = *p5
  49. }
  50. return this
  51. }
  52. func (this *Frustum) Copy(frustum *Frustum) *Frustum {
  53. for i := 0; i < 6; i++ {
  54. this.planes[i] = frustum.planes[i]
  55. }
  56. return this
  57. }
  58. func (this *Frustum) SetFromMatrix(m *Matrix4) *Frustum {
  59. planes := this.planes
  60. me0 := m[0]
  61. me1 := m[1]
  62. me2 := m[2]
  63. me3 := m[3]
  64. me4 := m[4]
  65. me5 := m[5]
  66. me6 := m[6]
  67. me7 := m[7]
  68. me8 := m[8]
  69. me9 := m[9]
  70. me10 := m[10]
  71. me11 := m[11]
  72. me12 := m[12]
  73. me13 := m[13]
  74. me14 := m[14]
  75. me15 := m[15]
  76. planes[0].SetComponents(me3-me0, me7-me4, me11-me8, me15-me12).Normalize()
  77. planes[1].SetComponents(me3+me0, me7+me4, me11+me8, me15+me12).Normalize()
  78. planes[2].SetComponents(me3+me1, me7+me5, me11+me9, me15+me13).Normalize()
  79. planes[3].SetComponents(me3-me1, me7-me5, me11-me9, me15-me13).Normalize()
  80. planes[4].SetComponents(me3-me2, me7-me6, me11-me10, me15-me14).Normalize()
  81. planes[5].SetComponents(me3+me2, me7+me6, me11+me10, me15+me14).Normalize()
  82. return this
  83. }
  84. /**
  85. SHOULD NOT DEPEND on core package (Move to core ?)
  86. func (this *Frustum) IntersectsObject(geometry *core.Geometry) bool {
  87. return false
  88. }
  89. */
  90. func (this *Frustum) IntersectsSphere(sphere *Sphere) bool {
  91. planes := this.planes
  92. negRadius := -sphere.Radius
  93. for i := 0; i < 6; i++ {
  94. distance := planes[i].DistanceToPoint(&sphere.Center)
  95. if distance < negRadius {
  96. return false
  97. }
  98. }
  99. return true
  100. }
  101. func (this *Frustum) IntersectsBox(box *Box3) bool {
  102. var p1 Vector3
  103. var p2 Vector3
  104. for i := 0; i < 6; i++ {
  105. plane := &this.planes[i]
  106. if plane.normal.X > 0 {
  107. p1.X = box.Min.X
  108. } else {
  109. p1.X = box.Max.X
  110. }
  111. if plane.normal.X > 0 {
  112. p2.X = box.Max.X
  113. } else {
  114. p2.X = box.Min.X
  115. }
  116. if plane.normal.Y > 0 {
  117. p2.Y = box.Min.Y
  118. } else {
  119. p2.Y = box.Max.Y
  120. }
  121. if plane.normal.Y > 0 {
  122. p2.Y = box.Max.Y
  123. } else {
  124. p2.Y = box.Min.Y
  125. }
  126. if plane.normal.Z > 0 {
  127. p1.Z = box.Min.Z
  128. } else {
  129. p1.Z = box.Max.Z
  130. }
  131. if plane.normal.Z > 0 {
  132. p1.Z = box.Max.Z
  133. } else {
  134. p2.Z = box.Min.Z
  135. }
  136. d1 := plane.DistanceToPoint(&p1)
  137. d2 := plane.DistanceToPoint(&p2)
  138. // if both outside plane, no intersection
  139. if d1 < 0 && d2 < 0 {
  140. return false
  141. }
  142. }
  143. return true
  144. }
  145. func (this *Frustum) ContainsPoint(point *Vector3) bool {
  146. for i := 0; i < 6; i++ {
  147. if this.planes[i].DistanceToPoint(point) < 0 {
  148. return false
  149. }
  150. }
  151. return true
  152. }
  153. func (this *Frustum) Clone() *Frustum {
  154. return NewFrustum(nil, nil, nil, nil, nil, nil).Copy(this)
  155. }