-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathboundsSphere.go
94 lines (74 loc) · 2.95 KB
/
boundsSphere.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package tetra3d
import "github.com/solarlune/tetra3d/math32"
// BoundingSphere represents a 3D sphere.
type BoundingSphere struct {
*Node
Radius float32
}
// NewBoundingSphere returns a new BoundingSphere instance.
func NewBoundingSphere(name string, radius float32) *BoundingSphere {
sphere := &BoundingSphere{
Node: NewNode(name),
Radius: radius,
}
sphere.owner = sphere
return sphere
}
// Clone returns a new BoundingSphere instance.
func (sphere *BoundingSphere) Clone() INode {
clone := NewBoundingSphere(sphere.name, sphere.Radius)
clone.Node = sphere.Node.clone(clone).(*Node)
if clone.Callbacks() != nil && clone.Callbacks().OnClone != nil {
clone.Callbacks().OnClone(clone)
}
return clone
}
// WorldRadius returns the radius of the BoundingSphere in world units, after taking into account its scale.
func (sphere *BoundingSphere) WorldRadius() float32 {
var scale Vector3
maxScale := float32(1.0)
if sphere.Node.Parent() != nil {
scale = sphere.Node.WorldScale() // We don't want to have to decompose the transform if we can help it
} else {
scale = sphere.Node.scale // We don't want to have to make a memory duplicate if we don't have to
}
maxScale = math32.Max(math32.Max(math32.Abs(scale.X), math32.Abs(scale.Y)), math32.Abs(scale.Z))
return sphere.Radius * maxScale
}
// Colliding returns true if the BoundingSphere is intersecting the other BoundingObject.
func (sphere *BoundingSphere) Colliding(other IBoundingObject) bool {
return sphere.Collision(other) != nil
}
// Collision returns a Collision if the BoundingSphere is intersecting another BoundingObject. If
// no intersection is reported, Collision returns nil.
func (sphere *BoundingSphere) Collision(other IBoundingObject) *Collision {
if other == sphere || other == nil {
return nil
}
switch otherBounds := other.(type) {
case *BoundingSphere:
return btSphereSphere(sphere, otherBounds)
case *BoundingAABB:
return btSphereAABB(sphere, otherBounds)
case *BoundingTriangles:
return btSphereTriangles(sphere, otherBounds)
case *BoundingCapsule:
return btSphereCapsule(sphere, otherBounds)
}
panic("Unimplemented bounds type")
}
// CollisionTest performs a collision test using the provided collision test settings structure.
// Collisions reported will be sorted in distance from closest to furthest.
// The function will return if a collision was found with the sphere at the settings specified.
func (sphere *BoundingSphere) CollisionTest(settings CollisionTestSettings) bool {
return commonCollisionTest(sphere, settings)
}
// PointInside returns whether the given point is inside of the sphere or not.
func (sphere *BoundingSphere) PointInside(point Vector3) bool {
return sphere.Node.WorldPosition().Sub(point).Magnitude() < sphere.WorldRadius()
}
/////
// Type returns the NodeType for this object.
func (sphere *BoundingSphere) Type() NodeType {
return NodeTypeBoundingSphere
}