private static TriangleIndexed[] GetModel_Composite_IndentedTriangles(Rhombicuboctahedron ball, double depth) { List <Point3D> points = new List <Point3D>(); List <Tuple <int, int, int> > triangles = new List <Tuple <int, int, int> >(); int index = 0; foreach (TriangleIndexed triangle in ball.Triangles) { Vector3D offset = triangle.NormalUnit * -depth; points.Add(triangle.Point0 + offset); points.Add(triangle.Point1 + offset); points.Add(triangle.Point2 + offset); //TODO: May need to wind these the other direction at times triangles.Add(Tuple.Create(index + 0, index + 1, index + 2)); index += 3; } Point3D[] allPoints = points.ToArray(); return(triangles.Select(o => new TriangleIndexed(o.Item1, o.Item2, o.Item3, allPoints)).ToArray()); }
private static TriangleIndexed[] GetModel_Composite_SquareSides(Rhombicuboctahedron ball, double depth) { List <TriangleIndexed> retVal = new List <TriangleIndexed>(); foreach (int[] square in UtilityCore.Iterate(ball.SquarePolys_Orth, ball.SquarePolys_Diag)) { Point3D[] initialPoints = square.Select(o => ball.AllPoints[o]).ToArray(); Vector3D offset = Math2D.GetPolygonNormal(initialPoints, PolygonNormalLength.Unit) * -depth; for (int cntr = 0; cntr < square.Length - 1; cntr++) { retVal.AddRange(GetModel_Composite_SquareSides_Side(initialPoints[cntr], initialPoints[cntr + 1], offset, depth)); } retVal.AddRange(GetModel_Composite_SquareSides_Side(initialPoints[square.Length - 1], initialPoints[0], offset, depth)); } return(retVal.ToArray()); }
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); }