Exemplo n.º 1
0
        public Heightmap CloneAndFlipX()
        {
            Heightmap heightmap = Clone();

            heightmap.heightmapData.FlipXInPlace();
            return(heightmap);
        }
Exemplo n.º 2
0
 public ShadowReceiver(Heightmap heightmap, Oblique heightmapExtendDirection)
 {
     if (heightmap == null)
     {
         throw new ArgumentNullException("heightmap");
     }
     this.heightmap = heightmap;
     this.heightmapExtendDirection = heightmapExtendDirection;
 }
Exemplo n.º 3
0
        /// <param name="baseHeightmap">NOTE: This gets used as a proxy for "is this a shadow receiver"</param>
        public void RefreshFromInstructions(Heightmap baseHeightmap)
        {
            if (instructions != null) // No instructions means we are raw data (do not touch!)
            {
                ClearToHeight(0);     // <- Start blank.

                foreach (var instruction in instructions)
                {
                    instruction.Process(this, baseHeightmap);
                }

                if (baseHeightmap == null)
                {
                    Optimise();
                }
            }
        }
Exemplo n.º 4
0
 /// <summary>Deserialize into new object instance</summary>
 public ShadowReceiver(AnimationDeserializeContext context)
 {
     heightmap = new Heightmap(context);
     heightmapExtendDirection = context.br.ReadOblique();
 }
Exemplo n.º 5
0
        /// <summary>Create a new heightmap that extends its content (non-default heights) out in oblique directions (sutiable for creating shadow heightmaps)</summary>
        public Heightmap CreateExtendedOblique(Oblique oblique)
        {
            // Expand the region containing content in the specified oblique direction(s)
            #region ASCII Art...
            //
            // Given a heightmap that looks like this:
            //      ________
            //     | /\  /\ |
            //     |/  \/  \|
            //     |\      /|
            //     |/      \|
            //     |\  /\  /|
            //     |_\/__\/_|
            //
            // Expand it by projecting its content in the oblique direction:
            //  ________________
            // |.  | /\  /\ |   |
            // | . |/  \/  \|   |
            // |  .|\      /.   |
            // |   ./      \|.  |
            // |   |\  /\  /| . |
            // |___|_\/__\/_|__.|
            //
            #endregion

            int extendedLeft  = StartX;
            int extendedRight = EndX - 1; // <- inclusive
            for (int z = StartZ; z < EndZ; z++)
            {
                for (int x = StartX; x < EndX; x++)
                {
                    if (this[x, z] != DefaultHeight)         // Has content to extend
                    {
                        int deltaFromFront = z - StartZ;     // (positive)
                        int deltaFromBack  = z - (EndZ - 1); // (negative)

                        int frontX = x - deltaFromFront * (int)oblique;
                        int backX  = x - deltaFromBack * (int)oblique;

                        // Expand:
                        if (frontX < extendedLeft)
                        {
                            extendedLeft = frontX;
                        }
                        if (frontX > extendedRight)
                        {
                            extendedRight = frontX;
                        }
                        if (backX < extendedLeft)
                        {
                            extendedLeft = backX;
                        }
                        if (backX > extendedRight)
                        {
                            extendedRight = backX;
                        }
                    }
                }
            }

            // HACK: To allow edges to have zero values when filled, without adding expansion to the Fill methods,
            //       simply expand by one pixel here:
            // TODO: Allow the FillLeft/FillRight methods to automatically expand the size of the heightmap sideways if necessary
            //       (So that zero values on the very edge aren't lost)
            extendedLeft  -= 1;
            extendedRight += 1;


            Rectangle destinationBounds = new Rectangle(extendedLeft, StartZ, extendedRight - extendedLeft + 1, EndZ - StartZ);

            Heightmap destination = new Heightmap(DefaultHeight);
            destination.heightmapData = new Data2D <byte>(destinationBounds);

            // Copy while extending content
            for (int destinationZ = destination.StartZ; destinationZ < destination.EndZ; destinationZ++)
            {
                for (int destinationX = destination.StartX; destinationX < destination.EndX; destinationX++)
                {
                    // We could add a bunch of early-outs here (but we don't care if this is a tad slow)
                    int sourceX = destinationX, sourceZ = destinationZ;

                    // Try and extend to find content:
                    if (this[sourceX, sourceZ] == DefaultHeight)
                    {
                        // Search backwards to back of heightmap
                        while (true)
                        {
                            sourceZ += 1;
                            sourceX += (int)oblique;
                            if (sourceZ >= this.EndZ)
                            {
                                goto searchForward;
                            }
                            if (this[sourceX, sourceZ] != DefaultHeight)
                            {
                                goto done;
                            }
                        }

                        // Search forward to front of heightmap
searchForward:
                        sourceX = destinationX; sourceZ = destinationZ;
                        while (true)
                        {
                            sourceZ -= 1;
                            sourceX -= (int)oblique;
                            if (sourceZ < this.StartZ)
                            {
                                goto fail;
                            }
                            if (this[sourceX, sourceZ] != DefaultHeight)
                            {
                                goto done;
                            }
                        }

fail:
                        sourceX = destinationX; sourceZ = destinationZ;
done:
                        ;
                    }
                    destination[destinationX, destinationZ] = this[sourceX, sourceZ];
                }
            }

            return(destination);
        }
Exemplo n.º 6
0
 public HeightmapView(Heightmap heightmap, Position position, bool flipX)
 {
     this.heightmap = heightmap;
     this.position  = position;
     this.flipX     = flipX;
 }
Exemplo n.º 7
0
        /// <param name="heightmap">The heightmap to apply the instruction to</param>
        /// <param name="baseHeightmap">When creating ShadowReceiver heightmaps, the AnimationSet heightmap</param>
        public void Process(Heightmap heightmap, Heightmap baseHeightmap)
        {
            switch (Operation)
            {
            case HeightmapOp.ClearToHeight:
                heightmap.ClearToHeight(Height);
                break;

            case HeightmapOp.SetFromFlatBaseMask:
                heightmap.SetFromFlatBaseMask(Mask.data, Height);
                break;

            case HeightmapOp.SetFromFlatTopMask:
                heightmap.SetFromFlatTopMask(Mask.data, Height);
                break;

            case HeightmapOp.SetFromObliqueTopMask:
                heightmap.SetFromObliqueTopMask(Mask.data, FrontEdgeDepth, ObliqueDirection);
                break;

            case HeightmapOp.SetFromRailingMask:
                heightmap.SetFromRailingMask(Mask.data);
                break;

            case HeightmapOp.SetFromFrontEdge:
                heightmap.SetFromFrontEdge(Mask.data, FrontEdgeDepth, Depth, ObliqueDirection, Slope, Offset);
                break;

            case HeightmapOp.SetFlatRelative:
                heightmap.SetFlatRelative(Mask.data, Height, Offset);
                break;

            case HeightmapOp.SetFromSideOblique:
                heightmap.SetFromObliqueSide(Mask.data, ObliqueDirection, Offset);
                break;

            case HeightmapOp.CreateExtendedObliqueFromBase:
            {
                var temp = baseHeightmap.CreateExtendedOblique(ObliqueDirection);
                heightmap.heightmapData = temp.heightmapData;         // <- suck out its brains
                heightmap.DefaultHeight = temp.DefaultHeight;
            }
            break;

            case HeightmapOp.ExtendOblique:
            {
                var temp = heightmap.CreateExtendedOblique(ObliqueDirection);
                heightmap.heightmapData = temp.heightmapData;         // <- suck out its brains
                heightmap.DefaultHeight = temp.DefaultHeight;
            }
            break;

            case HeightmapOp.FillLeft:
                heightmap.FillLeft(null);
                break;

            case HeightmapOp.FillLeftFixedHeight:
                heightmap.FillLeft(Height);
                break;

            case HeightmapOp.FillRight:
                heightmap.FillRight(null);
                break;

            case HeightmapOp.FillRightFixedHeight:
                heightmap.FillRight(Height);
                break;
            }
        }
Exemplo n.º 8
0
 public ShadowReceiver(byte height)
 {
     heightmap = new Heightmap(height); // No data heightmap (single height)
 }