raycaster.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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 core
  5. import (
  6. "github.com/g3n/engine/math32"
  7. "sort"
  8. )
  9. // Raycaster represents an empty object that can cast rays and check for ray intersections.
  10. type Raycaster struct {
  11. // The distance from the ray origin to the intersected points
  12. // must be greater than the value of this field to be considered.
  13. // The defaul value is 0.0
  14. Near float32
  15. // The distance from the ray origin to the intersected points
  16. // must be less than the value of this field to be considered.
  17. // The defaul value is +Infinity.
  18. Far float32
  19. // Minimum distance in world coordinates between the ray and
  20. // a line segment when checking intersects with lines.
  21. // The default value is 0.1
  22. LinePrecision float32
  23. // Minimum distance in world coordinates between the ray and
  24. // a point when checking intersects with points.
  25. // The default value is 0.1
  26. PointPrecision float32
  27. // This field must be set with the camera view matrix used
  28. // when checking for sprite intersections.
  29. // It is set automatically when using camera.SetRaycaster
  30. ViewMatrix math32.Matrix4
  31. // Embedded ray
  32. math32.Ray
  33. }
  34. // Intersect describes the intersection between a ray and an object
  35. type Intersect struct {
  36. // Distance between the origin of the ray and the intersect
  37. Distance float32
  38. // Point of intersection in world coordinates
  39. Point math32.Vector3
  40. // Intersected node
  41. Object INode
  42. // If the geometry has indices, this field is the
  43. // index in the Indices buffer of the vertex intersected
  44. // or the first vertex of the intersected face.
  45. // If the geometry doesn't have indices, this field is the
  46. // index in the positions buffer of the vertex intersected
  47. // or the first vertex of the insersected face.
  48. Index uint32
  49. }
  50. // NewRaycaster creates and returns a pointer to a new raycaster object
  51. // with the specified origin and direction.
  52. func NewRaycaster(origin, direction *math32.Vector3) *Raycaster {
  53. rc := new(Raycaster)
  54. rc.Ray.Set(origin, direction)
  55. rc.Near = 0
  56. rc.Far = math32.Inf(1)
  57. rc.LinePrecision = 0.1
  58. rc.PointPrecision = 0.1
  59. return rc
  60. }
  61. // IntersectObject checks intersections between this raycaster and
  62. // and the specified node. If recursive is true, it also checks
  63. // the intersection with the node's children.
  64. // Intersections are returned sorted by distance, closest first.
  65. func (rc *Raycaster) IntersectObject(inode INode, recursive bool) []Intersect {
  66. intersects := []Intersect{}
  67. rc.intersectObject(inode, &intersects, recursive)
  68. sort.Sort(Intersects(intersects))
  69. return intersects
  70. }
  71. // IntersectObjects checks intersections between this raycaster and
  72. // the specified array of scene nodes. If recursive is true, it also checks
  73. // the intersection with each nodes' children.
  74. // Intersections are returned sorted by distance, closest first.
  75. func (rc *Raycaster) IntersectObjects(inodes []INode, recursive bool) []Intersect {
  76. intersects := []Intersect{}
  77. for _, inode := range inodes {
  78. rc.intersectObject(inode, &intersects, recursive)
  79. }
  80. sort.Sort(Intersects(intersects))
  81. return intersects
  82. }
  83. func (rc *Raycaster) intersectObject(inode INode, intersects *[]Intersect, recursive bool) {
  84. node := inode.GetNode()
  85. if !node.Visible() {
  86. return
  87. }
  88. inode.Raycast(rc, intersects)
  89. if recursive {
  90. for _, child := range node.Children() {
  91. rc.intersectObject(child, intersects, true)
  92. }
  93. }
  94. return
  95. }
  96. // Intersects is the array type for Intersect objects. It's used for sorting intersects by distance.
  97. type Intersects []Intersect
  98. func (is Intersects) Len() int { return len(is) }
  99. func (is Intersects) Swap(i, j int) { is[i], is[j] = is[j], is[i] }
  100. func (is Intersects) Less(i, j int) bool {
  101. return is[i].Distance < is[j].Distance
  102. }