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));
            }

            // Exit Function
            return UtilityNewt.Combine(items.ToArray());
        }
Beispiel #2
0
        private void ChangeSwarmBots(SwarmFormation formation)
        {
            ChangeSwarmBotsSprtRemoveAll();

            if (formation == SwarmFormation.None)
            {
                _swarmbotFormation = SwarmFormation.None;
                return;
            }

            double startAngle, stepAngle;       // 0 is straight in front of the ship
            int numBots;
            double distanceMult;

            switch (formation)
            {
                case SwarmFormation.AllFront:
                    #region AllFront

                    startAngle = 0d;
                    stepAngle = 360d;

                    //numBots = 20;
                    numBots = _numSwarmbots;

                    distanceMult = 8d;

                    #endregion
                    break;

                case SwarmFormation.AllRear:
                    #region AllRear

                    startAngle = 180d;
                    stepAngle = 360d;

                    //numBots = 20;
                    numBots = _numSwarmbots;

                    distanceMult = 8d;

                    #endregion
                    break;

                case SwarmFormation.Triangle:
                    #region Triangle

                    startAngle = 0d;
                    stepAngle = 120d;

                    //numBots = 10;
                    numBots = _numSwarmbots / 3;
                    if (numBots % 3 != 0 || numBots == 0)
                    {
                        numBots++;
                    }

                    distanceMult = 9d;

                    #endregion
                    break;

                case SwarmFormation.ReverseTriangle:
                    #region ReverseTriangle

                    startAngle = 180d;
                    stepAngle = 120d;

                    //numBots = 10;
                    numBots = _numSwarmbots / 3;
                    if (numBots % 3 != 0 || numBots == 0)
                    {
                        numBots++;
                    }

                    distanceMult = 9d;

                    #endregion
                    break;

                case SwarmFormation.Pentagon:
                    #region Pentagon

                    startAngle = 0d;
                    stepAngle = 72d;

                    //numBots = 7;
                    numBots = _numSwarmbots / 5;
                    if (numBots % 5 != 0 || numBots == 0)
                    {
                        numBots++;
                    }

                    distanceMult = 9d;

                    #endregion
                    break;

                case SwarmFormation.ReversePentagon:
                    #region ReversePentagon

                    startAngle = 180d;
                    stepAngle = 72d;

                    //numBots = 7;
                    numBots = _numSwarmbots / 5;
                    if (numBots % 5 != 0 || numBots == 0)
                    {
                        numBots++;
                    }

                    distanceMult = 9d;

                    #endregion
                    break;

                case SwarmFormation.SurroundShip:
                    #region SurroundShip

                    startAngle = 0d;
                    stepAngle = 360d;

                    //numBots = 30;
                    numBots = _numSwarmbots;

                    distanceMult = 0d;

                    #endregion
                    break;

                default:
                    throw new ApplicationException("Unknown SwarmFormation: " + formation.ToString());
            }

            // Figure out how far away from the ship the bots should be
            double chaseOffsetDistance = (_radiusX + _radiusY) / 2d;
            chaseOffsetDistance *= distanceMult;

            // Build the swarms
            double angle = startAngle;
            while (angle < startAngle + 360d)
            {
                Vector3D chasePoint = new Vector3D(0, chaseOffsetDistance, 0);
                chasePoint = chasePoint.GetRotatedVector(new Vector3D(0, 0, 1), angle);

                _swarmBots.Add(ChangeSwarmBotsSprtSwarm(numBots, chasePoint));
                _swarmbotChasePoints.Add(chasePoint.ToPoint());

                PointVisualizer chasePointSprite = new PointVisualizer(_map.Viewport, _sharedVisuals);
                chasePointSprite.PositionRadius = .1d;
                chasePointSprite.VelocityAccelerationLengthMultiplier = .05d;
                chasePointSprite.ShowPosition = _showDebugVisuals;
                chasePointSprite.ShowVelocity = _showDebugVisuals;
                chasePointSprite.ShowAcceleration = _showDebugVisuals && DEBUGSHOWSACCELERATION;
                _swarmbotChasePointSprites.Add(chasePointSprite);

                angle += stepAngle;
            }

            _swarmbotFormation = formation;
        }
        private void CreateSpaceStations()
        {
            const double ZMIN = -20;
            const double ZMAX = -12;

            double xyCoord = _boundryMax.X * STATION_BOUNDRY_PERCENT;
            double zCoord = StaticRandom.NextDouble(ZMIN, ZMAX);
            double minDistanceBetweenStationsSquared = 200d * 200d;

            #region clear the old

            if (_stations != null)
            {
                foreach (var station in _stations)
                {
                    _map.RemoveItem(station);
                }
            }

            _currentlyOverStation = null;
            _stations = null;

            #endregion

            List<SpaceStation2D> stations = new List<SpaceStation2D>();

            #region Home Station

            // Make one right next to the player at startup
            Point3D homeLocation = Math3D.GetRandomVector_Circular_Shell(12).ToPoint();

            stations.Add(CreateSpaceStations_Build(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 = StaticRandom.NextDouble(ZMIN, ZMAX);

                    // See if this is too close to an existing station
                    bool isTooClose = false;
                    foreach (SpaceStation station in stations)
                    {
                        Vector3D offset = position - station.PositionWorld.ToVector();
                        if (offset.LengthSquared < minDistanceBetweenStationsSquared)
                        {
                            isTooClose = true;
                            break;
                        }
                    }

                    if (!isTooClose)
                    {
                        break;
                    }

                    #endregion
                }

                stations.Add(CreateSpaceStations_Build(position.ToPoint()));
            }

            _stations = stations.ToArray();
        }
Beispiel #4
0
        /// <summary>
        /// Calculates the angle and updates the arc according to the specifed vectors.
        /// </summary>
        /// <param name="start">The vector of the starting point.</param>
        /// <param name="middle">The vector of the middle point.</param>
        /// <param name="end">The vector of the end point.</param>
        /// <param name="desiredRadius">The desired arc radius.</param>
        public void Update(Vector3D start, Vector3D middle, Vector3D end, double desiredRadius = 0)
        {
            _vector1 = middle - start;
            _vector2 = middle - end;

            if (desiredRadius == 0)
            {
                desiredRadius = Math.Min(_vector1.Length, _vector2.Length);
            }
            
            _vector1.Normalize();
            _vector2.Normalize();

            _angle = Vector3D.AngleBetween(_vector1, _vector2);

            start = middle - desiredRadius * _vector1;
            end = middle - desiredRadius * _vector2;

            line1.Point = middle.ToPoint();
            line2.Point = start.ToPoint();
            angleFigure.StartPoint = end.ToPoint();

            arc.IsLargeArc = _angle > 180.0;
            arc.Point = end.ToPoint();
            arc.Size = new Size(desiredRadius, desiredRadius);
        }
Beispiel #5
0
        private void Brain_Flocking_ChasePoint()
        {
            // Calculate the center of position of the flock
            //TODO:  Have a vision limit

            #region Direction to center flock

            Vector3D centerPosition = new Vector3D(0, 0, 0);
            foreach (SwarmBot1 bot in _otherBots)
            {
                centerPosition += bot.PhysicsBody.PositionToWorld(bot.PhysicsBody.CenterOfMass).ToVector();
            }

            if (_otherBots.Count > 0)       // can't divide by zero
            {
                centerPosition /= _otherBots.Count;
            }

            // Figure out what direction to go in local coords
            Vector3D flockCenterDirection = StraightToTarget_VelocityAware1Worker(centerPosition.ToPoint());
            //Vector3D flockCenterDirection = StraightToTargetWorker(centerPosition.ToPoint());

            #endregion

            // Get a cumulative vector that tells how to avoid others
            Vector3D avoidDirection = AvoidWorker();

            // Get the average flock velocity
            Vector3D commonVelocityDirection = MatchVelocityWorker();

            // Go toward the chase point
            Vector3D chasePointDirection = StraightToTarget_VelocityAware1Worker(_chasePoint);



            // For now, I will just normalize the two and add them together with equal weight
            //NOTE:  Normalizing gives bad results.  The avoid already has a priority magnitude, normalizing wipes it
            //flockCenterDirection.Normalize();
            //avoidDirection.Normalize();

            flockCenterDirection /= 2;

            commonVelocityDirection.Normalize();

            chasePointDirection /= (chasePointDirection.Length / 2);

            Vector3D directionToGo = flockCenterDirection + avoidDirection + commonVelocityDirection + chasePointDirection;





            // Now that I know where to go, rotate the original thruster direction (0,1,0) to line up with the desired direction
            Vector3D axis;
            double radians;
            Math3D.GetRotation(out axis, out radians, _origThrustDirection, directionToGo);

            // Thrust Direction
            _thrustTransform = new RotateTransform3D(new AxisAngleRotation3D(axis, Math1D.RadiansToDegrees(radians)));

            // Thrust Strength
            if (_isAttacking)
            {
                _thrustPercent = 1d;
            }
            else
            {
                _thrustPercent = .5d;
            }
        }
        private RayHitTestParameters GetArrowRay(DraggingModifier whichArrow)
        {
            Vector3D origin = new Vector3D();
            Vector3D direction = new Vector3D();

            Vector3D position = this.Position.ToVector();
            Vector3D scale = this.Scale;
            RotateTransform3D rotateTransform = new RotateTransform3D(new QuaternionRotation3D(this.Orientation));

            switch (whichArrow)
            {
                case DraggingModifier.ArrowX1:
                    origin = position + rotateTransform.Transform(new Vector3D(GetDistance_Arrow(scale.X), 0, 0));
                    direction = rotateTransform.Transform(new Vector3D(1, 0, 0));
                    break;

                case DraggingModifier.ArrowX2:
                    origin = position - rotateTransform.Transform(new Vector3D(GetDistance_Arrow(scale.X), 0, 0));
                    direction = rotateTransform.Transform(new Vector3D(-1, 0, 0));
                    break;

                case DraggingModifier.ArrowY1:
                    origin = position + rotateTransform.Transform(new Vector3D(0, GetDistance_Arrow(scale.Y), 0));
                    direction = rotateTransform.Transform(new Vector3D(0, 1, 0));
                    break;

                case DraggingModifier.ArrowY2:
                    origin = position - rotateTransform.Transform(new Vector3D(0, GetDistance_Arrow(scale.Y), 0));
                    direction = rotateTransform.Transform(new Vector3D(0, -1, 0));
                    break;

                case DraggingModifier.ArrowZ1:
                    origin = position + rotateTransform.Transform(new Vector3D(0, 0, GetDistance_Arrow(scale.Z)));
                    direction = rotateTransform.Transform(new Vector3D(0, 0, 1));
                    break;

                case DraggingModifier.ArrowZ2:
                    origin = position - rotateTransform.Transform(new Vector3D(0, 0, GetDistance_Arrow(scale.Z)));
                    direction = rotateTransform.Transform(new Vector3D(0, 0, -1));
                    break;

                default:
                    throw new ApplicationException("Unexpected DraggingModifier: " + whichArrow.ToString());
            }

            // Exit Function
            return new RayHitTestParameters(origin.ToPoint(), direction);
        }
        private void GetContactPositionaAndNormal()
        {
            Vector3D position = new Vector3D();
            Vector3D normal = new Vector3D();
            //_material1.GetContactPositionAndNormal(ref position, ref normal);

            Newton.NewtonMaterialGetContactPositionAndNormal(_materialPtr, new NewtonVector3(position).NWVector3, new NewtonVector3(normal).NWVector3);


            _contactPositionWorld = position.ToPoint();
            _contactNormalWorld = normal;
        }
            private Tuple<IsInsideResult, ITriangle, Point3D> DrawZeroTorqueTestSprtIsInside(TriangleIndexed[] hull, Vector3D opposite)
            {
                if (Math3D.IsInside_Planes(hull, opposite.ToPoint()))
                {
                    return new Tuple<IsInsideResult, ITriangle, Point3D>(IsInsideResult.Inside, null, new Point3D());
                }

                Vector3D[] line = new Vector3D[] { opposite * .001d, opposite * .999d };

                foreach (ITriangle triangle in hull)
                {
                    Vector3D dummy1;
                    double dummy2;
                    Vector3D? intersectionPoint;
                    if (Math3D.IsIntersecting_Polygon2D_Line(new Vector3D[] { triangle.Point0.ToVector(), triangle.Point1.ToVector(), triangle.Point2.ToVector() }, line, 3, out dummy1, out dummy2, out intersectionPoint))
                    {
                        return new Tuple<IsInsideResult, ITriangle, Point3D>(IsInsideResult.Intersects, triangle, intersectionPoint.Value.ToPoint());
                    }
                }

                return new Tuple<IsInsideResult, ITriangle, Point3D>(IsInsideResult.Neither, null, new Point3D());
            }
            private void DrawZeroTorqueTest2()
            {
                //const double MINPERCENT = .005d;

                // Find 100% thrusters
                SortedList<int, List<int[]>> fullThrusts = DrawZeroTorqueTest2SprtGetFullThrusts(_vectors);

                if (fullThrusts.Count == 0)
                {
                    #region Draw them red

                    if (_showAxiis)
                    {
                        DrawAxiis(new Vector3D(0, 0, 0));
                    }

                    ScreenSpaceLines3D lines = new ScreenSpaceLines3D();
                    lines.Thickness = 3d;
                    lines.Color = UtilityWPF.ColorFromHex(LINE_RED);

                    for (int cntr = 0; cntr < _vectors.Length; cntr++)
                    {
                        lines.AddLine(new Point3D(0, 0, 0), _vectors[cntr].ToPoint());
                    }

                    _visuals.Add(lines);
                    _viewport.Children.Add(lines);

                    #endregion
                }
                else
                {
                    #region Draw all

                    double maxVectorLength = _vectors.Max(o => o.Length);
                    maxVectorLength *= 2.5d;

                    //double offsetX = (fullThrusts.Keys.Count * maxVectorLength) / -2d;
                    double offsetX = 0d;

                    ScreenSpaceLines3D linesFull = new ScreenSpaceLines3D();
                    linesFull.Thickness = 3d;
                    linesFull.Color = UtilityWPF.ColorFromHex(LINE_GREEN);
                    _visuals.Add(linesFull);
                    _viewport.Children.Add(linesFull);

                    ScreenSpaceLines3D linesCumulative = new ScreenSpaceLines3D();
                    linesCumulative.Thickness = 3d;
                    linesCumulative.Color = Colors.Chartreuse;
                    _visuals.Add(linesCumulative);
                    _viewport.Children.Add(linesCumulative);

                    ScreenSpaceLines3D linesCumulativeAnti = new ScreenSpaceLines3D();
                    linesCumulativeAnti.Thickness = 2d;
                    linesCumulativeAnti.Color = UtilityWPF.ColorFromHex(LINE_GREEN_ANTI);
                    _visuals.Add(linesCumulativeAnti);
                    _viewport.Children.Add(linesCumulativeAnti);

                    ScreenSpaceLines3D linesOther = new ScreenSpaceLines3D();
                    linesOther.Thickness = 3d;
                    linesOther.Color = UtilityWPF.ColorFromHex(LINE_BLUE);
                    _visuals.Add(linesOther);
                    _viewport.Children.Add(linesOther);

                    //NOTE: Only need to grab the key that represents the most number of vectors firing at 100%.  The lower keys are trumped
                    //by the higher key
                    int key = fullThrusts.Keys[fullThrusts.Keys.Count - 1];
                    //foreach (int key in fullThrusts.Keys)
                    //{

                    double offsetY = (fullThrusts[key].Count * maxVectorLength) / -2d;

                    foreach (int[] fulls in fullThrusts[key])
                    {
                        Vector3D cumulative = new Vector3D(0, 0, 0);
                        Vector3D offset = new Vector3D(offsetX, offsetY, 0);

                        for (int cntr = 0; cntr < _vectors.Length; cntr++)
                        {
                            if (_showAxiis)
                            {
                                DrawAxiis(offset);
                            }

                            if (fulls.Contains(cntr))
                            {
                                // Draw the 100%s as green lines (line and anti line)
                                linesFull.AddLine(offset.ToPoint(), (offset + _vectors[cntr]).ToPoint());
                                cumulative += _vectors[cntr];
                                //linesFullAnti.AddLine(offset.ToPoint(), (offset - _vectors[cntr]).ToPoint());
                            }
                            else
                            {
                                // Draw the remaining lines as blue
                                linesOther.AddLine(offset.ToPoint(), (offset + _vectors[cntr]).ToPoint());
                            }

                            // Draw the hull of the remaining lines
                            TriangleIndexed[] hull = GetHull(_vectors, fulls);
                            if (hull != null)
                            {
                                DrawPossibleHull(hull, offset);
                            }
                        }

                        // Draw the cumulative and anti (it's the anti that was compared to the hull)
                        linesCumulative.AddLine(offset.ToPoint(), (offset + cumulative).ToPoint());
                        linesCumulativeAnti.AddLine(offset.ToPoint(), (offset - cumulative).ToPoint());

                        offsetY += maxVectorLength;
                    }

                    //    offsetX += maxVectorLength;
                    //}

                    #endregion
                }
            }
        private ScreenSpaceLines3D[] AddLines(DoubleVector transformedLine, Vector3D rotationAxis)
        {
            ScreenSpaceLines3D[] retVal = new ScreenSpaceLines3D[4];

            for (int cntr = 0; cntr < retVal.Length; cntr++)
            {
                retVal[cntr] = new ScreenSpaceLines3D(true);
                retVal[cntr].Color = _colors.RotatedLine;

                if (cntr == 1)
                {
                    retVal[cntr].Thickness = 3d;		// this one isn't really used
                }
                else if (cntr == 3)
                {
                    retVal[cntr].Thickness = 1d;
                }
                else
                {
                    retVal[cntr].Thickness = 6d;
                }
            }

            retVal[0].AddLine(new Point3D(0, 0, 0), transformedLine.Standard.ToPoint());
            retVal[1].AddLine(new Point3D(0, 0, 0), new Point3D(0, 0, 0));		// just adding this so everything stays lined up
            retVal[2].AddLine(new Point3D(0, 0, 0), transformedLine.Orth.ToPoint());
            retVal[3].AddLine(new Point3D(0, 0, 0), rotationAxis.ToPoint());

            for (int cntr = 0; cntr < retVal.Length; cntr++)
            {
                _viewport.Children.Add(retVal[cntr]);
            }

            return retVal;
        }
        private void World_Updating(object sender, WorldUpdatingArgs e)
        {
            try
            {
                #region Remove temp bodies

                int index = 0;
                while (index < _tempBodies.Count)
                {
                    if (_tempBodies[index].ShouldDie())
                    {
                        foreach (Visual3D visual in _tempBodies[index].PhysicsBody.Visuals)
                        {
                            _viewport.Children.Remove(visual);
                        }

                        _tempBodies[index].PhysicsBody.Dispose();

                        _tempBodies.RemoveAt(index);
                    }
                    else
                    {
                        index++;
                    }
                }

                #endregion

                if (radFallingSand.IsChecked.Value || (radFallingSandPlates.IsChecked.Value && (DateTime.UtcNow - _lastSandAdd).TotalMilliseconds > 5000d))
                {
                    #region Falling Sand

                    bool isPlate = radFallingSandPlates.IsChecked.Value;
                    Color color = UtilityWPF.ColorFromHex("FFF5EE95");
                    Vector3D size = new Vector3D(.05, .05, .05);
                    double maxDist = 1.1 * size.LengthSquared;
                    double mass = trkMass.Value;
                    double radius = 1d;
                    double startHeight = 1d;
                    TimeSpan lifespan = TimeSpan.FromSeconds(15d);
                    Vector3D velocity = new Vector3D(0, 0, -trkSpeed.Value);
                    int numCubes = isPlate ? 150 : 1;

                    // Calculate positions (they must all be calculated up front, or some sand will be built later)
                    List<Vector3D> positions = new List<Vector3D>();
                    for (int cntr = 0; cntr < numCubes; cntr++)
                    {
                        Vector3D startPos;
                        while (true)
                        {
                            startPos = Math3D.GetRandomVector_Circular(radius);

                            if (!positions.Any(o => (o - startPos).LengthSquared < maxDist))
                            {
                                break;
                            }
                        }

                        positions.Add(startPos);
                    }

                    // Place the sand
                    for (int cntr = 0; cntr < numCubes; cntr++)
                    {
                        Vector3D startPos = new Vector3D(positions[cntr].X, positions[cntr].Y, startHeight);
                        Quaternion orientation = isPlate ? Quaternion.Identity : Math3D.GetRandomRotation();

                        Body body = GetNewBody(CollisionShapeType.Box, color, size, mass, startPos.ToPoint(), orientation, _material_Sand);
                        body.Velocity = velocity;
                        body.LinearDamping = 0d;
                        body.AngularDamping = new Vector3D(0d, 0d, 0d);

                        _tempBodies.Add(new TempBody(body, lifespan));
                    }

                    // Remember when this was done
                    _lastSandAdd = DateTime.UtcNow;

                    #endregion
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        private static ShipPartDNA[] GetRandomThrusters(int count, bool randomOrientations, ThrusterTypeValues thrustType)
        {
            const double MINRADIUS = 1.5;
            const double MAXRADIUS = 3;
            const double MINSIZE = .5;
            const double MAXSIZE = 1.5;

            if (count < 2)
            {
                throw new ApplicationException("Must have at least two thrusters");
            }

            List<ShipPartDNA> retVal = new List<ShipPartDNA>();

            Random rand = StaticRandom.GetRandomForThread();

            double stepAngle = 360d / count;
            double rangeAngle = 120d / count;       // the sum of these pie slices should cover 2/3 of the area

            Vector3D axis = new Vector3D(0, 0, 1);
            double startAngle = rand.NextDouble(360);

            for (int cntr = 0; cntr < count; cntr++)
            {
                double angle = startAngle + (cntr * stepAngle);
                angle += rand.NextDouble(-rangeAngle, rangeAngle);

                Vector3D position = new Vector3D(rand.NextDouble(MINRADIUS, MAXRADIUS), 0, 0);
                position = position.GetRotatedVector(axis, angle);

                double size = rand.NextDouble(MINSIZE, MAXSIZE);

                //Random direction
                Quaternion orientation = Quaternion.Identity;
                if (randomOrientations)
                {
                    Vector3D standardVect = new Vector3D(0, 0, 1);
                    Vector3D rotatedVect = Math3D.GetRandomVector_Cone(axis, 90);
                    orientation = Math3D.GetRotation(standardVect, rotatedVect);
                }

                ThrusterType type;
                switch (thrustType)
                {
                    case ThrusterTypeValues.Single:
                        type = ThrusterType.One;
                        break;

                    case ThrusterTypeValues.Dual:
                        type = ThrusterType.Two;
                        break;

                    case ThrusterTypeValues.Six:
                        type = ThrusterType.Two_Two_Two;
                        break;

                    case ThrusterTypeValues.Random:
                        type = UtilityCore.GetRandomEnum<ThrusterType>(ThrusterType.Custom);
                        break;

                    default:
                        throw new ApplicationException("Unknown ThrusterTypeValues: " + thrustType.ToString());
                }

                retVal.Add(new ThrusterDNA() { PartType = Thruster.PARTTYPE, Orientation = orientation, Position = position.ToPoint(), Scale = new Vector3D(size, size, size), ThrusterType = type });
            }

            return retVal.ToArray();
        }
        private void btnTowerSpikes_Click(object sender, RoutedEventArgs e)
        {
            const double BASERADIUS = 2d;

            try
            {
                ClearProjectilesAndExplosions();
                ClearBricks();

                #region Figure out how many spikes

                int spikeLimit;

                if (radFew.IsChecked.Value)
                {
                    spikeLimit = 15;
                }
                else if (radNormal.IsChecked.Value)
                {
                    spikeLimit = 20;
                }
                else if (radMany.IsChecked.Value)
                {
                    spikeLimit = 25;
                }
                else if (radExtreme.IsChecked.Value)
                {
                    spikeLimit = 30;
                }
                else
                {
                    MessageBox.Show("Unknow number of bricks", this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                #endregion

                List<Vector3D> prevPositions = new List<Vector3D>();

                for (int cntr = 0; cntr < spikeLimit; cntr++)
                {
                    #region Find non colliding position

                    Vector3D pos2D = new Vector3D();
                    bool havePosition = false;
                    for (int infiniteLoopCntr = 0; infiniteLoopCntr < 100; infiniteLoopCntr++)
                    {
                        // Try this one
                        pos2D = Math3D.GetRandomVector_Circular(20d);

                        havePosition = true;
                        foreach (Vector3D prevPos in prevPositions)
                        {
                            if ((pos2D - prevPos).Length < BASERADIUS * 2)
                            {
                                // Colliding with a previous tower
                                havePosition = false;
                                break;
                            }
                        }

                        if (havePosition)
                        {
                            // This is a unique position, quit trying
                            break;
                        }
                    }

                    if (!havePosition)
                    {
                        // Couldn't find a unique position, quit trying to make towers
                        break;
                    }

                    // Remember the location of this tower
                    prevPositions.Add(pos2D);

                    #endregion

                    BuildSpike(pos2D.ToPoint(), true);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }

        }
        private void btnBigSpinner_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                //Point3D position = Math3D.GetRandomVectorSpherical2D(_rand, 240).ToPoint();

                // I want this to act like a sword, so I don't want it starting in the center
                Vector3D position = new Vector3D(150, 0, 0);
                position = Math3D.RotateAroundAxis(position, new Vector3D(0, 0, 1), Math1D.GetNearZeroValue(Math.PI * 2d));
                position.Z = Math1D.GetNearZeroValue(5d) + 10d;
                Vector3D velocity = new Vector3D(0, 0, 0);
                Vector3D angularVelocity = new Vector3D(0, 0, UtilityCore.GetScaledValue_Capped(.1d, 5d, trkBulletSpeed.Minimum, trkBulletSpeed.Maximum, trkBulletSpeed.Value));

                //Vector3D dirFacingStand = new Vector3D(1, 0, Math3D.GetNearZeroValue(_rand, .01d));
                //Vector3D dirFacingOrth = new Vector3D(0, 0, 1);
                //dirFacingOrth = dirFacingOrth.GetRotatedVector(new Vector3D(0, -1, 0), Vector3D.AngleBetween(new Vector3D(1, 0, 0), dirFacingStand));
                //DoubleVector directionFacing = new DoubleVector(dirFacingStand, dirFacingOrth);

                DoubleVector directionFacing = _defaultDirectionFacing.GetRotatedVector(new Vector3D(0, 1, 0), Math1D.GetNearZeroValue(1d));

                Vector3D size = new Vector3D(350d, 7d, .25d);

                AddCannonBall(CollisionShapeType.Box, Colors.Silver, size, 3000d, position.ToPoint(), velocity, angularVelocity, directionFacing);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
Beispiel #15
0
 /// <summary>
 /// This is a helper method that transforms the position in local coords to the position in world coords
 /// </summary>
 public Vector3D PositionToWorld(Vector3D positionLocal)
 {
     //NOTE:  This transform method acts different based on whether a vector or point is passed in
     return this.VisualMatrix.Transform(positionLocal.ToPoint()).ToVector();
 }
            private static bool CanCounterVectors2(Vector3D[] tests, Vector3D[] others)
            {
                Vector3D cumulative = new Vector3D();
                foreach (Vector3D test in tests)
                {
                    cumulative += test;
                }

                // Make the cumulative point the opposite way (that's what all the tests need)
                cumulative = cumulative * -1d;

                // Check for 0D, 1D, 2D, 3D opposition
                if (others.Length == 0)
                {
                    #region 0D

                    // Nothing to oppose.  The only thing that works is if the test self cancel
                    return Math3D.IsNearZero(cumulative);

                    #endregion
                }
                else if (others.Length == 1)
                {
                    #region 1D

                    // Opposition is a single line
                    // If cumulative's length is longer, then the other is overwhelmed
                    // If the dot product isn't one, then they aren't lined up (cumulative has already been negated)
                    return cumulative.LengthSquared <= others[0].LengthSquared && Math1D.IsNearValue(Vector3D.DotProduct(cumulative.ToUnit(), others[0].ToUnit()), 1d);

                    #endregion
                }
                else if (others.Length == 2)
                {
                    #region 2D

                    // Opposition forms a parallelagram
                    Triangle triangle = new Triangle(new Point3D(0, 0, 0), others[0].ToPoint(), others[1].ToPoint());
                    if (!Math1D.IsNearZero(Vector3D.DotProduct(triangle.Normal, cumulative)))
                    {
                        return false;
                    }

                    Vector bary = Math3D.ToBarycentric(triangle, cumulative.ToPoint());
                    return bary.X >= 0d && bary.Y >= 0d && bary.X + bary.Y <= 2d;

                    #endregion
                }
                else
                {
                    #region 3D

                    //NOTE: The reason there is no need to check for 4D, 5D, etc is because cumulative is a 3D vector

                    // Build the hull out of others
                    Point3D[] extremes = GetRemainingExtremes(others, new int[0]);

                    TriangleIndexed[] hull = Math3D.GetConvexHull(extremes);
                    if (hull != null)
                    {
                        return Math3D.IsInside_Planes(hull, cumulative.ToPoint());
                    }

                    // If hull is null, the points could be coplanar, so try 2D
                    var perimiter = Math2D.GetConvexHull(extremes);
                    if (perimiter != null)
                    {
                        // These are coplanar, see if the cumulative is inside
                        Point? cumulative2D = perimiter.GetTransformedPoint(cumulative.ToPoint());

                        if (cumulative2D == null)
                        {
                            return false;
                        }
                        else
                        {
                            return perimiter.IsInside(cumulative2D.Value);
                        }
                    }

                    return false;

                    #endregion
                }
            }
Beispiel #17
0
        public Vector3D PositionFromWorld(Vector3D positionWorld)
        {
            Matrix3D matrix = this.VisualMatrix;
            matrix.Invert();

            //NOTE:  This transform method acts different based on whether a vector or point is passed in
            return matrix.Transform(positionWorld.ToPoint()).ToVector();
        }
        private void CreateSpaceStations()
        {
            double minDistanceBetweenStations = 200d;

            List<SpaceStation> stations = new List<SpaceStation>();

            #region Home Station

            // The center has become too violent

            //// 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(Math3D.GetRandomVectorSpherical(10d), Math3D.GetNearZeroValue(360d));

            //CreateSpaceStationsSprtBuild(homeLocation.ToPoint(), stations);

            #endregion

            // Make a few more
            for (int cntr = 0; cntr < 5; 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(_boundryMin.ToVector() * .7d, _boundryMax.ToVector() * .7d);

                    // See if this is too close to an existing station
                    bool isTooClose = false;
                    foreach (SpaceStation station in stations)
                    {
                        Vector3D offset = position - station.PositionWorld.ToVector();
                        if (offset.Length < minDistanceBetweenStations)
                        {
                            isTooClose = true;
                            break;
                        }
                    }

                    if (!isTooClose)
                    {
                        break;
                    }

                    #endregion
                }

                CreateSpaceStationsSprtBuild(position.ToPoint(), stations);
            }
        }
Beispiel #19
0
 public static MeshGeometry3D GetCube_IndependentFaces(Vector3D min, Vector3D max)
 {
     return GetCube_IndependentFaces(min.ToPoint(), max.ToPoint());
 }
Beispiel #20
0
        private void Brain_TowardCenterOfFlock()
        {
            // Calculate the center of position of the flock
            //TODO:  Have a vision limit

            Vector3D centerPosition = new Vector3D(0, 0, 0);
            foreach (SwarmBot1 bot in _otherBots)
            {
                centerPosition += bot.PhysicsBody.PositionToWorld(bot.PhysicsBody.CenterOfMass).ToVector();
            }

            if (_otherBots.Count > 0)       // can't divide by zero
            {
                centerPosition /= _otherBots.Count;
            }

            // Figure out what direction to go in local coords
            Vector3D flockCenterDirection = StraightToTarget_VelocityAware1Worker(centerPosition.ToPoint());





            // Now that I know where to go, rotate the original thruster direction (0,1,0) to line up with the desired direction
            Vector3D axis;
            double radians;
            Math3D.GetRotation(out axis, out radians, _origThrustDirection, flockCenterDirection);

            // Thrust Direction
            _thrustTransform = new RotateTransform3D(new AxisAngleRotation3D(axis, Math1D.RadiansToDegrees(radians)));

            // Thrust Strength
            if (_isAttacking)
            {
                _thrustPercent = 1d;
            }
            else
            {
                _thrustPercent = .5d;
            }
        }
        private void AddRope(Point3D bodyAttachPoint, Point3D anchorPoint, double? radianLimit)
        {
            const double SEGMENTLENGTH = .25d;

            if (_body == null)
            {
                throw new InvalidOperationException("The body must be created before this method is called");
            }

            // Figure out how many rope segments to make
            Vector3D dir = anchorPoint - bodyAttachPoint;
            int numSegments = Convert.ToInt32(dir.Length / SEGMENTLENGTH);
            if (numSegments == 0)
            {
                numSegments = 1;
            }

            double segmentLength = dir.Length / numSegments;

            DoubleVector dirDbl = new DoubleVector(dir, Math3D.GetArbitraryOrhonganal(dir));

            #region Anchor

            #region WPF Model

            // Material
            MaterialGroup materials = new MaterialGroup();
            materials.Children.Add(new DiffuseMaterial(new SolidColorBrush(_colors.Anchor)));
            materials.Children.Add(_colors.AnchorSpecular);

            // Geometry Mesh
            MeshGeometry3D mesh = UtilityWPF.GetSphere_LatLon(5, .1d);

            // Geometry Model
            GeometryModel3D geometry = new GeometryModel3D();
            geometry.Material = materials;
            geometry.BackMaterial = materials;
            geometry.Geometry = mesh;

            // Transform
            Transform3DGroup transform = new Transform3DGroup();		// rotate needs to be added before translate
            //rotation = _defaultDirectionFacing.GetAngleAroundAxis(dirDbl);
            //transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(rotation)));
            transform.Children.Add(new TranslateTransform3D(anchorPoint.ToVector()));

            // Model Visual
            ModelVisual3D model = new ModelVisual3D();
            model.Content = geometry;
            model.Transform = transform;

            #endregion

            // Body
            CollisionHull hull = CollisionHull.CreateNull(_world);
            Body body = new Body(hull, model.Transform.Value, 0, new Visual3D[] { model });
            hull.Dispose();

            _anchorBodies.Add(body);

            // Add to the viewport
            _viewport.Children.Add(model);

            #endregion

            #region Rope

            for (int cntr = 0; cntr < numSegments; cntr++)
            {
                #region WPF Model

                // Material
                materials = new MaterialGroup();
                materials.Children.Add(new DiffuseMaterial(new SolidColorBrush(_colors.Rope)));
                materials.Children.Add(_colors.RopeSpecular);

                // Geometry Mesh
                mesh = UtilityWPF.GetCylinder_AlongX(7, .03d, segmentLength);
                CollisionHull ropeHull = CollisionHull.CreateCylinder(_world, 0, .03d, segmentLength, null);

                // Geometry Model
                geometry = new GeometryModel3D();
                geometry.Material = materials;
                geometry.BackMaterial = materials;
                geometry.Geometry = mesh;

                // Transform
                transform = new Transform3DGroup();		// rotate needs to be added before translate
                //Quaternion rotation = _defaultDirectionFacing.GetAngleAroundAxis(dirDbl);

                Vector3D axisStandard;
                double radiansStandard;
                Math3D.GetRotation(out axisStandard, out radiansStandard, _defaultDirectionFacing.Standard, dirDbl.Standard);
                Quaternion rotationStandard = new Quaternion(axisStandard, Math1D.RadiansToDegrees(radiansStandard));

                //Vector3D axisOrth;
                //double radiansOrth;
                //Math3D.GetRotation(out axisOrth, out radiansOrth, _defaultDirectionFacing.Orth, dirDbl.Orth);
                //Quaternion rotationOrth = new Quaternion(axisOrth, Math3D.RadiansToDegrees(radiansOrth));

                //Quaternion rotation = rotationStandard.ToUnit() * rotationOrth.ToUnit();
                //Quaternion rotation = rotationOrth;
                Quaternion rotation = rotationStandard;		// adding the orth in just messes it up

                transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(rotation)));
                Vector3D segmentPosition = new Vector3D((segmentLength / 2d) + (segmentLength * cntr), 0, 0);
                segmentPosition = rotation.GetRotatedVector(segmentPosition);
                segmentPosition += bodyAttachPoint.ToVector();
                transform.Children.Add(new TranslateTransform3D(segmentPosition));

                // Model Visual
                model = new ModelVisual3D();
                model.Content = geometry;
                model.Transform = transform;

                #endregion

                // Body
                body = new Body(ropeHull, model.Transform.Value, .1, new Visual3D[] { model });
                ropeHull.Dispose();

                #region Joint

                if (cntr == 0)
                {
                    _ropeJoints.Add(JointBallAndSocket.CreateBallAndSocket(_world, bodyAttachPoint, _body, body));
                }
                else
                {
                    Vector3D connectPosition2 = new Vector3D(segmentLength * cntr, 0, 0);
                    connectPosition2 = rotation.GetRotatedVector(connectPosition2);
                    connectPosition2 += bodyAttachPoint.ToVector();

                    _ropeJoints.Add(JointBallAndSocket.CreateBallAndSocket(_world, connectPosition2.ToPoint(), _ropeBodies[_ropeBodies.Count - 1], body));
                }

                if (cntr == numSegments - 1)
                {
                    Vector3D connectPosition1 = new Vector3D(segmentLength * numSegments, 0, 0);
                    connectPosition1 = rotation.GetRotatedVector(connectPosition1);
                    connectPosition1 += bodyAttachPoint.ToVector();

                    _ropeJoints.Add(JointBallAndSocket.CreateBallAndSocket(_world, connectPosition1.ToPoint(), body, _anchorBodies[_anchorBodies.Count - 1]));
                }

                #endregion

                _ropeBodies.Add(body);

                // Add to the viewport
                _viewport.Children.Add(model);
            }

            if (radianLimit != null)
            {
                for (int cntr = 0; cntr < _ropeJoints.Count - 1; cntr++)		// the connection between the anchor point and rope will never have a limit
                {
                    ((JointBallAndSocket)_ropeJoints[cntr]).SetConeLimits(dir, radianLimit.Value, null);
                }
            }

            #endregion
        }
        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());
            }
        }