示例#1
0
        static int CountIntersections(PhysicsScene physicsScene, Vector3 v, Vector3 dist, float length)
        {
            v += dist * .01f;

            if (!kDebug)
            {
                var hitCount = physicsScene.Raycast(v, dist, s_RayCastHits, length, 1 << kWorkLayer);
                hitCount += physicsScene.Raycast(v + dist * length, -dist, s_RayCastHits, length, 1 << kWorkLayer);
                return(hitCount);
            }

            physicsScene.Raycast(v, dist, s_RayCastHits, length, 1 << kWorkLayer);
            int   hitLength = s_RayCastHits.Length;
            float maxDist   = 0;

            if (hitLength > 0)
            {
                maxDist = s_RayCastHits[s_RayCastHits.Length - 1].distance;
            }

            physicsScene.Raycast(v + dist * length, -dist, s_RayCastHits, length, 1 << kWorkLayer);
            if (s_RayCastHits.Length > 0)
            {
                float len = length - s_RayCastHits[0].distance;
                if (len > maxDist)
                {
                    maxDist = len;
                }
            }

            return(hitLength + s_RayCastHits.Length);
        }
示例#2
0
    float GetDistance2d(Vector3 point)
    {
        int        layerMask = ~(1 << 14);
        RaycastHit hit;

        if (!physicsScene.Raycast(point, Vector3.down, out hit, _maxHeight, layerMask))
        {
            return(1f);
        }
        float distance = hit.distance;

        distance = Mathf.Clamp(distance, -1f, 1f);
        return(distance);
    }
示例#3
0
        // Concave.
        private static bool IsInsideCollider(
            PhysicsScene scene,
            int mask,
            Vector3 point,
            Bounds bounds)
        {
            bounds.Expand(0.1f); // Pad.
            Vector4[] sides = new Vector4[]
            {
                // Ray origins, w = ray length.
                new Vector4(bounds.min.x, point.y, point.z, point.x - bounds.min.x),
                new Vector4(bounds.max.x, point.y, point.z, bounds.max.x - point.x),
                new Vector4(point.x, bounds.min.y, point.z, point.y - bounds.min.y),
                new Vector4(point.x, bounds.max.y, point.z, bounds.max.y - point.y),
                new Vector4(point.x, point.y, bounds.min.z, point.z - bounds.min.z),
                new Vector4(point.x, point.y, bounds.max.z, bounds.max.z - point.z)
            };

            for (int i = 0; i < 6; i++)
            {
                // NOTE PhysicsScene doesn't support linecast.
                // TODO Check against volume colliders?
                if (!scene.Raycast(
                        sides[i],
                        point - (Vector3)sides[i],
                        sides[i].w,
                        mask))
                {
                    return(false);
                }
            }
            // TODO Can we ignore all cells the rays have
            // already passed through at later cell checks?
            return(true);
        }
示例#4
0
    // --------------------------------------------------------------------

    private bool GetRaycastedPoint(Vector3 from, Vector3 to, out Vector3 hitPos, out Vector3 hitNormal, out Transform hitObj, Transform filterTransform = null)
    {
        hitObj    = null;
        hitNormal = Vector3.up;
        hitPos    = to;

        Vector3 dir = (to - from).normalized;

        PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage();

        if (prefabStage != null)
        {
            Scene        scene       = prefabStage.scene;
            PhysicsScene physicScene = scene.GetPhysicsScene();
            if (physicScene.Raycast(from, dir, out RaycastHit hit, 100, ~0, QueryTriggerInteraction.Ignore))
            {
                hitPos    = hit.point;
                hitObj    = hit.transform;
                hitNormal = hit.normal;

                return(!filterTransform || filterTransform && hitObj == filterTransform);
            }
            else
            {
                return(false);
            }
        }
示例#5
0
        static bool TestPointOcclusion(PhysicsScene physicsScene, RaycastHit[] hits, Vector3 camPosition, Vector3 lookPosition, bool ignoreClose, out int hitCount)
        {
            var direction = lookPosition - camPosition;
            var distance  = Vector3.Distance(camPosition, lookPosition);

            hitCount = physicsScene.Raycast(camPosition, direction, hits, distance);

            // without ignoring collisions very close to the marker, such as surfaces it is on or
            // the marker renderer itself, the raycast test can make the marker can appear occluded when it is not
            if (!ignoreClose)
            {
                return(hitCount > 0);
            }

            var ignoredCount = 0;

            for (var i = 0; i < hitCount; i++)
            {
                // we want to ignore collisions within 0.05m
                const float ignoreHitSqrMagnitude = 0.05f * 0.05f;
                if (Vector3.SqrMagnitude(lookPosition - hits[i].point) < ignoreHitSqrMagnitude)
                {
                    ignoredCount++;
                }
            }

            hitCount -= ignoredCount;
            return(hitCount > 0);
        }
示例#6
0
        // Casts /ray/ against the scene.
        public static object RaySnap(Ray ray)
        {
            PhysicsScene physicsScene = Physics.defaultPhysicsScene;
            Scene        customScene  = Camera.current.scene;

            if (customScene.IsValid())
            {
                physicsScene = customScene.GetPhysicsScene();
            }

            int numHits = physicsScene.Raycast(ray.origin, ray.direction, s_RaySnapHits, Mathf.Infinity, Camera.current.cullingMask, QueryTriggerInteraction.Ignore);

            // We are not sure at this point if the hits returned from RaycastAll are sorted or not, so go through them all
            float nearestHitDist  = Mathf.Infinity;
            int   nearestHitIndex = -1;

            if (ignoreRaySnapObjects != null)
            {
                for (int i = 0; i < numHits; i++)
                {
                    if (s_RaySnapHits[i].distance < nearestHitDist)
                    {
                        bool ignore = false;
                        for (int j = 0; j < ignoreRaySnapObjects.Length; j++)
                        {
                            if (s_RaySnapHits[i].transform == ignoreRaySnapObjects[j])
                            {
                                ignore = true;
                                break;
                            }
                        }
                        if (!ignore)
                        {
                            nearestHitDist  = s_RaySnapHits[i].distance;
                            nearestHitIndex = i;
                        }
                    }
                }
            }
            else
            {
                for (int i = 0; i < numHits; i++)
                {
                    if (s_RaySnapHits[i].distance < nearestHitDist)
                    {
                        nearestHitDist  = s_RaySnapHits[i].distance;
                        nearestHitIndex = i;
                    }
                }
            }

            if (nearestHitIndex >= 0)
            {
                return(s_RaySnapHits[nearestHitIndex]);
            }
            return(null);
        }
示例#7
0
        /// <summary>
        /// Compute a grid-aligned position for the brick on intersecting geometry or on a pre-defined world plane
        /// </summary>
        /// <param name="ray">The ray to shoot into the scene and intersect with a plane</param>
        /// <param name="worldPlane">A fallback plane we want to intersect with/find a new position on if no geometry is hit</param>
        /// <param name="physicsScene">The physics scene we are working in</param>
        /// <param name="collidingHit">Out parameter for a raycast hit</param>
        /// <returns>The grid aligned position aligned to LU_5</returns>
        public static bool GetGridAlignedPosition(Ray ray, Plane worldPlane, PhysicsScene physicsScene, float maxDistance, out RaycastHit collidingHit)
        {
            var ignore = ~LayerMask.GetMask(Connection.connectivityReceptorLayerName, Connection.connectivityConnectorLayerName);
            var hits   = physicsScene.Raycast(ray.origin, ray.direction, raycastBuffer, maxDistance, ignore, QueryTriggerInteraction.Ignore);

            if (hits > 0)
            {
                var shortestDistance = 10000.0f;
                var raycastHit       = new RaycastHit();
                var hasHit           = false;
                for (var i = 0; i < hits; i++)
                {
                    var hit   = raycastBuffer[i];
                    var go    = hit.collider.gameObject;
                    var brick = go.GetComponentInParent <Brick>();
                    if (brick == null)
                    {
                        var distance = Vector3.Distance(ray.origin, hit.point);
                        if (distance < shortestDistance)
                        {
                            hasHit           = true;
                            shortestDistance = distance;
                            raycastHit       = hit;
                        }
                    }
                }

                if (hasHit)
                {
                    collidingHit = raycastHit;
                    return(true);
                }
            }

            collidingHit = new RaycastHit();
            // Check if we hit the ground
            if (worldPlane.Raycast(ray, out float enter))
            {
                if (enter > maxDistance)
                {
                    return(false);
                }
                var hitPoint = ray.GetPoint(enter);
                collidingHit.point    = hitPoint;
                collidingHit.distance = enter;
                collidingHit.normal   = worldPlane.normal;
                return(true);
            }

            return(false);
        }
示例#8
0
    public void PerformShootRayCast(uint frame, ServerPlayer shooter)
    {
        int dif = (int)(ServerTick - 1 - frame);

        //get the position of the ray
        Vector3 firepoint;
        Vector3 direction;

        if (shooter.UpdateDataHistory.Count > dif)
        {
            firepoint = shooter.UpdateDataHistory[dif].Position;
            direction = shooter.UpdateDataHistory[dif].LookDirection * Vector3.forward;
        }
        else
        {
            firepoint = shooter.CurrentUpdateData.Position;
            direction = shooter.CurrentUpdateData.LookDirection * Vector3.forward;
        }

        firepoint += direction * 3f;

        //set all players back in time
        foreach (ServerPlayer player in ServerPlayers)
        {
            if (player.UpdateDataHistory.Count > dif)
            {
                player.Logic.CharacterController.enabled = false;
                player.transform.localPosition           = player.UpdateDataHistory[dif].Position;
            }
        }



        RaycastHit hit;

        if (physicsScene.Raycast(firepoint, direction, out hit, 200f))
        {
            if (hit.transform.CompareTag("Unit"))
            {
                hit.transform.GetComponent <ServerPlayer>().TakeDamage(5);
            }
        }


        //set all players back
        foreach (ServerPlayer player in ServerPlayers)
        {
            player.transform.localPosition           = player.CurrentUpdateData.Position;
            player.Logic.CharacterController.enabled = true;
        }
    }
示例#9
0
        public float RaycastDistance(Vector3 origin, Vector3 direction, int layerMask, float maxDistance = Mathf.Infinity)
        {
            RaycastHit hit;

            if (PhysicsScene.Raycast(
                    origin, direction,
                    out hit, maxDistance,
                    layerMask)
                )
            {
                return(hit.distance);
            }

            return(0f);
        }
示例#10
0
    // Update is called once per frame
    void Update()
    {
        Vector3    desiredCameraPos = transform.parent.TransformPoint(dollyDir * maxDistance);
        RaycastHit hit;

        if (scene.Raycast(transform.parent.position, (desiredCameraPos - transform.parent.position).normalized, out hit, maxDistance * 2.0f, masks))
        {
            distance = Mathf.Clamp((hit.distance * 0.87f), minDistance, maxDistance);
        }
        else
        {
            distance = maxDistance;
        }

        transform.localPosition = Vector3.Lerp(transform.localPosition, dollyDir * distance, Time.deltaTime * smooth);
    }
示例#11
0
        public float DistanceFromGround(Vector3 position)
        {
            RaycastHit hit;

            if (PhysicsScene.Raycast(
                    position,
                    Vector3.down,
                    out hit, Mathf.Infinity,
                    1 << SceneContext.GetStaticForegroundLayer())
                )
            {
                return(hit.distance);
            }

            return(0f);
        }
示例#12
0
 private bool IsGrounded()
 {
     return(pScene.Raycast(col.bounds.center, new Vector3(0, -1, 0), jumpDetectDistance, groundLayers));
 }
示例#13
0
        private void F(PhysicsScene physicsScene, float deltaTime, Transform root, Rigidbody rigidbody, Transform wheel,
                       Vehicle vehicle)
        {
            WheelBaseConfigAuthoring wbc = wheel.GetComponent <WheelBaseConfigAuthoring>();
            WheelBaseInfoAuthoring   wbi = wheel.GetComponent <WheelBaseInfoAuthoring>();

            float drift = 0F;

            wbi.MaxLength = wbc.RestLength + wbc.SpringTravel;
            wbi.MinLength = wbc.RestLength - wbc.SpringTravel;

            RaycastInput input = new RaycastInput
            {
                Start = wheel.position,
                End   = root.transform.up * -1,
            };

            // Debug.DrawRay(input.Start, input.End * wbi.MaxLength, Color.red);
            if (!physicsScene.Raycast(input.Start, input.End, out var hit, wbi.MaxLength, wbc.layerMask))
            {
                return;
            }

            wbi.LastLength     = wbi.SpringLength;
            wbi.SpringLength   = hit.distance;
            wbi.SpringLength   = math.clamp(wbi.SpringLength, wbi.MinLength, wbi.MaxLength);
            wbi.SpringVelocity = (wbi.LastLength - wbi.SpringLength) / deltaTime;

            wbi.SpringForce     = wbc.SpringStiffness * (wbc.RestLength - wbi.SpringLength);
            wbi.DamperForce     = wbc.DamperStiffness * wbi.SpringVelocity;
            wbi.SuspensionForce = (wbi.SpringForce + wbi.DamperForce) * rigidbody.transform.up;

            rigidbody.AddForceAtPosition(wbi.SuspensionForce, wheel.position);

            //=========================================================================================================
            quaternion rootRotation = root.rotation;

            var up      = math.mul(rootRotation, new float3(0, 1, 0));
            var forward = math.mul(rootRotation, new float3(0, 0, 1));

            var v = vehicle.vehicleInput.v;

            rigidbody.AddForceAtPosition(forward * (1000F) * v,
                                         hit.point + (wheel.position - hit.point) / 4f);

            var h = vehicle.vehicleInput.h;

            rigidbody.AddTorque(h * up * vehicle.turn);

            var linearVelocity  = rigidbody.velocity;
            var angularVelocity = rigidbody.angularVelocity;

            float3 localAngleVelocity = root.InverseTransformVector(angularVelocity);

            localAngleVelocity.y *= 0.9f + (drift / 10);
            angularVelocity       = root.TransformVector(localAngleVelocity);

            Vector3 localVelocity = root.InverseTransformVector(linearVelocity);

            localVelocity.x *= 0.9f + (drift / 10);
            linearVelocity   = root.TransformVector(localVelocity);

            rigidbody.velocity        = linearVelocity;
            rigidbody.angularVelocity = angularVelocity;
        }
示例#14
0
        private static List <ScanResultLOD> GetLODPointLists(
            PhysicsScene scene,
            Transform transform,
            GameObjectShape shape)
        {
            SplitVolumesIntoCells(shape.ScanLOD);

            int  mask    = 1 << transform.gameObject.layer;
            bool flatten = shape.Flatten;

            var result = ScanResultLOD.CreateList(flatten ? 1 : s_GlobalMaxLOD + 1);

            foreach (Volume vol in s_Volumes)
            {
                ToggleActiveColliders(vol);

                bool       isConcave       = vol.IsConcave;
                Vector3    cellSize        = vol.CellSize;
                Vector3Int gridSize        = vol.GridSize;
                Vector3    offset          = vol.Bounds.min + cellSize * 0.5f;
                Vector3    boundsCenter    = vol.Bounds.center;
                float      boundsMagnitude = vol.Bounds.size.magnitude;
                int        nx = gridSize.x - 1;
                int        ny = gridSize.y - 1;
                int        nz = gridSize.z - 1;


                // Find cells occupied by colliders.

                Clear(gridSize);

                for (int x = 0; x <= nx; x++)
                {
                    for (int y = 0; y <= ny; y++)
                    {
                        for (int z = 0; z <= nz; z++)
                        {
                            Vector3 worldPoint = Vector3.Scale(
                                new Vector3(x, y, z), cellSize) + offset;

                            bool isInside = isConcave
                                ? IsInsideCollider(
                                scene, mask, worldPoint, vol.Bounds)
                                : IsInsideCollider(
                                scene, mask, worldPoint, vol.Colliders);

                            s_HollowGrid[x, y, z] = isInside;
                            s_FilledGrid[x, y, z] = isInside;
                        }
                    }
                }


                // Reduce cell count, hollow out filled grid.

                for (int x = 1; x < nx; x++)
                {
                    for (int y = 1; y < ny; y++)
                    {
                        for (int z = 1; z < nz; z++)
                        {
                            if (s_FilledGrid[x, y, z])
                            {
                                s_HollowGrid[x, y, z] &=
                                    !(s_FilledGrid[x - 1, y, z]
                                      & s_FilledGrid[x + 1, y, z]
                                      & s_FilledGrid[x, y - 1, z]
                                      & s_FilledGrid[x, y + 1, z]
                                      & s_FilledGrid[x, y, z - 1]
                                      & s_FilledGrid[x, y, z + 1]);
                            }
                        }
                    }
                }


                // Downsample cells for generating LODs
                // and store points in corresponding groups.

                int   level = flatten ? 0 : vol.MaxLOD;
                float yFlat = transform.position.y;

                for (int x = 0; x <= nx; x++)
                {
                    for (int y = 0; y <= ny; y++)
                    {
                        for (int z = 0; z <= nz; z++)
                        {
                            if (s_HollowGrid[x, y, z])
                            {
                                Cell    cell       = new Cell(level, x, y, z);
                                Vector3 worldPoint = cell.Scale(cellSize) + offset;

                                if (flatten)
                                {
                                    cell.y       = 0;
                                    worldPoint.y = yFlat;
                                }

                                // Highest LOD.
                                AddPoint(cell, worldPoint);

                                for (int i = level; i > 0; i--)
                                {
                                    cell = cell.Downsample();
                                    AddPoint(cell, worldPoint);
                                }
                            }
                        }
                    }
                }


                // Write centroids to result.

                Matrix4x4 matrix     = transform.worldToLocalMatrix;
                float     projection = shape.Projection;
                bool      project    = projection > 0;

                foreach (var kvp in s_PointGroupsByCell)
                {
                    // KeyValuePair, Key: Cell, Value: PointGroup.
                    int     i          = kvp.Key.level;
                    Vector3 worldPoint = kvp.Value.Centroid;

                    if (project && i > 0)
                    {
                        // Project outward from volume bounds center,
                        // unless lowest LOD or flattened points -> i == 0.
                        // NOTE Doesn't work well with compound or concave colliders.
                        Vector3 normal = (worldPoint - boundsCenter).normalized;
                        if (scene.Raycast(boundsCenter + normal * boundsMagnitude,
                                          -normal, out RaycastHit hit, boundsMagnitude, mask))
                        {
                            worldPoint = Vector3.Lerp(worldPoint, hit.point, projection);
                        }
                    }
                    // World -> local.
                    result[i].LocalPoints.Add(matrix.MultiplyPoint3x4(worldPoint));
                }
            }

            ToggleActiveColliders();

            return(result);
        }
        static bool GetNearestHitFromPhysicsScene(Ray ray, PhysicsScene physicsScene, int cullingMask, bool ignorePrefabInstance, ref RaycastHit raycastHit)
        {
            float maxDist = raycastHit.distance;
            int   numHits = physicsScene.Raycast(ray.origin, ray.direction, s_RaySnapHits, maxDist, cullingMask, QueryTriggerInteraction.Ignore);

            // We are not sure at this point if the hits returned from RaycastAll are sorted or not, so go through them all
            float nearestHitDist  = maxDist;
            int   nearestHitIndex = -1;

            if (ignoreRaySnapObjects != null)
            {
                for (int i = 0; i < numHits; i++)
                {
                    if (s_RaySnapHits[i].distance < nearestHitDist)
                    {
                        Transform tr = s_RaySnapHits[i].transform;
                        if (ignorePrefabInstance && GameObjectUtility.IsPrefabInstanceHiddenForInContextEditing(tr.gameObject))
                        {
                            continue;
                        }

                        bool ignore = false;
                        for (int j = 0; j < ignoreRaySnapObjects.Length; j++)
                        {
                            if (tr == ignoreRaySnapObjects[j])
                            {
                                ignore = true;
                                break;
                            }
                        }
                        if (ignore)
                        {
                            continue;
                        }

                        nearestHitDist  = s_RaySnapHits[i].distance;
                        nearestHitIndex = i;
                    }
                }
            }
            else
            {
                for (int i = 0; i < numHits; i++)
                {
                    if (s_RaySnapHits[i].distance < nearestHitDist)
                    {
                        nearestHitDist  = s_RaySnapHits[i].distance;
                        nearestHitIndex = i;
                    }
                }
            }

            if (nearestHitIndex >= 0)
            {
                raycastHit = s_RaySnapHits[nearestHitIndex];
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#16
0
 public bool CastLine(Vector3 origin, Vector3 direction, float maxDistance = Mathf.Infinity, int layerMask = Physics3D.DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal)
 {
     return(_world.Raycast(origin, direction, maxDistance, layerMask, queryTriggerInteraction));
 }
示例#17
0
 public bool Raycast(Vector3 origin, Vector3 direction, float maxDistance, out RaycastHit raycastHit)
 {
     return(physicsScene.Raycast(origin, direction, out raycastHit, maxDistance, ignoreColliders));
 }