Example #1
0
                // Mineral
                public AsteroidOrMineralDefinition(PartSeparator_Part part, MineralDNA mineralDefinition)
                {
                    this.IsAsteroid = false;
                    this.Part = part;

                    this.MineralDefinition = mineralDefinition;

                    this.AsteroidTriangles = null;
                    this.AsteroidRadius = 0;
                }
Example #2
0
        public Inventory(MineralDNA mineral)
        {
            this.Ship = null;
            this.Part = null;
            this.Mineral = mineral;

            this.Count = 1;

            this.Volume = mineral.Volume;
            this.Mass = mineral.Density * mineral.Volume;

            this.Token = TokenGenerator.NextToken();
        }
            private ChangeInstruction(Point3D add_Position, Vector3D add_Velocity, Vector3D add_AngVel, AsteroidDNA asteroid, MineralDNA mineral, Asteroid[] remove_Asteroids, Mineral[] remove_Minerals)
            {
                this.InstructionType = MapPopulationManager.InstructionType.Merge;

                this.Add_Position = add_Position;
                this.Add_Velocity = add_Velocity;
                this.Add_AngVel = add_AngVel;

                this.Asteroid = asteroid;
                this.Mineral = mineral;

                this.Remove_Asteroids = remove_Asteroids;
                this.Remove_Minerals = remove_Minerals;
            }
 public ChangeInstruction(Point3D add_Position, Vector3D add_Velocity, Vector3D add_AngVel, MineralDNA mineral, Mineral[] remove_Minerals)
     : this(add_Position, add_Velocity, add_AngVel, null, mineral, null, remove_Minerals) { }
Example #5
0
            private static Tuple<int, MineralDNA[]>[] DistributeMinerals(MineralDNA[] mineralDefinitions, int[] destroyedIndicies)
            {
                // I was going to keep track of burdens, and assign each mineral to the least burdened shard, with some
                // randomness.  But that would be a lot of sorting and divisions and resorting
                //
                // There won't be enough minerals or destroyed shards to make all that effort worthwhile
                //
                // So instead, just randomly assigning them

                Random rand = StaticRandom.GetRandomForThread();

                List<MineralDNA>[] building = Enumerable.Range(0, destroyedIndicies.Length).
                    Select(o => new List<MineralDNA>()).
                    ToArray();

                foreach (MineralDNA mineral in mineralDefinitions)
                {
                    building[rand.Next(building.Length)].Add(mineral);
                }

                return Enumerable.Range(0, building.Length).
                    Select(o => Tuple.Create(destroyedIndicies[o], building[o].ToArray())).
                    Where(o => o.Item2.Length > 0).
                    ToArray();
            }
Example #6
0
            /// <summary>
            /// This will convert to real minerals, pull them apart, and place them on the map
            /// NOTE: If these are replacing an asteroid, be sure the asteroid is removed before calling this
            /// </summary>
            public void PlaceMinerals(MineralDNA[] minerals, Point3D position, Vector3D velocity, double? maxRandomVelocity = null)
            {
                //TODO: Angular velocity
                AsteroidOrMineralDefinition[] positioned = PositionMinerals(minerals, maxRandomVelocity);

                IMapObject[] mapObjects = ConvertToMapObjects(positioned, position, velocity, Quaternion.Identity);

                AddToMap(mapObjects);
            }
Example #7
0
                // Mineral
                public AsteroidOrMineralDefinition(PartSeparator_Part part, MineralDNA mineralDefinition, Vector3D velocity)
                {
                    this.IsAsteroid = false;
                    this.Part = part;

                    this.MineralDefinition = mineralDefinition;

                    this.Velocity = velocity;

                    this.AsteroidTriangles = null;
                    this.AsteroidRadius = 0;
                    this.ShouldAsteroidSelfDestruct = false;
                }
Example #8
0
                // Asteroid
                public AsteroidOrMineralDefinition(PartSeparator_Part part, ITriangleIndexed[] asteroidTriangles, double asteroidRadius, Vector3D velocity, bool shouldSelfDestruct, MineralDNA[] mineralsAfterSelfDestruct)
                {
                    this.IsAsteroid = true;
                    this.Part = part;

                    this.AsteroidTriangles = asteroidTriangles;
                    this.AsteroidRadius = asteroidRadius;
                    this.ShouldAsteroidSelfDestruct = shouldSelfDestruct;
                    this.MineralsAfterSelfDestruct = mineralsAfterSelfDestruct;

                    this.Velocity = velocity;

                    this.MineralDefinition = null;
                }
Example #9
0
            /// <summary>
            /// Defines the child asteroid shapes, then finds positions/orientations for all child asteroids and minerals (makes
            /// sure nothing overlaps)
            /// </summary>
            private AsteroidOrMineralDefinition[] PositionChildAsteroidsAndMinerals(double[] asteroidVolumes, MineralDNA[] mineralDefinitions)
            {
                const double FOURTHIRDSPI = 4d / 3d * Math.PI;
                const double ONETHRID = 1d / 3d;

                double positionRange = _radiusMin * .05;

                #region Asteroids

                PartSeparator_Part[] asteroidParts = new PartSeparator_Part[asteroidVolumes.Length];
                ITriangleIndexed[][] asteroidTriangles = new ITriangleIndexed[asteroidVolumes.Length][];
                double[] asteroidRadii = new double[asteroidVolumes.Length];

                for (int cntr = 0; cntr < asteroidVolumes.Length; cntr++)
                {
                    // r^3=v/(4/3pi)
                    asteroidRadii[cntr] = Math.Pow(asteroidVolumes[cntr] / FOURTHIRDSPI, ONETHRID);

                    asteroidTriangles[cntr] = GetHullTriangles_Initial(asteroidRadii[cntr]);

                    double currentMass = _getMassByRadius(asteroidRadii[cntr], asteroidTriangles[cntr]);

                    asteroidParts[cntr] = new PartSeparator_Part(asteroidTriangles[cntr][0].AllPoints, currentMass, Math3D.GetRandomVector_Spherical(positionRange).ToPoint(), Math3D.GetRandomRotation());
                }

                #endregion
                #region Minerals

                PartSeparator_Part[] mineralParts = new PartSeparator_Part[mineralDefinitions.Length];

                for (int cntr = 0; cntr < mineralDefinitions.Length; cntr++)
                {
                    //NOTE: Copied logic from Mineral that gets collision points and mass

                    // Points
                    Point3D[] mineralPoints = UtilityWPF.GetPointsFromMesh((MeshGeometry3D)_sharedVisuals.Value.GetMineralMesh(mineralDefinitions[cntr].MineralType));

                    // Mass
                    double mass = mineralDefinitions[cntr].Density * mineralDefinitions[cntr].Volume;

                    // Store it
                    mineralParts[cntr] = new PartSeparator_Part(mineralPoints, mass, Math3D.GetRandomVector_Spherical(positionRange).ToPoint(), Math3D.GetRandomRotation());
                }

                #endregion

                #region Pull Apart

                if (asteroidParts.Length + mineralParts.Length > 1)
                {
                    PartSeparator_Part[] allParts = UtilityCore.ArrayAdd(asteroidParts, mineralParts);

                    bool dummy;
                    CollisionHull[] hulls = PartSeparator.Separate(out dummy, allParts, _world);

                    foreach (CollisionHull hull in hulls)
                    {
                        hull.Dispose();
                    }
                }

                #endregion

                #region Build Return

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

                for (int cntr = 0; cntr < asteroidParts.Length; cntr++)
                {
                    retVal.Add(new AsteroidOrMineralDefinition(asteroidParts[cntr], asteroidTriangles[cntr], asteroidRadii[cntr]));
                }

                for (int cntr = 0; cntr < mineralParts.Length; cntr++)
                {
                    retVal.Add(new AsteroidOrMineralDefinition(mineralParts[cntr], mineralDefinitions[cntr]));
                }

                #endregion

                return retVal.ToArray();
            }
Example #10
0
            // This also creates minerals
            private IMapObject[] GetChildAsteroids(double overDamage, Point3D parentPos, Vector3D parentVel)
            {
                const double MAXOVERDMG = 13;       // overdamage of 1 is the smallest value (the asteroid was barely destroyed).  Larger values are overkill, and the asteroid becomes more fully destroyed
                const int MAXCHILDREN = 5;

                #region Child asteroid sizes

                // Figure out the radius of the child asteroids
                double radius = GetTotalChildRadius(_radius, overDamage, MAXOVERDMG);

                // Get the volumes of the child asteroids
                double[] asteroidVolumes = null;
                if (radius > _minChildRadius)
                {
                    double totalVolume = 4d / 3d * Math.PI * radius * radius * radius;
                    double minVolume = 4d / 3d * Math.PI * _minChildRadius * _minChildRadius * _minChildRadius;

                    int numChildren = GetNumChildren(radius, MAXCHILDREN, totalVolume, minVolume, overDamage, MAXOVERDMG);
                    asteroidVolumes = GetChildVolumes(numChildren, totalVolume, minVolume);
                }
                else
                {
                    // Not enough left, don't create any child asteroids
                    radius = 0;
                    asteroidVolumes = new double[0];
                }

                #endregion
                #region Mineral sizes

                MineralDNA[] mineralDefinitions = null;
                if (_getMineralsByDestroyedMass != null)
                {
                    //double destroyedMass = GetDestroyedMass(Math3D.Avg(_radius.X, _radius.Y, _radius.Z), radius, _getMassByRadius);       // using avg had too many cases where the returned mass was negative
                    double destroyedMass = GetDestroyedMass(Math1D.Max(_radius.X, _radius.Y, _radius.Z), radius, _getMassByRadius);
                    if (destroyedMass > 0)      // child radius is calculated using max of _radius, but avg was passed to the getmass method.  So there's a chance that getmass returns negative
                    {
                        mineralDefinitions = _getMineralsByDestroyedMass(destroyedMass);
                    }
                }

                if (mineralDefinitions == null)
                {
                    mineralDefinitions = new MineralDNA[0];
                }

                #endregion

                if (asteroidVolumes.Length == 0 && mineralDefinitions.Length == 0)
                {
                    // Nothing to spawn
                    return null;
                }

                // Figure out positions
                AsteroidOrMineralDefinition[] children = PositionChildAsteroidsAndMinerals(asteroidVolumes, mineralDefinitions);

                #region Create IMapObjects

                IMapObject[] retVal = new IMapObject[children.Length];

                for (int cntr = 0; cntr < retVal.Length; cntr++)
                {
                    Point3D position = parentPos + children[cntr].Part.Position.ToVector();

                    if (children[cntr].IsAsteroid)
                    {
                        // Asteroid
                        AsteroidExtra extra = new AsteroidExtra()
                        {
                            Triangles = children[cntr].AsteroidTriangles,
                            GetMineralsByDestroyedMass = _getMineralsByDestroyedMass,
                            MineralMaterialID = _mineralMaterialID,
                            MinChildRadius = _minChildRadius,
                        };

                        retVal[cntr] = new Asteroid(children[cntr].AsteroidRadius, _getMassByRadius, position, _world, _map, _materialID, extra);
                    }
                    else
                    {
                        // Mineral
                        MineralDNA mindef = children[cntr].MineralDefinition;
                        double densityMult = mindef.Density / Mineral.GetSettingsForMineralType(mindef.MineralType).Density;
                        retVal[cntr] = new Mineral(mindef.MineralType, position, mindef.Volume, _world, _mineralMaterialID, _sharedVisuals.Value, densityMult, mindef.Scale);
                    }

                    retVal[cntr].PhysicsBody.Rotation = children[cntr].Part.Orientation;

                    Vector3D velFromCenter = children[cntr].Part.Position.ToVector().ToUnit(false);
                    velFromCenter *= UtilityCore.GetScaledValue(1, 4, 1, MAXOVERDMG, overDamage);

                    retVal[cntr].PhysicsBody.Velocity = parentVel + velFromCenter;

                    retVal[cntr].PhysicsBody.AngularVelocity = Math3D.GetRandomVector_Spherical(UtilityCore.GetScaledValue(.5, 8, 1, MAXOVERDMG, overDamage));
                }

                #endregion

                return retVal;
            }
Example #11
0
            private AsteroidOrMineralDefinition[] PositionMinerals(MineralDNA[] minerals, double? maxRandomVelocity)
            {
                double positionRange = _radiusMin * .05;

                #region build parts

                PartSeparator_Part[] parts = new PartSeparator_Part[minerals.Length];

                for (int cntr = 0; cntr < minerals.Length; cntr++)
                {
                    //NOTE: Copied logic from Mineral that gets collision points and mass

                    // Points
                    Point3D[] mineralPoints = UtilityWPF.GetPointsFromMesh((MeshGeometry3D)_sharedVisuals.Value.GetMineralMesh(minerals[cntr].MineralType));

                    // Mass
                    double mass = minerals[cntr].Density * minerals[cntr].Volume;

                    // Store it
                    parts[cntr] = new PartSeparator_Part(mineralPoints, mass, Math3D.GetRandomVector_Spherical(positionRange).ToPoint(), Math3D.GetRandomRotation());
                }

                #endregion

                #region pull apart

                if (parts.Length > 1)
                {
                    bool dummy;
                    CollisionHull[] hulls = PartSeparator.Separate(out dummy, parts, _world);

                    foreach (CollisionHull hull in hulls)
                    {
                        hull.Dispose();
                    }
                }

                #endregion

                #region build return

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

                for (int cntr = 0; cntr < parts.Length; cntr++)
                {
                    Vector3D velocity = new Vector3D(0, 0, 0);
                    if (maxRandomVelocity != null)
                    {
                        velocity = Math3D.GetRandomVector_Spherical(maxRandomVelocity.Value);
                    }

                    retVal.Add(new AsteroidOrMineralDefinition(parts[cntr], minerals[cntr], velocity));
                }

                #endregion

                return retVal.ToArray();
            }