Ejemplo n.º 1
0
        /// <summary>
        /// 光线追踪测试
        /// </summary>
        /// <param name="ray"></param>
        /// <returns></returns>
        public override RayCastResult Intersection(Ray ray, float nowbest)
        {
            // 包围盒测试失败
            {
                (bool happened, float mint) = BoundBox.Intersection(ray);
                if (!happened || mint > nowbest)                   // 未相交 或 当前最小解已不是最优
                {
                    return(null);
                }
            }

            RayCastResult result = BVH.Intersection(ray, float.MaxValue);

            if (result != null)
            {
                result.material = Material;
                if (result.internalPoint)
                {
                    result.IOR = 1.0f;
                }
                else
                {
                    result.IOR = Material.Refraction.IOR;
                }
            }
            return(result);
        }
Ejemplo n.º 2
0
        unsafe RayCastResult GetRayCastResultFromNative(NativeRayCastResult *native)
        {
            RayCastResult result = new RayCastResult();

            if (native->shape != IntPtr.Zero)
            {
                result.Shape    = PhysXPhysicsWorld.Instance.GetShapeByNativePointer(native->shape);
                result.Position = native->worldImpact;
                result.Normal   = native->worldNormal;
                result.Distance = native->distance;
                if (result.Shape.ShapeType == Shape.Type.Mesh)
                {
                    MeshShape meshShape = (MeshShape)result.Shape;
                    if (meshShape.MeshType != MeshShape.MeshTypes.ConvexHullDecomposition)
                    {
                        result.TriangleID = native->faceID;
                    }
                }
                else if (result.Shape.ShapeType == Shape.Type.HeightField)
                {
                    result.TriangleID = native->faceID;
                }
                else
                {
                    result.TriangleID = 0;
                }
            }
            return(result);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Casts a convex shape against the collidable.
        /// </summary>
        /// <param name="castShape">Shape to cast.</param>
        /// <param name="startingTransform">Initial transform of the shape.</param>
        /// <param name="sweep">Sweep to apply to the shape.</param>
        /// <param name="filter">Test to apply to the entry. If it returns true, the entry is processed, otherwise the entry is ignored. If a collidable hierarchy is present
        /// in the entry, this filter will be passed into inner ray casts.</param>
        /// <param name="result">Hit data, if any.</param>
        /// <returns>Whether or not the cast hit anything.</returns>
        public bool ConvexCast(ConvexShapes.ConvexShape castShape, ref RigidTransform startingTransform, ref Vector3 sweep, Func <BroadPhaseEntry, bool> filter, out RayCastResult result)
        {
            var         outputOverlappedElements = PhysicsResources.GetCollidableList();
            BoundingBox boundingBox;

            castShape.GetSweptBoundingBox(ref startingTransform, ref sweep, out boundingBox);

            CollidableTree.GetOverlaps(boundingBox, outputOverlappedElements);
            result           = new RayCastResult();
            result.HitData.T = Fix64.MaxValue;
            for (int i = 0; i < outputOverlappedElements.Count; ++i)
            {
                RayHit hit;
                if (outputOverlappedElements.Elements[i].ConvexCast(castShape, ref startingTransform, ref sweep, filter, out hit))
                {
                    if (hit.T < result.HitData.T)
                    {
                        result.HitData   = hit;
                        result.HitObject = outputOverlappedElements.Elements[i];
                    }
                }
            }
            PhysicsResources.GiveBack(outputOverlappedElements);
            return(result.HitData.T < Fix64.MaxValue);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Move vessel up
        /// </summary>
        /// <param name="v"></param>
        private static void MoveUp(Vessel v)
        {
            v.ResetCollisionIgnores();

            // TODO: Try DisableSuspension() on wheels

            float upMovement = 0.0f;

            float   vesselHeight = bounds.topLength + bounds.bottomLength;
            Vector3 up           = (v.transform.position - FlightGlobals.currentMainBody.transform.position).normalized;

            while (upMovement < maxUpMovement)
            {
                RayCastResult alt = GetRaycastAltitude(v, bounds.bottomPoint + up * vesselHeight, rayCastMask); // mask: ground only

                if (alt.altitude - vesselHeight < minDownMovement)
                {
                    v.Translate(up * upMovementStep);
                    upMovement += upMovementStep;
                }
                else
                {
                    break;
                }
            }
        }
Ejemplo n.º 5
0
        private float TestObjectVisibility(GameObject go)
        {
            int             nSuccess       = 0;
            var             rayCastTargets = GetRayCastTargets(go);
            IList <Vector3> testPoints     = rayCastTargets.GetTargetPoints();

            for (int i = 0; i < testPoints.Count; i++)
            {
                var testPoint = testPoints[i];
                var result    = new RayCastResult();
                result.Go           = go;
                result.TestPoint    = testPoint;
                result.IsObstructed = false;
                if (IsInLineOfSight(go, testPoint, out var obstructionPoint))
                {
                    nSuccess++;
                    rayCastTargets.SetIsTargetVisible(i, true);
                }
                else
                {
                    result.IsObstructed     = true;
                    result.ObstructionPoint = obstructionPoint;
                    rayCastTargets.SetIsTargetVisible(i, false);
                }
                _raycastResults.Add(result);
            }
            return(nSuccess / (float)testPoints.Count);
        }
Ejemplo n.º 6
0
        public List <RayCastResult> CastRaysAroundPosition(Vector3D position, Vector3D forward, double distance, int raysCount)
        {
            var results = new List <RayCastResult>();

            for (int i = 0; i < raysCount; i++)
            {
                var rotation = MatrixD.CreateRotationY((2 * Math.PI / raysCount) * i);

                var direction = Vector3D.Rotate(forward, rotation);
                var from      = position;
                var to        = from + distance * direction;

                MyAPIGateway.Physics.CastRay(from, to, out var hitInfo);

                var result = new RayCastResult()
                {
                    From        = from,
                    To          = to,
                    MaxDistance = distance,
                };

                if (hitInfo != null)
                {
                    result.IsHit       = true;
                    result.HitDistance = hitInfo.Fraction * distance;
                    result.HitPosition = from + result.HitDistance.Value * direction;
                }

                results.Add(result);
            }

            return(results);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Move vessel down
        /// </summary>
        /// <param name="v"></param>
        private static void MoveDown(Vessel v)
        {
            bounds.findBoundPoints();

            RayCastResult alt  = GetRaycastAltitude(v, bounds.bottomPoint, rayCastMask);
            RayCastResult alt2 = GetRaycastAltitude(v, bounds.topPoint, rayCastMask);

            Vector3 referencePoint = bounds.bottomPoint;

            if (alt.collider != alt2.collider)
            {
                minDownMovement = lastResortAltitude;
                if (alt2.altitude < alt.altitude)
                {
                    referencePoint = bounds.topPoint;
                }
            }

            // Re-cast raycast including parts into the mask
            alt = GetRaycastAltitude(v, referencePoint, rayCastExtendedMask);
            float downMovement = alt.altitude;

            Vector3 up = (v.transform.position - FlightGlobals.currentMainBody.transform.position).normalized;

            if (downMovement < minDownMovement + Configuration.HeightOffset)
            {
                return;
            }

            downMovement -= minDownMovement;

            v.Translate(-downMovement * (Vector3d)up);
        }
Ejemplo n.º 8
0
        public override void Update(float time, float dTime)
        {
            MouseUsed = Window.MouseLeftDown;

            Vector3 rayStart = EngineBase.Renderer.Unproject(Window.MousePos, 0f);
            Vector3 rayEnd   = EngineBase.Renderer.Unproject(Window.MousePos, 1f);
            Vector3 dir      = (rayEnd - rayStart).Normalized();

            Editor.Profiler.Begin("RAYCAST");
            RayCastResult rc = level.Collisions.RayCast(rayStart, dir);

            Editor.Profiler.End("RAYCAST");

            if (rc.Hit)
            {
                level.AddNode(terrainEditCursor);
                terrainEditCursor.Position = rc.PositionSnapped;
                if (Window.MouseLeftDown)
                {
                    applyBrush(rc.Position);
                }
            }
            else
            {
                level.RemoveNode(terrainEditCursor);
            }

            base.Update(time, dTime);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Casts a convex shape against the collidable.
        /// </summary>
        /// <param name="castShape">Shape to cast.</param>
        /// <param name="startingTransform">Initial transform of the shape.</param>
        /// <param name="sweep">Sweep to apply to the shape.</param>
        /// <param name="result">Hit data, if any.</param>
        /// <returns>Whether or not the cast hit anything.</returns>
        public bool ConvexCast(ConvexShapes.ConvexShape castShape, ref RigidTransform startingTransform, ref Vector3 sweep, out RayCastResult result)
        {
            var         outputOverlappedElements = Resources.GetCollidableList();
            var         rayHits = Resources.GetRayHitList();
            BoundingBox boundingBox;

            Toolbox.GetExpandedBoundingBox(ref castShape, ref startingTransform, ref sweep, out boundingBox);

            CollidableTree.GetOverlaps(boundingBox, outputOverlappedElements);
            result           = new RayCastResult();
            result.HitData.T = float.MaxValue;
            for (int i = 0; i < outputOverlappedElements.count; ++i)
            {
                RayHit hit;
                if (outputOverlappedElements.Elements[i].ConvexCast(castShape, ref startingTransform, ref sweep, out hit))
                {
                    if (hit.T < result.HitData.T)
                    {
                        result.HitData   = hit;
                        result.HitObject = outputOverlappedElements.Elements[i];
                    }
                }
            }
            Resources.GiveBack(rayHits);
            Resources.GiveBack(outputOverlappedElements);
            return(result.HitData.T < float.MaxValue);
        }
Ejemplo n.º 10
0
        float testObjectVisibility(GameObject go, RayCastTargets targets)
        {
            int            nSuccess       = 0;
            var            rayCastTargets = getRayCastTargets(go);
            List <Vector2> testPoints     = rayCastTargets.getTargetPoints();

            for (int i = 0; i < testPoints.Count; i++)
            {
                var     testPoint = testPoints[i];
                Vector2 obstructionPoint;
                var     result = new RayCastResult();
                result.go           = go;
                result.testPoint    = testPoint;
                result.isObstructed = false;
                if (isInLineOfSight(go, testPoint, out obstructionPoint))
                {
                    nSuccess++;
                    rayCastTargets.SetIsTargetVisible(i, true);
                }
                else
                {
                    result.isObstructed     = true;
                    result.obstructionPoint = obstructionPoint;
                    rayCastTargets.SetIsTargetVisible(i, false);
                }
                raycastResults.Add(result);
            }

            return(nSuccess / (float)testPoints.Count);
        }
Ejemplo n.º 11
0
        private static bool IsValid(RayCastResult r, List <NiAVObject> ignore)
        {
            var havokObj = r.HavokObject;

            if (havokObj != IntPtr.Zero)
            {
                uint  flags = Memory.ReadUInt32(havokObj + 0x2C) & 0x7F;
                ulong mask  = (ulong)1 << (int)flags;
                if ((RaycastMask & mask) == 0)
                {
                    return(false);
                }
            }

            if (ignore != null && ignore.Count != 0)
            {
                var obj = r.Object;
                if (obj != null)
                {
                    for (int i = 0; i < ignore.Count; i++)
                    {
                        var o = ignore[i];
                        if (o != null && o.Equals(obj))
                        {
                            return(false);
                        }
                    }
                }
            }

            return(true);
        }
Ejemplo n.º 12
0
        public bool RayCastAgainstEntity(Vector3 from, Vector3 to, out Vector3 pos, out float distance, out Entity hitEntity)
        {
            hitEntity = null;
            var dir  = to - from;
            var dist = dir.Length();
            var ndir = dir.Normalized();

            distance = float.MaxValue;
            Ray ray = new Ray(from, ndir);

            pos = to;

            var rcr  = new RayCastResult();
            var bRay = MathConverter.Convert(ray);

            bool result = PhysSpace.RayCast(bRay, dist, out rcr);

            if (!result)
            {
                return(false);
            }

            var convex = rcr.HitObject as ConvexCollidable;

            pos = MathConverter.Convert(rcr.HitData.Location);

            if (convex != null)
            {
                hitEntity = convex.Entity.Tag as Entity;
            }

            distance = rcr.HitData.T;

            return(true);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// A convex-shaped ray-trace method for the special case of needing to handle Voxel collision types.
        /// </summary>
        /// <param name="shape">The shape of the convex ray source object.</param>
        /// <param name="start">The start of the ray.</param>
        /// <param name="dir">The normalized vector of the direction of the ray.</param>
        /// <param name="len">The length of the ray.</param>
        /// <param name="considerSolid">What materials are 'solid'.</param>
        /// <param name="filter">A function to identify what entities should be filtered out.</param>
        /// <param name="rayHit">Outputs the result of the ray trace.</param>
        /// <returns>Whether there was a collision.</returns>
        public bool SpecialCaseConvexTrace(ConvexShape shape, Location start, Location dir, double len, MaterialSolidity considerSolid, Func <BroadPhaseEntry, bool> filter, out RayCastResult rayHit)
        {
            RigidTransform rt = new RigidTransform(start.ToBVector(), BEPUutilities.Quaternion.Identity);

            BEPUutilities.Vector3 sweep = (dir * len).ToBVector();
            RayCastResult         best  = new RayCastResult(new RayHit()
            {
                T = len
            }, null);
            bool hA = false;

            if (considerSolid.HasFlag(MaterialSolidity.FULLSOLID))
            {
                if (PhysicsWorld.ConvexCast(shape, ref rt, ref sweep, filter, out RayCastResult rcr))
                {
                    best = rcr;
                    hA   = true;
                }
            }
            if (considerSolid == MaterialSolidity.FULLSOLID)
            {
                rayHit = best;
                return(hA);
            }
            sweep = dir.ToBVector();
            AABB box = new AABB()
            {
                Min = start,
                Max = start
            };

            box.Include(start + dir * len);
            foreach (KeyValuePair <Vector3i, Chunk> chunk in LoadedChunks)
            {
                if (chunk.Value == null || chunk.Value.FCO == null)
                {
                    continue;
                }
                if (!box.Intersects(new AABB()
                {
                    Min = chunk.Value.WorldPosition.ToLocation() * Chunk.CHUNK_SIZE,
                    Max = chunk.Value.WorldPosition.ToLocation() * Chunk.CHUNK_SIZE + new Location(Chunk.CHUNK_SIZE, Chunk.CHUNK_SIZE, Chunk.CHUNK_SIZE)
                }))
                {
                    continue;
                }
                if (chunk.Value.FCO.ConvexCast(shape, ref rt, ref sweep, len, considerSolid, out RayHit temp))
                {
                    hA = true;
                    if (temp.T < best.HitData.T)
                    {
                        best.HitData   = temp;
                        best.HitObject = chunk.Value.FCO;
                    }
                }
            }
            rayHit = best;
            return(hA);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// A ray-trace method for the special case of needing to handle Voxel collision types.
        /// </summary>
        /// <param name="start">The start of the ray.</param>
        /// <param name="dir">The normalized vector of the direction of the ray.</param>
        /// <param name="len">The length of the ray.</param>
        /// <param name="considerSolid">What materials are 'solid'.</param>
        /// <param name="filter">A function to identify what entities should be filtered out.</param>
        /// <param name="rayHit">Outputs the result of the ray trace.</param>
        /// <returns>Whether there was a collision.</returns>
        public bool SpecialCaseRayTrace(Location start, Location dir, double len, MaterialSolidity considerSolid, Func <BroadPhaseEntry, bool> filter, out RayCastResult rayHit)
        {
            Ray           ray  = new Ray(start.ToBVector(), dir.ToBVector());
            RayCastResult best = new RayCastResult(new RayHit()
            {
                T = len
            }, null);
            bool hA = false;

            if (considerSolid.HasFlag(MaterialSolidity.FULLSOLID))
            {
                if (PhysicsWorld.RayCast(ray, len, filter, out RayCastResult rcr))
                {
                    best = rcr;
                    hA   = true;
                }
            }
            if (considerSolid == MaterialSolidity.FULLSOLID)
            {
                rayHit = best;
                return(hA);
            }
            AABB box = new AABB()
            {
                Min = start,
                Max = start
            };

            box.Include(start + dir * len);
            foreach (Dictionary <Vector3i, Chunk> chkmap in LoadedChunks)
            {
                foreach (Chunk chunk in chkmap.Values)
                {
                    if (chunk == null || chunk.FCO == null)
                    {
                        continue;
                    }
                    if (!box.Intersects(new AABB()
                    {
                        Min = chunk.WorldPosition.ToLocation() * Chunk.CHUNK_SIZE,
                        Max = chunk.WorldPosition.ToLocation() * Chunk.CHUNK_SIZE + new Location(Chunk.CHUNK_SIZE, Chunk.CHUNK_SIZE, Chunk.CHUNK_SIZE)
                    }))
                    {
                        continue;
                    }
                    if (chunk.FCO.RayCast(ray, len, null, considerSolid, out RayHit temp))
                    {
                        hA = true;
                        if (temp.T < best.HitData.T)
                        {
                            best.HitData   = temp;
                            best.HitObject = chunk.FCO;
                        }
                    }
                }
            }
            rayHit = best;
            return(hA);
        }
Ejemplo n.º 15
0
 private static bool BlockProjectile(RayCastResult result)
 {
     return(ObjectsBulletCantPass.Contains(result.HitObject.Name)
            // Filter objects bullet can passthrough like ladder
            // Not an optimal solution: https://www.mythologicinteractiveforums.com/viewtopic.php?f=31&t=3952&p=23291#p23291
            || (result.HitObject.GetCollisionFilter().BlockExplosions &&
                !ObjectsBulletCanDestroy.Contains(result.HitObject.Name)));
 }
Ejemplo n.º 16
0
        protected override RayCastResult[] OnRayCastPiercing(Ray ray, int contactGroup)
        {
            if (float.IsNaN(ray.Origin.X))
            {
                Log.Fatal("PhysicsWorld.RayCast: Single.IsNaN(ray.Origin.X)");
            }
            if (float.IsNaN(ray.Direction.X))
            {
                Log.Fatal("PhysicsWorld.RayCast: Single.IsNaN(ray.Direction.X)");
            }
            if (ray.Direction == Vec3.Zero)
            {
                return(emptyPiercingRayCastResult);
            }

            Vec3  dirNormal = ray.Direction;
            float length    = dirNormal.Normalize();

            Ode.dGeomRaySet(rayCastGeomID, ray.Origin.X, ray.Origin.Y, ray.Origin.Z,
                            dirNormal.X, dirNormal.Y, dirNormal.Z);
            Ode.dGeomRaySetLength(rayCastGeomID, length);

            int    count;
            IntPtr data;

            Ode.DoRayCastPiercing(neoAxisAdditionsID, contactGroup, out count, out data);

            if (count == 0)
            {
                return(emptyPiercingRayCastResult);
            }

            RayCastResult[] array = new RayCastResult[count];

            unsafe
            {
                Ode.RayCastResult *pointer = (Ode.RayCastResult *)data;
                for (int n = 0; n < count; n++)
                {
                    RayCastResult result = new RayCastResult();

                    result.Shape      = shapesDictionary[pointer->shapeDictionaryIndex].shape;
                    result.Position   = Convert.ToNet(pointer->position);
                    result.Normal     = Convert.ToNet(pointer->normal);
                    result.Distance   = pointer->distance;
                    result.TriangleID = pointer->triangleID;

                    array[n] = result;

                    pointer++;
                }
            }

            //sort by distance
            ArrayUtils.SelectionSort(array, rayCastResultDistanceComparer);

            return(array);
        }
Ejemplo n.º 17
0
        void RenderEntityOverCursor(Camera camera)
        {
            Vec2 mouse = renderTarget.GetFloatMousePosition();

            _mouseOver = null;

            if (mouse.X < 0 || mouse.X > 1 || mouse.Y < 0 || mouse.Y > 1)
            {
                _worldViewModel.ClearMouseOverEntity();
            }
            else
            {
                // Find entity under cursor of mouse
                Ray ray = camera.GetCameraToViewportRay(mouse);
                Map.Instance.GetObjects(ray, delegate(MapObject obj, float scale)
                {
                    if (obj.UserData == null || !(obj.UserData is EntityModel))
                    {
                        return(true);
                    }
                    _mouseOver = obj;
                    return(false);
                });

                if (_mouseOver != null)
                {
                    // Put a yellow box around it and a tooltip
                    camera.DebugGeometry.Color = new ColorValue(1, 1, 0);
                    camera.DebugGeometry.AddBounds(_mouseOver.MapBounds);
                    _worldViewModel.SetMouseOverEntity(((EntityModel)_mouseOver.UserData).Id);
                }
                else
                {
                    _worldViewModel.ClearMouseOverEntity();
                }

                RayCastResult result = PhysicsWorld.Instance.RayCast(ray, (int)ContactGroup.CastOnlyCollision);
                _mouseIntersection = result.Position;
                if (result.Shape != null)
                {
                    camera.DebugGeometry.Color = new ColorValue(1, 0, 0);
                    camera.DebugGeometry.AddSphere(new Sphere(result.Position, 0.2f));
                }
            }
            SetToolTipString();

            // Show all selected entities with a blue box around them
            // except MouseOver as it will be yellow
            camera.DebugGeometry.Color = new ColorValue(0.5f, 0.5f, 1);
            foreach (MapObject mo in _worldViewModel.SelectedEntities
                     .Select(evm => Entities.Instance.GetByName(evm.Entity.Id.ToString()))
                     .OfType <MapObject>()
                     .Where(mo => mo != _mouseOver))
            {
                camera.DebugGeometry.AddBounds(mo.MapBounds);
            }
        }
        public bool RayCast(Vector3 pos, Vector3 dir, float dst, out RayCastResult result)
        {
            pos = TransformPointToLocalSpace(pos);
            dir = TransformDirToLocalSpace(dir);

            const float step = 0.1f;

            int prevX = int.MaxValue;
            int prevY = int.MaxValue;
            int prevZ = int.MaxValue;

            Vector3 stepOffset = dir.normalized * step;

            for (int i = 0; i < dst / step; i++)
            {
                int x = (int)Mathf.Floor(pos.x);
                int y = (int)Mathf.Floor(pos.y);
                int z = (int)Mathf.Floor(pos.z);

                if (x != prevX || y != prevY || z != prevZ)
                {
                    for (int zo = 0; zo < 2; zo++)
                    {
                        for (int yo = 0; yo < 2; yo++)
                        {
                            for (int xo = 0; xo < 2; xo++)
                            {
                                int bx = x + xo;
                                int by = y + yo;
                                int bz = z + zo;

                                var chunk = GetChunk(ChunkPos.FromVoxel(bx, by, bz, ChunkSize));

                                if (chunk != null)
                                {
                                    int material = chunk.GetMaterial(((bx % ChunkSize) + ChunkSize) % ChunkSize, ((by % ChunkSize) + ChunkSize) % ChunkSize, ((bz % ChunkSize) + ChunkSize) % ChunkSize);
                                    if (material != 0)
                                    {
                                        result = new RayCastResult(new Vector3(x, y, z), new Vector3(prevX, prevY, prevZ), chunk);
                                        return(true);
                                    }
                                }
                            }
                        }
                    }

                    prevX = x;
                    prevY = y;
                    prevZ = z;
                }

                pos += stepOffset;
            }

            result = new RayCastResult(Vector3.zero, Vector3.zero, null);
            return(false);
        }
Ejemplo n.º 19
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="normal"></param>
        /// <param name="pos"></param>
        /// <returns></returns>
        public bool RayCastAgainstAll(Vector3 from, Vector3 to, out Vector3 normal, out Vector3 pos, out Entity hitEnt, Entity entToSkip = null)
        {
            var dir  = to - from;
            var dist = dir.Length();
            var ndir = dir.Normalized();
            Ray ray  = new Ray(from, ndir);

            normal = Vector3.Zero;
            pos    = to;
            hitEnt = null;

            Func <BroadPhaseEntry, bool> filterFunc = delegate(BroadPhaseEntry bpe)
            {
                if (entToSkip == null)
                {
                    return(true);
                }

                ConvexCollidable cc = bpe as ConvexCollidable;
                if (cc == null)
                {
                    return(true);
                }

                Entity ent = cc.Entity.Tag as Entity;
                if (ent == null)
                {
                    return(true);
                }

                if (ent == entToSkip)
                {
                    return(false);
                }

                return(true);
            };


            var rcr = new RayCastResult();

            bool result = Space.RayCast(ray, dist, filterFunc, out rcr);

            if (!result)
            {
                return(false);
            }

            var convex = rcr.HitObject as ConvexCollidable;

            normal = rcr.HitData.Normal.Normalized();
            pos    = rcr.HitData.Location;

            hitEnt = (convex == null) ? null : convex.Entity.Tag as Entity;

            return(true);
        }
Ejemplo n.º 20
0
        public override RayCastResult Intersection(Ray ray, float nowbest)
        {
            {
                float distance = (Position - ray.Origin).Length();
                if (nowbest + R < distance)
                {
                    return(null);
                }
            }
            Vector3f A = ray.Origin, B = ray.Direction, C = Position;
            Float    a = Vector3f.Dot(B, B);
            Float    b = Vector3f.Dot(B, (A - C)) * 2.0f;
            Float    c = (A - C).LengthSquared() - R * R;

            float drt = b * b - 4 * a * c;

            if (drt < 0)
            {
                return(null);
            }
            drt = Math.Sqrt(drt);
            float x1 = (-b + drt) / a / 2;
            float x2 = (-b - drt) / a / 2;

            if (x1 < 0 && x2 < 0)
            {
                return(null);
            }

            float d;

            if (x1 > 0 && x2 > 0)
            {
                d = Math.Max(x1, x2);
            }
            else if (x1 > 0)
            {
                d = x1;
            }
            else
            {
                d = x2;
            }

            RayCastResult result = new RayCastResult();

            //result.happened = true;
            result.obj      = this;
            result.material = Material;
            result.coords   = ray.Origin + ray.Direction * d;
            result.distance = d;
            result.normal   = Vector3f.Normalize(result.coords - Position);

            return(result);
        }
        /// <summary>
        /// Casts a convex shape against the collidable.
        /// </summary>
        /// <param name="castShape">Shape to cast.</param>
        /// <param name="startingTransform">Initial transform of the shape.</param>
        /// <param name="sweep">Sweep to apply to the shape.</param>
        /// <param name="filter">Test to apply to the entry. If it returns true, the entry is processed, otherwise the entry is ignored. If a collidable hierarchy is present
        /// in the entry, this filter will be passed into inner ray casts.</param>
        /// <param name="result">Data and hit object from the first impact, if any.</param>
        /// <returns>Whether or not the cast hit anything.</returns>
        public bool ConvexCast(CollisionShapes.ConvexShapes.ConvexShape castShape, ref RigidTransform startingTransform, ref Vector3 sweep, Func <BroadPhaseEntry, bool> filter, out RayCastResult result)
        {
            CompoundChild hitChild;
            RayHit        rayHit;
            bool          hit = ConvexCast(castShape, ref startingTransform, ref sweep, filter, out rayHit, out hitChild);

            result = new RayCastResult {
                HitData = rayHit, HitObject = hitChild.CollisionInformation
            };
            return(hit);
        }
        /// <summary>
        /// Tests a ray against the compound.
        /// </summary>
        /// <param name="ray">Ray to test.</param>
        /// <param name="maximumLength">Maximum length, in units of the ray's direction's length, to test.</param>
        /// <param name="rayHit">Hit data and the hit child collidable, if any.</param>
        /// <param name="filter">Test to apply to the entry. If it returns true, the entry is processed, otherwise the entry is ignored. If a collidable hierarchy is present
        /// in the entry, this filter will be passed into inner ray casts.</param>
        /// <returns>Whether or not the ray hit the entry.</returns>
        public bool RayCast(Ray ray, float maximumLength, Func <BroadPhaseEntry, bool> filter, out RayCastResult rayHit)
        {
            RayHit        hitData;
            CompoundChild hitChild;
            bool          hit = RayCast(ray, maximumLength, filter, out hitData, out hitChild);

            rayHit = new RayCastResult {
                HitData = hitData, HitObject = hitChild.CollisionInformation
            };
            return(hit);
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Casts a convex shape against the collidable.
        /// </summary>
        /// <param name="castShape">Shape to cast.</param>
        /// <param name="startingTransform">Initial transform of the shape.</param>
        /// <param name="sweep">Sweep to apply to the shape.</param>
        /// <param name="result">Data and hit object from the first impact, if any.</param>
        /// <returns>Whether or not the cast hit anything.</returns>
        public bool ConvexCast(CollisionShapes.ConvexShapes.ConvexShape castShape, ref RigidTransform startingTransform, ref System.Numerics.Vector3 sweep, out RayCastResult result)
        {
            CompoundChild hitChild;
            RayHit        rayHit;
            bool          hit = ConvexCast(castShape, ref startingTransform, ref sweep, out rayHit, out hitChild);

            result = new RayCastResult {
                HitData = rayHit, HitObject = hitChild.CollisionInformation
            };
            return(hit);
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Tests a ray against the compound.
        /// </summary>
        /// <param name="ray">Ray to test.</param>
        /// <param name="maximumLength">Maximum length, in units of the ray's direction's length, to test.</param>
        /// <param name="rayHit">Hit data and the hit child collidable, if any.</param>
        /// <returns>Whether or not the ray hit the entry.</returns>
        public bool RayCast(Ray ray, Fix64 maximumLength, out RayCastResult rayHit)
        {
            RayHit        hitData;
            CompoundChild hitChild;
            bool          hit = RayCast(ray, maximumLength, out hitData, out hitChild);

            rayHit = new RayCastResult {
                HitData = hitData, HitObject = hitChild.CollisionInformation
            };
            return(hit);
        }
Ejemplo n.º 25
0
        private void Trackball_GetOrbitRadius(object sender, GetOrbitRadiusArgs e)
        {
            //TODO:  e should also pass in the mouse click point, so there is camera position, and click position, this
            // listener can decide which they want (I can't reuse the same direction, because of the perspective)

            RayCastResult result = _world.CastRay(e.Position, e.Direction, 30d, World.BodyFilterType.ExcludeBodies);

            if (result != null)
            {
                e.Result = result.HitDistance;
            }
        }
Ejemplo n.º 26
0
 static int SortRayCastResultsMethod(RayCastResult r1, RayCastResult r2)
 {
     if (r1.Distance < r2.Distance)
     {
         return(-1);
     }
     if (r1.Distance > r2.Distance)
     {
         return(1);
     }
     return(0);
 }
Ejemplo n.º 27
0
        public override RayCastResult Intersection(Ray ray, float nowbest)
        {
            if (ray.OriginObject == this)
            {
                return(null);
            }
            {
                (bool happened, Float mint) = BoundBox.Intersection(ray);
                if (!happened || mint > nowbest)                   // 未相交 或 当前最小解已不是最优
                {
                    return(null);
                }
            }
            Float    u, v, t_tmp = 0;
            Vector3f pvec = Vector3f.Cross(ray.Direction, e2);             // S1
            Float    det  = Vector3f.Dot(e1, pvec);

            Float    det_inv = 1.0f / det;
            Vector3f tvec    = ray.Origin - v0;          // S

            u = Vector3f.Dot(tvec, pvec) * det_inv;
            if (u < 0 || u > 1)
            {
                return(null);
            }
            Vector3f qvec = Vector3f.Cross(tvec, e1);             // S2

            v = Vector3f.Dot(ray.Direction, qvec) * det_inv;
            if (v < 0 || u + v > 1)
            {
                return(null);
            }
            t_tmp = Vector3f.Dot(e2, qvec) * det_inv;
            if (t_tmp < 0)
            {
                return(null);
            }

            RayCastResult result = new RayCastResult();

            result.distance      = t_tmp;
            result.obj           = this;
            result.coords        = ray.Origin + t_tmp * ray.Direction;
            result.uv            = new Vector2f(u, v);
            result.normal        = Tools.UVMerge(u, v, n0, n1, n2);
            result.internalPoint = (Vector3f.Dot(result.normal, ray.Direction) > 0);
            if (result.internalPoint)
            {
                result.normal = -result.normal;
            }
            return(result);
        }
Ejemplo n.º 28
0
        OnCalculateIrradianceVolumeCell(Vec3 position)
        {
            tempCellLightItemList.Clear();

            foreach (MyLight light in lights)
            {
                //simple culling method. need use grid
                if (!light.Bounds.IsContainsPoint(position))
                {
                    continue;
                }

                //calculate illumination
                float illumination = light.GetIllumination(position);
                if (illumination <= .00001f)
                {
                    continue;
                }

                //check for direct visibility
                bool shadowed = false;

                if (calculateShadows)
                {
                    Ray ray = light.GetCheckVisibilityRay(position);

                    RayCastResult result = physicsScene.RayCast(ray, contactGroup);
                    if (result.Shape != null)
                    {
                        shadowed = true;
                    }
                }

                float power = 1;

                if (shadowed)
                {
                    float coef = 1.0f - (shadowColor.Red + shadowColor.Green + shadowColor.Blue) / 3.0f;
                    power *= coef;
                }

                if (power <= .005f)
                {
                    continue;
                }

                tempCellLightItemList.Add(new IrradianceVolumeCellLightItem(light.Data, power));
            }


            return(tempCellLightItemList.ToArray());
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Get altitude of a RayCast
        /// </summary>
        /// <param name="v"></param>
        /// <param name="originPoint"></param>
        /// <param name="layerMask"></param>
        /// <returns></returns>
        internal static RayCastResult GetRaycastAltitude(Vessel v, Vector3 originPoint, int layerMask)
        {
            RaycastHit    hit;
            Vector3       up     = (v.transform.position - FlightGlobals.currentMainBody.transform.position).normalized;
            RayCastResult result = new RayCastResult();

            if (Physics.Raycast(originPoint, -up, out hit, v.vesselRanges.landed.unload, layerMask))
            {
                result.altitude = Vector3.Project(hit.point - originPoint, up).magnitude;
                result.collider = hit.collider;
            }
            return(result);
        }
Ejemplo n.º 30
0
        } // Raycast

        /// <summary>
        /// Indicates if a ray intercepts a game object.
        /// </summary>
        public static GameObject3D Raycast(Ray ray, float distance, out RayCastResult result)
        {
            GameObject3D go = null;

            if (Scene.RayCast(ray, distance, out result))
            {
                var entityCollision = result.HitObject as EntityCollidable;
                if (entityCollision != null)
                {
                    go = (GameObject3D)entityCollision.Entity.Tag;
                }
            }
            return(go);
        } // Raycast
 /// <summary>
 /// Tests a ray against the collidable.
 /// </summary>
 /// <param name="ray">Ray to test.</param>
 /// <param name="maximumLength">Maximum length, in units of the ray's direction's length, to test.</param>
 /// <param name="result">Hit data, if any.</param>
 /// <returns>Whether or not the ray hit the entry.</returns>
 public bool RayCast(Ray ray, float maximumLength, out RayCastResult result)
 {
     var outputOverlappedElements = PhysicsResources.GetCollidableList();
     CollidableTree.GetOverlaps(ray, maximumLength, outputOverlappedElements);
     result = new RayCastResult();
     result.HitData.T = float.MaxValue;
     for (int i = 0; i < outputOverlappedElements.Count; ++i)
     {
         RayHit hit;
         if (outputOverlappedElements.Elements[i].RayCast(ray, maximumLength, out hit))
         {
             if (hit.T < result.HitData.T)
             {
                 result.HitData = hit;
                 result.HitObject = outputOverlappedElements.Elements[i];
             }
         }
     }
     PhysicsResources.GiveBack(outputOverlappedElements);
     return result.HitData.T < float.MaxValue;
 }
Ejemplo n.º 32
0
        /// <summary>
        /// Casts a convex shape against the collidable.
        /// </summary>
        /// <param name="castShape">Shape to cast.</param>
        /// <param name="startingTransform">Initial transform of the shape.</param>
        /// <param name="sweep">Sweep to apply to the shape.</param>
        /// <param name="result">Hit data, if any.</param>
        /// <returns>Whether or not the cast hit anything.</returns>
        public bool ConvexCast(ConvexShapes.ConvexShape castShape, ref RigidTransform startingTransform, ref System.Numerics.Vector3 sweep, out RayCastResult result)
        {
            var outputOverlappedElements = PhysicsResources.GetCollidableList();
            BoundingBox boundingBox;
            castShape.GetSweptBoundingBox(ref startingTransform, ref sweep, out boundingBox);

            CollidableTree.GetOverlaps(boundingBox, outputOverlappedElements);
            result = new RayCastResult();
            result.HitData.T = float.MaxValue;
            for (int i = 0; i < outputOverlappedElements.Count; ++i)
            {
                RayHit hit;
                if (outputOverlappedElements.Elements[i].ConvexCast(castShape, ref startingTransform, ref sweep, out hit))
                {
                    if (hit.T < result.HitData.T)
                    {
                        result.HitData = hit;
                        result.HitObject = outputOverlappedElements.Elements[i];
                    }
                }
            }
            PhysicsResources.GiveBack(outputOverlappedElements);
            return result.HitData.T < float.MaxValue;
        }
Ejemplo n.º 33
0
		protected override RayCastResult[] OnRayCastPiercing( Ray ray, int contactGroup )
		{
			if( float.IsNaN( ray.Origin.X ) )
				Log.Fatal( "PhysicsWorld.RayCast: Single.IsNaN(ray.Origin.X)" );
			if( float.IsNaN( ray.Direction.X ) )
				Log.Fatal( "PhysicsWorld.RayCast: Single.IsNaN(ray.Direction.X)" );
			if( ray.Direction == Vec3.Zero )
				return emptyPiercingRayCastResult;

			Vec3 dirNormal = ray.Direction;
			float length = dirNormal.Normalize();
			Ode.dGeomRaySet( rayCastGeomID, ray.Origin.X, ray.Origin.Y, ray.Origin.Z,
				dirNormal.X, dirNormal.Y, dirNormal.Z );
			Ode.dGeomRaySetLength( rayCastGeomID, length );

			int count;
			IntPtr data;
			Ode.DoRayCastPiercing( neoAxisAdditionsID, contactGroup, out count, out data );

			if( count == 0 )
				return emptyPiercingRayCastResult;

			RayCastResult[] array = new RayCastResult[ count ];

			unsafe
			{
				Ode.RayCastResult* pointer = (Ode.RayCastResult*)data;
				for( int n = 0; n < count; n++ )
				{
					RayCastResult result = new RayCastResult();

					result.Shape = shapesDictionary[ pointer->shapeDictionaryIndex ].shape;
					result.Position = Convert.ToNet( pointer->position );
					result.Normal = Convert.ToNet( pointer->normal );
					result.Distance = pointer->distance;
					result.TriangleID = pointer->triangleID;

					array[ n ] = result;

					pointer++;
				}
			}

			//sort by distance
			ArrayUtils.SelectionSort( array, rayCastResultDistanceComparer );

			return array;
		}
Ejemplo n.º 34
0
 /// <summary>
 /// Tests a ray against the compound.
 /// </summary>
 /// <param name="ray">Ray to test.</param>
 /// <param name="maximumLength">Maximum length, in units of the ray's direction's length, to test.</param>
 /// <param name="rayHit">Hit data and the hit child collidable, if any.</param>
 /// <returns>Whether or not the ray hit the entry.</returns>
 public bool RayCast(Ray ray, float maximumLength, out RayCastResult rayHit)
 {
     rayHit = new RayCastResult();
     var hitElements = Resources.GetCompoundChildList();
     if (hierarchy.Tree.GetOverlaps(ray, maximumLength, hitElements))
     {
         rayHit.HitData.T = float.MaxValue;
         for (int i = 0; i < hitElements.count; i++)
         {
             EntityCollidable candidate = hitElements.Elements[i].CollisionInformation;
             RayHit tempHit;
             if (candidate.RayCast(ray, maximumLength, out tempHit) && tempHit.T < rayHit.HitData.T)
             {
                 rayHit.HitData = tempHit;
                 rayHit.HitObject = candidate;
             }
         }
         Resources.GiveBack(hitElements);
         return rayHit.HitData.T != float.MaxValue;
     }
     Resources.GiveBack(hitElements);
     return false;
 }
Ejemplo n.º 35
0
        /// <summary>
        /// Casts a convex shape against the collidable.
        /// </summary>
        /// <param name="castShape">Shape to cast.</param>
        /// <param name="startingTransform">Initial transform of the shape.</param>
        /// <param name="sweep">Sweep to apply to the shape.</param>
        /// <param name="result">Hit data, if any.</param>
        /// <returns>Whether or not the cast hit anything.</returns>
        public bool ConvexCast(ConvexShapes.ConvexShape castShape, ref RigidTransform startingTransform, ref Vector3 sweep, out RayCastResult result)
        {
            var outputOverlappedElements = Resources.GetCollidableList();
            var rayHits = Resources.GetRayHitList();
            BoundingBox boundingBox;
            Toolbox.GetExpandedBoundingBox(ref castShape, ref startingTransform, ref sweep, out boundingBox);

            CollidableTree.GetOverlaps(boundingBox, outputOverlappedElements);
            result = new RayCastResult();
            result.HitData.T = float.MaxValue;
            for (int i = 0; i < outputOverlappedElements.count; ++i)
            {
                RayHit hit;
                if (outputOverlappedElements.Elements[i].ConvexCast(castShape, ref startingTransform, ref sweep, out hit))
                {
                    if (hit.T < result.HitData.T)
                    {
                        result.HitData = hit;
                        result.HitObject = outputOverlappedElements.Elements[i];
                    }
                }
            }
            Resources.GiveBack(rayHits);
            Resources.GiveBack(outputOverlappedElements);
            return result.HitData.T < float.MaxValue;
        }
 /// <summary>
 /// Casts a convex shape against the collidable.
 /// </summary>
 /// <param name="castShape">Shape to cast.</param>
 /// <param name="startingTransform">Initial transform of the shape.</param>
 /// <param name="sweep">Sweep to apply to the shape.</param>
 /// <param name="filter">Test to apply to the entry. If it returns true, the entry is processed, otherwise the entry is ignored. If a collidable hierarchy is present
 /// in the entry, this filter will be passed into inner ray casts.</param>
 /// <param name="result">Data and hit object from the first impact, if any.</param>
 /// <returns>Whether or not the cast hit anything.</returns>
 public bool ConvexCast(CollisionShapes.ConvexShapes.ConvexShape castShape, ref RigidTransform startingTransform, ref Vector3 sweep, Func<BroadPhaseEntry, bool> filter, out RayCastResult result)
 {
     CompoundChild hitChild;
     RayHit rayHit;
     bool hit = ConvexCast(castShape, ref startingTransform, ref sweep, filter, out rayHit, out hitChild);
     result = new RayCastResult { HitData = rayHit, HitObject = hitChild.CollisionInformation };
     return hit;
 }
 /// <summary>
 /// Tests a ray against the compound.
 /// </summary>
 /// <param name="ray">Ray to test.</param>
 /// <param name="maximumLength">Maximum length, in units of the ray's direction's length, to test.</param>
 /// <param name="rayHit">Hit data and the hit child collidable, if any.</param>
 /// <param name="filter">Test to apply to the entry. If it returns true, the entry is processed, otherwise the entry is ignored. If a collidable hierarchy is present
 /// in the entry, this filter will be passed into inner ray casts.</param>
 /// <returns>Whether or not the ray hit the entry.</returns>
 public bool RayCast(Ray ray, float maximumLength, Func<BroadPhaseEntry, bool> filter, out RayCastResult rayHit)
 {
     RayHit hitData;
     CompoundChild hitChild;
     bool hit = RayCast(ray, maximumLength, filter, out hitData, out hitChild);
     rayHit = new RayCastResult { HitData = hitData, HitObject = hitChild.CollisionInformation };
     return hit;
 }
Ejemplo n.º 38
0
		protected override RayCastResult OnRayCast( Ray ray, int contactGroup )
		{
			if( float.IsNaN( ray.Origin.X ) )
				Log.Fatal( "PhysicsWorld.RayCast: Single.IsNaN(ray.Origin.X)" );
			if( float.IsNaN( ray.Direction.X ) )
				Log.Fatal( "PhysicsWorld.RayCast: Single.IsNaN(ray.Direction.X)" );
			if( ray.Direction == Vec3.Zero )
				return new RayCastResult();

			Vec3 dirNormal = ray.Direction;
			float length = dirNormal.Normalize();
			Ode.dGeomRaySet( rayCastGeomID, ray.Origin.X, ray.Origin.Y, ray.Origin.Z,
				dirNormal.X, dirNormal.Y, dirNormal.Z );
			Ode.dGeomRaySetLength( rayCastGeomID, length );

			int count;
			IntPtr data;
			Ode.DoRayCast( neoAxisAdditionsID, contactGroup, out count, out data );

			RayCastResult result = new RayCastResult();

			if( count != 0 )
			{
				unsafe
				{
					Ode.RayCastResult* pointer = (Ode.RayCastResult*)data;

					result.Shape = shapesDictionary[ pointer->shapeDictionaryIndex ].shape;
					result.Position = Convert.ToNet( pointer->position );
					result.Normal = Convert.ToNet( pointer->normal );
					result.Distance = pointer->distance;
					result.TriangleID = pointer->triangleID;
				}
			}

			return result;
		}
Ejemplo n.º 39
0
		static int SortRayCastResultsMethod( RayCastResult r1, RayCastResult r2 )
		{
			if( r1.Distance < r2.Distance )
				return -1;
			if( r1.Distance > r2.Distance )
				return 1;
			return 0;
		}
Ejemplo n.º 40
0
        protected unsafe override RayCastResult[] OnRayCastPiercing( Ray ray, int contactGroup )
        {
            if( float.IsNaN( ray.Origin.X ) )
                Log.Fatal( "PhysicsWorld.RayCast: Single.IsNaN(ray.Origin.X)" );
            if( float.IsNaN( ray.Direction.X ) )
                Log.Fatal( "PhysicsWorld.RayCast: Single.IsNaN(ray.Direction.X)" );
            if( ray.Direction == Vec3.Zero )
                return emptyPiercingRayCastResult;

            Vec3 normalDir = ray.Direction;
            float length = normalDir.Normalize();
            Vec3 origin = ray.Origin;
            int count = PhysXNativeWrapper.PhysXNativeScene.RayCast( nativeScene, ref origin, ref normalDir,
                length, GetContactGroupMask( contactGroup ), true );
            if( count == 0 )
                return emptyPiercingRayCastResult;

            NativeRayCastResult* results = PhysXNativeScene.GetLastRayCastResults( nativeScene );

            RayCastResult[] items = new RayCastResult[ count ];
            NativeRayCastResult* nativeResult = results;
            for( int n = 0; n < count; n++ )
            {
                items[ n ] = GetRayCastResultFromNative( nativeResult );
                nativeResult++;
            }

            return items;
        }
Ejemplo n.º 41
0
        /// <summary>
        /// This is a high-level function to cuts fixtures inside the given world, using the start and end points.
        /// Note: We don't support cutting when the start or end is inside a shape.
        /// </summary>
        /// <param name="world">The world.</param>
        /// <param name="start">The startpoint.</param>
        /// <param name="end">The endpoint.</param>
        /// <param name="thickness">The thickness of the cut</param>
        public static Vector2 Cut(World world, Vector2 start, Vector2 end, float thickness, Category collisionCategories = Category.None)
        {

            // The left side of the cut will remain part of the existing body;
            // the right side will be made into a new body

            List<Fixture> fixtures = new List<Fixture>();
            List<Vector2> entryPoints = new List<Vector2>();
            List<Vector2> exitPoints = new List<Vector2>();



            List<RayCastResult> results = new List<RayCastResult>();
            //float blockingFraction = float.MaxValue;
            Vector2 stoppingPoint = end;

            //We don't support cutting when the start or end is inside a shape.
            //if (world.TestPoint(start) != null || world.TestPoint(end) != null)
            //    return;

            //Get the entry points
            world.RayCast((f, p, n, fr) =>
                              {
                                  RayCastResult r = new RayCastResult();
                                  r.f = f;
                                  r.p = p;
                                  r.fr = fr;
                                  results.Add(r);

                                  return 1;
                                 
                              }, start, end);


            results = results.OrderBy(p => p.fr).ToList();

            foreach (RayCastResult r in results)
            {
                if ((r.f.CollisionCategories & collisionCategories) != Category.None)
                {
                    stoppingPoint = r.p;
                    break;
                }
                if (!r.f.TestPoint(ref end))
                {
                    if (world.FixtureCut != null)
                        world.FixtureCut(r.f);
                    fixtures.Add(r.f);
                    entryPoints.Add(r.p);
                }
            }


            //Reverse the ray to get the exitpoints
            world.RayCast((f, p, n, fr) =>
                              {
                                  if (fixtures.Contains(f))
                                  {
                                      exitPoints.Add(p);
                                  }
                                  return 1;
                              }, end, start);

            Debug.Assert(entryPoints.Count == exitPoints.Count && entryPoints.Count == fixtures.Count);

            //Fixture containsEnd = world.TestPoint(end);
            //if (containsEnd != null)
            //{
            //    entryPoints.RemoveAt(0);
            //    fixtures.Remove(containsEnd);
            //}
            //Fixture containsStart = world.TestPoint(start);
            //if (containsStart != null)
            //{
            //    exitPoints.RemoveAt(exitPoints.Count - 1);
            //    fixtures.Remove(containsStart);
            //}

            //We only have a single point. We need at least 2
            if (entryPoints.Count + exitPoints.Count < 2)
                return stoppingPoint;

            var query =
                (from fix in fixtures
                select fix.Body).Distinct();

            foreach (Body b in query) 
            {

                if (b == null || b.BodyType == BodyType.Static)
                    continue;

                ContactEdge edge = b.ContactList;
                while (edge != null)
                {
                    Contact c = edge.Contact;
                    edge = edge.Next;
                    world.ContactManager.Destroy(c);
                }

                List<Body> leftBodies = new List<Body>();
                List<Body> rightBodies = new List<Body>();
                //Body rightBody = new Body(world);

                List<Joint> leftJoints = new List<Joint>();
                List<Joint> rightJoints = new List<Joint>();

                foreach (Joint j in b.JointList)
                {
                    if (isLeft(start, end, j.WorldAnchorA))
                        leftJoints.Add(j);
                    else
                        rightJoints.Add(j);
                }

                //List<Fixture> leftList = new List<Fixture>();
                //List<Fixture> rightList = new List<Fixture>();
                Fixture[] bodyFixtures = new Fixture[b.FixtureList.Count];
                b.FixtureList.CopyTo(bodyFixtures);
                b.FixtureList.Clear();
                //leftBodies.Add(b);

                // For each fixture that was sliced through...
                foreach (Fixture fix in (from f in bodyFixtures where fixtures.Contains(f) select f))
                {
                    
                    
                    int i = fixtures.IndexOf(fix);

                    // split this in half and put the halves in the over/under lists
                    Vertices first;
                    Vertices second;
                    SplitShape(fix, entryPoints[i], exitPoints[i], thickness, out first, out second);
                    if (!SanityCheck(first) || !SanityCheck(second))
                    {
                        continue;
                    }
                    PolygonShape leftShape = new PolygonShape(first, fix.Shape.Density);
                    PolygonShape rightShape = new PolygonShape(second, fix.Shape.Density);

                    if (!b.FixtureList.Any())
                    {
                        if (leftShape.MassData.Area > rightShape.MassData.Area)
                        {
                            b.CreateFixture(leftShape, fix.UserData);
                            leftBodies.Add(b);
                            GlomFixture(world, b, rightBodies, rightShape, fix.UserData, rightJoints);
                        }
                        else
                        {
                            b.CreateFixture(rightShape, fix.UserData);
                            rightBodies.Add(b);
                            GlomFixture(world, b, leftBodies, leftShape, fix.UserData, leftJoints);
                        }
                    }
                    else
                    {
                        GlomFixture(world, b, leftBodies, leftShape, fix.UserData, leftJoints);
                        GlomFixture(world, b, rightBodies, rightShape, fix.UserData, rightJoints);
                    }

                                      
                }

                // for each fixture that was NOT sliced through...
                foreach (Fixture fix in (from f in bodyFixtures where !fixtures.Contains(f) select f)) {

                    if (isLeft(start, end, fix))
                    {
                        GlomFixture(world, b, leftBodies, fix.Shape, fix.UserData, leftJoints);
                    }
                    else
                    {
                        GlomFixture(world, b, rightBodies, fix.Shape, fix.UserData, rightJoints);
                        //rightBody.CreateFixture(fix.Shape.Clone(), fix.UserData);
                    }

                    
                }

                foreach (Body bod in leftBodies.Concat(rightBodies))
                {
                    bod.ResetMassData();
                    bod.BodyType = BodyType.Dynamic;
                    bod.Rotation = b.Rotation;
                    bod.LinearVelocity = b.LinearVelocity;
                    bod.AngularVelocity = b.AngularVelocity;
                    bod.Position = b.Position;
                }

                //b.JointList = null;
                //world.RemoveBody(b);

                foreach (Fixture f in bodyFixtures)
                {
                    b.DestroyFixture(f);
                }
                world.ProcessChanges();
            }

            return stoppingPoint;

        }
Ejemplo n.º 42
0
 unsafe RayCastResult GetRayCastResultFromNative( NativeRayCastResult* native )
 {
     RayCastResult result = new RayCastResult();
     if( native->shape != IntPtr.Zero )
     {
         result.Shape = PhysXPhysicsWorld.Instance.GetShapeByNativePointer( native->shape );
         result.Position = native->worldImpact;
         result.Normal = native->worldNormal;
         result.Distance = native->distance;
         if( result.Shape.ShapeType == Shape.Type.Mesh )
         {
             MeshShape meshShape = (MeshShape)result.Shape;
             if( meshShape.MeshType != MeshShape.MeshTypes.ConvexHullDecomposition )
                 result.TriangleID = native->faceID;
         }
         else if( result.Shape.ShapeType == Shape.Type.HeightField )
             result.TriangleID = native->faceID;
         else
             result.TriangleID = 0;
     }
     return result;
 }
Ejemplo n.º 43
0
 /// <summary>
 /// Casts a convex shape against the collidable.
 /// </summary>
 /// <param name="castShape">Shape to cast.</param>
 /// <param name="startingTransform">Initial transform of the shape.</param>
 /// <param name="sweep">Sweep to apply to the shape.</param>
 /// <param name="result">Data and hit object from the first impact, if any.</param>
 /// <returns>Whether or not the cast hit anything.</returns>
 public bool ConvexCast(CollisionShapes.ConvexShapes.ConvexShape castShape, ref RigidTransform startingTransform, ref System.Numerics.Vector3 sweep, out RayCastResult result)
 {
     CompoundChild hitChild;
     RayHit rayHit;
     bool hit = ConvexCast(castShape, ref startingTransform, ref sweep, out rayHit, out hitChild);
     result = new RayCastResult { HitData = rayHit, HitObject = hitChild.CollisionInformation };
     return hit;
 }