public Inventory(ShipPartDNA part) { this.Ship = null; this.Part = part; this.Mineral = null; this.Count = 1; this.Volume = Math1D.Avg(part.Scale.X, part.Scale.Y, part.Scale.Z); this.Mass = 1; this.Token = TokenGenerator.NextToken(); }
public Icon3D(ShipPartDNA dna, EditorOptions options) { InitializeComponent(); // Need to set position to zero, or the image won't be centered (part's model considers position/orientation) dna = ShipPartDNA.Clone(dna); dna.Position = new Point3D(); dna.Orientation = Quaternion.Identity; PartDesignBase part = BotConstructor.GetPartDesign(dna, options, false); this.ItemName = part.PartType; this.Part = part; lblName.Text = this.ItemName; lblName.Visibility = _showName ? Visibility.Visible : Visibility.Collapsed; InitializeTrackball(); RenderPart(); InitializeLight(); }
internal static void GetMass(out double mass, out double volume, out double radius, out Vector3D actualScale, ShipPartDNA dna, ItemOptions itemOptions) { double radiusLocal = ((dna.Scale.X * SensorVisionDesign.SIZEPERCENTOFSCALE_XY) + (dna.Scale.Y * SensorVisionDesign.SIZEPERCENTOFSCALE_XY)) / (2d * 2d); // scale is diameter, so divide an extra two to get radius double heightLocal = dna.Scale.Z * SensorVisionDesign.SIZEPERCENTOFSCALE_Z; double halfHeightLocal = heightLocal / 2d; volume = Math.PI * radiusLocal * radiusLocal * heightLocal; // get volume of the cylinder // This isn't the radius of the cylinder, it is the radius of the bounding sphere radius = Math.Sqrt((radiusLocal * radiusLocal) + (halfHeightLocal * halfHeightLocal)); mass = volume * itemOptions.Sensor_Density; actualScale = new Vector3D(dna.Scale.X * SensorVisionDesign.SIZEPERCENTOFSCALE_XY, dna.Scale.Y * SensorVisionDesign.SIZEPERCENTOFSCALE_XY, dna.Scale.Z * SensorVisionDesign.SIZEPERCENTOFSCALE_Z); }
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); } }
public SensorVision(EditorOptions options, ItemOptionsArco itemOptions, ShipPartDNA dna, Map map, double searchRadius, Type filterType = null) : base(options, dna, itemOptions.VisionSensor_Damage.HitpointMin, itemOptions.VisionSensor_Damage.HitpointSlope, itemOptions.VisionSensor_Damage.Damage) { _itemOptions = itemOptions; _map = map; _filterType = filterType; this.Design = new SensorVisionDesign(options, true); this.Design.SetDNA(dna); double radius, volume; GetMass(out _mass, out volume, out radius, out _scaleActual, dna, itemOptions); this.Radius = radius; _neurons = CreateNeurons(dna, itemOptions, itemOptions.VisionSensor_NeuronDensity, true, true); #region Store stats about neurons if (_neurons.Length == 0) { throw new ApplicationException("CreateNeurons should have guaranteed at least one neuron"); } else if (_neurons.Length == 1) { // Since the neuron was forced to not be at the origin, just take the offset from origin (a single neuron vision // field is pretty useless anyway) _neuronDistBetween = _neurons[0].Position.ToVector().Length; } else { // Get the distance between each neuron List<Tuple<int, int, double>> distances = new List<Tuple<int, int, double>>(); for (int outer = 0; outer < _neurons.Length - 1; outer++) { for (int inner = outer + 1; inner < _neurons.Length; inner++) { double distance = (_neurons[outer].Position - _neurons[inner].Position).LengthSquared; distances.Add(Tuple.Create(outer, inner, distance)); } } // Get the average of the minimum distance of each index _neuronDistBetween = Enumerable.Range(0, _neurons.Length). Select(o => distances. Where(p => p.Item1 == o || p.Item2 == o). // get the disances that mention this index Min(p => p.Item3)). // only keep the smallest of those distances Average(); // get the average of all the mins } // Find the one that's farthest away from the origin (since they form a circle, there will be an outer ring of them that // are about the same distance from the center) _neuronMaxRadius = _neurons.Max(o => o.PositionLength); #endregion this.SearchRadius = searchRadius; // need to set this last, because it populates _distProps }
private void CreateBrains(ShipPartDNA[] dna) { if (_brains != null) { throw new InvalidOperationException("Existing brains should have been wiped out before calling CreateBrains"); } _brains = new BrainStuff[dna.Length]; for (int cntr = 0; cntr < dna.Length; cntr++) { _brains[cntr] = new BrainStuff(); BrainStuff brain = _brains[cntr]; brain.Brain = new Brain(_editorOptions, _itemOptions, dna[cntr], _containers == null ? null : _containers.Energy); brain.DNAInternalLinks = dna[cntr].InternalLinks; brain.DNAExternalLinks = dna[cntr].ExternalLinks; #region Ship Visual // WPF ModelVisual3D model = new ModelVisual3D(); model.Content = brain.Brain.Model; _viewport.Children.Add(model); brain.Visual = model; // Physics using (CollisionHull hull = brain.Brain.CreateCollisionHull(_world)) { brain.Body = new Body(hull, Matrix3D.Identity, brain.Brain.TotalMass, new Visual3D[] { model }); brain.Body.MaterialGroupID = _material_Ship; brain.Body.LinearDamping = .01f; brain.Body.AngularDamping = new Vector3D(.01f, .01f, .01f); } #endregion #region Neuron Visuals BuildNeuronVisuals(out brain.Neurons, out model, brain.Brain.Neruons_All, brain.Brain, _colors); brain.NeuronVisual = model; _viewportNeural.Children.Add(model); #endregion } UpdateCountReport(); }
private void CreateContainers(ShipPartDNA energyDNA, ShipPartDNA fuelDNA) { if (_containers != null) { throw new InvalidOperationException("Existing containers should have been wiped out before calling CreateContainers"); } _containers = new ContainerStuff(); // Energy _containers.Energy = new EnergyTank(_editorOptions, _itemOptions, energyDNA); _containers.Energy.QuantityCurrent = _containers.Energy.QuantityMax; // Fuel _containers.Fuel = new FuelTank(_editorOptions, _itemOptions, fuelDNA); _containers.Fuel.QuantityCurrent = _containers.Fuel.QuantityMax; #region Ship Visuals (energy) // WPF ModelVisual3D model = new ModelVisual3D(); model.Content = _containers.Energy.Model; _viewport.Children.Add(model); _containers.EnergyVisual = model; // Physics CollisionHull hull = _containers.Energy.CreateCollisionHull(_world); _containers.EnergyBody = new Body(hull, Matrix3D.Identity, _containers.Energy.TotalMass, new Visual3D[] { model }); hull.Dispose(); _containers.EnergyBody.MaterialGroupID = _material_Ship; _containers.EnergyBody.LinearDamping = .01f; _containers.EnergyBody.AngularDamping = new Vector3D(.01f, .01f, .01f); #endregion #region Ship Visuals (fuel) // WPF model = new ModelVisual3D(); model.Content = _containers.Fuel.Model; _viewport.Children.Add(model); _containers.FuelVisual = model; // Physics hull = _containers.Fuel.CreateCollisionHull(_world); _containers.FuelBody = new Body(hull, Matrix3D.Identity, _containers.Fuel.TotalMass, new Visual3D[] { model }); hull.Dispose(); _containers.FuelBody.MaterialGroupID = _material_Ship; _containers.FuelBody.LinearDamping = .01f; _containers.FuelBody.AngularDamping = new Vector3D(.01f, .01f, .01f); #endregion }
private void btnGravitySensor_Click(object sender, RoutedEventArgs e) { try { double size; if (!double.TryParse(txtGravitySensorSize.Text, out size)) { MessageBox.Show("Couldn't parse sensor size", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning); return; } int numSensors; if (!int.TryParse(txtGravitySensorCount.Text, out numSensors)) { MessageBox.Show("Couldn't parse number of sensors", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning); return; } if (numSensors < 1) { MessageBox.Show("The number of sensors must be greater than zero", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning); return; } // Wipe Existing ClearGravSensors(); if (_containers == null) { CreateContainers(); } // Build DNA ShipPartDNA dna = new ShipPartDNA(); dna.PartType = SensorGravity.PARTTYPE; dna.Position = new Point3D(-1.5, 0, 0); dna.Orientation = Quaternion.Identity; dna.Scale = new Vector3D(size, size, size); ShipPartDNA[] gravDNA = new ShipPartDNA[numSensors]; for (int cntr = 0; cntr < numSensors; cntr++) { if (numSensors == 1) { gravDNA[cntr] = dna; } else { ShipPartDNA dnaCopy = ShipPartDNA.Clone(dna); double angle = 360d / Convert.ToDouble(numSensors); dnaCopy.Position += new Vector3D(0, .75, 0).GetRotatedVector(new Vector3D(1, 0, 0), angle * cntr); gravDNA[cntr] = dnaCopy; } } // Build/show sensors CreateGravSensors(gravDNA); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private static void ModifyDNA(ShipPartDNA dna, bool randSize, bool randOrientation) { if (randSize) { dna.Scale = Math3D.GetRandomVector(new Vector3D(.25, .25, .25), new Vector3D(2.5, 2.5, 2.5)); } if (randOrientation) { dna.Orientation = Math3D.GetRandomRotation(); } }
public virtual bool IsEqual(ShipPartDNA dna, bool comparePositionOrientation = false, bool compareNeural = false) { if (dna == null) { return false; } if (this.PartType != dna.PartType) { return false; } if (!Math3D.IsNearValue(this.Scale, dna.Scale)) { return false; } if (comparePositionOrientation) { if (!Math3D.IsNearValue(this.Position, dna.Position)) { return false; } if (!Math3D.IsNearValue(this.Orientation, dna.Orientation)) { return false; } } if (compareNeural) { throw new ApplicationException("finish this"); } return true; }
public static ShipPartDNA Clone(ShipPartDNA dna) { // PartDNA could be a derived type, but since these are designed to be serializable, serialize it to do a deep clone using (MemoryStream stream = new MemoryStream()) { XamlServices.Save(stream, dna); stream.Position = 0; return XamlServices.Load(stream) as ShipPartDNA; } }
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 PartBase GetRandomPart() { Point3D position = Math3D.GetRandomVector(2d).ToPoint(); Quaternion orientation = Math3D.GetRandomRotation(); double radius = 1d + StaticRandom.NextDouble() * 4d; double height = 1d + StaticRandom.NextDouble() * 4d; switch (StaticRandom.Next(8)) { case 0: #region Spin double spinSize = 5d + (StaticRandom.NextDouble() * 8d); ShipPartDNA dnaSpin = new ShipPartDNA() { PartType = SensorSpin.PARTTYPE, Position = position, Orientation = orientation, Scale = new Vector3D(spinSize, spinSize, spinSize) }; return new SensorSpin(_editorOptions, _itemOptions, dnaSpin, null); #endregion case 1: #region Fuel ShipPartDNA dnaFuel = new ShipPartDNA() { PartType = FuelTank.PARTTYPE, Position = position, Orientation = orientation, Scale = new Vector3D(radius, radius, height) }; FuelTank fuel = new FuelTank(_editorOptions, _itemOptions, dnaFuel); fuel.QuantityCurrent = fuel.QuantityMax; // without this, the fuel tank gets tossed around because it's so light return fuel; #endregion case 2: #region Energy ShipPartDNA dnaEnergy = new ShipPartDNA() { PartType = EnergyTank.PARTTYPE, Position = position, Orientation = orientation, Scale = new Vector3D(radius, radius, height) }; return new EnergyTank(_editorOptions, _itemOptions, dnaEnergy); #endregion case 3: #region Brain ShipPartDNA dnaBrain = new ShipPartDNA() { PartType = Brain.PARTTYPE, Position = position, Orientation = orientation, Scale = new Vector3D(radius, radius, radius) }; return new Brain(_editorOptions, _itemOptions, dnaBrain, null); #endregion case 4: #region Thruster ThrusterDNA dnaThruster1 = new ThrusterDNA() { PartType = Thruster.PARTTYPE, Position = position, Orientation = orientation, Scale = new Vector3D(height, height, height), ThrusterType = UtilityCore.GetRandomEnum(ThrusterType.Custom) }; return new Thruster(_editorOptions, _itemOptions, dnaThruster1, null); #endregion case 5: #region Solar ConverterRadiationToEnergyDNA dnaSolar = new ConverterRadiationToEnergyDNA() { PartType = ConverterRadiationToEnergy.PARTTYPE, Position = position, Orientation = orientation, Scale = new Vector3D(height, 1d + StaticRandom.NextDouble() * 4d, 1d), Shape = UtilityCore.GetRandomEnum<SolarPanelShape>() }; return new ConverterRadiationToEnergy(_editorOptions, _itemOptions, dnaSolar, null, _radiation); #endregion case 6: #region Fuel->Energy ShipPartDNA dnaBurner = new ShipPartDNA() { PartType = ConverterFuelToEnergy.PARTTYPE, Position = position, Orientation = orientation, Scale = new Vector3D(radius, radius, height) }; return new ConverterFuelToEnergy(_editorOptions, _itemOptions, dnaBurner, null, null); #endregion case 7: #region Energy->Ammo ShipPartDNA dnaReplicator = new ShipPartDNA() { PartType = ConverterEnergyToAmmo.PARTTYPE, Position = position, Orientation = orientation, Scale = new Vector3D(radius, radius, height) }; return new ConverterEnergyToAmmo(_editorOptions, _itemOptions, dnaReplicator, null, null); #endregion default: throw new ApplicationException("Unexpected integer"); } }
private void btnTwoOdd1_Click(object sender, RoutedEventArgs e) { try { //PartDNA dnaFuel = new PartDNA() { PartType = FuelTank.PARTTYPE, Position = new Point3D(-1d, 0, 0), Orientation = new Quaternion(new Vector3D(1, 1, 0), 90d), Scale = new Vector3D(.25d, .25d, 4d) }; //FuelTank fuel = new FuelTank(_editorOptions, _itemOptions, dnaFuel); //fuel.QuantityCurrent = fuel.QuantityMax; ShipPartDNA dnaEnergy = new ShipPartDNA() { PartType = EnergyTank.PARTTYPE, Position = new Point3D(-1d, 0, 0), Orientation = new Quaternion(new Vector3D(1, 1, 0), 90d), Scale = new Vector3D(.25d, .25d, 4d) }; //PartDNA dnaEnergy = new PartDNA() { PartType = EnergyTank.PARTTYPE, Position = new Point3D(-1d, 0, 0), Orientation = new Quaternion(new Vector3D(1, 1, 0), 10d), Scale = new Vector3D(4d, 4d, .25d) }; EnergyTank energy = new EnergyTank(_editorOptions, _itemOptions, dnaEnergy); //energy.QuantityCurrent = fuel.QuantityMax; ShipPartDNA dnaBrain = new ShipPartDNA() { PartType = Brain.PARTTYPE, Position = new Point3D(0, 0, 0), Orientation = Quaternion.Identity, Scale = new Vector3D(2d, 2d, 2d) }; Brain brain = new Brain(_editorOptions, _itemOptions, dnaBrain, null); //StartScene(new PartBase[] { fuel, brain }); StartScene(new PartBase[] { energy, brain }, 7); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void btnTwoCylinderCylinder_Click(object sender, RoutedEventArgs e) { try { bool isEnergy1 = StaticRandom.Next(2) == 0; bool isEnergy2 = StaticRandom.Next(2) == 0; ShipPartDNA dna1 = new ShipPartDNA() { PartType = isEnergy1 ? EnergyTank.PARTTYPE : FuelTank.PARTTYPE, Position = new Point3D(-.5, -.1, 0), Orientation = Math3D.GetRandomRotation(), Scale = new Vector3D(4, 4, 3) }; ShipPartDNA dna2 = new ShipPartDNA() { PartType = isEnergy2 ? EnergyTank.PARTTYPE : FuelTank.PARTTYPE, Position = new Point3D(.5, .1, 0), Orientation = Math3D.GetRandomRotation(), Scale = new Vector3D(4, 4, 3) }; PartBase cylinder1 = null; if (isEnergy1) { cylinder1 = new EnergyTank(_editorOptions, _itemOptions, dna1); } else { cylinder1 = new FuelTank(_editorOptions, _itemOptions, dna1); } PartBase cylinder2 = null; if (isEnergy2) { cylinder2 = new EnergyTank(_editorOptions, _itemOptions, dna2); } else { cylinder2 = new FuelTank(_editorOptions, _itemOptions, dna2); } StartScene(new PartBase[] { cylinder1, cylinder2 }, 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); } }
internal static Neuron_SensorPosition[] CreateNeurons(ShipPartDNA dna, ItemOptions itemOptions, double neuronDensity, bool hasHoleInMiddle, bool ignoreSetValue) { #region Calculate Counts // Figure out how many to make //NOTE: This radius isn't taking SCALE into account. The other neural parts do this as well, so the neural density properties can be more consistent double radius = (dna.Scale.X + dna.Scale.Y) / (2d * 2d); // XY should always be the same anyway (not looking at Z for this. Z is just to keep the sensors from getting too close to each other) double area = Math.Pow(radius, itemOptions.Sensor_NeuronGrowthExponent); int neuronCount = Convert.ToInt32(Math.Ceiling(neuronDensity * area)); if (neuronCount == 0) { neuronCount = 1; } #endregion Point3D[] staticPositions = null; if (hasHoleInMiddle) { staticPositions = new Point3D[] { new Point3D(0, 0, 0) }; } // Place them evenly within a circle. // I don't want a neuron in the center, so placing a static point there to force the neurons away from the center Vector3D[] positions = Brain.GetNeuronPositions_Even2D(dna.Neurons, staticPositions, 1d, neuronCount, radius); // Exit Function return positions.Select(o => new Neuron_SensorPosition(o.ToPoint(), true, ignoreSetValue)).ToArray(); }
/// <summary> /// NOTE: A final consumer should call PartBase.GetNewDNA() if you want a fully filled out dna. PartDesignBase.GetDNA() is /// for things like editors. It won't have things like neural positions, or memory of activity --- only structural /// /// NOTE: If a derived class has custom props, then you must override this method and return your own derived dna. Don't call /// base.GetDNA, but instead call base.FillDNA, which will fill out the properties that this class knows about /// </summary> public virtual ShipPartDNA GetDNA() { ShipPartDNA retVal = new ShipPartDNA(); FillDNA(retVal); return retVal; }
private DesignPart CreateDesignPart(ShipPartDNA dna) { #region Find ToolItem // Find the corresponding tool item List<PartToolItemBase> toolItems = _partToolItems.Where(o => o.PartType == dna.PartType).ToList(); if (toolItems.Count == 0) { throw new ApplicationException("Couldn't find the tool item for \"" + dna.PartType + "\""); } // Narrow down to one PartToolItemBase toolItem = null; if (toolItems.Count == 1) // if there's more than one, then it needs to be further filtered { toolItem = toolItems[0]; } else if (dna.PartType == ConverterRadiationToEnergy.PARTTYPE) { #region ConverterRadiationToEnergy ConverterRadiationToEnergyDNA dnaCast = (ConverterRadiationToEnergyDNA)dna; List<PartToolItemBase> additionalFilter = toolItems.Where(o => ((ConverterRadiationToEnergyToolItem)o).Shape == dnaCast.Shape).ToList(); if (additionalFilter.Count == 1) { toolItem = additionalFilter[0]; } #endregion } else if (dna.PartType == Thruster.PARTTYPE) { #region Thruster ThrusterDNA dnaCast = (ThrusterDNA)dna; if (dnaCast.ThrusterType == ThrusterType.Custom) { // Make a new one with the dna's directions toolItem = new ThrusterToolItem(editor1.Options, dnaCast.ThrusterDirections, "Custom"); } else { List<PartToolItemBase> additionalFilter = toolItems.Where(o => ((ThrusterToolItem)o).ThrusterType == dnaCast.ThrusterType).ToList(); if (additionalFilter.Count == 1) { toolItem = additionalFilter[0]; } } #endregion } else { throw new ApplicationException("Should have only found one tool item for this part type: " + dna.PartType); } if (toolItem == null) { throw new ApplicationException("Couldn't find the tool item for this part type: " + dna.PartType); } #endregion DesignPart retVal = new DesignPart(editor1.Options); retVal.Part2D = toolItem; retVal.Part3D = toolItem.GetNewDesignPart(); retVal.Part3D.SetDNA(dna); ModelVisual3D visual = new ModelVisual3D(); visual.Content = retVal.Part3D.Model; retVal.Model = visual; return retVal; }
/// <summary> /// This loads this class up with the properties in the dna /// NOTE: This will fix errors in DNA. It changes the object passed in /// </summary> /// <remarks> /// NOTE: If a derived class has custom props, then you must override this method and store your own derived dna. Don't call /// base.SetDNA, but instead call base.StoreDNA, which will store the properties that this class knows about /// /// At first, I wasn't modifying dna, but then noticed PartBase constructor stores this.DNA /// </remarks> public virtual void SetDNA(ShipPartDNA dna) { if (this.PartType != dna.PartType) { throw new ArgumentException(string.Format("The dna passed in is not for this class. DNA={0}, this={1}", dna.PartType, this.PartType)); } StoreDNA(dna); }
private void btnBrain_Click(object sender, RoutedEventArgs e) { try { double size; if (!double.TryParse(txtBrainSize.Text, out size)) { MessageBox.Show("Couldn't parse brain size", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning); return; } int numBrains; if (!int.TryParse(txtBrainCount.Text, out numBrains)) { MessageBox.Show("Couldn't parse number of brains", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning); return; } if (numBrains < 1) { MessageBox.Show("The number of brains must be greater than zero", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning); return; } // Wipe Existing ClearBrains(); if (_containers == null) { CreateContainers(); } // Build DNA ShipPartDNA dna = new ShipPartDNA(); dna.PartType = Brain.PARTTYPE; dna.Position = new Point3D(0, 0, 0); dna.Orientation = Quaternion.Identity; dna.Scale = new Vector3D(size, size, size); dna.Neurons = null; dna.AltNeurons = null; dna.InternalLinks = null; dna.ExternalLinks = null; ShipPartDNA[] brainDNA = new ShipPartDNA[numBrains]; for (int cntr = 0; cntr < numBrains; cntr++) { if (numBrains == 1) { brainDNA[cntr] = dna; } else { ShipPartDNA dnaCopy = ShipPartDNA.Clone(dna); double angle = 360d / Convert.ToDouble(numBrains); dnaCopy.Position += new Vector3D(0, 1, 0).GetRotatedVector(new Vector3D(1, 0, 0), angle * cntr); brainDNA[cntr] = dnaCopy; } } // Build/Show brains CreateBrains(brainDNA); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
/// <summary> /// This will populate the dna class with the values from this base class. You should only bother to override this method if your /// inheritance will go 3+ deep, and each shell can fill up what it knows about /// </summary> protected virtual void FillDNA(ShipPartDNA dna) { dna.PartType = this.PartType; dna.Scale = this.Scale; //NOTE: Scale, Position, Orientation used to store their values in transforms, but GetDNA could come from any thread, so I had to store a threadsafe vector as well as a transform. ugly dna.Position = this.Position; dna.Orientation = this.Orientation; //NOTE: This is done in NeuralUtility.PopulateDNALinks //if(this is INeuronContainer) //{ // dna.Neurons = // dna.AltNeurons = // dna.InternalLinks = // dna.ExternalLinks = //} }
private void CreateGravSensors(ShipPartDNA[] dna) { if (_gravSensors != null) { throw new InvalidOperationException("Existing gravity sensors should have been wiped out before calling CreateGravSensors"); } _gravSensors = new GravSensorStuff[dna.Length]; for (int cntr = 0; cntr < dna.Length; cntr++) { _gravSensors[cntr] = new GravSensorStuff(); _gravSensors[cntr].Sensor = new SensorGravity(_editorOptions, _itemOptions, dna[cntr], _containers == null ? null : _containers.Energy, _gravityField); _gravSensors[cntr].Sensor.RequestWorldLocation += new EventHandler<PartRequestWorldLocationArgs>(Sensor_RequestWorldLocation); #region Ship Visual // WPF ModelVisual3D model = new ModelVisual3D(); model.Content = _gravSensors[cntr].Sensor.Model; //TODO: Offset this if there are multiple parts _viewport.Children.Add(model); _gravSensors[cntr].Visual = model; // Physics using (CollisionHull hull = _gravSensors[cntr].Sensor.CreateCollisionHull(_world)) { _gravSensors[cntr].Body = new Body(hull, Matrix3D.Identity, _gravSensors[cntr].Sensor.TotalMass, new Visual3D[] { model }); _gravSensors[cntr].Body.MaterialGroupID = _material_Ship; _gravSensors[cntr].Body.LinearDamping = .01f; _gravSensors[cntr].Body.AngularDamping = new Vector3D(.01f, .01f, .01f); } #endregion #region Gravity Visual //NOTE: Since the neurons are semitransparent, they need to be added last _gravSensors[cntr].Gravity = new ScreenSpaceLines3D(); _gravSensors[cntr].Gravity.Thickness = 2d; _gravSensors[cntr].Gravity.Color = _colors.TrackballAxisMajorColor; _viewportNeural.Children.Add(_gravSensors[cntr].Gravity); #endregion #region Neuron Visuals BuildNeuronVisuals(out _gravSensors[cntr].Neurons, out model, _gravSensors[cntr].Sensor.Neruons_All, _gravSensors[cntr].Sensor, _colors); _gravSensors[cntr].NeuronVisual = model; _viewportNeural.Children.Add(model); #endregion } UpdateGravity(); // this shows the gravity line UpdateCountReport(); }
/// <summary> /// This is used when saving to DNA. /// Individual parts don't hold links, so when you call PartBase.GetNewDNA, the links will always be null. /// This populates dna.InternalLinks and dna.ExternalLinks based on the links stored in outputs. /// </summary> /// <param name="dna">This is the dna to populate</param> /// <param name="dnaSource">This is the container that the dna came from</param> /// <param name="outputs">This is all of the containers, and their links</param> public static void PopulateDNALinks(ShipPartDNA dna, INeuronContainer dnaSource, IEnumerable<ContainerOutput> outputs) { // Find the output for the source passed in ContainerOutput output = outputs.Where(o => o.Container == dnaSource).FirstOrDefault(); if (output == null) { return; } // Internal dna.InternalLinks = null; if (output.InternalLinks != null) { dna.InternalLinks = output.InternalLinks.Select(o => new NeuralLinkDNA() { From = o.From.Position, To = o.To.Position, Weight = o.Weight, BrainChemicalModifiers = o.BrainChemicalModifiers == null ? null : o.BrainChemicalModifiers.ToArray() // using ToArray to make a copy }).ToArray(); } // External dna.ExternalLinks = null; if (output.ExternalLinks != null) { dna.ExternalLinks = output.ExternalLinks.Select(o => new NeuralLinkExternalDNA() { FromContainerPosition = o.FromContainer.Position, FromContainerOrientation = o.FromContainer.Orientation, From = o.From.Position, To = o.To.Position, Weight = o.Weight, BrainChemicalModifiers = o.BrainChemicalModifiers == null ? null : o.BrainChemicalModifiers.ToArray() // using ToArray to make a copy }).ToArray(); } }
private void CreateContainers() { const double HEIGHT = .07d; const double OFFSET = 1.5d; double offset2 = ((.1d - HEIGHT) / 2d) + (HEIGHT / 2d); ShipPartDNA dnaEnergy = new ShipPartDNA(); dnaEnergy.PartType = EnergyTank.PARTTYPE; dnaEnergy.Position = new Point3D(OFFSET - offset2, 0, 0); dnaEnergy.Orientation = new Quaternion(new Vector3D(0, 1, 0), 90); dnaEnergy.Scale = new Vector3D(1.3, 1.3, HEIGHT); // the energy tank is slightly wider than the fuel tank ShipPartDNA dnaFuel = new ShipPartDNA(); dnaFuel.PartType = FuelTank.PARTTYPE; dnaFuel.Position = new Point3D(OFFSET + offset2, 0, 0); dnaFuel.Orientation = new Quaternion(new Vector3D(0, 1, 0), 90); dnaFuel.Scale = new Vector3D(1.5, 1.5, HEIGHT); CreateContainers(dnaEnergy, dnaFuel); }
private static bool IsInList(List<ShipPartDNA> parts, ShipPartDNA part, bool removeIfFound) { int index = 0; while (index < parts.Count) { if (parts[index].IsEqual(part)) { if (removeIfFound) { parts.RemoveAt(index); } return true; } index++; } return false; }
/// <summary> /// NOTE: This will fix scale /// </summary> protected virtual void StoreDNA(ShipPartDNA dna) { if (this.PartType != dna.PartType) { throw new ArgumentException(string.Format("The dna passed in is not for this class. DNA={0}, this={1}", dna.PartType, this.PartType)); } PartDesignAllowedScale allowedScale = this.AllowedScale; switch (allowedScale) { case PartDesignAllowedScale.XYZ: double scale1 = Math1D.Avg(dna.Scale.X, dna.Scale.Y, dna.Scale.Z); dna.Scale = new Vector3D(scale1, scale1, scale1); break; case PartDesignAllowedScale.XY_Z: double scale2 = Math1D.Avg(dna.Scale.X, dna.Scale.Y); dna.Scale = new Vector3D(scale2, scale2, dna.Scale.Z); break; case PartDesignAllowedScale.None: case PartDesignAllowedScale.X_Y_Z: break; default: throw new ApplicationException("Unknown PartDesignAllowedScale: " + allowedScale); } this.Scale = dna.Scale; this.Position = dna.Position; this.Orientation = dna.Orientation; }
private void btnRGB_Click(object sender, RoutedEventArgs e) { try { if (_offline1 == null) { MessageBox.Show("Start a scene first", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning); return; } ShipPartDNA energyDNA = new ShipPartDNA() { PartType = EnergyTank.PARTTYPE, Orientation = Quaternion.Identity, Position = new Point3D(), Scale = new Vector3D(10, 10, 10) }; EnergyTank energy = new EnergyTank(_editorOptions, _itemOptions, energyDNA); energy.QuantityCurrent = energy.QuantityMax; ShipPartDNA dna = new ShipPartDNA() { PartType = CameraColorRGB.PARTTYPE, Orientation = Quaternion.Identity, Position = new Point3D(0, 0, 0), Scale = new Vector3D(1, 1, 1) }; CameraColorRGB camera = new CameraColorRGB(_editorOptions, _itemOptions, dna, energy, _cameraPool); camera.RequestWorldLocation += new EventHandler<PartRequestWorldLocationArgs>(TestCamera_RequestWorldLocation); //var location = camera.GetWorldLocation_Camera(); //_offline1.SyncCamera(_camera); //IBitmapCustom bitmap = UtilityWPF.RenderControl(_offline1.Control, camera.PixelWidthHeight, camera.PixelWidthHeight, true, Colors.Black, false); //camera.StoreSnapshot(bitmap); camera.Update_MainThread(1); camera.Update_AnyThread(1); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
/// <summary> /// WARNING: This will modify the dna's scale (if the scale is invalid) /// </summary> /// <remarks> /// How these classes get instantiated and shared is a bit odd. Not sure if this is the best way or not. There are two+ different /// paths these parts are used: /// /// Editor: /// PartToolItemBase -> PartDesignBase -> PartDNA /// /// World: /// PartDNA -> PartBase -> (which internally creates PartDesignBase) /// </remarks> public PartBase(EditorOptions options, ShipPartDNA dna, double hitpointMin, double hitpointSlope, TakesDamageWorker damageWorker) { if (dna.PartType != this.PartType) { throw new ArgumentException(string.Format("The dna passed in is not meant for this class. DNA: \"{0}\", this: \"{1}\"", dna.PartType, this.PartType)); } this.Options = options; this.DNA = dna; this.Token = TokenGenerator.NextToken(); // Can't use this.ScaleActual yet double size = Math1D.Avg(dna.Scale.X, dna.Scale.Y, dna.Scale.Z); this.HitPoints_Max = hitpointMin + (size * hitpointSlope); if (dna.PercentDamaged <= 0) { this.HitPoints_Current = this.HitPoints_Max; } else if (dna.PercentDamaged >= 1) { this.HitPoints_Current = 0; } else { this.HitPoints_Current = UtilityCore.GetScaledValue(0, this.HitPoints_Max, 0, 1, 1 - dna.PercentDamaged); } _damageWorker = damageWorker; _initialized = true; }
private void StoreInStation(ShipPartDNA dna) { Inventory inventory = new Inventory(dna); _spaceDock.AddInventory(inventory, true); }