func (me *Frustum) HasSphere(pos, center *unum.Vec3, radius, zNear, zFar float64) (fullyInside, intersect bool) { if radius == 0 { fullyInside, intersect = me.HasPoint(pos, center, zNear, zFar), false return } var axPos, z, d float64 cp := center.Sub(pos) if axPos = cp.Dot(&me.Axes.Z); axPos > zFar+radius || axPos < zNear-radius { return } if axPos > zFar-radius || axPos < zNear+radius { intersect = true } z, d = axPos*me.tanRadHalfAspect, me.sphereFactor.X*radius if axPos = cp.Dot(&me.Axes.X); axPos > z+d || axPos < -z-d { intersect = false return } if axPos > z-d || axPos < -z+d { intersect = true } z, d = z/me.aspectRatio, me.sphereFactor.Y*radius if axPos = cp.Dot(&me.Axes.Y); axPos > z+d || axPos < -z-d { intersect = false return } if axPos > z-d || axPos < -z+d { intersect = true } fullyInside = !intersect return }
func (me *Frustum) HasPoint(pos, point *unum.Vec3, zNear, zFar float64) bool { var axisPos float64 pp := point.Sub(pos) if axisPos = pp.Dot(&me.Axes.Z); axisPos > zFar || axisPos < zNear { return false } halfHeight := axisPos * me.tanRadHalf if axisPos = pp.Dot(&me.Axes.Y); -halfHeight > axisPos || axisPos > halfHeight { return false } halfWidth := halfHeight * me.aspectRatio if axisPos = pp.Dot(&me.Axes.X); -halfWidth > axisPos || axisPos > halfWidth { return false } return true }
func (me *FrustumPlane) setFrom(p1, p2, p3 *unum.Vec3) { var v3 unum.Vec3 v3.SetFromCrossOf(p3.Sub(p2), p1.Sub(p2)) v3.Normalize() me.SetFromVec3(&v3) me.W = -v3.Dot(p2) }
func (me *FrustumPlane) Normalize() { v3 := unum.Vec3{me.X, me.Y, me.Z} me.NormalizeFrom(v3.Magnitude()) }
func (me *AaBb) UpdateMinMax(vec *unum.Vec3) { vec.Clamp(&me.Min, &me.Max) }