raycaster.go 3.6 KB

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