예제 #1
0
        public static VFixedPoint distancePointBoxSquared(VInt3 point, VIntTransform boxTransform, VInt3 boxExtent, ref VInt3 boxParam)
        {
            VInt3 closest = boxTransform.InverseTransformPoint(point);

            VFixedPoint sqrDistance = VFixedPoint.Zero;

            for (int ax = 0; ax < 3; ax++)
            {
                if (closest[ax] < -boxExtent[ax])
                {
                    VFixedPoint delta = closest[ax] + boxExtent[ax];
                    sqrDistance += delta * delta;
                    closest[ax]  = -boxExtent[ax];
                }
                else if (closest[ax] > boxExtent[ax])
                {
                    VFixedPoint delta = closest[ax] - boxExtent[ax];
                    sqrDistance += delta * delta;
                    closest[ax]  = boxExtent[ax];
                }
            }
            boxParam = closest;

            return(sqrDistance);
        }
예제 #2
0
        public static bool rayTestBox(VInt3 fromPos, VInt3 toPos, VInt3 boxHalfExtent, VIntTransform boxTransform, ref VFixedPoint t, ref VInt3 normal)
        {
            VInt3 rayFromPointLocal = boxTransform.InverseTransformPoint(fromPos);
            VInt3 rayToPointLocal   = boxTransform.InverseTransformPoint(toPos);

            t = VFixedPoint.One;
            VInt3 normalInLocal = VInt3.zero;

            if (AabbUtils.RayAabb(rayFromPointLocal, rayToPointLocal, -boxHalfExtent, boxHalfExtent, ref t, ref normalInLocal))
            {
                normal = -boxTransform.TransformDirection(normalInLocal);
                return(true);
            }

            return(false);
        }
예제 #3
0
        public static bool getSphereDistance(BoxShape boxShape, VIntTransform m44T, VInt3 sphereCenter, VFixedPoint radius, out VInt3 normal, out VFixedPoint penetrationDepth)
        {
            VInt3       boxHalfExtent = boxShape.getHalfExtent();
            VFixedPoint boxMargin     = boxShape.getMargin();

            penetrationDepth = VFixedPoint.Zero;

            // convert the sphere position to the box's local space
            VInt3 sphereRelPos = m44T.InverseTransformPoint(sphereCenter);

            // Determine the closest point to the sphere center in the box
            VInt3 closestPoint = sphereRelPos;

            closestPoint.x = (FMath.Min(boxHalfExtent.x, closestPoint.x));
            closestPoint.x = (FMath.Max(-boxHalfExtent.x, closestPoint.x));
            closestPoint.y = (FMath.Min(boxHalfExtent.y, closestPoint.y));
            closestPoint.y = (FMath.Max(-boxHalfExtent.y, closestPoint.y));
            closestPoint.z = (FMath.Min(boxHalfExtent.z, closestPoint.z));
            closestPoint.z = (FMath.Max(-boxHalfExtent.z, closestPoint.z));

            VFixedPoint intersectionDist = radius + boxMargin;
            VFixedPoint contactDist      = intersectionDist;

            normal = sphereRelPos - closestPoint;

            //if there is no penetration, we are done
            VFixedPoint dist2 = normal.sqrMagnitude;

            if (dist2 > contactDist * contactDist)
            {
                return(false);
            }

            VFixedPoint distance;

            //special case if the sphere center is inside the box
            if (dist2 <= Globals.EPS)
            {
                distance = -getSpherePenetration(boxHalfExtent, sphereRelPos, ref closestPoint, out normal);
            }
            else //compute the penetration details
            {
                distance = normal.magnitude;
                normal  /= distance;
            }

            //	v3PointOnSphere = sphereRelPos - (normal * fRadius);
            penetrationDepth = distance - intersectionDist;

            VInt3 tmp = m44T.TransformDirection(normal);

            normal = tmp;

            return(true);
        }
예제 #4
0
        public static VFixedPoint distanceLineBoxSquared(VInt3 lineOrigin, VInt3 lineDirection,
                                                         VInt3 boxExtent, VIntTransform boxTransform, ref VFixedPoint lineParam, ref VInt3 boxParam)
        {
            // compute coordinates of line in box coordinate system
            VInt3 pnt = boxTransform.InverseTransformPoint(lineOrigin);
            VInt3 dir = boxTransform.InverseTransformDirection(lineDirection);

            // Apply reflections so that direction vector has nonnegative components.
            bool[] reflect = new bool[3];
            for (int i = 0; i < 3; i++)
            {
                if (dir[i] < VFixedPoint.Zero)
                {
                    pnt[i]     = -pnt[i];
                    dir[i]     = -dir[i];
                    reflect[i] = true;
                }
                else
                {
                    reflect[i] = false;
                }
            }

            VFixedPoint sqrDistance = VFixedPoint.Zero;

            if (dir.x > VFixedPoint.Zero)
            {
                if (dir.y > VFixedPoint.Zero)
                {
                    if (dir.z > VFixedPoint.Zero)
                    {
                        caseNoZero(ref pnt, dir, boxExtent, ref lineParam, ref sqrDistance);
                    }
                    else
                    {
                        case0(0, 1, 2, ref pnt, dir, boxExtent, ref lineParam, ref sqrDistance);
                    }
                }
                else
                {
                    if (dir.z > VFixedPoint.Zero)
                    {
                        case0(0, 2, 1, ref pnt, dir, boxExtent, ref lineParam, ref sqrDistance);                            // (+,0,+)
                    }
                    else
                    {
                        case00(0, 1, 2, ref pnt, dir, boxExtent, ref lineParam, ref sqrDistance);       // (+,0,0)
                    }
                }
            }
            else
            {
                if (dir.y > VFixedPoint.Zero)
                {
                    if (dir.z > VFixedPoint.Zero)
                    {
                        case0(1, 2, 0, ref pnt, dir, boxExtent, ref lineParam, ref sqrDistance);                            // (0,+,+)
                    }
                    else
                    {
                        case00(1, 0, 2, ref pnt, dir, boxExtent, ref lineParam, ref sqrDistance);   // (0,+,0)
                    }
                }
                else
                {
                    if (dir.z > VFixedPoint.Zero)
                    {
                        case00(2, 0, 1, ref pnt, dir, boxExtent, ref lineParam, ref sqrDistance);                           // (0,0,+)
                    }
                    else
                    {
                        case000(ref pnt, boxExtent, ref sqrDistance);                                       // (0,0,0)
                        lineParam = VFixedPoint.Zero;
                    }
                }
            }

            for (int i = 0; i < 3; i++)
            {
                boxParam[i] = pnt[i] * (reflect[i] ? -1 : 1);
            }

            return(sqrDistance);
        }