Exemplo n.º 1
0
        private static void OnReserveVoxelPositionRequest(ref ReserveVoxelPositionMsg msg, MyNetworkClient sender)
        {
            if (!Sync.IsServer)
            {
                return;
            }

            MyTransportMessageEnum responseState = MyTransportMessageEnum.Success;
            ReservedEntityData     entityData;
            MyVoxelBase            voxelMap = null;

            if (!MySession.Static.VoxelMaps.Instances.TryGetValue(msg.EntityId, out voxelMap))
            {
                return;
            }

            Vector3I voxelMapSize = voxelMap.StorageMax - voxelMap.StorageMin;

            Debug.Assert(voxelMapSize.AbsMax() < 2 * 10E6, "Voxel map size too large to reserve unique voxel position");
            // Integer overflow won't even happen on the next line for voxel maps smaller than roughly (2.5M)^3, and most Vector3I member functions have broken down way before that
            var entityId = new KeyValuePair <long, long>(msg.EntityId, msg.VoxelPos.X + msg.VoxelPos.Y * voxelMapSize.X + msg.VoxelPos.Z * voxelMapSize.X * voxelMapSize.Y);

            if (m_reservedEntities.TryGetValue(entityId, out entityData))
            {
                if (entityData.ReserverId == new MyPlayer.PlayerId(sender.SteamUserId, msg.SenderSerialId))
                {
                    entityData.ReservationTimer = Stopwatch.GetTimestamp() + Stopwatch.Frequency * msg.ReservationTimeMs / 1000;
                }
                else
                {
                    responseState = MyTransportMessageEnum.Failure;
                }
            }
            else
            {
                m_reservedEntities.Add(entityId, new ReservedEntityData()
                {
                    EntityId         = msg.EntityId,
                    GridPos          = msg.VoxelPos,
                    ReservationTimer = Stopwatch.GetTimestamp() + Stopwatch.Frequency * msg.ReservationTimeMs / 1000,
                    ReserverId       = new MyPlayer.PlayerId(sender.SteamUserId, msg.SenderSerialId)
                });
            }

            Sync.Layer.SendMessage(ref msg, sender.SteamUserId, responseState);
        }
        private bool IsFaceTriangle(MyNavigationTriangle triangle, Vector3I cubePosition, Vector3I direction)
        {
            var e = triangle.GetVertexEnumerator();

            // Quantize the point positions to 1/256ths inside each cube (but multiplied by 256 :-) )
            e.MoveNext();
            Vector3I positionA = Vector3I.Round(e.Current * 256);

            e.MoveNext();
            Vector3I positionB = Vector3I.Round(e.Current * 256);

            e.MoveNext();
            Vector3I positionC = Vector3I.Round(e.Current * 256);

            cubePosition = cubePosition * 256;

            // Change the point coordinates to be relative to the face center
            Vector3I faceCenter = cubePosition + direction * 128;

            positionA -= faceCenter;
            positionB -= faceCenter;
            positionC -= faceCenter;

            // Discard all triangles whose points are not on the plane of the face
            if (positionA * direction != Vector3I.Zero)
            {
                return(false);
            }
            if (positionB * direction != Vector3I.Zero)
            {
                return(false);
            }
            if (positionC * direction != Vector3I.Zero)
            {
                return(false);
            }

            // Discard all triangles that are not contained inside the face's square
            return(positionA.AbsMax() <= 128 && positionB.AbsMax() <= 128 && positionC.AbsMax() <= 128);
        }
        private static void OnReserveVoxelPositionRequest(long entityId, Vector3I voxelPosition, long reservationTimeMs, int senderSerialId)
        {
            EndpointId sender;

            if (MyEventContext.Current.IsLocallyInvoked)
            {
                sender = new EndpointId(Sync.MyId);
            }
            else
            {
                sender = MyEventContext.Current.Sender;
            }

            bool success = true;
            ReservedEntityData entityData;
            MyVoxelBase        voxelMap = null;

            if (!MySession.Static.VoxelMaps.Instances.TryGetValue(entityId, out voxelMap))
            {
                return;
            }

            Vector3I voxelMapSize = voxelMap.StorageMax - voxelMap.StorageMin;

            Debug.Assert(voxelMapSize.AbsMax() < 2 * 10E6, "Voxel map size too large to reserve unique voxel position");
            // Integer overflow won't even happen on the next line for voxel maps smaller than roughly (2.5M)^3, and most Vector3I member functions have broken down way before that
            var entityIdPair = new KeyValuePair <long, long>(entityId, voxelPosition.X + voxelPosition.Y * voxelMapSize.X + voxelPosition.Z * voxelMapSize.X * voxelMapSize.Y);

            if (m_reservedEntities.TryGetValue(entityIdPair, out entityData))
            {
                if (entityData.ReserverId == new MyPlayer.PlayerId(sender.Value, senderSerialId))
                {
                    entityData.ReservationTimer = Stopwatch.GetTimestamp() + Stopwatch.Frequency * reservationTimeMs / 1000;
                }
                else
                {
                    success = false;
                }
            }
            else
            {
                m_reservedEntities.Add(entityIdPair, new ReservedEntityData()
                {
                    EntityId         = entityId,
                    GridPos          = voxelPosition,
                    ReservationTimer = Stopwatch.GetTimestamp() + Stopwatch.Frequency * reservationTimeMs / 1000,
                    ReserverId       = new MyPlayer.PlayerId(sender.Value, senderSerialId)
                });
            }

            if (MyEventContext.Current.IsLocallyInvoked)
            {
                if (success)
                {
                    OnReserveVoxelPositionSuccess(entityId, voxelPosition, senderSerialId);
                }
                else
                {
                    OnReserveVoxelPositionFailure(entityId, voxelPosition, senderSerialId);
                }
            }
            else
            {
                if (success)
                {
                    MyMultiplayer.RaiseStaticEvent(s => MyAiTargetManager.OnReserveVoxelPositionSuccess, entityId, voxelPosition, senderSerialId, sender);
                }
                else
                {
                    MyMultiplayer.RaiseStaticEvent(s => MyAiTargetManager.OnReserveVoxelPositionFailure, entityId, voxelPosition, senderSerialId, sender);
                }
            }
        }
        // Math magic by Whiplash
        internal static void BresenhamLineDraw(Vector3I start, Vector3I end, List <Vector3I> points)
        {
            points.Clear();
            points.Add(start);
            Vector3I delta = end - start;
            Vector3I step  = Vector3I.Sign(delta);

            delta *= step;
            int max = delta.AbsMax();

            if (max == delta.X)
            {
                int p1 = 2 * delta.Y - delta.X;
                int p2 = 2 * delta.Z - delta.X;
                while (start.X != end.X)
                {
                    start.X += step.X;
                    if (p1 >= 0)
                    {
                        start.Y += step.Y;
                        p1      -= 2 * delta.X;
                    }

                    if (p2 >= 0)
                    {
                        start.Z += step.Z;
                        p2      -= 2 * delta.X;
                    }
                    p1 += 2 * delta.Y;
                    p2 += 2 * delta.Z;
                    points.Add(start);
                }
            }
            else if (max == delta.Y)
            {
                int p1 = 2 * delta.X - delta.Y;
                int p2 = 2 * delta.Z - delta.Y;
                while (start.Y != end.Y)
                {
                    start.Y += step.Y;
                    if (p1 >= 0)
                    {
                        start.X += step.X;
                        p1      -= 2 * delta.Y;
                    }

                    if (p2 >= 0)
                    {
                        start.Z += step.Z;
                        p2      -= 2 * delta.Y;
                    }
                    p1 += 2 * delta.X;
                    p2 += 2 * delta.Z;
                    points.Add(start);
                }
            }
            else
            {
                int p1 = 2 * delta.X - delta.Z;
                int p2 = 2 * delta.Y - delta.Z;
                while (start.Z != end.Z)
                {
                    start.Z += step.Z;
                    if (p1 >= 0)
                    {
                        start.X += step.X;
                        p1      -= 2 * delta.Z;
                    }

                    if (p2 >= 0)
                    {
                        start.Y += step.Y;
                        p2      -= 2 * delta.Z;
                    }
                    p1 += 2 * delta.X;
                    p2 += 2 * delta.Y;
                    points.Add(start);
                }
            }
        }
Exemplo n.º 5
0
        internal static bool BresenhamGridIntersection(MyCubeGrid grid, ref Vector3D worldStart, ref Vector3D worldEnd, out Vector3D?hitPos, MyCubeBlock weapon = null, GridAi ai = null)
        {
            var      start = grid.WorldToGridInteger(worldStart);
            var      end   = grid.WorldToGridInteger(worldEnd);
            Vector3I delta = end - start;
            Vector3I step  = Vector3I.Sign(delta);

            delta *= step;
            int max = delta.AbsMax();

            hitPos = null;

            var gMinX = grid.Min.X;
            var gMinY = grid.Min.Y;
            var gMinZ = grid.Min.Z;
            var gMaxX = grid.Max.X;
            var gMaxY = grid.Max.Y;
            var gMaxZ = grid.Max.Z;

            if (ai != null)
            {
                var dir        = (worldEnd - worldStart);
                var ray        = new RayD(ref worldStart, ref dir);
                var gridMatrix = ai.MyGrid.PositionComp.WorldMatrixRef;

                foreach (var sub in ai.SubGrids)
                {
                    if (sub == grid)
                    {
                        continue;
                    }
                    var subDist = sub.PositionComp.WorldVolume.Intersects(ray);
                    if (subDist.HasValue)
                    {
                        //var rotMatrix = Quaternion.CreateFromRotationMatrix(ai.MyGrid.WorldMatrix);
                        //var obb = new MyOrientedBoundingBoxD(ai.MyGrid.PositionComp.WorldAABB.Center, ai.MyGrid.PositionComp.LocalAABB.HalfExtents, rotMatrix);
                        var box = ai.MyGrid.PositionComp.LocalAABB;
                        var obb = new MyOrientedBoundingBoxD(box, gridMatrix);

                        Vector3D?ignoreHit;
                        if (obb.Intersects(ref ray) != null && BresenhamGridIntersection(sub, ref worldStart, ref worldEnd, out ignoreHit, weapon))
                        {
                            return(true);
                        }
                    }
                }
            }

            if (max == delta.X)
            {
                int p1 = 2 * delta.Y - delta.X;
                int p2 = 2 * delta.Z - delta.X;
                while (start.X != end.X)
                {
                    start.X += step.X;
                    if (p1 >= 0)
                    {
                        start.Y += step.Y;
                        p1      -= 2 * delta.X;
                    }

                    if (p2 >= 0)
                    {
                        start.Z += step.Z;
                        p2      -= 2 * delta.X;
                    }
                    p1 += 2 * delta.Y;
                    p2 += 2 * delta.Z;
                    var contained = gMinX <= start.X && start.X <= gMaxX && (gMinY <= start.Y && start.Y <= gMaxY) && (gMinZ <= start.Z && start.Z <= gMaxZ);
                    if (!contained)
                    {
                        return(false);
                    }

                    MyCube cube;
                    if (grid.TryGetCube(start, out cube) && cube.CubeBlock != weapon?.SlimBlock)
                    {
                        return(true);
                    }
                }
            }
            else if (max == delta.Y)
            {
                int p1 = 2 * delta.X - delta.Y;
                int p2 = 2 * delta.Z - delta.Y;
                while (start.Y != end.Y)
                {
                    start.Y += step.Y;
                    if (p1 >= 0)
                    {
                        start.X += step.X;
                        p1      -= 2 * delta.Y;
                    }

                    if (p2 >= 0)
                    {
                        start.Z += step.Z;
                        p2      -= 2 * delta.Y;
                    }
                    p1 += 2 * delta.X;
                    p2 += 2 * delta.Z;

                    var contained = gMinX <= start.X && start.X <= gMaxX && (gMinY <= start.Y && start.Y <= gMaxY) && (gMinZ <= start.Z && start.Z <= gMaxZ);
                    if (!contained)
                    {
                        return(false);
                    }

                    MyCube cube;
                    if (grid.TryGetCube(start, out cube) && cube.CubeBlock != weapon?.SlimBlock)
                    {
                        return(true);
                    }
                }
            }
            else
            {
                int p1 = 2 * delta.X - delta.Z;
                int p2 = 2 * delta.Y - delta.Z;
                while (start.Z != end.Z)
                {
                    start.Z += step.Z;
                    if (p1 >= 0)
                    {
                        start.X += step.X;
                        p1      -= 2 * delta.Z;
                    }

                    if (p2 >= 0)
                    {
                        start.Y += step.Y;
                        p2      -= 2 * delta.Z;
                    }
                    p1 += 2 * delta.X;
                    p2 += 2 * delta.Y;

                    var contained = gMinX <= start.X && start.X <= gMaxX && (gMinY <= start.Y && start.Y <= gMaxY) && (gMinZ <= start.Z && start.Z <= gMaxZ);
                    if (!contained)
                    {
                        return(false);
                    }

                    MyCube cube;
                    if (grid.TryGetCube(start, out cube) && cube.CubeBlock != weapon?.SlimBlock)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Exemplo n.º 6
0
        private bool IsFaceTriangle(MyNavigationTriangle triangle, Vector3I cubePosition, Vector3I direction)
        {
            MyWingedEdgeMesh.FaceVertexEnumerator vertexEnumerator = triangle.GetVertexEnumerator();
            vertexEnumerator.MoveNext();
            vertexEnumerator.MoveNext();
            vertexEnumerator.MoveNext();
            cubePosition *= 0x100;
            Vector3I vectori4 = (Vector3I)(cubePosition + (direction * 0x80));
            Vector3I vectori  = Vector3I.Round(vertexEnumerator.Current * 256f) - vectori4;
            Vector3I vectori2 = Vector3I.Round(vertexEnumerator.Current * 256f) - vectori4;
            Vector3I vectori3 = Vector3I.Round(vertexEnumerator.Current * 256f) - vectori4;

            return(!((vectori * direction) != Vector3I.Zero) ? (!((vectori2 * direction) != Vector3I.Zero) ? (!((vectori3 * direction) != Vector3I.Zero) ? ((vectori.AbsMax() <= 0x80) && ((vectori2.AbsMax() <= 0x80) && (vectori3.AbsMax() <= 0x80))) : false) : false) : false);
        }