示例#1
0
文件: Map.cs 项目: kernelbitch/Lemma
        protected void calculateAdjacency(IEnumerable<Box> boxes)
        {
            foreach (Box box in boxes)
                box.Adjacent = new List<Box>();

            Dictionary<BoxRelationship, bool> relationships = new Dictionary<BoxRelationship, bool>();

            foreach (Box box in boxes)
            {
                this.additions.Add(box);
                // Front face
                for (int x = box.X; x < box.X + box.Width; x++)
                {
                    for (int y = box.Y; y < box.Y + box.Height; )
                    {
                        Box adjacent = this.GetBox(x, y, box.Z + box.Depth);
                        if (adjacent != null)
                        {
                            BoxRelationship relationship1 = new BoxRelationship { A = box, B = adjacent };
                            BoxRelationship relationship2 = new BoxRelationship { A = adjacent, B = box };
                            if (!relationships.ContainsKey(relationship1) && !relationships.ContainsKey(relationship2))
                            {
                                relationships[relationship1] = true;
                                box.Adjacent.Add(adjacent);
                                adjacent.Adjacent.Add(box);
                            }
                            y = adjacent.Y + adjacent.Height;
                        }
                        else
                            y++;
                    }
                }

                // Back face
                for (int x = box.X; x < box.X + box.Width; x++)
                {
                    for (int y = box.Y; y < box.Y + box.Height; )
                    {
                        Box adjacent = this.GetBox(x, y, box.Z - 1);
                        if (adjacent != null)
                        {
                            BoxRelationship relationship1 = new BoxRelationship { A = box, B = adjacent };
                            BoxRelationship relationship2 = new BoxRelationship { A = adjacent, B = box };
                            if (!relationships.ContainsKey(relationship1) && !relationships.ContainsKey(relationship2))
                            {
                                relationships[relationship1] = true;
                                box.Adjacent.Add(adjacent);
                                adjacent.Adjacent.Add(box);
                            }
                            y = adjacent.Y + adjacent.Height;
                        }
                        else
                            y++;
                    }
                }

                // Right face
                for (int z = box.Z; z < box.Z + box.Depth; z++)
                {
                    for (int y = box.Y; y < box.Y + box.Height; )
                    {
                        Box adjacent = this.GetBox(box.X + box.Width, y, z);
                        if (adjacent != null)
                        {
                            BoxRelationship relationship1 = new BoxRelationship { A = box, B = adjacent };
                            BoxRelationship relationship2 = new BoxRelationship { A = adjacent, B = box };
                            if (!relationships.ContainsKey(relationship1) && !relationships.ContainsKey(relationship2))
                            {
                                relationships[relationship1] = true;
                                box.Adjacent.Add(adjacent);
                                adjacent.Adjacent.Add(box);
                            }
                            y = adjacent.Y + adjacent.Height;
                        }
                        else
                            y++;
                    }
                }

                // Left face
                for (int z = box.Z; z < box.Z + box.Depth; z++)
                {
                    for (int y = box.Y; y < box.Y + box.Height; )
                    {
                        Box adjacent = this.GetBox(box.X - 1, y, z);
                        if (adjacent != null)
                        {
                            BoxRelationship relationship1 = new BoxRelationship { A = box, B = adjacent };
                            BoxRelationship relationship2 = new BoxRelationship { A = adjacent, B = box };
                            if (!relationships.ContainsKey(relationship1) && !relationships.ContainsKey(relationship2))
                            {
                                relationships[relationship1] = true;
                                box.Adjacent.Add(adjacent);
                                adjacent.Adjacent.Add(box);
                            }
                            y = adjacent.Y + adjacent.Height;
                        }
                        else
                            y++;
                    }
                }

                // Top face
                for (int x = box.X; x < box.X + box.Width; x++)
                {
                    for (int z = box.Z; z < box.Z + box.Depth; )
                    {
                        Box adjacent = this.GetBox(x, box.Y + box.Height, z);
                        if (adjacent != null)
                        {
                            BoxRelationship relationship1 = new BoxRelationship { A = box, B = adjacent };
                            BoxRelationship relationship2 = new BoxRelationship { A = adjacent, B = box };
                            if (!relationships.ContainsKey(relationship1) && !relationships.ContainsKey(relationship2))
                            {
                                relationships[relationship1] = true;
                                box.Adjacent.Add(adjacent);
                                adjacent.Adjacent.Add(box);
                            }
                            z = adjacent.Z + adjacent.Depth;
                        }
                        else
                            z++;
                    }
                }

                // Bottom face
                for (int x = box.X; x < box.X + box.Width; x++)
                {
                    for (int z = box.Z; z < box.Z + box.Depth; )
                    {
                        Box adjacent = this.GetBox(x, box.Y - 1, z);
                        if (adjacent != null)
                        {
                            BoxRelationship relationship1 = new BoxRelationship { A = box, B = adjacent };
                            BoxRelationship relationship2 = new BoxRelationship { A = adjacent, B = box };
                            if (!relationships.ContainsKey(relationship1) && !relationships.ContainsKey(relationship2))
                            {
                                relationships[relationship1] = true;
                                box.Adjacent.Add(adjacent);
                                adjacent.Adjacent.Add(box);
                            }
                            z = adjacent.Z + adjacent.Depth;
                        }
                        else
                            z++;
                    }
                }
            }
        }
示例#2
0
文件: Map.cs 项目: kernelbitch/Lemma
        public override void InitializeProperties()
        {
            this.updateBounds();

            if (Map.workThread == null)
            {
                Map.workThread = new Thread(new ThreadStart(Map.worker));
                Map.workThread.Start();
                this.main.Exiting += delegate(object a, EventArgs b)
                {
                    Map.workThread.Abort();
                };
                Main m = this.main;
                Map.spawner = new Updater
                {
                    delegate(float dt)
                    {
                        DynamicMapFactory factory = Factory.Get<DynamicMapFactory>();
                        BlockFactory blockFactory = Factory.Get<BlockFactory>();
                        List<SpawnGroup> spawns = null;
                        lock (Map.spawns)
                        {
                            spawns = Map.spawns.ToList();
                            Map.spawns.Clear();
                        }
                        foreach (SpawnGroup spawn in spawns)
                        {
                            List<DynamicMap> spawnedMaps = new List<DynamicMap>();
                            foreach (List<Box> island in spawn.Islands)
                            {
                                Box firstBox = island.First();
                                if (island.Count == 1 && firstBox.Width * firstBox.Height * firstBox.Depth == 1)
                                {
                                    // Just create a temporary physics block instead of a full-blown map
                                    Coordinate coord = new Coordinate { X = firstBox.X, Y = firstBox.Y, Z = firstBox.Z };
                                    Entity block = blockFactory.CreateAndBind(main);
                                    block.Get<Transform>().Matrix.Value = this.Transform;
                                    block.Get<Transform>().Position.Value = this.GetAbsolutePosition(coord);
                                    firstBox.Type.ApplyToBlock(block);
                                    block.Get<ModelInstance>().GetVector3Parameter("Offset").Value = this.GetRelativePosition(coord);
                                    main.Add(block);
                                }
                                else
                                {
                                    Entity newMap = factory.CreateAndBind(spawn.Source.main, firstBox.X, firstBox.Y, firstBox.Z);
                                    newMap.Get<Transform>().Matrix.Value = spawn.Source.Transform;
                                    DynamicMap newMapComponent = newMap.Get<DynamicMap>();
                                    newMapComponent.Offset.Value = spawn.Source.Offset;
                                    newMapComponent.BuildFromBoxes(island);
                                    spawn.Source.notifyEmptied(island.SelectMany(x => x.GetCoords()), newMapComponent);
                                    newMapComponent.notifyFilled(island.SelectMany(x => x.GetCoords()), spawn.Source);
                                    newMapComponent.Transform.Reset();
                                    if (spawn.Source is DynamicMap)
                                        newMapComponent.IsAffectedByGravity.Value = ((DynamicMap)spawn.Source).IsAffectedByGravity;
                                    spawn.Source.main.Add(newMap);
                                    spawnedMaps.Add(newMapComponent);
                                }
                            }
                            if (spawn.Callback != null)
                                spawn.Callback(spawnedMaps);
                        }
                    }
                };
                Map.spawner.EnabledInEditMode.Value = true;
                Map.spawner.EnabledWhenPaused.Value = true;
                this.main.AddComponent(Map.spawner);
            }

            this.Data.Get = delegate()
            {
                List<int> result = new List<int>();
                lock (this.mutationLock)
                {
                    List<Box> boxes = this.Chunks.Where(x => x.Data != null).SelectMany(x => x.Boxes).ToList();
                    bool[] modifications = this.simplify(boxes);
                    this.simplify(boxes, modifications);
                    this.applyChanges(boxes, modifications);

                    boxes = this.Chunks.SelectMany(x => x.Boxes).ToList();

                    result.Add(boxes.Count);

                    Dictionary<Box, int> indexLookup = new Dictionary<Box, int>();

                    int index = 0;
                    foreach (Box box in boxes)
                    {
                        result.Add(box.X);
                        result.Add(box.Y);
                        result.Add(box.Z);
                        result.Add(box.Width);
                        result.Add(box.Height);
                        result.Add(box.Depth);
                        result.Add(box.Type.ID);
                        for (int i = 0; i < 6; i++)
                        {
                            Surface surface = box.Surfaces[i];
                            result.Add(surface.MinU);
                            result.Add(surface.MinV);
                            result.Add(surface.MaxU);
                            result.Add(surface.MaxV);
                        }
                        indexLookup.Add(box, index);
                        index++;
                    }

                    Dictionary<BoxRelationship, bool> relationships = new Dictionary<BoxRelationship, bool>();
                    index = 0;
                    foreach (Box box in boxes)
                    {
                        if (box.Adjacent == null)
                            continue;
                        foreach (Box adjacent in box.Adjacent)
                        {
                            if (box.Type.Permanent && adjacent.Type.Permanent)
                                continue;

                            BoxRelationship relationship1 = new BoxRelationship { A = box, B = adjacent };
                            BoxRelationship relationship2 = new BoxRelationship { A = adjacent, B = box };
                            if (!relationships.ContainsKey(relationship1) && !relationships.ContainsKey(relationship2))
                            {
                                relationships[relationship1] = true;
                                result.Add(index);
                                result.Add(indexLookup[adjacent]);
                            }
                        }
                        index++;
                    }
                }

                return Map.serializeData(result.ToArray());
            };

            this.Data.Set = delegate(string value)
            {
                int[] data = Map.deserializeData(value);

                int boxCount = data[0];

                Box[] boxes = new Box[boxCount];

                const int boxDataSize = 31;

                for (int i = 0; i < boxCount; i++)
                {
                    // Format:
                    // x
                    // y
                    // z
                    // width
                    // height
                    // depth
                    // type
                    // MinU, MinV, MaxU, MaxV for each of six surfaces
                    int index = 1 + (i * boxDataSize);
                    if (data[index + 6] != 0)
                    {
                        CellState state = WorldFactory.States[data[index + 6]];
                        int x = data[index], y = data[index + 1], z = data[index + 2], w = data[index + 3], h = data[index + 4], d = data[index + 5];
                        int chunkX = this.minX + ((x - this.minX) / this.chunkSize) * this.chunkSize, chunkY = this.minY + ((y - this.minY) / this.chunkSize) * this.chunkSize, chunkZ = this.minZ + ((z - this.minZ) / this.chunkSize) * this.chunkSize;
                        int nextChunkX = this.minX + ((x + w - this.minX) / this.chunkSize) * this.chunkSize, nextChunkY = this.minY + ((y + h - this.minY) / this.chunkSize) * this.chunkSize, nextChunkZ = this.minZ + ((z + d - this.minZ) / this.chunkSize) * this.chunkSize;
                        for (int ix = chunkX; ix <= nextChunkX; ix += this.chunkSize)
                        {
                            for (int iy = chunkY; iy <= nextChunkY; iy += this.chunkSize)
                            {
                                for (int iz = chunkZ; iz <= nextChunkZ; iz += this.chunkSize)
                                {
                                    int bx = Math.Max(ix, x), by = Math.Max(iy, y), bz = Math.Max(iz, z);
                                    Box box = new Box
                                    {
                                        X = bx,
                                        Y = by,
                                        Z = bz,
                                        Width = Math.Min(x + w, ix + this.chunkSize) - bx,
                                        Height = Math.Min(y + h, iy + this.chunkSize) - by,
                                        Depth = Math.Min(z + d, iz + this.chunkSize) - bz,
                                        Type = state,
                                        Active = true,
                                    };
                                    if (box.Width > 0 && box.Height > 0 && box.Depth > 0)
                                    {
                                        boxes[i] = box;
                                        Chunk chunk = this.GetChunk(bx, by, bz);
                                        if (chunk.DataBoxes == null)
                                            chunk.DataBoxes = new List<Box>();
                                        chunk.DataBoxes.Add(box);
                                        box.Chunk = chunk;
                                        for (int x1 = box.X - chunk.X; x1 < box.X + box.Width - chunk.X; x1++)
                                        {
                                            for (int y1 = box.Y - chunk.Y; y1 < box.Y + box.Height - chunk.Y; y1++)
                                            {
                                                for (int z1 = box.Z - chunk.Z; z1 < box.Z + box.Depth - chunk.Z; z1++)
                                                    chunk.Data[x1, y1, z1] = box;
                                            }
                                        }
                                        box.Surfaces[(int)Direction.NegativeX].W = box.X;
                                        box.Surfaces[(int)Direction.PositiveX].W = box.X + box.Width;
                                        box.Surfaces[(int)Direction.NegativeY].W = box.Y;
                                        box.Surfaces[(int)Direction.PositiveY].W = box.Y + box.Height;
                                        box.Surfaces[(int)Direction.NegativeZ].W = box.Z;
                                        box.Surfaces[(int)Direction.PositiveZ].W = box.Z + box.Depth;
                                        for (int j = 0; j < 6; j++)
                                        {
                                            int baseIndex = index + (j * 4) + 7;
                                            Surface surface = box.Surfaces[j];
                                            surface.MinU = data[baseIndex + 0];
                                            surface.MinV = data[baseIndex + 1];
                                            surface.MaxU = data[baseIndex + 2];
                                            surface.MaxV = data[baseIndex + 3];
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                for (int i = 1 + (boxCount * boxDataSize); i < data.Length; i += 2)
                {
                    Box box1 = boxes[data[i]], box2 = boxes[data[i + 1]];
                    if (box1 != null && box2 != null)
                    {
                        box1.Adjacent.Add(box2);
                        box2.Adjacent.Add(box1);
                    }
                }

                this.postDeserialization();
            };
            Map.Maps.Add(this);
        }