예제 #1
0
        // 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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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;
        }