private static GeometryModel3D GetModel_WoodIron_Ring_Band(double ballRadius, double z, System.Windows.Media.Media3D.Material material, TriangleIndexed[] ball, SortedList <string, double> from, SortedList <string, double> to, string prefix) { const double ENLARGE = 1.04d; GeometryModel3D retVal = new GeometryModel3D(); retVal.Material = material; retVal.BackMaterial = material; double bandHeight = WeaponDNA.GetKeyValue(prefix + "Height", from, to, StaticRandom.NextPercent(ballRadius * .15, .5)); double bandHeightHalf = bandHeight / 2d; // Slice the hull at the top and bottom band z's Point3D[] slice1 = Math3D.GetIntersection_Hull_Plane(ball, new Triangle(new Point3D(0, 0, z - bandHeightHalf), new Point3D(1, 0, z - bandHeightHalf), new Point3D(0, 1, z - bandHeightHalf))); Point3D[] slice2 = Math3D.GetIntersection_Hull_Plane(ball, new Triangle(new Point3D(0, 0, z + bandHeightHalf), new Point3D(1, 0, z + bandHeightHalf), new Point3D(0, 1, z + bandHeightHalf))); // Enlarge those polygons xy, leave z alone slice1 = slice1.Select(o => new Point3D(o.X * ENLARGE, o.Y * ENLARGE, o.Z)).ToArray(); slice2 = slice2.Select(o => new Point3D(o.X * ENLARGE, o.Y * ENLARGE, o.Z)).ToArray(); // Now turn those two polygons into a 3d hull TriangleIndexed[] band = Math3D.GetConvexHull(UtilityCore.Iterate(slice1, slice2).ToArray()); retVal.Geometry = UtilityWPF.GetMeshFromTriangles(band); return(retVal); }
//TODO: random chance of randomly placing metal fittings on the handle private static void GetModel_Rod_Wood(Model3DGroup geometries, WeaponHandleDNA dna, WeaponHandleDNA finalDNA, WeaponMaterialCache materials) { const double PERCENT = 1; Random rand = StaticRandom.GetRandomForThread(); var from = dna.KeyValues; var to = finalDNA.KeyValues; GeometryModel3D geometry = new GeometryModel3D(); #region material switch (dna.HandleMaterial) { case WeaponHandleMaterial.Soft_Wood: geometry.Material = materials.Handle_SoftWood; break; case WeaponHandleMaterial.Hard_Wood: geometry.Material = materials.Handle_HardWood; break; default: throw new ApplicationException("Unexpected WeaponHandleMaterial: " + dna.HandleMaterial.ToString()); } geometry.BackMaterial = geometry.Material; #endregion #region tube double maxX1 = WeaponDNA.GetKeyValue("maxX1", from, to, rand.NextDouble(.45, .7)); double maxX2 = WeaponDNA.GetKeyValue("maxX2", from, to, rand.NextDouble(.45, .7)); double maxY1 = WeaponDNA.GetKeyValue("maxY1", from, to, rand.NextDouble(.85, 1.05)); double maxY2 = WeaponDNA.GetKeyValue("maxY2", from, to, rand.NextDouble(.85, 1.05)); List <TubeRingBase> rings = new List <TubeRingBase>(); rings.Add(new TubeRingRegularPolygon(0, false, maxX1 * .45, maxY1 * .75, true)); rings.Add(new TubeRingRegularPolygon(WeaponDNA.GetKeyValue("ring1", from, to, rand.NextPercent(.5, PERCENT)), false, maxX1 * .5, maxY1 * 1, false)); rings.Add(new TubeRingRegularPolygon(WeaponDNA.GetKeyValue("ring2", from, to, rand.NextPercent(2, PERCENT)), false, maxX1 * .4, maxY1 * .8, false)); rings.Add(new TubeRingRegularPolygon(WeaponDNA.GetKeyValue("ring3", from, to, rand.NextPercent(5, PERCENT)), false, Math1D.Avg(maxX1, maxX2) * .35, Math1D.Avg(maxY1, maxY2) * .75, false)); rings.Add(new TubeRingRegularPolygon(WeaponDNA.GetKeyValue("ring4", from, to, rand.NextPercent(5, PERCENT)), false, maxX2 * .4, maxY2 * .8, false)); rings.Add(new TubeRingRegularPolygon(WeaponDNA.GetKeyValue("ring5", from, to, rand.NextPercent(2, PERCENT)), false, maxX2 * .5, maxY2 * 1, false)); rings.Add(new TubeRingRegularPolygon(WeaponDNA.GetKeyValue("ring6", from, to, rand.NextPercent(.5, PERCENT)), false, maxX2 * .45, maxY2 * .75, true)); rings = TubeRingBase.FitNewSize(rings, dna.Radius * Math.Max(maxX1, maxX2), dna.Radius * Math.Max(maxY1, maxY2), dna.Length); // multiplying x by maxX, because the rings were defined with x maxing at maxX, and y maxing at 1 geometry.Geometry = UtilityWPF.GetMultiRingedTube(10, rings, true, true, new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 90))); // the tube builds along z, but this class wants along x #endregion geometries.Children.Add(geometry); }
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); }
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_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); }
private static void GetModel_Rod_Moon(Model3DGroup geometries, WeaponHandleDNA dna, WeaponHandleDNA finalDNA, WeaponMaterialCache materials) { const double PERCENT = 1; Random rand = StaticRandom.GetRandomForThread(); var from = dna.KeyValues; var to = finalDNA.KeyValues; #region shaft GeometryModel3D shaft = new GeometryModel3D(); shaft.Material = materials.Handle_Moon; shaft.BackMaterial = shaft.Material; double maxRad1 = WeaponDNA.GetKeyValue("maxRad1", from, to, rand.NextDouble(.7, 1.02)); double maxRad2 = WeaponDNA.GetKeyValue("maxRad2", from, to, rand.NextDouble(.7, 1.02)); double maxRad12 = Math.Max(maxRad1, maxRad2); // this is used in several places List <TubeRingBase> rings = new List <TubeRingBase>(); rings.Add(new TubeRingRegularPolygon(0, false, maxRad1 * .4, maxRad1 * .4, true)); rings.Add(new TubeRingRegularPolygon(WeaponDNA.GetKeyValue("tube1", from, to, rand.NextPercent(.25, PERCENT)), false, maxRad1 * .8, maxRad1 * .8, false)); rings.Add(new TubeRingRegularPolygon(WeaponDNA.GetKeyValue("tube2", from, to, rand.NextPercent(.3, PERCENT)), false, maxRad1 * .85, maxRad1 * .85, false)); rings.Add(new TubeRingRegularPolygon(WeaponDNA.GetKeyValue("tube3", from, to, rand.NextPercent(.75, PERCENT)), false, maxRad1 * .6, maxRad1 * .6, false)); rings.Add(new TubeRingRegularPolygon(WeaponDNA.GetKeyValue("tube4", from, to, rand.NextPercent(20, PERCENT)), false, maxRad2 * .8, maxRad2 * .8, false)); rings.Add(new TubeRingRegularPolygon(WeaponDNA.GetKeyValue("tube5", from, to, rand.NextPercent(1, PERCENT)), false, maxRad2 * .9, maxRad2 * .9, false)); rings.Add(new TubeRingRegularPolygon(WeaponDNA.GetKeyValue("tube6", from, to, rand.NextPercent(1, PERCENT)), false, maxRad2 * 1, maxRad2 * 1, false)); rings.Add(new TubeRingDome(WeaponDNA.GetKeyValue("tube7", from, to, rand.NextPercent(2.5, PERCENT)), false, 4)); rings = TubeRingBase.FitNewSize(rings, maxRad12 * dna.Radius, maxRad12 * dna.Radius, dna.Length); shaft.Geometry = UtilityWPF.GetMultiRingedTube(10, rings, true, true, new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), -90))); // the tube builds along z, but this class wants along x #endregion // Number of gems int numIfNew = 0; if (rand.NextDouble() > .66d) // only 33% will get gems { // Of the handles with gems, only 5% will get 2 numIfNew = rand.NextDouble() > .95 ? 2 : 1; } int numGems = Convert.ToInt32(WeaponDNA.GetKeyValue("numGems", from, to, numIfNew)); if (numGems == 0) { geometries.Children.Add(shaft); return; } #region gems List <double> percents = new List <double>(); for (int cntr = 0; cntr < numGems; cntr++) { string keyPrefix = "gem" + cntr.ToString(); // Get a placement for this gem double percentIfNew = 0; do { percentIfNew = rand.NextDouble(.15, .85); if (percents.Count == 0) { break; } } while (percents.Any(o => Math.Abs(percentIfNew - o) < .15)); double percent = WeaponDNA.GetKeyValue(keyPrefix + "Percent", from, to, percentIfNew); percents.Add(percent); // Gem GeometryModel3D gem = new GeometryModel3D(); gem.Material = materials.Handle_MoonGem; gem.BackMaterial = gem.Material; double width = WeaponDNA.GetKeyValue(keyPrefix + "Width", from, to, rand.NextDouble(maxRad12 * 1d, maxRad12 * 1.4d)); gem.Geometry = UtilityWPF.GetSphere_LatLon(5, dna.Radius * width); Point3D position = new Point3D((dna.Length * percent) - (dna.Length / 2d), 0, 0); gem.Transform = new TranslateTransform3D(position.ToVector()); // Light PointLight pointLight = new PointLight(materials.Handle_MoonGemLight, position); UtilityWPF.SetAttenuation(pointLight, dna.Radius * 120d, .1d); geometries.Children.Add(pointLight); geometries.Children.Add(gem); } // Adding this after so that you don't see the shaft through the gems geometries.Children.Add(shaft); #endregion }
private static void GetModel_Rod_Composite(Model3DGroup geometries, WeaponHandleDNA dna, WeaponHandleDNA finalDNA, WeaponMaterialCache materials) { Random rand = StaticRandom.GetRandomForThread(); finalDNA.MaterialsForCustomizable = WeaponHandleDNA.GetRandomMaterials_Composite(dna.MaterialsForCustomizable); var from = dna.KeyValues; var to = finalDNA.KeyValues; double halfLength = dna.Length / 2d; double halfBeamThickness = dna.Radius / 8d; double halfCoreThickness = (dna.Radius * .66d) / 2d; double washerRadius = dna.Radius * 1.1; double washerThickness1 = WeaponDNA.GetKeyValue("washerThickness1", from, to, dna.Length * rand.NextPercent(.015d, .5d)); double washerThickness2 = WeaponDNA.GetKeyValue("washerThickness2", from, to, dna.Length * rand.NextPercent(.15d, .5d)); double washerOffset = WeaponDNA.GetKeyValue("washerOffset", from, to, rand.NextPercent(.05d, .5d)); var material = GetModel_Rod_Composite_Material(finalDNA.MaterialsForCustomizable[0]); //NOTE: The beam/core dimensions shouldn't be randomized. This should look like a manufactured, almost mass produced product #region beams // Beam1 GeometryModel3D geometry = new GeometryModel3D(); geometry.Material = material; geometry.BackMaterial = material; geometry.Geometry = UtilityWPF.GetCube_IndependentFaces(new Point3D(-halfLength, -dna.Radius, -halfBeamThickness), new Point3D(halfLength, dna.Radius, halfBeamThickness)); geometries.Children.Add(geometry); // Beam2 geometry = new GeometryModel3D(); geometry.Material = material; geometry.BackMaterial = material; geometry.Geometry = UtilityWPF.GetCube_IndependentFaces(new Point3D(-halfLength, -halfBeamThickness, -dna.Radius), new Point3D(halfLength, halfBeamThickness, dna.Radius)); geometries.Children.Add(geometry); #endregion #region core material = GetModel_Rod_Composite_Material(finalDNA.MaterialsForCustomizable[1]); geometry = new GeometryModel3D(); geometry.Material = material; geometry.BackMaterial = material; geometry.Geometry = UtilityWPF.GetCube_IndependentFaces(new Point3D(-halfLength, -halfCoreThickness, -halfCoreThickness), new Point3D(halfLength, halfCoreThickness, halfCoreThickness)); geometry.Transform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(1, 0, 0), 45)); geometries.Children.Add(geometry); #endregion #region washers material = GetModel_Rod_Composite_Material(finalDNA.MaterialsForCustomizable[2]); var locations = new Tuple <double, double>[] { Tuple.Create(0d, washerThickness1), Tuple.Create(washerOffset, washerThickness1), Tuple.Create(.5d, washerThickness2), Tuple.Create(1d - washerOffset, washerThickness1), Tuple.Create(1d, washerThickness1) }; foreach (var loc in locations) { geometry = new GeometryModel3D(); geometry.Material = material; geometry.BackMaterial = material; geometry.Geometry = UtilityWPF.GetCylinder_AlongX(8, washerRadius, loc.Item2); geometry.Transform = new TranslateTransform3D(-halfLength + (dna.Length * loc.Item1), 0, 0); geometries.Children.Add(geometry); } #endregion }
private static void GetModel_Rod_Metal(Model3DGroup geometries, WeaponHandleDNA dna, WeaponHandleDNA finalDNA, WeaponMaterialCache materials) { Random rand = StaticRandom.GetRandomForThread(); var from = dna.KeyValues; var to = finalDNA.KeyValues; #region materials System.Windows.Media.Media3D.Material material1, material2; switch (dna.HandleMaterial) { case WeaponHandleMaterial.Bronze: material1 = materials.Handle_Bronze; // the property get returns a slightly random color material2 = materials.Handle_Bronze; break; case WeaponHandleMaterial.Iron: material1 = materials.Handle_Iron; material2 = materials.Handle_Iron; break; case WeaponHandleMaterial.Steel: material1 = materials.Handle_Steel; material2 = materials.Handle_Steel; break; default: throw new ApplicationException("Unexpected WeaponHandleMaterial: " + dna.HandleMaterial.ToString()); } #endregion #region ends double capRadius = dna.Radius * 1.1; List <TubeRingBase> rings = new List <TubeRingBase>(); rings.Add(new TubeRingRegularPolygon(0, false, capRadius * .75, capRadius * .75, true)); rings.Add(new TubeRingRegularPolygon(capRadius * .2, false, capRadius, capRadius, false)); rings.Add(new TubeRingRegularPolygon(WeaponDNA.GetKeyValue("capWidth", from, to, capRadius * (1d + rand.NextPow(7d, 2.2d))), false, capRadius, capRadius, false)); rings.Add(new TubeRingRegularPolygon(capRadius * .8, false, capRadius * .75, capRadius * .75, true)); double capHeight = TubeRingBase.GetTotalHeight(rings); double halfLength = dna.Length / 2d; double halfCap = capHeight / 2d; // Cap 1 GeometryModel3D geometry = new GeometryModel3D(); geometry.Material = material1; geometry.BackMaterial = material1; Transform3DGroup transform = new Transform3DGroup(); transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 90))); // the tube builds along z, but this class wants along x transform.Children.Add(new TranslateTransform3D(-halfLength + halfCap, 0, 0)); geometry.Geometry = UtilityWPF.GetMultiRingedTube(6, rings, false, true, transform); geometries.Children.Add(geometry); // Cap 2 geometry = new GeometryModel3D(); geometry.Material = material1; geometry.BackMaterial = material1; transform = new Transform3DGroup(); transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), -90))); // the tube builds along z, but this class wants along x transform.Children.Add(new TranslateTransform3D(halfLength - halfCap, 0, 0)); geometry.Geometry = UtilityWPF.GetMultiRingedTube(6, rings, false, true, transform); geometries.Children.Add(geometry); #endregion #region shaft geometry = new GeometryModel3D(); geometry.Material = material2; geometry.BackMaterial = material2; rings = new List <TubeRingBase>(); rings.Add(new TubeRingRegularPolygon(0, false, dna.Radius * .8, dna.Radius * .8, true)); rings.Add(new TubeRingRegularPolygon(dna.Length - capHeight, false, dna.Radius * .8, dna.Radius * .8, true)); transform = new Transform3DGroup(); transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 90))); // the tube builds along z, but this class wants along x transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(1, 0, 0), 45))); // make the bar impact along the edge instead of the flat part geometry.Geometry = UtilityWPF.GetMultiRingedTube(4, rings, false, true, transform); geometries.Children.Add(geometry); #endregion }
private static AxeSecondProps GetModel_Second_Props(SortedList <string, double> from, SortedList <string, double> to, bool hasBeard) { AxeSecondProps retVal = new AxeSecondProps(); Random rand = StaticRandom.GetRandomForThread(); #region Points // Edge retVal.EndTR = new Point3D(2, -1.1, 0) + WeaponDNA.GetKeyValue_Vector("EndTR", from, to, Math3D.GetRandomVector_Circular(.25)); retVal.EndBR = new Point3D(1.3, 1.8, 0) + WeaponDNA.GetKeyValue_Vector("EndBR", from, to, Math3D.GetRandomVector_Circular(.25)); // Left retVal.EndTL = new Point3D(-1.5, -1, 0); retVal.EndBL_1 = new Point3D(-1.5, .5, 0); if (hasBeard) { // Put an extra point along the bottom (left of this is that circle cutout) retVal.EndBL_2 = retVal.EndBL_1; // 2 is now the last point retVal.EndBL_1 = new Point3D(.3, 1.2, 0) + WeaponDNA.GetKeyValue_Vector("EndBL_1", from, to, Math3D.GetRandomVector_Circular(.25)); } else { retVal.EndBL_2 = null; } if (retVal.EndBL_2 != null && WeaponDNA.GetKeyValue_Bool("shouldExtendBeard", from, to, rand.NextBool())) { // Extend the beard retVal.EndBR += new Vector3D(0, WeaponDNA.GetKeyValue("extendBR", from, to, rand.NextDouble(.25, 2.2)), 0); retVal.EndBL_1 += new Vector3D(0, WeaponDNA.GetKeyValue("extendBL", from, to, rand.NextDouble(.25, 1.8)), 0); } double maxY = retVal.EndBR.Y - .25; if (retVal.EndBL_2 != null && retVal.EndBL_1.Y > maxY) { retVal.EndBL_1 = new Point3D(retVal.EndBL_1.X, maxY, retVal.EndBL_1.Z); // can't let the middle point get lower, because the 3D would look wrong) } #endregion #region Curve Controls retVal.EdgeAngleT = WeaponDNA.GetKeyValue("EdgeAngleT", from, to, rand.NextPercent(15, .25)); retVal.EdgePercentT = WeaponDNA.GetKeyValue("EdgePercentT", from, to, rand.NextPercent(.3, .25)); retVal.EdgeAngleB = WeaponDNA.GetKeyValue("EdgeAngleB", from, to, rand.NextPercent(15, .25)); retVal.EdgePercentB = WeaponDNA.GetKeyValue("EdgePercentB", from, to, rand.NextPercent(.3, .25)); // Only used if EndBL_2 is null retVal.B1AngleR = WeaponDNA.GetKeyValue("B1AngleR", from, to, rand.NextPercent(10, .25)); retVal.B1PercentR = WeaponDNA.GetKeyValue("B1PercentR", from, to, rand.NextPercent(.5, .25)); retVal.B1AngleL = WeaponDNA.GetKeyValue("B1AngleL", from, to, rand.NextPercent(10, .25)); retVal.B1PercentL = WeaponDNA.GetKeyValue("B1PercentL", from, to, rand.NextPercent(.33, .25)); // Only used if EndBL_2 is populated retVal.B2AngleR = WeaponDNA.GetKeyValue("B2AngleR", from, to, rand.NextDouble(40, 80)); retVal.B2PercentR = WeaponDNA.GetKeyValue("B2PercentR", from, to, rand.NextPercent(.6, .25)); retVal.B2AngleL = WeaponDNA.GetKeyValue("B2AngleL", from, to, rand.NextDouble(40, 80)); retVal.B2PercentL = WeaponDNA.GetKeyValue("B2PercentL", from, to, rand.NextPercent(.4, .25)); #endregion return(retVal); }
// Second design private static Model3DGroup GetModel_Second(WeaponAxeDNA dna, WeaponAxeDNA finalDNA, WeaponMaterialCache materials, bool hasBeard) { Model3DGroup retVal = new Model3DGroup(); var from = dna.KeyValues; var to = finalDNA.KeyValues; // Define the curves AxeSecondProps arg = GetModel_Second_Props(from, to, hasBeard); BezierSegment3D[][] segmentSets = GetModel_Second_Curves(arg); //TODO: Use WeaponMaterialCache MaterialGroup materialMiddle = new MaterialGroup(); materialMiddle.Children.Add(new DiffuseMaterial(new SolidColorBrush(Colors.DimGray))); Color derivedColor = UtilityWPF.AlphaBlend(Colors.DimGray, Colors.White, .8d); materialMiddle.Children.Add(new SpecularMaterial(new SolidColorBrush(Color.FromArgb(128, derivedColor.R, derivedColor.G, derivedColor.B)), 2d)); MaterialGroup materialEdge = new MaterialGroup(); materialEdge.Children.Add(new DiffuseMaterial(new SolidColorBrush(Colors.GhostWhite))); materialEdge.Children.Add(new SpecularMaterial(new SolidColorBrush(UtilityWPF.AlphaBlend(Colors.GhostWhite, Colors.White, .5d)), 5d)); #region Axe Blade (right) Model3D model = GetModel_Second_Axe(segmentSets, materialMiddle, materialEdge); double scale = dna.SizeSingle / (((arg.EndBL_2 ?? arg.EndBL_1).Y - arg.EndTL.Y) * 2); Transform3DGroup transform = new Transform3DGroup(); transform.Children.Add(new TranslateTransform3D(-arg.EndTL.X, 0, 0)); transform.Children.Add(new ScaleTransform3D(scale, scale, scale)); model.Transform = transform; retVal.Children.Add(model); #endregion if (dna.Sides == WeaponAxeSides.Double) { #region Axe Blade (left) model = GetModel_Second_Axe(segmentSets, materialMiddle, materialEdge); transform = new Transform3DGroup(); transform.Children.Add(new TranslateTransform3D(-arg.EndTL.X, 0, 0)); transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 180))); transform.Children.Add(new ScaleTransform3D(scale, scale, scale)); model.Transform = transform; retVal.Children.Add(model); #endregion } Point3D topLeft = segmentSets[2][0].EndPoint0; Point3D bottomLeft = segmentSets[2][segmentSets[2].Length - 1].EndPoint1; double z = Math.Abs(segmentSets[0][0].EndPoint0.Z); if (dna.Sides == WeaponAxeSides.Single_BackSpike) { // Spike retVal.Children.Add(GetAxeSpike(z * .9, Math.Abs(topLeft.Y - bottomLeft.Y) * WeaponDNA.GetKeyValue("spikeLength", from, to, StaticRandom.NextDouble(.9, 1.4)), scale, -.2, materialMiddle, materialEdge)); } if (dna.Sides != WeaponAxeSides.Double) // double centerfilled is the only case that shouldn't have a collar { // Collar retVal.Children.Add(GetAxeCylinder(z * 1.33, Math.Abs(topLeft.Y - bottomLeft.Y) * 1.15, scale, -.2, materialMiddle)); } return(retVal); }
private static AxeSymetricalProps GetModel_Symetrical_Props(SortedList <string, double> from, SortedList <string, double> to) { AxeSymetricalProps retVal = new AxeSymetricalProps(); Random rand = StaticRandom.GetRandomForThread(); // Center Filled retVal.isCenterFilled = WeaponDNA.GetKeyValue_Bool("isCenterFilled", from, to, rand.NextBool()); // Edge retVal.edgeAngle = WeaponDNA.GetKeyValue("edgeAngle", from, to, rand.NextPercent(45, 1)); retVal.edgePercent = WeaponDNA.GetKeyValue("edgePercent", from, to, rand.NextPercent(.33, .75)); // Left retVal.leftAway = WeaponDNA.GetKeyValue_Bool("leftAway", from, to, rand.NextBool()); if (retVal.leftAway) { retVal.leftAngle = WeaponDNA.GetKeyValue("leftAngle", from, to, rand.NextDouble(0, 15)); retVal.leftPercent = WeaponDNA.GetKeyValue("leftPercent", from, to, rand.NextPercent(.25, .5)); } else { retVal.leftAngle = WeaponDNA.GetKeyValue("leftAngle", from, to, rand.NextPercent(20, .5)); retVal.leftPercent = WeaponDNA.GetKeyValue("leftPercent", from, to, rand.NextPercent(.25, .75)); } // Right retVal.rightAway = retVal.leftAway ? true : WeaponDNA.GetKeyValue_Bool("rightAway", from, to, rand.NextBool()); // it looks like a vase when left is away, and right is toward if (retVal.rightAway) { retVal.rightAngle = WeaponDNA.GetKeyValue("rightAngle", from, to, rand.NextDouble(0, 15)); retVal.rightPercent = WeaponDNA.GetKeyValue("rightPercent", from, to, rand.NextPercent(.25, .5)); } else { retVal.rightAngle = WeaponDNA.GetKeyValue("rightAngle", from, to, rand.NextPercent(20, .75)); retVal.rightPercent = WeaponDNA.GetKeyValue("rightPercent", from, to, rand.NextPercent(.25, .75)); } // Points retVal.leftX = -WeaponDNA.GetKeyValue("leftX", from, to, rand.NextDouble(1, 3)); if (retVal.leftAway) { retVal.leftY = WeaponDNA.GetKeyValue("leftY", from, to, rand.NextDouble(2, 2.5)); } else { retVal.leftY = WeaponDNA.GetKeyValue("leftY", from, to, rand.NextDouble(1.25, 2.5)); } retVal.rightX = 2; retVal.rightY = 3.4; // Z retVal.Scale1X = WeaponDNA.GetKeyValue("Scale1X", from, to, rand.NextDouble(.6, .8)); retVal.Scale1Y = WeaponDNA.GetKeyValue("Scale1Y", from, to, rand.NextDouble(.8, .95)); retVal.Z1 = WeaponDNA.GetKeyValue("Z1", from, to, rand.NextPercent(.2, .5)); retVal.Scale2X = WeaponDNA.GetKeyValue("Scale2X", from, to, rand.NextPercent(.4, .25)); retVal.Scale2Y = WeaponDNA.GetKeyValue("Scale2Y", from, to, rand.NextPercent(.4, .25)); retVal.Z2L = WeaponDNA.GetKeyValue("Z2L", from, to, rand.NextPercent(.55, .25)); retVal.Z2R = WeaponDNA.GetKeyValue("Z2R", from, to, rand.NextPercent(.33, .25)); return(retVal); }