示例#1
0
        internal static UtilityNewt.IObjectMassBreakdown GetMassBreakdown(Vector3D scale, double cellSize)
        {
            // Convert this.Scale into a size that the mass breakdown will use
            Vector3D size = new Vector3D(scale.X, scale.Y, scale.Z);

            return(UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Sphere, UtilityNewt.MassDistribution.Uniform, size, cellSize));
        }
示例#2
0
        public override UtilityNewt.IObjectMassBreakdown GetMassBreakdown(double cellSize)
        {
            if (_massBreakdown != null && _massBreakdown.Scale == Scale && _massBreakdown.CellSize == cellSize)
            {
                // This has already been built for this size
                return(_massBreakdown.Breakdown);
            }

            // Convert this.Scale into a size that the mass breakdown will use (mass breakdown wants height along X, and scale is for radius, but the mass breakdown wants diameter
            // Reducing Z a bit, because the energy tank has a rounded cap
            Vector3D size = new Vector3D(this.Scale.Z * HEIGHTPERCENTOFSCALE, this.Scale.X * RADIUSPERCENTOFSCALE * 2d, this.Scale.Y * RADIUSPERCENTOFSCALE * 2d);

            // Cylinder
            UtilityNewt.ObjectMassBreakdown cylinder = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Cylinder, UtilityNewt.MassDistribution.Uniform, size, cellSize);

            Transform3D transform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 90));          // the physics hull is along x, but dna is along z

            // Rotated
            UtilityNewt.ObjectMassBreakdownSet combined = new UtilityNewt.ObjectMassBreakdownSet(
                new UtilityNewt.ObjectMassBreakdown[] { cylinder },
                new Transform3D[] { transform });

            // Store this
            _massBreakdown = new MassBreakdownCache(combined, Scale, cellSize);

            return(_massBreakdown.Breakdown);
        }
示例#3
0
        internal static UtilityNewt.IObjectMassBreakdown GetSensorMassBreakdown(ref MassBreakdownCache existing, Vector3D scale, double cellSize)
        {
            if (existing != null && existing.Scale == scale && existing.CellSize == cellSize)
            {
                // This has already been built for this size
                return(existing.Breakdown);
            }

            // Convert this.Scale into a size that the mass breakdown will use (mass breakdown wants height along X, and scale is for radius, but the mass breakdown wants diameter)
            Vector3D size = new Vector3D(scale.Z * SIZEPERCENTOFSCALE_Z, scale.X * SIZEPERCENTOFSCALE_XY * 2, scale.Y * SIZEPERCENTOFSCALE_XY * 2);

            var cylinder = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Cylinder, UtilityNewt.MassDistribution.Uniform, size, cellSize);

            Transform3D transform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 90));          // the physics hull is along x, but dna is along z

            // Rotated
            UtilityNewt.ObjectMassBreakdownSet combined = new UtilityNewt.ObjectMassBreakdownSet(
                new UtilityNewt.ObjectMassBreakdown[] { cylinder },
                new Transform3D[] { transform });

            // Store this
            existing = new MassBreakdownCache(combined, scale, cellSize);

            return(existing.Breakdown);
        }
示例#4
0
        public override UtilityNewt.IObjectMassBreakdown GetMassBreakdown(double cellSize)
        {
            if (_massBreakdown != null && _massBreakdown.Scale == Scale && _massBreakdown.CellSize == cellSize)
            {
                // This has already been built for this size
                return(_massBreakdown.Breakdown);
            }

            var breakdown = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Box, UtilityNewt.MassDistribution.Uniform, this.Scale, cellSize);

            // Store this
            _massBreakdown = new MassBreakdownCache(breakdown, Scale, cellSize);

            return(_massBreakdown.Breakdown);
        }
示例#5
0
        private static UtilityNewt.ObjectMassBreakdownSet GetMassBreakdown_Trapazoid(Point[] verticies, Vector3D size, double cellSize, bool isRight)
        {
            if (verticies.Length != 4)
            {
                throw new ApplicationException("There should be exactly 4 verticies passed in: " + verticies.Length.ToString());
            }

            double base1  = (verticies[2].X - verticies[3].X) * size.X;         // the verticies are built counter clockwise, starting at the lower left corner
            double base2  = (verticies[1].X - verticies[0].X) * size.X;
            double height = (verticies[2].Y - verticies[1].Y) * size.Y;

            List <Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double> > items = new List <Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double> >();

            if (isRight)
            {
                // Rectangle
                double rectBase  = base1;
                var    rectangle = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Box, UtilityNewt.MassDistribution.Uniform, new Vector3D(rectBase, height, size.Z), cellSize);
                items.Add(new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(rectangle, new Vector3D((base1 * .5d) - (base2 * .5d), 0d, 0d).ToPoint(), Quaternion.Identity, rectBase * height));

                // Triangle
                double triangleBase = base2 - base1;
                var    triangle     = GetMassBreakdown_Triangle(new Vector3D(triangleBase, height, size.Z), cellSize, true);
                items.Add(new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(triangle.Item1, new Vector3D(base1 * .5d, 0d, 0d) + triangle.Item2.ToPoint(), Quaternion.Identity, triangleBase * height * .5d));
            }
            else
            {
                // Rectangle
                double rectBase  = base1;
                var    rectangle = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Box, UtilityNewt.MassDistribution.Uniform, new Vector3D(rectBase, height, size.Z), cellSize);
                items.Add(new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(rectangle, new Vector3D(0d, 0d, 0d).ToPoint(), Quaternion.Identity, rectBase * height));

                // Triangle - right
                double   triangleBase   = (base2 - base1) * .5d;
                var      triangle       = GetMassBreakdown_Triangle(new Vector3D(triangleBase, height, size.Z), cellSize, true);
                Vector3D triangleOffset = new Vector3D((rectBase * .5d) + (triangleBase * .5d), 0d, 0d) + triangle.Item2;
                double   triangleArea   = triangleBase * height * .5d;
                items.Add(new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(triangle.Item1, triangleOffset.ToPoint(), Quaternion.Identity, triangleArea));

                // Triangle - left
                triangleOffset = new Vector3D(triangleOffset.X * -1d, triangleOffset.Y, triangleOffset.Z);
                Quaternion triangleOrientation = new Quaternion(new Vector3D(0, 1, 0), 180d);
                items.Add(new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(triangle.Item1, triangleOffset.ToPoint(), triangleOrientation, triangleArea));
            }

            return(UtilityNewt.Combine(items.ToArray()));
        }
示例#6
0
        public override UtilityNewt.IObjectMassBreakdown GetMassBreakdown(double cellSize)
        {
            if (_massBreakdown != null && _massBreakdown.Scale == Scale && _massBreakdown.CellSize == cellSize)
            {
                // This has already been built for this size
                return(_massBreakdown.Breakdown);
            }

            // Convert this.Scale into a size that the mass breakdown will use (mass breakdown wants height along X)

            //DNA plays with X and Z as the 2D axis and height is along Y

            //Vector3D size = new Vector3D(Scale.X, Scale.Y, Scale.Z * THICKNESS);
            //Vector3D size = new Vector3D(Scale.Z * THICKNESS, Scale.X, Scale.Y);
            //Vector3D size = new Vector3D(Scale.X, Scale.Z * THICKNESS, Scale.Y);
            Vector3D size = new Vector3D(Scale.X, Scale.Y * THICKNESS, Scale.Z);

            //Vector3D size = new Vector3D(Scale.Z, Scale.X, Scale.Y);

            UtilityNewt.IObjectMassBreakdown breakdown = null;

            switch (this.Shape)
            {
            case SolarPanelShape.Square:
                breakdown = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Box, UtilityNewt.MassDistribution.Uniform, size, cellSize);
                break;

            case SolarPanelShape.Right_Triangle:
            case SolarPanelShape.Triangle:
                var triangleBreakdown = GetMassBreakdown_Triangle(size, cellSize, this.Shape == SolarPanelShape.Right_Triangle);
                breakdown = UtilityNewt.Combine(new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>[] { new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(triangleBreakdown.Item1, triangleBreakdown.Item2.ToPoint(), Quaternion.Identity, 1d) });
                break;

            case SolarPanelShape.Right_Trapazoid:
            case SolarPanelShape.Trapazoid:
                breakdown = GetMassBreakdown_Trapazoid(this.Vertices.ToArray(), size, cellSize, this.Shape == SolarPanelShape.Right_Trapazoid);
                break;

            default:
                throw new ApplicationException("Unknown SolarPanelShape: " + this.Shape.ToString());
            }

            // Store this
            _massBreakdown = new MassBreakdownCache(breakdown, Scale, cellSize);

            return(_massBreakdown.Breakdown);
        }
示例#7
0
        internal static UtilityNewt.IObjectMassBreakdown GetCameraMassBreakdown(ref MassBreakdownCache existing, Vector3D scale, double cellSize)
        {
            if (existing != null && existing.Scale == scale && existing.CellSize == cellSize)
            {
                // This has already been built for this size
                return(existing.Breakdown);
            }

            // Convert this.Scale into a size that the mass breakdown will use
            Vector3D size = new Vector3D(scale.X * SCALE, scale.Y * SCALE, scale.Z * SCALE);

            var breakdown = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Sphere, UtilityNewt.MassDistribution.Uniform, size, cellSize);

            // Store this
            existing = new MassBreakdownCache(breakdown, scale, cellSize);

            return(existing.Breakdown);
        }
示例#8
0
        public override UtilityNewt.IObjectMassBreakdown GetMassBreakdown(double cellSize)
        {
            if (_massBreakdown != null && _massBreakdown.Scale == Scale && _massBreakdown.CellSize == cellSize)
            {
                // This has already been built for this size
                return(_massBreakdown.Breakdown);
            }

            // Convert this.Scale into a size that the mass breakdown will use
            Vector3D size = new Vector3D(this.Scale.X, this.Scale.Y * RATIOY, this.Scale.Z * RATIOZ);

            var breakdown = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Box, UtilityNewt.MassDistribution.Uniform, size, cellSize);

            // Store this
            _massBreakdown = new MassBreakdownCache(breakdown, Scale, cellSize);

            return(_massBreakdown.Breakdown);
        }
示例#9
0
        public override UtilityNewt.IObjectMassBreakdown GetMassBreakdown(double cellSize)
        {
            if (_massBreakdown != null && _massBreakdown.Scale == Scale && _massBreakdown.CellSize == cellSize)
            {
                // This has already been built for this size
                return(_massBreakdown.Breakdown);
            }

            // Convert this.Scale into a size that the mass breakdown will use
            Vector3D size = new Vector3D(this.Scale.X * DirectionControllerRingDesign.SIZEPERCENTOFSCALE, this.Scale.Y * DirectionControllerRingDesign.SIZEPERCENTOFSCALE, this.Scale.Z * DirectionControllerRingDesign.SIZEPERCENTOFSCALE);

            var breakdown = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Sphere, UtilityNewt.MassDistribution.Uniform, size, cellSize);

            // Store this
            _massBreakdown = new MassBreakdownCache(breakdown, Scale, cellSize);

            return(_massBreakdown.Breakdown);
        }
示例#10
0
        internal static UtilityNewt.IObjectMassBreakdown GetMassBreakdown(Vector3D scale, double cellSize)
        {
            // Convert this.Scale into a size that the mass breakdown will use (mass breakdown wants height along X, and scale is for radius, but the mass breakdown wants diameter
            Vector3D size = new Vector3D(scale.Z * HEIGHTPERCENTOFSCALE, scale.X * RADIUSPERCENTOFSCALE * 2d, scale.Y * RADIUSPERCENTOFSCALE * 2d);

            // Center
            Vector3D centerSize     = new Vector3D(size.X * .4d, size.Y * .65d, size.Z * .65d);
            double   centerVolume   = Math.Pow((centerSize.Y + centerSize.Z) / 4d, 2d) * Math.PI * centerSize.X;        // dividing by 4, because div 2 is the average, then another 2 is to convert diameter to radius
            var      centerCylinder = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Cylinder, UtilityNewt.MassDistribution.Uniform, centerSize, cellSize);

            // Bulb
            Vector3D bulbSize     = new Vector3D(size.X * .18d, size.Y, size.Z);
            double   bulbVolume   = Math.Pow((bulbSize.Y + bulbSize.Z) / 4d, 2d) * Math.PI * bulbSize.X;
            var      bulbCylinder = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Cylinder, UtilityNewt.MassDistribution.Uniform, bulbSize, cellSize);

            // Tip
            Vector3D tipSize     = new Vector3D(size.X * .12d, size.Y * .5d, size.Z * .5d);
            double   tipVolume   = Math.Pow((tipSize.Y + tipSize.Z) / 4d, 2d) * Math.PI * tipSize.X;
            var      tipCylinder = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Cylinder, UtilityNewt.MassDistribution.Uniform, tipSize, cellSize);

            // Combined shape
            double     offsetXBulb = (centerSize.X * .5d) + (bulbSize.X * .5d);
            double     offsetXTip  = (centerSize.X * .5d) + bulbSize.X + (tipSize.X * .5d);
            Quaternion rotate      = new Quaternion(new Vector3D(0, 1, 0), 90);

            var objects = new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double> [5];

            objects[0] = new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(centerCylinder, new Point3D(0, 0, 0), rotate, centerVolume);

            objects[1] = new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(bulbCylinder, new Point3D(0, 0, offsetXBulb), rotate, bulbVolume);             // the breakdowns were build along X, but now putting them back along Z
            objects[2] = new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(bulbCylinder, new Point3D(0, 0, -offsetXBulb), rotate, bulbVolume);

            objects[3] = new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(tipCylinder, new Point3D(0, 0, offsetXTip), rotate, tipVolume);
            objects[4] = new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(tipCylinder, new Point3D(0, 0, -offsetXTip), rotate, tipVolume);

            var combined = UtilityNewt.Combine(objects);

            return(combined);
        }
示例#11
0
        private static Tuple <UtilityNewt.ObjectMassBreakdown, Vector3D> GetMassBreakdown_Triangle(Vector3D size, double cellSize, bool isRight)
        {
            // This is just a hack, because I'm too lazy to make the breakdown calculate a triangle.
            // I figure if the area of the breakdown is the same as the area of the triangle, and if the breakdown is offset, it should be pretty close
            // (actually, probably not, because distance counts more than mass: mr^2, so this rectangle approach will probably give a lower inertia
            // than it should)
            Vector sizeExtended = new Vector(size.X * 1.1, size.Y * 1.1);     // compensating for the lower inertia of the hack rectangle by assuming the triangle is larger
            double area         = sizeExtended.X * sizeExtended.Y * .5d;      // cache the area of this triangle
            double areaRoot     = Math.Sqrt(area);                            // take the square root to see what the average width/height should be
            double x            = sizeExtended.X / sizeExtended.Y * areaRoot; // use the ratio of x to y to see how much of that square root should be
            double y            = sizeExtended.Y / sizeExtended.X * areaRoot;

            // When the ratio of x to y is too great, the derived x and y become larger than the original, so cap them
            if (x > sizeExtended.X)
            {
                x = sizeExtended.X;
                y = 2d * area / x;              // since x was capped, make y take up the slack
            }
            else if (y > sizeExtended.Y)
            {
                y = sizeExtended.Y;
                x = 2d * area / y;
            }

            // Now shift the hack rectangle so that it's more over the triangle portion
            double offsetX = 0d;

            if (isRight)
            {
                offsetX = size.X * -.12d;
            }

            double offsetY = size.Y * -.12d;

            // Build the breakdown and return the breakdown along with the offset
            var breakdown = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Box, UtilityNewt.MassDistribution.Uniform, new Vector3D(x, y, size.Z), cellSize);

            return(new Tuple <UtilityNewt.ObjectMassBreakdown, Vector3D>(breakdown, new Vector3D(offsetX, offsetY, 0d)));
        }
示例#12
0
        public override UtilityNewt.IObjectMassBreakdown GetMassBreakdown(double cellSize)
        {
            if (_massBreakdown != null && _massBreakdown.Scale == Scale && _massBreakdown.CellSize == cellSize)
            {
                // This has already been built for this size
                return(_massBreakdown.Breakdown);
            }

            // Convert this.Scale into a size that the mass breakdown will use (mass breakdown wants height along X, and scale is for radius, but the mass breakdown wants diameter
            Vector3D size = new Vector3D(this.Scale.Z * HEIGHTPERCENTOFSCALE * 2d, this.Scale.X * RADIUSPERCENTOFSCALE * 2d, this.Scale.Y * RADIUSPERCENTOFSCALE * 2d);         // HEIGHTPERCENTOFSCALE is a radius, so it needs to be doubled too

            // Center
            Vector3D centerSize     = new Vector3D(size.X * .5d, size.Y, size.Z);
            double   centerVolume   = Math.Pow((centerSize.Y + centerSize.Z) / 4d, 2d) * Math.PI * centerSize.X;        // dividing by 4, because div 2 is the average, then another 2 is to convert diameter to radius
            var      centerCylinder = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Cylinder, UtilityNewt.MassDistribution.Uniform, centerSize, cellSize);

            // Cap
            Vector3D capSize     = new Vector3D(size.X * .25d, size.Y * .6d, size.Z * .6d);
            double   capVolume   = Math.Pow((capSize.Y + capSize.Z) / 4d, 2d) * Math.PI * capSize.X;
            var      capCylinder = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Cylinder, UtilityNewt.MassDistribution.Uniform, capSize, cellSize);

            // Combined shape
            double     offsetX = (centerSize.X * .5d) + (capSize.X * .5d);
            Quaternion rotate  = new Quaternion(new Vector3D(0, 1, 0), 90);

            var objects = new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double> [3];

            objects[0] = new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(centerCylinder, new Point3D(0, 0, 0), rotate, centerVolume);
            objects[1] = new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(capCylinder, new Point3D(0, 0, offsetX), rotate, capVolume);           // the breakdowns were build along X, but now putting them back along Z
            objects[2] = new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(capCylinder, new Point3D(0, 0, -offsetX), rotate, capVolume);

            var combined = UtilityNewt.Combine(objects);

            // Store this
            _massBreakdown = new MassBreakdownCache(combined, Scale, cellSize);

            return(_massBreakdown.Breakdown);
        }
示例#13
0
        internal static UtilityNewt.IObjectMassBreakdown GetTankMassBreakdown(ref MassBreakdownCache existing, Vector3D scale, double cellSize)
        {
            if (existing != null && existing.Scale == scale && existing.CellSize == cellSize)
            {
                // This has already been built for this size
                return(existing.Breakdown);
            }

            // Convert this.Scale into a size that the mass breakdown will use (mass breakdown wants height along X, and scale is for radius, but the mass breakdown wants diameter
            Vector3D size = new Vector3D(scale.Z, scale.X * RADIUSPERCENTOFSCALE * 2d, scale.Y * RADIUSPERCENTOFSCALE * 2d);

            // Main Cylinder
            Vector3D mainSize     = new Vector3D(size.X * .75d, size.Y, size.Z);
            double   mainVolume   = Math.Pow((mainSize.Y + mainSize.Z) / 4d, 2d) * Math.PI * mainSize.X;        // dividing by 4, because div 2 is the average, then another 2 is to convert diameter to radius
            var      mainCylinder = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Cylinder, UtilityNewt.MassDistribution.Uniform, mainSize, cellSize);

            // End Caps
            Vector3D capSize     = new Vector3D(size.X * .125d, size.Y * .5d, size.Z * .5d);
            double   capVolume   = Math.Pow((capSize.Y + capSize.Z) / 4d, 2d) * Math.PI * capSize.X;
            var      capCylinder = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Cylinder, UtilityNewt.MassDistribution.Uniform, capSize, cellSize);

            // Combined shape
            double     offsetX = (mainSize.X * .5d) + (capSize.X * .5d);
            Quaternion rotate  = new Quaternion(new Vector3D(0, 1, 0), 90);

            var objects = new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double> [3];

            objects[0] = new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(mainCylinder, new Point3D(0, 0, 0), rotate, mainVolume);
            objects[1] = new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(capCylinder, new Point3D(0, 0, offsetX), rotate, capVolume);           // the breakdowns were build along X, but now putting them back along Z
            objects[2] = new Tuple <UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(capCylinder, new Point3D(0, 0, -offsetX), rotate, capVolume);
            var combined = UtilityNewt.Combine(objects);

            // Store this
            existing = new MassBreakdownCache(combined, scale, cellSize);

            return(existing.Breakdown);
        }
        private void DrawMassBreakdown(UtilityNewt.IObjectMassBreakdown breakdown, double cellSize)
        {
            #region Draw masses as cubes

            double radMult = (cellSize * .75d) / breakdown.Max(o => o.Item2);
            DoubleVector dirFacing = new DoubleVector(1, 0, 0, 0, 1, 0);

            Model3DGroup geometries = new Model3DGroup();

            foreach (var pointMass in breakdown)
            {
                double radius = pointMass.Item2 * radMult;

                CollisionHull dummy1; Transform3DGroup dummy2; Quaternion dummy3; DiffuseMaterial dummy4;
                geometries.Children.Add(GetWPFGeometry(out dummy1, out dummy2, out dummy3, out dummy4, CollisionShapeType.Box, _colors.MassBall, _colors.MassBallReflect, _colors.MassBallReflectIntensity, new Vector3D(radius, radius, radius), pointMass.Item1, dirFacing, false));
            }

            ModelVisual3D visual = new ModelVisual3D();
            visual.Content = geometries;
            _viewport.Children.Add(visual);
            _currentVisuals.Add(visual);

            #endregion
            #region Draw Axiis

            ScreenSpaceLines3D line = new ScreenSpaceLines3D();
            line.Color = Colors.DimGray;
            line.Thickness = 2d;
            line.AddLine(new Point3D(0, 0, 0), new Point3D(10, 0, 0));
            _viewport.Children.Add(line);
            _currentVisuals.Add(line);

            line = new ScreenSpaceLines3D();
            line.Color = Colors.Silver;
            line.Thickness = 2d;
            line.AddLine(new Point3D(0, 0, 0), new Point3D(0, 10, 0));
            _viewport.Children.Add(line);
            _currentVisuals.Add(line);

            line = new ScreenSpaceLines3D();
            line.Color = Colors.White;
            line.Thickness = 2d;
            line.AddLine(new Point3D(0, 0, 0), new Point3D(0, 0, 10));
            _viewport.Children.Add(line);
            _currentVisuals.Add(line);

            #endregion
        }