// Real-time Collision Detection, p179. public float RayCast(Vector3 from, Vector3 to, float maxFraction = 1.0f) { float tMin = float.MinValue; float tMax = float.MaxValue; Vector3 d = to - from; Vector3 absD = VectorUtil.Abs(d); for (int i = 0; i < 3; ++i) { float dComp = VectorUtil.GetComopnent(d, i); float absDComp = VectorUtil.GetComopnent(absD, i); float fromComp = VectorUtil.GetComopnent(from, i); float minComp = VectorUtil.GetComopnent(Min, i); float maxComp = VectorUtil.GetComopnent(Max, i); if (absDComp < float.Epsilon) { // parallel? if (fromComp < minComp || maxComp < fromComp) { return(float.MinValue); } } else { float invD = 1.0f / dComp; float t1 = (minComp - fromComp) * invD; float t2 = (maxComp - fromComp) * invD; if (t1 > t2) { float temp = t1; t1 = t2; t2 = temp; } tMin = Mathf.Max(tMin, t1); tMax = Mathf.Min(tMax, t2); if (tMin > tMax) { return(float.MinValue); } } } // does the ray start inside the box? // does the ray intersect beyond the max fraction? if (tMin < 0.0f || maxFraction < tMin) { return(float.MinValue); } // intersection detected return(tMin); }
private static Vector3 Quantize(Vector3 v, float step) { Vector3 s = new Vector3(Mathf.Sign(v.x), Mathf.Sign(v.y), Mathf.Sign(v.z)); v += 0.125f * step * Vector3.one; v = VectorUtil.CompDiv(v, 0.25f * step * Vector3.one); v = VectorUtil.Abs(v); v = new Vector3(Mathf.Floor(v.x), Mathf.Floor(v.y), Mathf.Floor(v.z)); v = VectorUtil.CompMul(s, v); return(v); }
public Aabb BoundaryShapeBounds(SdfBrush.BoundaryShapeEnum boundaryShape, float radius) { Vector3 size = transform.localScale; Aabb bounds = Aabb.Empty; switch (boundaryShape) { case SdfBrush.BoundaryShapeEnum.Box: { Vector3 r = 0.5f * size; bounds = new Aabb(-r, r); bounds.Rotate(RotationRs(transform.rotation)); break; } case SdfBrush.BoundaryShapeEnum.Sphere: { Vector3 r = radius * size; bounds = new Aabb(-r, r); bounds.Rotate(RotationRs(transform.rotation)); break; } case SdfBrush.BoundaryShapeEnum.Cylinder: { Vector3 r = new Vector3(radius, 0.5f * size.y, radius); bounds = new Aabb(-r, r); bounds.Rotate(RotationRs(transform.rotation)); break; } case SdfBrush.BoundaryShapeEnum.Torus: { Vector3 r = new Vector3(0.5f * size.x, 0.0f, 0.5f * size.z); bounds = new Aabb(-r, r); bounds.Rotate(RotationRs(transform.rotation)); Vector3 round = radius * Vector3.one; bounds.Min -= round; bounds.Max += round; break; } case SdfBrush.BoundaryShapeEnum.SolidAngle: { Vector3 r = radius * VectorUtil.Abs(transform.localScale); bounds = new Aabb(-r, r); break; } } return(bounds); }
public void Rotate(Quaternion q) { Vector3 oldExtentsA = Extent; Vector3 newExtents = oldExtentsA; newExtents = VectorUtil.Max(newExtents, VectorUtil.Abs(q * new Vector3(oldExtentsA.x, oldExtentsA.y, oldExtentsA.z))); newExtents = VectorUtil.Max(newExtents, VectorUtil.Abs(q * new Vector3(-oldExtentsA.x, oldExtentsA.y, oldExtentsA.z))); newExtents = VectorUtil.Max(newExtents, VectorUtil.Abs(q * new Vector3(oldExtentsA.x, -oldExtentsA.y, oldExtentsA.z))); newExtents = VectorUtil.Max(newExtents, VectorUtil.Abs(q * new Vector3(oldExtentsA.x, oldExtentsA.y, -oldExtentsA.z))); Vector3 newCenter = q * Center; Min = newCenter - newExtents; Max = newCenter + newExtents; }