Пример #1
0
        private static Model3D[] CreateIcons_Rotate(double arcRadius, double arcThickness, double arrowThickness, double sphereRadius)
        {
            const int NUMSIDES_TOTAL = 13;
            const int NUMSIDES_USE   = 9;

            #region create triangles

            Point[] pointsTheta = Math2D.GetCircle_Cached(NUMSIDES_TOTAL);

            var circlePoints = pointsTheta.
                               Select(o => GetCirclePoints(o, arcRadius, arcThickness, sphereRadius)).
                               ToArray();

            List <Triangle> triangles = new List <Triangle>();

            for (int cntr = 0; cntr < NUMSIDES_USE - 1; cntr++)
            {
                triangles.Add(new Triangle(circlePoints[cntr].inner, circlePoints[cntr].outer, circlePoints[cntr + 1].inner));
                triangles.Add(new Triangle(circlePoints[cntr].outer, circlePoints[cntr + 1].outer, circlePoints[cntr + 1].inner));
            }

            int i1 = NUMSIDES_USE - 1;
            int i2 = NUMSIDES_USE;

            var arrowBase = GetCirclePoints(pointsTheta[i1], arcRadius, arrowThickness, sphereRadius);
            var arrowTip  = GetCirclePoints(pointsTheta[i2], arcRadius, arcThickness * .75, sphereRadius);       //NOTE: Not using mid, because that curls the arrow too steeply (looks odd).  So using outer as a comprimise between pointing in and pointing straight

            triangles.Add(new Triangle(arrowBase.inner, circlePoints[i1].inner, arrowTip.outer));
            triangles.Add(new Triangle(circlePoints[i1].inner, circlePoints[i1].outer, arrowTip.outer));
            triangles.Add(new Triangle(circlePoints[i1].outer, arrowBase.outer, arrowTip.outer));

            // It would be more efficient to build the link triangles directly, but a lot more logic
            ITriangleIndexed[] indexedTriangles = TriangleIndexed.ConvertToIndexed(triangles.ToArray());

            #endregion

            List <Model3D> retVal = new List <Model3D>();

            MaterialGroup material = new MaterialGroup();
            material.Children.Add(new DiffuseMaterial(new SolidColorBrush(WorldColors.ImpulseEngine_Icon_Color)));
            material.Children.Add(WorldColors.ImpulseEngine_Icon_Specular);
            material.Children.Add(WorldColors.ImpulseEngine_Icon_Emissive);

            foreach (Transform3D transform in GetRotations_Tetrahedron(sphereRadius))
            {
                GeometryModel3D geometry = new GeometryModel3D();
                geometry.Material     = material;
                geometry.BackMaterial = material;
                geometry.Geometry     = UtilityWPF.GetMeshFromTriangles(indexedTriangles);
                geometry.Transform    = transform;

                retVal.Add(geometry);
            }

            return(retVal.ToArray());
        }
Пример #2
0
        private void BuildTerrain()
        {
            // Figure out where the extra ring of points should go
            double radius = BuildTerrainSprtRadius(_neurons.Select(o => o.Position.ToPoint2D()).ToArray());

            // Figure out how many extra points to make
            int numExtra = BuildTerrainSprtNumExtra(_neurons.Length);

            // Lay down all the points into a single array
            _terrainPoints = UtilityCore.Iterate(
                _neurons.Select(o => o.Position),                                                         // first points are the neuron's locations (don't worry about Z right now, they will change each update)
                Math2D.GetCircle_Cached(numExtra).Select(o => new Point3D(o.X * radius, o.Y * radius, 0)) // tack on a bunch of points around the edge
                ).ToArray();

            // Get the delaunay of these points
            TriangleIndexed[] triangles = Math2D.GetDelaunayTriangulation(_terrainPoints.Select(o => o.ToPoint2D()).ToArray(), _terrainPoints);

            // Convert into linked triangles
            List <TriangleIndexedLinked> trianglesLinked = triangles.Select(o => new TriangleIndexedLinked(o.Index0, o.Index1, o.Index2, o.AllPoints)).ToList();

            TriangleIndexedLinked.LinkTriangles_Edges(trianglesLinked, true);

            _terrainTriangles = trianglesLinked.ToArray();
        }
Пример #3
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);
        }