private void btnThreeCubesRand_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                ShipPartDNA dnaGrav = new ShipPartDNA() { PartType = SensorGravity.PARTTYPE, Position = Math3D.GetRandomVector(2d).ToPoint(), Orientation = Math3D.GetRandomRotation(), Scale = new Vector3D(10, 10, 10) };
                ShipPartDNA dnaSpin = new ShipPartDNA() { PartType = SensorSpin.PARTTYPE, Position = Math3D.GetRandomVector(2d).ToPoint(), Orientation = Math3D.GetRandomRotation(), Scale = new Vector3D(10, 10, 10) };
                ShipPartDNA dnaVel = new ShipPartDNA() { PartType = SensorVelocity.PARTTYPE, Position = Math3D.GetRandomVector(2d).ToPoint(), Orientation = Math3D.GetRandomRotation(), Scale = new Vector3D(10, 10, 10) };

                SensorGravity grav = new SensorGravity(_editorOptions, _itemOptions, dnaGrav, null, null);
                SensorSpin spin = new SensorSpin(_editorOptions, _itemOptions, dnaSpin, null);
                SensorVelocity vel = new SensorVelocity(_editorOptions, _itemOptions, dnaVel, null);

                StartScene(new PartBase[] { grav, spin, vel }, 7);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        private void btnTwoCubeCylinder_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                bool isEnergy = StaticRandom.Next(2) == 0;

                ShipPartDNA dna1 = new ShipPartDNA() { PartType = isEnergy ? EnergyTank.PARTTYPE : FuelTank.PARTTYPE, Position = new Point3D(-.5, 0, 0), Orientation = Quaternion.Identity, Scale = new Vector3D(4, 4, 3) };
                ShipPartDNA dnaSpin = new ShipPartDNA() { PartType = SensorSpin.PARTTYPE, Position = new Point3D(.5, 0, 0), Orientation = Quaternion.Identity, Scale = new Vector3D(10, 10, 10) };

                PartBase cylinder = null;
                if (isEnergy)
                {
                    cylinder = new EnergyTank(_editorOptions, _itemOptions, dna1);
                }
                else
                {
                    cylinder = new FuelTank(_editorOptions, _itemOptions, dna1);
                }
                SensorSpin spin = new SensorSpin(_editorOptions, _itemOptions, dnaSpin, null);

                StartScene(new PartBase[] { cylinder, spin }, 7);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        private void btnIntersectingCubes3_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                EnsureWorldStarted();
                ClearCurrent();

                //PartDNA dnaGrav = new PartDNA() { PartType = SensorGravity.PARTTYPE, Position = new Point3D(-1.01, 0, 0), Orientation = Quaternion.Identity, Scale = new Vector3D(10, 10, 10) };
                //PartDNA dnaSpin = new PartDNA() { PartType = SensorSpin.PARTTYPE, Position = new Point3D(1.01, 0, 0), Orientation = new Quaternion(new Vector3D(0, 0, 1), 30), Scale = new Vector3D(10, 10, 10) };
                ShipPartDNA dnaGrav = new ShipPartDNA() { PartType = SensorGravity.PARTTYPE, Position = new Point3D(-1.01, 0, 0), Orientation = new Quaternion(new Vector3D(0, 0, -1), 15), Scale = new Vector3D(10, 10, 10) };
                ShipPartDNA dnaSpin = new ShipPartDNA() { PartType = SensorSpin.PARTTYPE, Position = new Point3D(1.01, 0, 0), Orientation = new Quaternion(new Vector3D(0, 0, 1), 45), Scale = new Vector3D(10, 10, 10) };

                SensorGravity grav = new SensorGravity(_editorOptions, _itemOptions, dnaGrav, null, null);
                SensorSpin spin = new SensorSpin(_editorOptions, _itemOptions, dnaSpin, null);

                PartBase[] parts = new PartBase[] { grav, spin };

                // Draw before
                DrawParts(parts, new Vector3D(-5, 0, 0));

                // Separate them
                CollisionHull.IntersectionPoint[] intersections;
                EnsurePartsNotIntersecting.Separate(out intersections, parts, _world, .01d);

                DrawLines(intersections.Select(o => Tuple.Create(o.ContactPoint, o.Normal.ToUnit() * o.PenetrationDistance)).ToArray(), new Vector3D(-5, -5, 0), Colors.Red);

                // Draw after
                DrawParts(parts, new Vector3D(5, 0, 0));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        private void btnTwoCubes3_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                //PartDNA dnaGrav = new PartDNA() { PartType = SensorGravity.PARTTYPE, Position = new Point3D(-1.01, 0, 0), Orientation = Quaternion.Identity, Scale = new Vector3D(10, 10, 10) };
                //PartDNA dnaSpin = new PartDNA() { PartType = SensorSpin.PARTTYPE, Position = new Point3D(1.01, 0, 0), Orientation = new Quaternion(new Vector3D(0, 0, 1), 30), Scale = new Vector3D(10, 10, 10) };
                ShipPartDNA dnaGrav = new ShipPartDNA() { PartType = SensorGravity.PARTTYPE, Position = new Point3D(-1.01, 0, 0), Orientation = new Quaternion(new Vector3D(0, 0, -1), 15), Scale = new Vector3D(10, 10, 10) };
                ShipPartDNA dnaSpin = new ShipPartDNA() { PartType = SensorSpin.PARTTYPE, Position = new Point3D(1.01, 0, 0), Orientation = new Quaternion(new Vector3D(0, 0, 1), 45), Scale = new Vector3D(10, 10, 10) };

                SensorGravity grav = new SensorGravity(_editorOptions, _itemOptions, dnaGrav, null, null);
                SensorSpin spin = new SensorSpin(_editorOptions, _itemOptions, dnaSpin, null);

                StartScene(new PartBase[] { grav, spin }, 7);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        private void btnIntersectingCubes_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                EnsureWorldStarted();
                ClearCurrent();

                ShipPartDNA dnaGrav = new ShipPartDNA() { PartType = SensorGravity.PARTTYPE, Position = new Point3D(-.5, 0, 0), Orientation = Quaternion.Identity, Scale = new Vector3D(10, 10, 10) };
                ShipPartDNA dnaSpin = new ShipPartDNA() { PartType = SensorSpin.PARTTYPE, Position = new Point3D(.5, 0, 0), Orientation = Quaternion.Identity, Scale = new Vector3D(10, 10, 10) };
                //PartDNA dnaGrav = new PartDNA() { PartType = SensorGravity.PARTTYPE, Position = new Point3D(-1, 0, 0), Orientation = Quaternion.Identity, Scale = new Vector3D(10, 10, 10) };
                //PartDNA dnaSpin = new PartDNA() { PartType = SensorSpin.PARTTYPE, Position = new Point3D(1, 0, 0), Orientation = Quaternion.Identity, Scale = new Vector3D(10, 10, 10) };

                SensorGravity grav = new SensorGravity(_editorOptions, _itemOptions, dnaGrav, null, null);
                SensorSpin spin = new SensorSpin(_editorOptions, _itemOptions, dnaSpin, null);

                PartBase[] parts = new PartBase[] { grav, spin };

                // Draw before
                DrawParts(parts, new Vector3D(-5, 0, 0));

                // Separate them
                CollisionHull.IntersectionPoint[] intersections;
                EnsurePartsNotIntersecting.Separate(out intersections, parts, _world, .01d);

                DrawLines(intersections.Select(o => Tuple.Create(o.ContactPoint, o.Normal.ToUnit() * o.PenetrationDistance)).ToArray(), new Vector3D(-5, -5, 0), Colors.Red);

                // Draw after
                DrawParts(parts, new Vector3D(5, 0, 0));

                #region Test

                //CollisionHull hull1a, hull2a;
                //Transform3DGroup dummy2;
                //Quaternion dummy3;
                //DiffuseMaterial dummy4;
                //double size = 10d * .2d;
                //Visual3D model = GetWPFModel(out hull1a, out dummy2, out dummy3, out dummy4, CollisionShapeType.Box, Colors.Tan, Colors.Tan, 1d, new Vector3D(size, size, size), new Point3D(-.6, 5, 0), _defaultDirectionFacing, true);		// this doesn't use the offset in the collision hull
                //_currentVisuals.Add(model);
                //_viewport.Children.Add(model);

                //model = GetWPFModel(out hull2a, out dummy2, out dummy3, out dummy4, CollisionShapeType.Box, Colors.Chartreuse, Colors.Chartreuse, 1d, new Vector3D(size, size, size), new Point3D(.6, 5, 0), _defaultDirectionFacing, true);
                //_currentVisuals.Add(model);
                //_viewport.Children.Add(model);


                //TranslateTransform3D offset1 = new TranslateTransform3D(-.6, 0, 0);
                //TranslateTransform3D offset2 = new TranslateTransform3D(.6, 0, 0);


                //CollisionHull.IntersectionPoint[] points1a = hull1a.GetIntersectingPoints_HullToHull(100, hull2a, 0, offset1, offset2);
                //CollisionHull.IntersectionPoint[] points2a = hull2a.GetIntersectingPoints_HullToHull(100, hull1a, 0, offset2, offset1);

                //CollisionHull hull1b = CollisionHull.CreateBox(_world, 0, new Vector3D(size, size, size), offset1.Value);
                //CollisionHull hull2b = CollisionHull.CreateBox(_world, 0, new Vector3D(size, size, size), offset2.Value);

                //CollisionHull.IntersectionPoint[] points1b = hull1b.GetIntersectingPoints_HullToHull(100, hull2b, 0, null, null);
                //CollisionHull.IntersectionPoint[] points2b = hull2b.GetIntersectingPoints_HullToHull(100, hull1b, 0, null, null);

                #endregion
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }