private Tuple <Point3D, Vector3D> GetPositionVelocity(double mass) { //mass of ice = .46 //mass of platinum = 10.7 //small asteroid = 80-226 //large asteroid = 550-916 // Percent (more massive toward the center) double percent = UtilityCore.GetScaledValue_Capped(.05, .85, 0, 1000, mass); percent = 1d - percent; //GetScaledValue can't handle inverted ranges, so invert outside of it percent = percent * percent * percent; // it works better with nonlinear // Position Vector3D posXY = Math3D.GetRandomVector_Circular(_boundryMax.X * (percent - .03), _boundryMax.X * (percent + .03)); double z = Math1D.GetNearZeroValue(_boundryMax.Z) * .15; Point3D position = new Point3D(posXY.X, posXY.Y, z); // Velocity double speed = UtilityCore.GetScaledValue_Capped(_boundryMax.X * .001, _boundryMax.X * .05, 0, 1, percent); Vector3D velocity = posXY.ToUnit().GetRotatedVector(new Vector3D(0, 0, 1), -90) * speed; return(Tuple.Create(position, velocity)); }
private void RandomCamera_Click(object sender, RoutedEventArgs e) { try { // Position Vector3D position = Math3D.GetRandomVector_Spherical(CAMERADISTANCE / 2, CAMERADISTANCE * 2); // Look Direction Vector3D lookDirection = position * -1; Vector3D rotateAxis = Math3D.GetRandomVector_Cone(Math3D.GetArbitraryOrhonganal(lookDirection), 0, 20, 1, 1); Quaternion rotate = new Quaternion(rotateAxis, Math1D.GetNearZeroValue(20)); lookDirection = rotate.GetRotatedVector(lookDirection); // Up Vector Vector3D up = Math3D.GetArbitraryOrhonganal(lookDirection); // Commit _camera.Position = position.ToPoint(); _camera.LookDirection = lookDirection; _camera.UpDirection = up; } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void CreateSpaceStationsSprtBuild(Point3D position) { SpaceStation spaceStation = new SpaceStation(); spaceStation.SpinDegreesPerSecond = Math1D.GetNearZeroValue(10d); spaceStation.HullColor = UtilityWPF.AlphaBlend(UtilityWPF.GetRandomColor(108, 148), Colors.Gray, .25); spaceStation.CreateStation(_map, position); _spaceStations.Add(spaceStation); }
private void CreateSpaceStations() { double xyCoord = _boundryMax.X * .7; double zCoord = _boundryMin.Z - 3; double minDistanceBetweenStations = 200d; #region Home Station // Make one right next to the player at startup (always a distance of 10*sqrt(2), but at a random angle, just so it's not boring) Vector3D homeLocation = new Vector3D(14.142, 0, 0); homeLocation = homeLocation.GetRotatedVector(new Vector3D(0, 0, 1), Math1D.GetNearZeroValue(360d)); CreateSpaceStationsSprtBuild(new Point3D(homeLocation.X, homeLocation.Y, zCoord)); #endregion // Make a few more for (int cntr = 0; cntr < 4; cntr++) { // Come up with a position that isn't too close to any other station Vector3D position = new Vector3D(); while (true) { #region Figure out position position = Math3D.GetRandomVector_Circular(xyCoord); position.Z = zCoord; // See if this is too close to an existing station bool isTooClose = false; foreach (SpaceStation station in _spaceStations) { Vector3D offset = position - station.PositionWorld.ToVector(); if (offset.Length < minDistanceBetweenStations) { isTooClose = true; break; } } if (!isTooClose) { break; } #endregion } CreateSpaceStationsSprtBuild(position.ToPoint()); } }
private void CreateSpaceStationsSprtBuild(Point3D position, List <SpaceStation> allStations) { SpaceStation spaceStation = new SpaceStation(position, _world, _material_SpaceStation, Math3D.GetRandomRotation()); spaceStation.SpinDegreesPerSecond = Math1D.GetNearZeroValue(.33, 1.1); //double angularSpeed = Math3D.GetNearZeroValue(.33d, .66d); //spaceStation.PhysicsBody.AngularVelocity = spaceStation.PhysicsBody.DirectionToWorld(new Vector3D(0, 0, angularSpeed)); //spaceStation.PhysicsBody.ApplyForceAndTorque += new EventHandler<BodyApplyForceAndTorqueArgs>(Body_ApplyForceAndTorque); _map.AddItem(spaceStation); allStations.Add(spaceStation); }
private static Tuple <int, int, double>[] BuildLinksRandomSprtLinks(int fromCount, int toCount, int count, bool isSameList) { SortedList <Tuple <int, int>, double> retVal = new SortedList <Tuple <int, int>, double>(); Random rand = StaticRandom.GetRandomForThread(); int fromIndex, toIndex; double weight; // Come up with links for (int cntr = 0; cntr < count; cntr++) { fromIndex = rand.Next(fromCount); if (isSameList) { toIndex = rand.Next(toCount - 1); // a neuron can't point to itself, so pick from one less than the size of the list if (toIndex >= fromIndex) { toIndex++; } } else { toIndex = rand.Next(toCount); } weight = Math1D.GetNearZeroValue(MAXWEIGHT); Tuple <int, int> key = new Tuple <int, int>(fromIndex, toIndex); // Add to the return (don't allow dupes) if (retVal.ContainsKey(key)) { retVal[key] += weight; } else { retVal.Add(key, weight); } } // Exit Function return(retVal.Keys.Select(o => new Tuple <int, int, double>(o.Item1, o.Item2, retVal[o])).ToArray()); }
private void Update_SparklyCount() { if (!_isVisualAdded) { return; } int count = 0; if (_ramDirHistory == null || _ramDirHistory.Count == 0) { count = 0; } else { count = _ramDirHistory.Count / 4; } if (count == _sparklies.Count) { return; } else if (count < _sparklies.Count) { #region Too Many while (count < _sparklies.Count) { int index = StaticRandom.Next(_sparklies.Count); _modelGroup.Children.Remove(_sparklies[index].Item1); _sparklies.RemoveAt(index); } #endregion } else { #region Too Few while (_sparklies.Count < count) { Random rand = StaticRandom.GetRandomForThread(); GeometryModel3D geometry = new GeometryModel3D(); geometry.Material = _sparklyMaterial.Value; geometry.BackMaterial = _sparklyMaterial.Value; geometry.Geometry = UtilityWPF.GetSphere_LatLon(1, rand.NextPercent(.09, .33)); // this radius will be affected by scale Transform3DGroup transform = new Transform3DGroup(); // Translate Vector3D translate = Math3D.GetRandomVector_Circular(.5, 1).ToVector2D().ToVector3D(Math1D.GetNearZeroValue(.375)); transform.Children.Add(new TranslateTransform3D(translate)); // Rotate from Z to X transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 90))); // Animated rotate around X AxisAngleRotation3D axisAngle = new AxisAngleRotation3D(new Vector3D(1, 0, 0), 10); double angle = rand.NextDouble(180, 360); if (rand.Next(2) == 0) { angle *= -1; } AnimateRotation animate = AnimateRotation.Create_Constant(axisAngle, angle); transform.Children.Add(new RotateTransform3D(axisAngle)); // Scale transform.Children.Add(_scale); geometry.Transform = transform; _modelGroup.Children.Add(geometry); _sparklies.Add(Tuple.Create(geometry, animate)); } #endregion } }
public void CreateMineral(MaterialManager materialManager, Map map, SharedVisuals sharedVisuals, Vector3D position, bool randomOrientation, double volumeInCubicMeters) { _map = map; _sharedVisuals = sharedVisuals; if (_mineralType == MineralType.Custom) { #region Validate if (_numSides < 3) { throw new ApplicationException("The number of sides must at least be 3"); } if (_rings.Count == 0) { throw new ApplicationException("Need at least one ring"); } #endregion } else { // Overwrite my public properties based on the mineral type StoreSettingsForMineralType(volumeInCubicMeters); } RotateTransform3D randomRotation = null; if (randomOrientation) { randomRotation = new RotateTransform3D(new AxisAngleRotation3D(Math3D.GetRandomVector_Spherical(1d), Math1D.GetNearZeroValue(360d))); } if (_mineralType == MineralType.Rixium) { #region Rixium Visuals Model3DGroup ringModels = new Model3DGroup(); ringModels.Children.Add(GetRixiumTorusVisual(new Vector3D(0, 0, -.6), .38, .5, randomRotation)); ringModels.Children.Add(GetRixiumTorusVisual(new Vector3D(0, 0, -.3), .44, .75, randomRotation)); ringModels.Children.Add(GetRixiumTorusVisual(new Vector3D(0, 0, 0), .5, 1, randomRotation)); ringModels.Children.Add(GetRixiumTorusVisual(new Vector3D(0, 0, .3), .44, .75, randomRotation)); ringModels.Children.Add(GetRixiumTorusVisual(new Vector3D(0, 0, .6), .38, .5, randomRotation)); //TODO: Look at the global lighting options PointLight pointLight = new PointLight(); pointLight.Color = Color.FromArgb(255, 54, 147, 168); pointLight.Range = 20; pointLight.LinearAttenuation = .33; ringModels.Children.Add(pointLight); ModelVisual3D ringModel = new ModelVisual3D(); // this is the expensive one, so as few of these should be made as possible ringModel.Content = ringModels; _visuals.Add(ringModel); _map.Viewport.Children.Add(ringModel); #endregion } #region WPF Model // Material MaterialGroup materials = new MaterialGroup(); if (_diffuseColor.A > 0) { materials.Children.Add(new DiffuseMaterial(new SolidColorBrush(_diffuseColor))); } if (_specularColor.A > 0) { materials.Children.Add(new SpecularMaterial(new SolidColorBrush(_specularColor), _specularPower)); } if (_emissiveColor.A > 0) { materials.Children.Add(new EmissiveMaterial(new SolidColorBrush(_emissiveColor))); } // Geometry Model GeometryModel3D geometry = new GeometryModel3D(); geometry.Material = materials; geometry.BackMaterial = materials; if (_mineralType == MineralType.Custom) { geometry.Geometry = UtilityWPF.GetMultiRingedTube_ORIG(_numSides, _rings, false, true); } else { geometry.Geometry = _sharedVisuals.GetMineralMesh(_mineralType); } if (randomOrientation) { geometry.Transform = randomRotation; } // Model Visual ModelVisual3D model = new ModelVisual3D(); model.Content = geometry; model.Transform = new TranslateTransform3D(position); // Add to the viewport _visuals.Add(model); _map.Viewport.Children.Add(model); #endregion #region Physics Body // Make a physics body that represents this shape _physicsBody = new ConvexBody3D(_map.World, model); _physicsBody.MaterialGroupID = materialManager.MineralMaterialID; _physicsBody.NewtonBody.UserData = this; _physicsBody.Mass = Convert.ToSingle(_mass); _physicsBody.LinearDamping = .01f; _physicsBody.AngularDamping = new Vector3D(.01f, .01f, .01f); _physicsBody.Override2DEnforcement_Rotation = true; _physicsBody.ApplyForce += new BodyForceEventHandler(Body_ApplyForce); #endregion // Add to the map _map.AddItem(this); }
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 void button6_Click(object sender, RoutedEventArgs e) { for (int cntr = 1; cntr <= 1; cntr++) { // Material MaterialGroup materials = new MaterialGroup(); materials.Children.Add(new DiffuseMaterial(new SolidColorBrush(UtilityWPF.GetRandomColor(64, 192)))); materials.Children.Add(new SpecularMaterial(Brushes.White, 100d)); // Geometry Model GeometryModel3D geometry = new GeometryModel3D(); geometry.Material = materials; //geometry.Geometry = UtilityWPF.GetCube(.5d); //geometry.Geometry = UtilityWPF.GetRectangle3D() //geometry.Geometry = model.get // Transform Transform3DGroup transform = new Transform3DGroup(); // rotate needs to be added before translate transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(Math3D.GetRandomVector_Spherical(10), Math1D.GetNearZeroValue(360d)))); transform.Children.Add(new TranslateTransform3D(Math3D.GetRandomVector(_boundryMin, _boundryMax))); // Model Visual //ModelVisual3D model = new ModelVisual3D(); //model.Content = geometry; //model.Transform = transform; SphereVisual3D model = new SphereVisual3D(); //model.Content = geometry; model.Transform = transform; _viewport.Children.Add(model); } }
private void btnAdd_Click(object sender, RoutedEventArgs e) { const double MINRATIO = .25d; const double MAXRATIO = 2d; const double MINMASS = .9d; const double MAXMASS = 5d; try { double ratioX, ratioY, ratioZ; if (chkRandomRatios.IsChecked.Value) { ratioX = UtilityCore.GetScaledValue(MINRATIO, MAXRATIO, 0d, 1d, StaticRandom.NextDouble()); ratioY = UtilityCore.GetScaledValue(MINRATIO, MAXRATIO, 0d, 1d, StaticRandom.NextDouble()); ratioZ = UtilityCore.GetScaledValue(MINRATIO, MAXRATIO, 0d, 1d, StaticRandom.NextDouble()); } else { ratioX = UtilityCore.GetScaledValue(MINRATIO, MAXRATIO, trkX.Minimum, trkX.Maximum, trkX.Value); ratioY = UtilityCore.GetScaledValue(MINRATIO, MAXRATIO, trkY.Minimum, trkY.Maximum, trkY.Value); ratioZ = UtilityCore.GetScaledValue(MINRATIO, MAXRATIO, trkZ.Minimum, trkZ.Maximum, trkZ.Value); } #region WPF Model // Material MaterialGroup materials = new MaterialGroup(); materials.Children.Add(new DiffuseMaterial(new SolidColorBrush(UtilityWPF.GetRandomColor(64, 192)))); materials.Children.Add(new SpecularMaterial(Brushes.White, 100d)); // Geometry Model GeometryModel3D geometry = new GeometryModel3D(); geometry.Material = materials; geometry.BackMaterial = materials; geometry.Geometry = UtilityWPF.GetCube(new Point3D(-ratioX, -ratioY, -ratioZ), new Point3D(ratioX, ratioY, ratioZ)); //geometry.Geometry = UtilityWPF.GetRectangle3D() // Transform Transform3DGroup transform = new Transform3DGroup(); // rotate needs to be added before translate transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(Math3D.GetRandomVector_Spherical(10), Math1D.GetNearZeroValue(360d)))); transform.Children.Add(new TranslateTransform3D(Math3D.GetRandomVector(_boundryMin, _boundryMax))); // Model Visual ModelVisual3D model = new ModelVisual3D(); model.Content = geometry; model.Transform = transform; #endregion // Add to the viewport _viewport.Children.Add(model); // Make a physics body that represents this cube ConvexBody3D body = new ConvexBody3D(_world, model); if (chkConstantMass.IsChecked.Value) { body.Mass = 1f; } else { // If I try to be realistic, then it's boring, so I'll scale the result. (density shrinks a bit as things get larger) double mass = ratioX * ratioY * ratioZ; mass = UtilityCore.GetScaledValue(MINMASS, MAXMASS, Math.Pow(MINRATIO, 3), Math.Pow(MAXRATIO, 3), mass); body.Mass = Convert.ToSingle(mass); } body.LinearDamping = .01f; body.AngularDamping = new Vector3D(.01f, .01f, .01f); //TODO: Make this work //body.Velocity = //needed? //_world.AddBody(body); body.ApplyForce += new BodyForceEventHandler(Body_ApplyForce); _cubes.Add(body); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void addSimple1_AddBody(object sender, AddBodyArgs e) { try { #region WPF Model (plus collision hull) // Material MaterialGroup materials = new MaterialGroup(); materials.Children.Add(new DiffuseMaterial(new SolidColorBrush(UtilityWPF.GetRandomColor(64, 192)))); materials.Children.Add(new SpecularMaterial(Brushes.White, 100d)); // Geometry Model GeometryModel3D geometry = new GeometryModel3D(); geometry.Material = materials; geometry.BackMaterial = materials; CollisionHull hull = null; switch (e.CollisionShape) { case CollisionShapeType.Box: Vector3D halfSize = e.Size / 2d; geometry.Geometry = UtilityWPF.GetCube_IndependentFaces(new Point3D(-halfSize.X, -halfSize.Y, -halfSize.Z), new Point3D(halfSize.X, halfSize.Y, halfSize.Z)); hull = CollisionHull.CreateBox(_world, 0, e.Size, null); break; case CollisionShapeType.Sphere: geometry.Geometry = UtilityWPF.GetSphere_LatLon(5, e.Size.X, e.Size.Y, e.Size.Z); hull = CollisionHull.CreateSphere(_world, 0, e.Size, null); break; case CollisionShapeType.Cylinder: geometry.Geometry = UtilityWPF.GetCylinder_AlongX(20, e.Radius, e.Height); hull = CollisionHull.CreateCylinder(_world, 0, e.Radius, e.Height, null); break; case CollisionShapeType.Cone: geometry.Geometry = UtilityWPF.GetCone_AlongX(20, e.Radius, e.Height); hull = CollisionHull.CreateCone(_world, 0, e.Radius, e.Height, null); break; case CollisionShapeType.Capsule: case CollisionShapeType.ChamferCylinder: MessageBox.Show("finish this"); return; default: throw new ApplicationException("Unknown ConvexBody3D.CollisionShape: " + e.CollisionShape.ToString()); } // Transform Transform3DGroup transform = new Transform3DGroup(); // rotate needs to be added before translate transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(Math3D.GetRandomVector_Spherical(10), Math1D.GetNearZeroValue(360d)))); transform.Children.Add(new TranslateTransform3D(Math3D.GetRandomVector_Spherical(CREATEOBJECTBOUNDRY))); // Model Visual ModelVisual3D model = new ModelVisual3D(); model.Content = geometry; model.Transform = transform; // Add to the viewport _viewport.Children.Add(model); #endregion #region Physics Body // Make a physics body that represents this shape Body body = new Body(hull, transform.Value, e.Mass, new Visual3D[] { model }); hull.Dispose(); body.Velocity = Math3D.GetRandomVector_Circular(1d); //body.LinearDamping = .01f; //body.AngularDamping = new Vector3D(.01f, .01f, .01f); body.ApplyForceAndTorque += new EventHandler <BodyApplyForceAndTorqueArgs>(Body_ApplyForceAndTorque); Body[] bodySet = new Body[] { body }; _bodySets.Add(bodySet); #endregion BodiesAdded(bodySet); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void btnAdd_Click(object sender, RoutedEventArgs e) { try { // Figure out the ratios and mass of this body ConvexBody3D.CollisionShape shape; double ratioX, ratioY, ratioZ, mass; GetRatiosMass(out shape, out ratioX, out ratioY, out ratioZ, out mass); #region WPF Model // Material MaterialGroup materials = new MaterialGroup(); materials.Children.Add(new DiffuseMaterial(new SolidColorBrush(UtilityWPF.GetRandomColor(64, 192)))); materials.Children.Add(new SpecularMaterial(Brushes.White, 100d)); // Geometry Model GeometryModel3D geometry = new GeometryModel3D(); geometry.Material = materials; geometry.BackMaterial = materials; switch (shape) { case ConvexBody3D.CollisionShape.Cube: geometry.Geometry = UtilityWPF.GetCube(new Point3D(-ratioX, -ratioY, -ratioZ), new Point3D(ratioX, ratioY, ratioZ)); break; case ConvexBody3D.CollisionShape.Sphere: geometry.Geometry = UtilityWPF.GetSphere_LatLon(5, ratioX, ratioY, ratioZ); //geometry.Geometry = UtilityWPF.GetTorus(30, 10, ratioX * .2, ratioX); // break; case ConvexBody3D.CollisionShape.Capsule: case ConvexBody3D.CollisionShape.ChamferCylinder: case ConvexBody3D.CollisionShape.Cone: case ConvexBody3D.CollisionShape.Cylinder: default: throw new ApplicationException("Unknown ConvexBody3D.CollisionShape: " + shape.ToString()); } // Transform Transform3DGroup transform = new Transform3DGroup(); // rotate needs to be added before translate transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(Math3D.GetRandomVector_Spherical(10), Math1D.GetNearZeroValue(360d)))); transform.Children.Add(new TranslateTransform3D(Math3D.GetRandomVector(CREATEOBJECTBOUNDRY))); // Model Visual ModelVisual3D model = new ModelVisual3D(); model.Content = geometry; model.Transform = transform; #endregion // Add to the viewport _viewport.Children.Add(model); // Make a physics body that represents this shape ConvexBody3D body = new ConvexBody3D(_world, model); body.Mass = Convert.ToSingle(mass); body.LinearDamping = .01f; body.AngularDamping = new Vector3D(.01f, .01f, .01f); body.ApplyForce += new BodyForceEventHandler(Body_ApplyForce); _bodies.Add(body); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }