示例#1
0
        public override void OnUpdateModelPositions(TerrainChangeParameters parameters)
        {
            var center = new Vector2(parameters.Center.X, parameters.Center.Y);

            foreach (var inst in DoodadInstances)
            {
                if (inst == null || inst.RenderInstance == null)
                {
                    continue;
                }

                var pos  = mDoodadDefs[inst.MddfIndex].Position;
                var invZ = 64.0f * Metrics.TileSize - pos.Z;
                var dist = (new Vector2(pos.X, invZ) - center).Length();
                if (dist > parameters.OuterRadius)
                {
                    continue;
                }

                if (WorldFrame.Instance.MapManager.GetLandHeight(pos.X, pos.Z, out pos.Y))
                {
                    mDoodadDefs[inst.MddfIndex].Position = pos;
                    inst.RenderInstance.UpdatePosition(new Vector3(pos.X, invZ, pos.Y));
                }
            }
        }
示例#2
0
文件: MapChunk.cs 项目: veserine/Neo
        private bool HandleElevateTerrain(TerrainChangeParameters parameters)
        {
            var amount  = parameters.Amount * (float)parameters.TimeDiff.TotalSeconds;
            var changed = false;
            var radius  = parameters.OuterRadius;

            for (var i = 0; i < 145; ++i)
            {
                var p    = Vertices[i].Position;
                var dist = (new Vector2(p.X, p.Y) - new Vector2(parameters.Center.X, parameters.Center.Y)).Length();
                if (dist > radius)
                {
                    continue;
                }

                changed = true;
                var factor = dist / radius;

                switch (parameters.Algorithm)
                {
                case TerrainAlgorithm.Flat:
                    p.Z += amount * (parameters.Inverted ? -1 : 1);
                    break;

                case TerrainAlgorithm.Linear:
                    p.Z += (amount * (1.0f - factor)) * (parameters.Inverted ? -1 : 1);
                    break;

                case TerrainAlgorithm.Quadratic:
                    p.Z += (((-amount) / (radius * radius) * (dist * dist)) + amount) * (parameters.Inverted ? -1 : 1);
                    break;

                case TerrainAlgorithm.Trigonometric:
                    var cs = Math.Cos(factor * Math.PI / 2);
                    p.Z += (amount * (float)cs) * (parameters.Inverted ? -1 : 1);
                    break;
                }

                if (p.Z < mMinHeight)
                {
                    mMinHeight = p.Z;
                }
                if (p.Z > mMaxHeight)
                {
                    mMaxHeight = p.Z;
                }

                Vertices[i].Position = p;
            }

            return(changed);
        }
示例#3
0
文件: MapArea.cs 项目: veserine/Neo
        public override bool OnChangeTerrain(TerrainChangeParameters parameters)
        {
            var changed = false;
            foreach (var chunk in mChunks)
            {
                if (chunk == null) continue;

                if (chunk.OnTerrainChange(parameters))
                    changed = true;
            }

            if (changed)
                mWasChanged = true;

            return changed;
        }
示例#4
0
文件: MapChunk.cs 项目: veserine/Neo
        public virtual bool OnTerrainChange(TerrainChangeParameters parameters)
        {
            var diffVec = new Vector2(mMidPoint.X, mMidPoint.Y) - new Vector2(parameters.Center.X, parameters.Center.Y);
            var dsquare = Vector2.Dot(diffVec, diffVec);

            var maxRadius = parameters.OuterRadius + Metrics.ChunkRadius;

            if (dsquare > maxRadius * maxRadius)
            {
                return(false);
            }

            // always update the normals if we are closer than ChunkRadius to the modified area
            // since nearby changes might affect the normals of this chunk even if the positions
            // them self didn't change
            mUpdateNormals = true;

            var changed = false;

            switch (parameters.Method)
            {
            case TerrainChangeType.Elevate:
                changed = HandleElevateTerrain(parameters);
                break;

            case TerrainChangeType.Flatten:
                changed = HandleFlatten(parameters);
                break;

            case TerrainChangeType.Blur:
                changed = HandleBlur(parameters);
                break;

            case TerrainChangeType.Shading:
                changed = HandleMccvPaint(parameters);
                break;
            }

            return(changed);
        }
示例#5
0
        public override bool OnTerrainChange(TerrainChangeParameters parameters)
        {
            var changed = base.OnTerrainChange(parameters);

            if (changed)
            {
                MapArea parent;
                mParent.TryGetTarget(out parent);

                var omin = BoundingBox.Minimum;
                var omax = BoundingBox.Maximum;
                BoundingBox = new BoundingBox(new Vector3(omin.X, omin.Y, mMinHeight),
                                              new Vector3(omax.X, omax.Y, mMaxHeight));

                if (parent != null)
                {
                    parent.UpdateBoundingBox(BoundingBox);
                }
            }

            return(changed);
        }
示例#6
0
        protected override bool HandleMccvPaint(TerrainChangeParameters parameters)
        {
            var amount  = (parameters.Amount / 75.0f) * (float)parameters.TimeDiff.TotalSeconds;
            var changed = false;

            var destColor = parameters.Shading;

            if (parameters.Inverted)
            {
                destColor.X = 2 - destColor.X;
                destColor.Y = 2 - destColor.Y;
                destColor.Z = 2 - destColor.Z;
            }

            var radius = parameters.OuterRadius;

            for (var i = 0; i < 145; ++i)
            {
                var p    = Vertices[i].Position;
                var dist = (new Vector2(p.X, p.Y) - new Vector2(parameters.Center.X, parameters.Center.Y)).Length();
                if (dist > radius)
                {
                    continue;
                }

                HasMccv = true;
                changed = true;
                var factor = dist / radius;
                if (dist < parameters.InnerRadius)
                {
                    factor = 1.0f;
                }

                var curColor = mShadingFloats[i];
                var dr       = destColor.X - curColor.Z;
                var dg       = destColor.Y - curColor.Y;
                var db       = destColor.Z - curColor.X;

                var cr = Math.Min(Math.Abs(dr), amount * factor);
                var cg = Math.Min(Math.Abs(dg), amount * factor);
                var cb = Math.Min(Math.Abs(db), amount * factor);

                if (dr < 0)
                {
                    curColor.Z -= cr;
                    if (curColor.Z < destColor.X)
                    {
                        curColor.Z = destColor.X;
                    }
                }
                else
                {
                    curColor.Z += cr;
                    if (curColor.Z > destColor.X)
                    {
                        curColor.Z = destColor.X;
                    }
                }
                if (dg < 0)
                {
                    curColor.Y -= cg;
                    if (curColor.Y < destColor.Y)
                    {
                        curColor.Y = destColor.Y;
                    }
                }
                else
                {
                    curColor.Y += cg;
                    if (curColor.Y > destColor.Y)
                    {
                        curColor.Y = destColor.Y;
                    }
                }
                if (db < 0)
                {
                    curColor.X -= cb;
                    if (curColor.X < destColor.Z)
                    {
                        curColor.X = destColor.Z;
                    }
                }
                else
                {
                    curColor.X += cb;
                    if (curColor.X > destColor.Z)
                    {
                        curColor.X = destColor.Z;
                    }
                }

                mShadingFloats[i] = curColor;

                curColor.X = Math.Min(Math.Max(curColor.X, 0), 2);
                curColor.Y = Math.Min(Math.Max(curColor.Y, 0), 2);
                curColor.Z = Math.Min(Math.Max(curColor.Z, 0), 2);

                var r = (byte)((curColor.Z / 2.0f) * 255.0f);
                var g = (byte)((curColor.Y / 2.0f) * 255.0f);
                var b = (byte)((curColor.X / 2.0f) * 255.0f);
                var a = (byte)((curColor.W / 2.0f) * 255.0f);

                var color = (uint)((a << 24) | (r << 16) | (g << 8) | b);
                Vertices[i].Color = color;
            }

            return(changed);
        }
示例#7
0
文件: MapChunk.cs 项目: veserine/Neo
        private bool HandleFlatten(TerrainChangeParameters parameters)
        {
            var radius = parameters.OuterRadius;
            var amount = parameters.Amount / 550.0f;

            if (amount > 1)
            {
                amount = 1;
            }

            amount = 1 - amount;
            var changed = false;

            for (var i = 0; i < 145; ++i)
            {
                var p    = Vertices[i].Position;
                var dist = (new Vector2(p.X, p.Y) - new Vector2(parameters.Center.X, parameters.Center.Y)).Length();
                if (dist > radius)
                {
                    continue;
                }

                changed = true;
                var factor = dist / radius;

                switch (parameters.Algorithm)
                {
                case TerrainAlgorithm.Flat:
                    p.Z = amount * p.Z + (1 - amount) * parameters.Center.Z;
                    break;

                case TerrainAlgorithm.Linear:
                {
                    var nremain = 1 - (1 - amount) * (1 - factor);
                    p.Z = nremain * p.Z + (1 - nremain) * parameters.Center.Z;
                    break;
                }

                case TerrainAlgorithm.Quadratic:
                {
                    var nremain = 1 - (float)Math.Pow(1 - amount, 1 + factor);
                    p.Z = nremain * p.Z + (1 - nremain) * parameters.Center.Z;
                    break;
                }

                case TerrainAlgorithm.Trigonometric:
                {
                    var nremain = 1 - (1 - amount) * (1 - (float)Math.Cos(factor * Math.PI / 2.0f));
                    p.Z = nremain * p.Z + (1 - nremain) * parameters.Center.Z;
                    break;
                }
                }

                if (p.Z < mMinHeight)
                {
                    mMinHeight = p.Z;
                }
                if (p.Z > mMaxHeight)
                {
                    mMaxHeight = p.Z;
                }

                Vertices[i].Position = p;
            }

            return(changed);
        }
示例#8
0
文件: MapChunk.cs 项目: veserine/Neo
        private bool HandleBlur(TerrainChangeParameters parameters)
        {
            var radius = parameters.OuterRadius;
            var amount = parameters.Amount / 550.0f;

            if (amount > 1)
            {
                amount = 1;
            }

            amount = 1 - amount;
            var changed = false;

            for (var i = 0; i < 145; ++i)
            {
                var p    = Vertices[i].Position;
                var dist = (new Vector2(p.X, p.Y) - new Vector2(parameters.Center.X, parameters.Center.Y)).Length();
                if (dist > radius)
                {
                    continue;
                }

                changed = true;
                var totalHeight = 0.0f;
                var totalWeight = 0.0f;
                var rad         = (int)(radius / Metrics.UnitSize);
                for (var j = -rad; j <= rad; ++j)
                {
                    var ty = parameters.Center.Y + j * Metrics.UnitSize;
                    for (var k = -rad; k <= rad; ++k)
                    {
                        var tx    = parameters.Center.X + k * Metrics.UnitSize;
                        var xdiff = tx - p.X;
                        var ydiff = ty - p.Y;
                        var diff  = xdiff * xdiff + ydiff * ydiff;
                        if (diff > radius * radius)
                        {
                            continue;
                        }

                        float height;
                        if (WorldFrame.Instance.MapManager.GetLandHeight(tx, 64.0f * Metrics.TileSize - ty, out height) ==
                            false)
                        {
                            height = p.Z;
                        }

                        var dist2 = (float)Math.Sqrt(diff);
                        totalHeight += (1 - dist2 / radius) * height;
                        totalWeight += (1 - dist2 / radius);
                    }
                }

                var h = totalHeight / totalWeight;
                switch (parameters.Algorithm)
                {
                case TerrainAlgorithm.Flat:
                    p.Z = amount * p.Z + (1 - amount) * h;
                    break;

                case TerrainAlgorithm.Linear:
                {
                    var nremain = 1 - (1 - amount) * (1 - dist / radius);
                    p.Z = nremain * p.Z + (1 - nremain) * h;
                }
                break;

                case TerrainAlgorithm.Quadratic:
                {
                    var nremain = 1 - (float)Math.Pow(1 - amount, 1 + dist / radius);
                    p.Z = nremain * p.Z + (1 - nremain) * h;
                }
                break;

                case TerrainAlgorithm.Trigonometric:
                {
                    var nremain = 1 - (1 - amount) * (float)Math.Cos(dist / radius);
                    p.Z = nremain * p.Z + (1 - nremain) * h;
                }
                break;
                }

                if (p.Z < mMinHeight)
                {
                    mMinHeight = p.Z;
                }
                if (p.Z > mMaxHeight)
                {
                    mMaxHeight = p.Z;
                }

                Vertices[i].Position = p;
            }

            return(changed);
        }
示例#9
0
文件: MapChunk.cs 项目: veserine/Neo
 protected abstract bool HandleMccvPaint(TerrainChangeParameters parameters);