Esempio n. 1
0
        public override void SolverUpdate()
        {
            // Pass-through by default
            this.GoalPosition = WorkingPos;
            this.GoalRotation = WorkingRot;

            // Determine raycast params
            Ray ray = new Ray(GetRaycastOrigin(), GetRaycastDirection());

            // Skip if there's no valid direction
            if (ray.direction == Vector3.zero)
            {
                return;
            }

            float ScaleOverride = GetScaleOverride();
            float len;
            bool  bHit;
            RaycastResultHelper result;
            Vector3             hitDelta;

            switch (raycastMode)
            {
            case RaycastModeEnum.Simple:
            default:

                // Do the cast!
                bHit = DefaultRaycast(ray.origin, ray.direction, MaxDistance, MagneticSurface, out result);

                OnSurface = bHit;

                if (UseTexCoordNormals)
                {
                    result.OverrideNormalFromTextureCoord();
                }

                // Enforce CloseDistance
                hitDelta = result.Point - ray.origin;
                len      = hitDelta.magnitude;
                if (len < CloseDistance)
                {
                    result.OverridePoint(ray.origin + ray.direction * CloseDistance);
                }

                // Apply results
                if (bHit)
                {
                    GoalPosition = result.Point + SurfaceNormalOffset * result.Normal + SurfaceRayOffset * ray.direction;
                    GoalRotation = CalculateMagnetismOrientation(ray.direction, result.Normal);
                }
                break;

            case RaycastModeEnum.Box:

                Vector3 scale = transform.lossyScale;
                if (ScaleOverride > 0)
                {
                    scale = scale.normalized * ScaleOverride;
                }

                Quaternion orientation  = orientationMode == OrientModeEnum.None ? Quaternion.LookRotation(ray.direction, Vector3.up) : CalculateMagnetismOrientation(ray.direction, Vector3.up);
                Matrix4x4  targetMatrix = Matrix4x4.TRS(Vector3.zero, orientation, scale);

                if (m_BoxCollider == null)
                {
                    m_BoxCollider = this.GetComponent <BoxCollider>();
                }

                Vector3 extents = m_BoxCollider.size;

                Vector3[] positions;
                Vector3[] normals;
                bool[]    hits;

                if (RaycastHelper.CastBoxExtents(extents, transform.position, targetMatrix, ray, MaxDistance, MagneticSurface, DefaultRaycast, BoxRaysPerEdge, OrthoBoxCast, out positions, out normals, out hits))
                {
                    Plane plane;
                    float distance;

                    // place an unconstrained plane down the ray.  Never use vertical constrain.
                    FindPlacementPlane(ray.origin, ray.direction, positions, normals, hits, m_BoxCollider.size.x, MaximumNormalVariance, false, orientationMode == OrientModeEnum.None, out plane, out distance);

                    // If placing on a horzizontal surface, need to adjust the calculated distance by half the app height
                    float verticalCorrectionOffset = 0;
                    if (IsNormalVertical(plane.normal) && !Mathf.Approximately(ray.direction.y, 0))
                    {
                        float   boxSurfaceOffsetVert = targetMatrix.MultiplyVector(new Vector3(0, extents.y / 2f, 0)).magnitude;
                        Vector3 correctionVec        = boxSurfaceOffsetVert * (ray.direction / ray.direction.y);
                        verticalCorrectionOffset = -correctionVec.magnitude;
                    }

                    float boxSurfaceOffset = targetMatrix.MultiplyVector(new Vector3(0, 0, extents.z / 2f)).magnitude;

                    // Apply boxSurfaceOffset to rayDir and not surfaceNormalDir to reduce sliding
                    GoalPosition = ray.origin + ray.direction * Mathf.Max(CloseDistance, distance + SurfaceRayOffset + boxSurfaceOffset + verticalCorrectionOffset) + plane.normal * (0 * boxSurfaceOffset + SurfaceNormalOffset);
                    GoalRotation = CalculateMagnetismOrientation(ray.direction, plane.normal);
                    OnSurface    = true;
                }
                else
                {
                    OnSurface = false;
                }
                break;

            case RaycastModeEnum.Sphere:

                // Do the cast!
                float size = ScaleOverride > 0 ? ScaleOverride : transform.lossyScale.x * SphereSize;
                bHit      = DefaultSpherecast(ray.origin, ray.direction, size, MaxDistance, MagneticSurface, out result);
                OnSurface = bHit;

                // Enforce CloseDistance
                hitDelta = result.Point - ray.origin;
                len      = hitDelta.magnitude;
                if (len < CloseDistance)
                {
                    result.OverridePoint(ray.origin + ray.direction * CloseDistance);
                }

                // Apply results
                if (bHit)
                {
                    GoalPosition = result.Point + SurfaceNormalOffset * result.Normal + SurfaceRayOffset * ray.direction;
                    GoalRotation = CalculateMagnetismOrientation(ray.direction, result.Normal);
                }
                break;
            }

            // Do frame to frame updates of transform, smoothly toward the goal, if desired
            UpdateWorkingPosToGoal();
            UpdateWorkingRotToGoal();
        }
Esempio n. 2
0
 private static bool DefaultSpherecast(Vector3 origin, Vector3 direction, float radius, float distance, LayerMask surface, out RaycastResultHelper result)
 {
     return(RaycastHelper.SphereFirst(origin, direction, radius, distance, surface, out result));
 }