Beispiel #1
0
        /// <summary>
        /// This returns a random ball, with some optional fixed values
        /// </summary>
        public static WeaponSpikeBallDNA GetRandomDNA(WeaponSpikeBallMaterial?material = null, double?radius = null)
        {
            WeaponSpikeBallDNA retVal = new WeaponSpikeBallDNA();

            Random rand = StaticRandom.GetRandomForThread();

            // Radius
            if (radius != null)
            {
                retVal.Radius = radius.Value;
            }
            else
            {
                retVal.Radius = rand.NextDouble(.2, .5);
            }

            // Material
            if (material == null)
            {
                retVal.Material = UtilityCore.GetRandomEnum <WeaponSpikeBallMaterial>();
            }
            else
            {
                retVal.Material = material.Value;
            }

            return(retVal);
        }
Beispiel #2
0
        public WeaponSpikeBall(WeaponMaterialCache materials, WeaponSpikeBallDNA dna)
        {
            _materials = materials;

            var model = GetModel(dna, materials);

            this.Model = model.Item1;
            this.DNA   = model.Item2;
        }
        public WeaponSpikeBall(WeaponMaterialCache materials, WeaponSpikeBallDNA dna)
        {
            _materials = materials;

            var model = GetModel(dna, materials);

            this.Model = model.Item1;
            this.DNA = model.Item2;
        }
Beispiel #4
0
        private static Model3DGroup GetModel_IronSteel(WeaponSpikeBallDNA dna, WeaponSpikeBallDNA finalDNA, WeaponMaterialCache materials)
        {
            Model3DGroup retVal = new Model3DGroup();
            var          from   = dna.KeyValues;
            var          to     = finalDNA.KeyValues;

            double spikeLength = WeaponDNA.GetKeyValue("spikeLen", from, to, dna.Radius * StaticRandom.NextDouble(1.3d, 1.8d));
            double ballRadius  = spikeLength * .6d;

            #region Spikes

            System.Windows.Media.Media3D.Material material = materials.Spike_Steel;     // the property get returns a slightly random color

            GeometryModel3D geometry = new GeometryModel3D();

            geometry.Material     = material;
            geometry.BackMaterial = material;

            double[]          radii     = new double[] { spikeLength, ballRadius *WeaponDNA.GetKeyValue("spikeRadMult", from, to, StaticRandom.NextDouble(.7, .87)) };
            TriangleIndexed[] triangles = UtilityWPF.GetIcosahedron(radii);

            geometry.Geometry = UtilityWPF.GetMeshFromTriangles_IndependentFaces(triangles);

            retVal.Children.Add(geometry);

            #endregion

            #region Ball

            material = materials.Ball_Iron;     // the property get returns a slightly random color

            geometry = new GeometryModel3D();

            geometry.Material     = material;
            geometry.BackMaterial = material;

            triangles = UtilityWPF.GetIcosahedron(ballRadius, 1);

            geometry.Geometry = UtilityWPF.GetMeshFromTriangles_IndependentFaces(triangles);

            retVal.Children.Add(geometry);

            #endregion

            return(retVal);
        }
Beispiel #5
0
        //TODO: Have an explicit attach point
        private static Tuple <Model3DGroup, WeaponSpikeBallDNA> GetModel(WeaponSpikeBallDNA dna, WeaponMaterialCache materials)
        {
            WeaponSpikeBallDNA finalDNA = UtilityCore.Clone(dna);

            if (finalDNA.KeyValues == null)
            {
                finalDNA.KeyValues = new SortedList <string, double>();
            }

            Model3DGroup model = null;

            switch (finalDNA.Material)
            {
            case WeaponSpikeBallMaterial.Wood:
                model = GetModel_WoodIron(dna, finalDNA, materials);
                break;

            case WeaponSpikeBallMaterial.Bronze_Iron:
                model = GetModel_BronzeIron(dna, finalDNA, materials);
                break;

            case WeaponSpikeBallMaterial.Iron_Steel:
                model = GetModel_IronSteel(dna, finalDNA, materials);
                break;

            case WeaponSpikeBallMaterial.Composite:
                model = GetModel_Composite(dna, finalDNA, materials);
                break;

            case WeaponSpikeBallMaterial.Klinth:
                model = GetModel_Klinth(dna, finalDNA, materials);
                break;

            case WeaponSpikeBallMaterial.Moon:
                model = GetModel_Moon(dna, finalDNA, materials);
                break;

            default:
                throw new ApplicationException("Unknown WeaponSpikeBallMaterial: " + finalDNA.Material.ToString());
            }

            return(Tuple.Create(model, finalDNA));
        }
        //TODO: Have an explicit attach point
        private static Tuple<Model3DGroup, WeaponSpikeBallDNA> GetModel(WeaponSpikeBallDNA dna, WeaponMaterialCache materials)
        {
            WeaponSpikeBallDNA finalDNA = UtilityCore.Clone(dna);
            if (finalDNA.KeyValues == null)
            {
                finalDNA.KeyValues = new SortedList<string, double>();
            }

            Model3DGroup model = null;

            switch (finalDNA.Material)
            {
                case WeaponSpikeBallMaterial.Wood:
                    model = GetModel_WoodIron(dna, finalDNA, materials);
                    break;

                case WeaponSpikeBallMaterial.Bronze_Iron:
                    model = GetModel_BronzeIron(dna, finalDNA, materials);
                    break;

                case WeaponSpikeBallMaterial.Iron_Steel:
                    model = GetModel_IronSteel(dna, finalDNA, materials);
                    break;

                case WeaponSpikeBallMaterial.Composite:
                    model = GetModel_Composite(dna, finalDNA, materials);
                    break;

                case WeaponSpikeBallMaterial.Klinth:
                    model = GetModel_Klinth(dna, finalDNA, materials);
                    break;

                case WeaponSpikeBallMaterial.Moon:
                    model = GetModel_Moon(dna, finalDNA, materials);
                    break;

                default:
                    throw new ApplicationException("Unknown WeaponSpikeBallMaterial: " + finalDNA.Material.ToString());
            }

            return Tuple.Create(model, finalDNA);
        }
        /// <summary>
        /// This returns a random ball that will fit well with the handle passed in
        /// </summary>
        public static WeaponSpikeBallDNA GetRandomDNA(WeaponHandleDNA handle)
        {
            WeaponSpikeBallDNA retVal = new WeaponSpikeBallDNA();

            Random rand = StaticRandom.GetRandomForThread();

            // Radius
            retVal.Radius = GetRandomRadius(handle.Radius, handle.Length);

            #region Material

            // Choose a ball material that goes with the handle's material
            //NOTE: This is assuming that the ball is an appropriate radius for the handle it will be attached to.
            //A large soft wood could safely handle a very small ball, etc

            WeaponSpikeBallMaterial[] ballMaterials = null;

            switch (handle.HandleMaterial)
            {
                case WeaponHandleMaterial.Soft_Wood:
                    ballMaterials = new[] { WeaponSpikeBallMaterial.Wood, WeaponSpikeBallMaterial.Composite };
                    break;

                case WeaponHandleMaterial.Hard_Wood:
                    ballMaterials = new[] { WeaponSpikeBallMaterial.Wood, WeaponSpikeBallMaterial.Bronze_Iron, WeaponSpikeBallMaterial.Iron_Steel, WeaponSpikeBallMaterial.Composite, WeaponSpikeBallMaterial.Klinth };
                    break;

                case WeaponHandleMaterial.Bronze:
                case WeaponHandleMaterial.Iron:
                case WeaponHandleMaterial.Steel:
                    ballMaterials = new[] { WeaponSpikeBallMaterial.Bronze_Iron, WeaponSpikeBallMaterial.Iron_Steel, WeaponSpikeBallMaterial.Moon };
                    break;

                case WeaponHandleMaterial.Composite:
                    ballMaterials = new[] { WeaponSpikeBallMaterial.Bronze_Iron, WeaponSpikeBallMaterial.Iron_Steel, WeaponSpikeBallMaterial.Composite, WeaponSpikeBallMaterial.Klinth, WeaponSpikeBallMaterial.Moon };
                    break;

                case WeaponHandleMaterial.Klinth:
                    ballMaterials = new[] { WeaponSpikeBallMaterial.Bronze_Iron, WeaponSpikeBallMaterial.Iron_Steel, WeaponSpikeBallMaterial.Klinth, WeaponSpikeBallMaterial.Moon };
                    break;

                case WeaponHandleMaterial.Moon:
                    ballMaterials = new[] { WeaponSpikeBallMaterial.Iron_Steel, WeaponSpikeBallMaterial.Klinth, WeaponSpikeBallMaterial.Moon };
                    break;

                default:
                    throw new ApplicationException("Unknown WeaponHandleMaterial: " + handle.HandleMaterial.ToString());
            }

            // Choose one from the filtered list
            retVal.Material = rand.NextItem(ballMaterials);

            #endregion

            #region Color

            ColorHSV? basedOn = null;
            if (handle.MaterialsForCustomizable != null && handle.MaterialsForCustomizable.Length > 0 && !string.IsNullOrEmpty(handle.MaterialsForCustomizable[0].DiffuseColor))
            {
                basedOn = UtilityWPF.ColorFromHex(handle.MaterialsForCustomizable[0].DiffuseColor).ToHSV();
            }

            switch (retVal.Material)
            {
                case WeaponSpikeBallMaterial.Composite:
                    retVal.MaterialsForCustomizable = WeaponHandleDNA.GetRandomMaterials_Composite(null, basedOn);
                    break;

                case WeaponSpikeBallMaterial.Klinth:
                    retVal.MaterialsForCustomizable = WeaponHandleDNA.GetRandomMaterials_Klinth(null, basedOn);
                    break;
            }

            #endregion

            return retVal;
        }
        private static Model3DGroup GetModel_Moon(WeaponSpikeBallDNA dna, WeaponSpikeBallDNA finalDNA, WeaponMaterialCache materials)
        {
            //TODO: Animate the spikes (shafts of light) by choosing one as the independently rotated spike, and the others run through one step of Math3D.GetRandomVectors_SphericalShell_EvenDist
            //TODO: Also animate each spike's radius and length (or at least length)
            //TODO: Also animate each spike's color opacity

            Model3DGroup retVal = new Model3DGroup();

            double spikeLength = dna.Radius * 2d;
            double ballRadius = dna.Radius * 1d;

            double spikeRadius = dna.Radius * .033;

            System.Windows.Media.Media3D.Material material;
            GeometryModel3D geometry;

            #region Ball

            material = materials.Ball_Moon;     // the property get returns a slightly random color

            geometry = new GeometryModel3D();

            geometry.Material = material;
            geometry.BackMaterial = material;

            geometry.Geometry = UtilityWPF.GetSphere_LatLon(5, ballRadius);

            retVal.Children.Add(geometry);

            #endregion

            #region Spikes

            foreach (Vector3D spikeLocation in Math3D.GetRandomVectors_SphericalShell_EvenDist(30, ballRadius, .03, 100))
            {
                material = materials.Spike_Moon;

                geometry = new GeometryModel3D();

                geometry.Material = material;
                geometry.BackMaterial = material;

                RotateTransform3D transform = new RotateTransform3D(new QuaternionRotation3D(Math3D.GetRotation(new Vector3D(0, 0, 1), spikeLocation)));       // the tube builds along z

                List<TubeRingBase> rings = new List<TubeRingBase>();

                double spikeLengthMid = spikeLength * .75d;

                rings.Add(new TubeRingRegularPolygon(0, false, spikeRadius, spikeRadius, false));
                rings.Add(new TubeRingRegularPolygon(spikeLengthMid, false, spikeRadius, spikeRadius, false));
                rings.Add(new TubeRingDome(spikeLength - spikeLengthMid, false, 2));

                geometry.Geometry = UtilityWPF.GetMultiRingedTube(9, rings, true, false, transform);

                retVal.Children.Add(geometry);
            }

            #endregion

            return retVal;
        }
        private static Model3DGroup GetModel_Klinth(WeaponSpikeBallDNA dna, WeaponSpikeBallDNA finalDNA, WeaponMaterialCache materials)
        {
            Model3DGroup retVal = new Model3DGroup();

            var from = dna.KeyValues;
            var to = finalDNA.KeyValues;

            double spikeLength = WeaponDNA.GetKeyValue("spikeLength", from, to, StaticRandom.NextPercent(dna.Radius * 1.1d, .05));
            double ballRadius = dna.Radius;

            double spikeRadius = WeaponDNA.GetKeyValue("spikeRadius", from, to, StaticRandom.NextPercent(dna.Radius * .2, .1));

            var color = WeaponMaterialCache.GetKlinth(dna.MaterialsForCustomizable);
            finalDNA.MaterialsForCustomizable = color.Item3;

            GeometryModel3D geometry;

            #region Ball

            geometry = new GeometryModel3D();

            geometry.Material = color.Item1;
            geometry.BackMaterial = color.Item1;

            Icosidodecahedron ball = UtilityWPF.GetIcosidodecahedron(ballRadius);

            geometry.Geometry = UtilityWPF.GetMeshFromTriangles_IndependentFaces(ball.AllTriangles);

            retVal.Children.Add(geometry);

            #endregion

            #region Spikes

            // Put a spike through the center of each pentagon
            foreach (Vector3D spikeLocation in ball.PentagonPolys.Select(o => Math3D.GetCenter(o.Select(p => ball.AllPoints[p]))))
            {
                geometry = new GeometryModel3D();

                geometry.Material = color.Item2;
                geometry.BackMaterial = color.Item2;

                RotateTransform3D transform = new RotateTransform3D(new QuaternionRotation3D(Math3D.GetRotation(new Vector3D(0, 0, 1), spikeLocation)));       // the tube builds along z

                List<TubeRingBase> rings = new List<TubeRingBase>();

                double spikeLengthMid = spikeLength * .8d;

                rings.Add(new TubeRingRegularPolygon(0, false, spikeRadius, spikeRadius, false));
                rings.Add(new TubeRingRegularPolygon(spikeLengthMid, false, spikeRadius, spikeRadius, false));
                rings.Add(new TubeRingDome(spikeLength - spikeLengthMid, false, 3));

                geometry.Geometry = UtilityWPF.GetMultiRingedTube(9, rings, false, false, transform);

                retVal.Children.Add(geometry);
            }

            #endregion

            return retVal;
        }
        private static Model3DGroup GetModel_Composite(WeaponSpikeBallDNA dna, WeaponSpikeBallDNA finalDNA, WeaponMaterialCache materials)
        {
            Model3DGroup retVal = new Model3DGroup();

            Random rand = StaticRandom.GetRandomForThread();

            var from = dna.KeyValues;
            var to = finalDNA.KeyValues;

            double spikeOrthLength = WeaponDNA.GetKeyValue("spikeOrthLength", from, to, rand.NextPercent(dna.Radius * 1.4d, .1));
            double spikeDiagLength = WeaponDNA.GetKeyValue("spikeDiagLength", from, to, rand.NextPercent(dna.Radius * 1.15d, .05));
            double ballRadius = dna.Radius;

            double spikeOrthRadius = WeaponDNA.GetKeyValue("spikeOrthRadius", from, to, rand.NextPercent(dna.Radius * .5, .1));
            double spikeDiagRadius = WeaponDNA.GetKeyValue("spikeDiagRadius", from, to, rand.NextPercent(dna.Radius * .5, .1));

            double ballRadiusDepth = ballRadius * .1;       //this is how far the triangle parts of the ball sink in

            var color = WeaponMaterialCache.GetComposite(dna.MaterialsForCustomizable);
            finalDNA.MaterialsForCustomizable = color.Item4;

            GeometryModel3D geometry;

            #region Ball - outer

            geometry = new GeometryModel3D();

            geometry.Material = color.Item1;
            geometry.BackMaterial = color.Item1;

            Rhombicuboctahedron ball = UtilityWPF.GetRhombicuboctahedron(ballRadius * 2, ballRadius * 2, ballRadius * 2);

            TriangleIndexed[] usedTriangles = UtilityCore.Iterate(
                ball.Squares_Orth.SelectMany(o => o),
                ball.Squares_Diag.SelectMany(o => o),
                GetModel_Composite_SquareSides(ball, ballRadiusDepth * 1.1)       // this builds plates that go toward the center of the ball, because the triangles are indented
                ).ToArray();

            geometry.Geometry = UtilityWPF.GetMeshFromTriangles_IndependentFaces(usedTriangles);

            retVal.Children.Add(geometry);

            #endregion
            #region Ball - inner

            geometry = new GeometryModel3D();

            geometry.Material = color.Item2;
            geometry.BackMaterial = color.Item2;

            // Use the triangles, but suck them in a bit
            geometry.Geometry = UtilityWPF.GetMeshFromTriangles_IndependentFaces(GetModel_Composite_IndentedTriangles(ball, ballRadiusDepth));

            retVal.Children.Add(geometry);

            #endregion

            #region Spikes

            var spikeLocations = UtilityCore.Iterate(ball.SquarePolys_Orth.Select(o => Tuple.Create(true, o)), ball.SquarePolys_Diag.Select(o => Tuple.Create(false, o))).
                Select(o => new { IsOrth = o.Item1, Center = Math3D.GetCenter(o.Item2.Select(p => ball.AllPoints[p])).ToVector() });

            // Put a spike through the center of each square
            foreach (var spikeLocation in spikeLocations)
            {
                geometry = new GeometryModel3D();

                geometry.Material = color.Item3;
                geometry.BackMaterial = color.Item3;

                RotateTransform3D transform = new RotateTransform3D(new QuaternionRotation3D(Math3D.GetRotation(new Vector3D(0, 0, 1), spikeLocation.Center)));       // the tube builds along z

                List<TubeRingBase> rings = new List<TubeRingBase>();

                double spikeLengthActual = spikeLocation.IsOrth ? spikeOrthLength : spikeDiagLength;
                double spikeRadiusActual = spikeLocation.IsOrth ? spikeOrthRadius : spikeDiagRadius;

                rings.Add(new TubeRingRegularPolygon(0, false, spikeRadiusActual, spikeRadiusActual, false));
                rings.Add(new TubeRingPoint(spikeLengthActual, false));

                geometry.Geometry = UtilityWPF.GetMultiRingedTube(9, rings, true, false, transform);

                retVal.Children.Add(geometry);
            }

            #endregion

            return retVal;
        }
        private static Model3DGroup GetModel_IronSteel(WeaponSpikeBallDNA dna, WeaponSpikeBallDNA finalDNA, WeaponMaterialCache materials)
        {
            Model3DGroup retVal = new Model3DGroup();
            var from = dna.KeyValues;
            var to = finalDNA.KeyValues;

            double spikeLength = WeaponDNA.GetKeyValue("spikeLen", from, to, dna.Radius * StaticRandom.NextDouble(1.3d, 1.8d));
            double ballRadius = spikeLength * .6d;

            #region Spikes

            System.Windows.Media.Media3D.Material material = materials.Spike_Steel;     // the property get returns a slightly random color

            GeometryModel3D geometry = new GeometryModel3D();

            geometry.Material = material;
            geometry.BackMaterial = material;

            double[] radii = new double[] { spikeLength, ballRadius * WeaponDNA.GetKeyValue("spikeRadMult", from, to, StaticRandom.NextDouble(.7, .87)) };
            TriangleIndexed[] triangles = UtilityWPF.GetIcosahedron(radii);

            geometry.Geometry = UtilityWPF.GetMeshFromTriangles_IndependentFaces(triangles);

            retVal.Children.Add(geometry);

            #endregion

            #region Ball

            material = materials.Ball_Iron;     // the property get returns a slightly random color

            geometry = new GeometryModel3D();

            geometry.Material = material;
            geometry.BackMaterial = material;

            triangles = UtilityWPF.GetIcosahedron(ballRadius, 1);

            geometry.Geometry = UtilityWPF.GetMeshFromTriangles_IndependentFaces(triangles);

            retVal.Children.Add(geometry);

            #endregion

            return retVal;
        }
Beispiel #12
0
        private static Model3DGroup GetModel_Composite(WeaponSpikeBallDNA dna, WeaponSpikeBallDNA finalDNA, WeaponMaterialCache materials)
        {
            Model3DGroup retVal = new Model3DGroup();

            Random rand = StaticRandom.GetRandomForThread();

            var from = dna.KeyValues;
            var to   = finalDNA.KeyValues;

            double spikeOrthLength = WeaponDNA.GetKeyValue("spikeOrthLength", from, to, rand.NextPercent(dna.Radius * 1.4d, .1));
            double spikeDiagLength = WeaponDNA.GetKeyValue("spikeDiagLength", from, to, rand.NextPercent(dna.Radius * 1.15d, .05));
            double ballRadius      = dna.Radius;

            double spikeOrthRadius = WeaponDNA.GetKeyValue("spikeOrthRadius", from, to, rand.NextPercent(dna.Radius * .5, .1));
            double spikeDiagRadius = WeaponDNA.GetKeyValue("spikeDiagRadius", from, to, rand.NextPercent(dna.Radius * .5, .1));

            double ballRadiusDepth = ballRadius * .1;       //this is how far the triangle parts of the ball sink in

            var color = WeaponMaterialCache.GetComposite(dna.MaterialsForCustomizable);

            finalDNA.MaterialsForCustomizable = color.Item4;

            GeometryModel3D geometry;

            #region Ball - outer

            geometry = new GeometryModel3D();

            geometry.Material     = color.Item1;
            geometry.BackMaterial = color.Item1;

            Rhombicuboctahedron ball = UtilityWPF.GetRhombicuboctahedron(ballRadius * 2, ballRadius * 2, ballRadius * 2);

            TriangleIndexed[] usedTriangles = UtilityCore.Iterate(
                ball.Squares_Orth.SelectMany(o => o),
                ball.Squares_Diag.SelectMany(o => o),
                GetModel_Composite_SquareSides(ball, ballRadiusDepth * 1.1)       // this builds plates that go toward the center of the ball, because the triangles are indented
                ).ToArray();

            geometry.Geometry = UtilityWPF.GetMeshFromTriangles_IndependentFaces(usedTriangles);

            retVal.Children.Add(geometry);

            #endregion
            #region Ball - inner

            geometry = new GeometryModel3D();

            geometry.Material     = color.Item2;
            geometry.BackMaterial = color.Item2;

            // Use the triangles, but suck them in a bit
            geometry.Geometry = UtilityWPF.GetMeshFromTriangles_IndependentFaces(GetModel_Composite_IndentedTriangles(ball, ballRadiusDepth));

            retVal.Children.Add(geometry);

            #endregion

            #region Spikes

            var spikeLocations = UtilityCore.Iterate(ball.SquarePolys_Orth.Select(o => Tuple.Create(true, o)), ball.SquarePolys_Diag.Select(o => Tuple.Create(false, o))).
                                 Select(o => new { IsOrth = o.Item1, Center = Math3D.GetCenter(o.Item2.Select(p => ball.AllPoints[p])).ToVector() });

            // Put a spike through the center of each square
            foreach (var spikeLocation in spikeLocations)
            {
                geometry = new GeometryModel3D();

                geometry.Material     = color.Item3;
                geometry.BackMaterial = color.Item3;

                RotateTransform3D transform = new RotateTransform3D(new QuaternionRotation3D(Math3D.GetRotation(new Vector3D(0, 0, 1), spikeLocation.Center)));       // the tube builds along z

                List <TubeRingBase> rings = new List <TubeRingBase>();

                double spikeLengthActual = spikeLocation.IsOrth ? spikeOrthLength : spikeDiagLength;
                double spikeRadiusActual = spikeLocation.IsOrth ? spikeOrthRadius : spikeDiagRadius;

                rings.Add(new TubeRingRegularPolygon(0, false, spikeRadiusActual, spikeRadiusActual, false));
                rings.Add(new TubeRingPoint(spikeLengthActual, false));

                geometry.Geometry = UtilityWPF.GetMultiRingedTube(9, rings, true, false, transform);

                retVal.Children.Add(geometry);
            }

            #endregion

            return(retVal);
        }
        private static Model3DGroup GetModel_WoodIron(WeaponSpikeBallDNA dna, WeaponSpikeBallDNA finalDNA, WeaponMaterialCache materials)
        {
            Model3DGroup retVal = new Model3DGroup();

            Random rand = StaticRandom.GetRandomForThread();
            var from = dna.KeyValues;
            var to = finalDNA.KeyValues;

            double spikeLength = dna.Radius * 1.4d;
            double ballRadius = dna.Radius * 1d;

            double spikeRadius = dna.Radius * .2;

            #region Ball

            System.Windows.Media.Media3D.Material material = materials.Ball_Wood;     // the property get returns a slightly random color

            GeometryModel3D geometry = new GeometryModel3D();

            geometry.Material = material;
            geometry.BackMaterial = material;

            // Create a convex hull out of semi evenly distibuted points
            int numHullPoints = Convert.ToInt32(WeaponDNA.GetKeyValue("numHullPoints", from, to, rand.Next(20, 50)));
            TriangleIndexed[] ball = Math3D.GetConvexHull(Math3D.GetRandomVectors_SphericalShell_EvenDist(numHullPoints, ballRadius, .03, 10).Select(o => o.ToPoint()).ToArray());

            geometry.Geometry = UtilityWPF.GetMeshFromTriangles(ball);

            retVal.Children.Add(geometry);

            #endregion

            // These are placed where the rings are, to push spikes away (so that spikes don't poke through the rings)
            List<Vector3D> staticPoints = new List<Vector3D>();

            #region Rings

            material = materials.Spike_Iron;     // the property get returns a slightly random color

            // 0, 1 or 2 rings.  Higher chance of 0 than 2
            int numRings = Convert.ToInt32(WeaponDNA.GetKeyValue("numRings", from, to, Math.Floor(rand.NextPow(2, 2.3))));

            double[] zs = new double[0];

            switch (numRings)
            {
                case 0:
                    break;

                case 1:
                    zs = new double[] { WeaponDNA.GetKeyValue("ringZ1", from, to, Math1D.GetNearZeroValue(ballRadius * .75)) };
                    break;

                case 2:
                    double z1 = WeaponDNA.GetKeyValue("ringZ1", from, to, Math1D.GetNearZeroValue(ballRadius * .75));
                    double z2 = 0;

                    if (from == null || !from.TryGetValue("ringZ2", out z2))
                    {
                        do
                        {
                            z2 = Math1D.GetNearZeroValue(ballRadius * .75);
                        } while (Math.Abs(z1 - z2) < ballRadius * .4);

                        to.Add("ringZ2", z2);
                    }

                    zs = new double[] { z1, z2 };
                    break;

                default:
                    throw new ApplicationException("Unexpected number of rings: " + numRings.ToString());
            }

            // Build the rings at the z offsets that were calculated above
            for (int cntr = 0; cntr < zs.Length; cntr++)
            {
                retVal.Children.Add(GetModel_WoodIron_Ring_Band(ballRadius, zs[cntr], material, ball, from, to, "ringZ" + cntr.ToString()));

                // Store points at the rings
                double ringRadiusAvg = Math.Sqrt((ballRadius * ballRadius) - (zs[cntr] * zs[cntr]));
                staticPoints.AddRange(Math2D.GetCircle_Cached(7).Select(o => (o.ToVector() * ringRadiusAvg).ToVector3D(zs[cntr])));
            }

            #endregion

            #region Spikes

            Vector3D[] staticPointsArr = staticPoints.Count == 0 ? null : staticPoints.ToArray();
            double[] staticRepulse = staticPoints.Count == 0 ? null : Enumerable.Range(0, staticPoints.Count).Select(o => .005d).ToArray();

            int numSpikes = Convert.ToInt32(WeaponDNA.GetKeyValue("numSpikes", from, to, rand.Next(8, 14)));

            Vector3D[] spikeLocations;
            if (from != null && from.ContainsKey("spikeLoc0X"))
            {
                spikeLocations = new Vector3D[numSpikes];

                for (int cntr = 0; cntr < numSpikes; cntr++)
                {
                    string prefix = "spikeLoc" + cntr.ToString();
                    spikeLocations[cntr] = new Vector3D(to[prefix + "X"], to[prefix + "Y"], to[prefix + "Z"]);
                }
            }
            else
            {
                spikeLocations = Math3D.GetRandomVectors_SphericalShell_EvenDist(numSpikes, ballRadius, .03, 10, null, staticPointsArr, staticRepulse);

                for (int cntr = 0; cntr < numSpikes; cntr++)
                {
                    string prefix = "spikeLoc" + cntr.ToString();
                    to.Add(prefix + "X", spikeLocations[cntr].X);
                    to.Add(prefix + "Y", spikeLocations[cntr].Y);
                    to.Add(prefix + "Z", spikeLocations[cntr].Z);
                }
            }

            for (int cntr = 0; cntr < spikeLocations.Length; cntr++)
            {
                material = materials.Spike_Iron;     // the property get returns a slightly random color

                geometry = new GeometryModel3D();

                geometry.Material = material;
                geometry.BackMaterial = material;

                RotateTransform3D transform = new RotateTransform3D(new QuaternionRotation3D(Math3D.GetRotation(new Vector3D(0, 0, 1), spikeLocations[cntr])));       // the tube builds along z

                List<TubeRingBase> rings = new List<TubeRingBase>();

                double spikeRadiusA = WeaponDNA.GetKeyValue("spikeRad" + cntr.ToString(), from, to, rand.NextPercent(spikeRadius, .33));

                rings.Add(new TubeRingRegularPolygon(0, false, spikeRadiusA, spikeRadiusA, false));
                rings.Add(new TubeRingPoint(WeaponDNA.GetKeyValue("spikeLen" + cntr.ToString(), from, to, rand.NextDouble(spikeLength * .9, spikeLength * 1.1)), false));

                int numSegments = Convert.ToInt32(WeaponDNA.GetKeyValue("spikeSegs" + cntr.ToString(), from, to, rand.Next(3, 6)));
                bool isSoft = Math1D.IsNearZero(WeaponDNA.GetKeyValue("spikeSoft" + cntr.ToString(), from, to, rand.Next(2)));
                geometry.Geometry = UtilityWPF.GetMultiRingedTube(numSegments, rings, isSoft, false, transform);

                retVal.Children.Add(geometry);
            }

            #endregion

            return retVal;
        }
Beispiel #14
0
        private static Model3DGroup GetModel_WoodIron(WeaponSpikeBallDNA dna, WeaponSpikeBallDNA finalDNA, WeaponMaterialCache materials)
        {
            Model3DGroup retVal = new Model3DGroup();

            Random rand = StaticRandom.GetRandomForThread();
            var    from = dna.KeyValues;
            var    to   = finalDNA.KeyValues;

            double spikeLength = dna.Radius * 1.4d;
            double ballRadius  = dna.Radius * 1d;

            double spikeRadius = dna.Radius * .2;

            #region Ball

            System.Windows.Media.Media3D.Material material = materials.Ball_Wood;     // the property get returns a slightly random color

            GeometryModel3D geometry = new GeometryModel3D();

            geometry.Material     = material;
            geometry.BackMaterial = material;

            // Create a convex hull out of semi evenly distibuted points
            int numHullPoints      = Convert.ToInt32(WeaponDNA.GetKeyValue("numHullPoints", from, to, rand.Next(20, 50)));
            TriangleIndexed[] ball = Math3D.GetConvexHull(Math3D.GetRandomVectors_SphericalShell_EvenDist(numHullPoints, ballRadius, .03, 10).Select(o => o.ToPoint()).ToArray());

            geometry.Geometry = UtilityWPF.GetMeshFromTriangles(ball);

            retVal.Children.Add(geometry);

            #endregion

            // These are placed where the rings are, to push spikes away (so that spikes don't poke through the rings)
            List <Vector3D> staticPoints = new List <Vector3D>();

            #region Rings

            material = materials.Spike_Iron;     // the property get returns a slightly random color

            // 0, 1 or 2 rings.  Higher chance of 0 than 2
            int numRings = Convert.ToInt32(WeaponDNA.GetKeyValue("numRings", from, to, Math.Floor(rand.NextPow(2, 2.3))));

            double[] zs = new double[0];

            switch (numRings)
            {
            case 0:
                break;

            case 1:
                zs = new double[] { WeaponDNA.GetKeyValue("ringZ1", from, to, Math1D.GetNearZeroValue(ballRadius * .75)) };
                break;

            case 2:
                double z1 = WeaponDNA.GetKeyValue("ringZ1", from, to, Math1D.GetNearZeroValue(ballRadius * .75));
                double z2 = 0;

                if (from == null || !from.TryGetValue("ringZ2", out z2))
                {
                    do
                    {
                        z2 = Math1D.GetNearZeroValue(ballRadius * .75);
                    } while (Math.Abs(z1 - z2) < ballRadius * .4);

                    to.Add("ringZ2", z2);
                }

                zs = new double[] { z1, z2 };
                break;

            default:
                throw new ApplicationException("Unexpected number of rings: " + numRings.ToString());
            }

            // Build the rings at the z offsets that were calculated above
            for (int cntr = 0; cntr < zs.Length; cntr++)
            {
                retVal.Children.Add(GetModel_WoodIron_Ring_Band(ballRadius, zs[cntr], material, ball, from, to, "ringZ" + cntr.ToString()));

                // Store points at the rings
                double ringRadiusAvg = Math.Sqrt((ballRadius * ballRadius) - (zs[cntr] * zs[cntr]));
                staticPoints.AddRange(Math2D.GetCircle_Cached(7).Select(o => (o.ToVector() * ringRadiusAvg).ToVector3D(zs[cntr])));
            }

            #endregion

            #region Spikes

            Vector3D[] staticPointsArr = staticPoints.Count == 0 ? null : staticPoints.ToArray();
            double[]   staticRepulse   = staticPoints.Count == 0 ? null : Enumerable.Range(0, staticPoints.Count).Select(o => .005d).ToArray();

            int numSpikes = Convert.ToInt32(WeaponDNA.GetKeyValue("numSpikes", from, to, rand.Next(8, 14)));

            Vector3D[] spikeLocations;
            if (from != null && from.ContainsKey("spikeLoc0X"))
            {
                spikeLocations = new Vector3D[numSpikes];

                for (int cntr = 0; cntr < numSpikes; cntr++)
                {
                    string prefix = "spikeLoc" + cntr.ToString();
                    spikeLocations[cntr] = new Vector3D(to[prefix + "X"], to[prefix + "Y"], to[prefix + "Z"]);
                }
            }
            else
            {
                spikeLocations = Math3D.GetRandomVectors_SphericalShell_EvenDist(numSpikes, ballRadius, .03, 10, null, staticPointsArr, staticRepulse);

                for (int cntr = 0; cntr < numSpikes; cntr++)
                {
                    string prefix = "spikeLoc" + cntr.ToString();
                    to.Add(prefix + "X", spikeLocations[cntr].X);
                    to.Add(prefix + "Y", spikeLocations[cntr].Y);
                    to.Add(prefix + "Z", spikeLocations[cntr].Z);
                }
            }

            for (int cntr = 0; cntr < spikeLocations.Length; cntr++)
            {
                material = materials.Spike_Iron;     // the property get returns a slightly random color

                geometry = new GeometryModel3D();

                geometry.Material     = material;
                geometry.BackMaterial = material;

                RotateTransform3D transform = new RotateTransform3D(new QuaternionRotation3D(Math3D.GetRotation(new Vector3D(0, 0, 1), spikeLocations[cntr])));       // the tube builds along z

                List <TubeRingBase> rings = new List <TubeRingBase>();

                double spikeRadiusA = WeaponDNA.GetKeyValue("spikeRad" + cntr.ToString(), from, to, rand.NextPercent(spikeRadius, .33));

                rings.Add(new TubeRingRegularPolygon(0, false, spikeRadiusA, spikeRadiusA, false));
                rings.Add(new TubeRingPoint(WeaponDNA.GetKeyValue("spikeLen" + cntr.ToString(), from, to, rand.NextDouble(spikeLength * .9, spikeLength * 1.1)), false));

                int  numSegments = Convert.ToInt32(WeaponDNA.GetKeyValue("spikeSegs" + cntr.ToString(), from, to, rand.Next(3, 6)));
                bool isSoft      = Math1D.IsNearZero(WeaponDNA.GetKeyValue("spikeSoft" + cntr.ToString(), from, to, rand.Next(2)));
                geometry.Geometry = UtilityWPF.GetMultiRingedTube(numSegments, rings, isSoft, false, transform);

                retVal.Children.Add(geometry);
            }

            #endregion

            return(retVal);
        }
Beispiel #15
0
        /// <summary>
        /// This returns a random ball that will fit well with the handle passed in
        /// </summary>
        public static WeaponSpikeBallDNA GetRandomDNA(WeaponHandleDNA handle)
        {
            WeaponSpikeBallDNA retVal = new WeaponSpikeBallDNA();

            Random rand = StaticRandom.GetRandomForThread();

            // Radius
            retVal.Radius = GetRandomRadius(handle.Radius, handle.Length);

            #region Material

            // Choose a ball material that goes with the handle's material
            //NOTE: This is assuming that the ball is an appropriate radius for the handle it will be attached to.
            //A large soft wood could safely handle a very small ball, etc

            WeaponSpikeBallMaterial[] ballMaterials = null;

            switch (handle.HandleMaterial)
            {
            case WeaponHandleMaterial.Soft_Wood:
                ballMaterials = new[] { WeaponSpikeBallMaterial.Wood, WeaponSpikeBallMaterial.Composite };
                break;

            case WeaponHandleMaterial.Hard_Wood:
                ballMaterials = new[] { WeaponSpikeBallMaterial.Wood, WeaponSpikeBallMaterial.Bronze_Iron, WeaponSpikeBallMaterial.Iron_Steel, WeaponSpikeBallMaterial.Composite, WeaponSpikeBallMaterial.Klinth };
                break;

            case WeaponHandleMaterial.Bronze:
            case WeaponHandleMaterial.Iron:
            case WeaponHandleMaterial.Steel:
                ballMaterials = new[] { WeaponSpikeBallMaterial.Bronze_Iron, WeaponSpikeBallMaterial.Iron_Steel, WeaponSpikeBallMaterial.Moon };
                break;

            case WeaponHandleMaterial.Composite:
                ballMaterials = new[] { WeaponSpikeBallMaterial.Bronze_Iron, WeaponSpikeBallMaterial.Iron_Steel, WeaponSpikeBallMaterial.Composite, WeaponSpikeBallMaterial.Klinth, WeaponSpikeBallMaterial.Moon };
                break;

            case WeaponHandleMaterial.Klinth:
                ballMaterials = new[] { WeaponSpikeBallMaterial.Bronze_Iron, WeaponSpikeBallMaterial.Iron_Steel, WeaponSpikeBallMaterial.Klinth, WeaponSpikeBallMaterial.Moon };
                break;

            case WeaponHandleMaterial.Moon:
                ballMaterials = new[] { WeaponSpikeBallMaterial.Iron_Steel, WeaponSpikeBallMaterial.Klinth, WeaponSpikeBallMaterial.Moon };
                break;

            default:
                throw new ApplicationException("Unknown WeaponHandleMaterial: " + handle.HandleMaterial.ToString());
            }

            // Choose one from the filtered list
            retVal.Material = rand.NextItem(ballMaterials);

            #endregion

            #region Color

            ColorHSV?basedOn = null;
            if (handle.MaterialsForCustomizable != null && handle.MaterialsForCustomizable.Length > 0 && !string.IsNullOrEmpty(handle.MaterialsForCustomizable[0].DiffuseColor))
            {
                basedOn = UtilityWPF.ColorFromHex(handle.MaterialsForCustomizable[0].DiffuseColor).ToHSV();
            }

            switch (retVal.Material)
            {
            case WeaponSpikeBallMaterial.Composite:
                retVal.MaterialsForCustomizable = WeaponHandleDNA.GetRandomMaterials_Composite(null, basedOn);
                break;

            case WeaponSpikeBallMaterial.Klinth:
                retVal.MaterialsForCustomizable = WeaponHandleDNA.GetRandomMaterials_Klinth(null, basedOn);
                break;
            }

            #endregion

            return(retVal);
        }
Beispiel #16
0
        private static Model3DGroup GetModel_Moon(WeaponSpikeBallDNA dna, WeaponSpikeBallDNA finalDNA, WeaponMaterialCache materials)
        {
            //TODO: Animate the spikes (shafts of light) by choosing one as the independently rotated spike, and the others run through one step of Math3D.GetRandomVectors_SphericalShell_EvenDist
            //TODO: Also animate each spike's radius and length (or at least length)
            //TODO: Also animate each spike's color opacity

            Model3DGroup retVal = new Model3DGroup();

            double spikeLength = dna.Radius * 2d;
            double ballRadius  = dna.Radius * 1d;

            double spikeRadius = dna.Radius * .033;

            System.Windows.Media.Media3D.Material material;
            GeometryModel3D geometry;

            #region Ball

            material = materials.Ball_Moon;     // the property get returns a slightly random color

            geometry = new GeometryModel3D();

            geometry.Material     = material;
            geometry.BackMaterial = material;

            geometry.Geometry = UtilityWPF.GetSphere_LatLon(5, ballRadius);

            retVal.Children.Add(geometry);

            #endregion

            #region Spikes

            foreach (Vector3D spikeLocation in Math3D.GetRandomVectors_SphericalShell_EvenDist(30, ballRadius, .03, 100))
            {
                material = materials.Spike_Moon;

                geometry = new GeometryModel3D();

                geometry.Material     = material;
                geometry.BackMaterial = material;

                RotateTransform3D transform = new RotateTransform3D(new QuaternionRotation3D(Math3D.GetRotation(new Vector3D(0, 0, 1), spikeLocation)));       // the tube builds along z

                List <TubeRingBase> rings = new List <TubeRingBase>();

                double spikeLengthMid = spikeLength * .75d;

                rings.Add(new TubeRingRegularPolygon(0, false, spikeRadius, spikeRadius, false));
                rings.Add(new TubeRingRegularPolygon(spikeLengthMid, false, spikeRadius, spikeRadius, false));
                rings.Add(new TubeRingDome(spikeLength - spikeLengthMid, false, 2));

                geometry.Geometry = UtilityWPF.GetMultiRingedTube(9, rings, true, false, transform);

                retVal.Children.Add(geometry);
            }

            #endregion

            return(retVal);
        }
Beispiel #17
0
        private static Model3DGroup GetModel_Klinth(WeaponSpikeBallDNA dna, WeaponSpikeBallDNA finalDNA, WeaponMaterialCache materials)
        {
            Model3DGroup retVal = new Model3DGroup();

            var from = dna.KeyValues;
            var to   = finalDNA.KeyValues;

            double spikeLength = WeaponDNA.GetKeyValue("spikeLength", from, to, StaticRandom.NextPercent(dna.Radius * 1.1d, .05));
            double ballRadius  = dna.Radius;

            double spikeRadius = WeaponDNA.GetKeyValue("spikeRadius", from, to, StaticRandom.NextPercent(dna.Radius * .2, .1));

            var color = WeaponMaterialCache.GetKlinth(dna.MaterialsForCustomizable);

            finalDNA.MaterialsForCustomizable = color.Item3;

            GeometryModel3D geometry;

            #region Ball

            geometry = new GeometryModel3D();

            geometry.Material     = color.Item1;
            geometry.BackMaterial = color.Item1;

            Icosidodecahedron ball = UtilityWPF.GetIcosidodecahedron(ballRadius);

            geometry.Geometry = UtilityWPF.GetMeshFromTriangles_IndependentFaces(ball.AllTriangles);

            retVal.Children.Add(geometry);

            #endregion

            #region Spikes

            // Put a spike through the center of each pentagon
            foreach (Vector3D spikeLocation in ball.PentagonPolys.Select(o => Math3D.GetCenter(o.Select(p => ball.AllPoints[p]))))
            {
                geometry = new GeometryModel3D();

                geometry.Material     = color.Item2;
                geometry.BackMaterial = color.Item2;

                RotateTransform3D transform = new RotateTransform3D(new QuaternionRotation3D(Math3D.GetRotation(new Vector3D(0, 0, 1), spikeLocation)));       // the tube builds along z

                List <TubeRingBase> rings = new List <TubeRingBase>();

                double spikeLengthMid = spikeLength * .8d;

                rings.Add(new TubeRingRegularPolygon(0, false, spikeRadius, spikeRadius, false));
                rings.Add(new TubeRingRegularPolygon(spikeLengthMid, false, spikeRadius, spikeRadius, false));
                rings.Add(new TubeRingDome(spikeLength - spikeLengthMid, false, 3));

                geometry.Geometry = UtilityWPF.GetMultiRingedTube(9, rings, false, false, transform);

                retVal.Children.Add(geometry);
            }

            #endregion

            return(retVal);
        }
        /// <summary>
        /// This returns a random ball, with some optional fixed values
        /// </summary>
        public static WeaponSpikeBallDNA GetRandomDNA(WeaponSpikeBallMaterial? material = null, double? radius = null)
        {
            WeaponSpikeBallDNA retVal = new WeaponSpikeBallDNA();

            Random rand = StaticRandom.GetRandomForThread();

            // Radius
            if (radius != null)
            {
                retVal.Radius = radius.Value;
            }
            else
            {
                retVal.Radius = rand.NextDouble(.2, .5);
            }

            // Material
            if (material == null)
            {
                retVal.Material = UtilityCore.GetRandomEnum<WeaponSpikeBallMaterial>();
            }
            else
            {
                retVal.Material = material.Value;
            }

            return retVal;
        }
        private void btnGenerateSpikeBall_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                _viewport.Children.RemoveAll(_visuals);

                string selectedItem = cboMaterial.SelectedItem as string;

                WeaponSpikeBallMaterial material;
                if (selectedItem == null || !Enum.TryParse(selectedItem, out material))
                {
                    MessageBox.Show("Unrecognized material", "CharacterStatsPanel", MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                WeaponSpikeBallDNA dna = new WeaponSpikeBallDNA()
                {
                    Radius = 1d,
                    Material = material
                };

                ModelVisual3D visual = new ModelVisual3D();
                visual.Content = new WeaponSpikeBall(new WeaponMaterialCache(), dna).Model;

                _visuals.Add(visual);
                _viewport.Children.Add(visual);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "CharacterStatsPanel", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }