public Vec3D Multiply(double s) { Vec3D r = new Vec3D(this); r.X *= s; r.Y *= s; r.Z *= s; return(r); }
public static bool IsPointInside(Polygon3D poly, Vec3D p) { if (p.Z < poly.bottom || p.Z > poly.top) { return(false); } return(Polygon2D.IsPointInside(poly.footprint, new Vec2D(p.X, p.Y))); }
public Vec3D Add(Vec3D v2) { Vec3D r = new Vec3D(this); r.X += v2.X; r.Y += v2.Y; r.Z += v2.Z; return(r); }
public Vec3D Subtract(Vec3D v2) { Vec3D r = new Vec3D(this); r.X -= v2.X; r.Y -= v2.Y; r.Z -= v2.Z; return(r); }
public Vec3D VectorDistanceTo(Vec3D v2) { Vec3D r = new Vec3D(v2); r.X -= X; r.Y -= Y; r.Z -= Z; return(r); }
public static bool IsPointInside(Polygon3D poly, Vec3D p) { if (p.Z < poly.bottom || p.Z > poly.top) { return false; } return Polygon2D.IsPointInside(poly.footprint, new Vec2D(p.X, p.Y)); }
static public SimulationEvent BuildMoveObjectRequestEvent(ref SimulationModelInfo simModel, int time, string userID, string objectID, Vec3D destination, double throttle) { SimulationEvent sc = SimulationEventFactory.BuildEvent(ref simModel, "MoveObjectRequest"); ((StringValue)sc["UserID"]).value = userID; ((StringValue)sc["ObjectID"]).value = objectID; ((IntegerValue)sc["Time"]).value = time; ((DoubleValue)sc["Throttle"]).value = throttle; sc["DestinationLocation"] = destination.ToLocationValue(); return sc; }
//find t public static double FindT(Vec3D sensorPoint, Vec3D emitterPoint, Vec3D coneDirection) { double t = 0.0; t = coneDirection.X*(emitterPoint.X - sensorPoint.X); t += coneDirection.Y * (emitterPoint.Y - sensorPoint.Y); t += coneDirection.Z * (emitterPoint.Z - sensorPoint.Z); t /= (Math.Pow(coneDirection.X,2)+ Math.Pow(coneDirection.Y,2) + Math.Pow(coneDirection.Z, 2)); return t; }
//find closest point public static Vec3D FindClosestPoint(Vec3D sensingPoint, Vec3D sensingDirection, Vec3D emittingPoint) { Vec3D closestPoint = new Vec3D(sensingPoint); //will add to this when t is defined double t = FindT(sensingPoint, emittingPoint, sensingDirection); closestPoint.X += t * sensingDirection.X; closestPoint.Y += t * sensingDirection.Y; closestPoint.Z += t * sensingDirection.Z; return(closestPoint);//closestPoint; }
//find t public static double FindT(Vec3D sensorPoint, Vec3D emitterPoint, Vec3D coneDirection) { double t = 0.0; t = coneDirection.X * (emitterPoint.X - sensorPoint.X); t += coneDirection.Y * (emitterPoint.Y - sensorPoint.Y); t += coneDirection.Z * (emitterPoint.Z - sensorPoint.Z); t /= (Math.Pow(coneDirection.X, 2) + Math.Pow(coneDirection.Y, 2) + Math.Pow(coneDirection.Z, 2)); return(t); }
//find closest point public static Vec3D FindClosestPoint(Vec3D sensingPoint, Vec3D sensingDirection, Vec3D emittingPoint) { Vec3D closestPoint = new Vec3D(sensingPoint); //will add to this when t is defined double t = FindT(sensingPoint, emittingPoint, sensingDirection); closestPoint.X += t * sensingDirection.X; closestPoint.Y += t * sensingDirection.Y; closestPoint.Z += t * sensingDirection.Z; return closestPoint;//closestPoint; }
//Find obstructions //public static List<string> FindObstructions(List<string> allObstructions, Vec3D sensorPoint, Vec3D emitterPoint) //{//should pass a list of SimulationObjectProxies? // List<string> obstructionList = new List<string>(); // SimulationObject obj; // //do obstruction calculations // foreach (string region in allObstructions) // { // obj = bbc // Polygon3D reg = new Polygon3D( // } // return obstructionList; // //return a list of ACVs? //} /// <summary> /// This method determines if 2 objects are within a certain range. Returns true if /// the distance between the two objects is less than the range, otherwise returns false. Offers easy /// calculation of two LocationValue objects. /// </summary> /// <param name="range">The max distance that can be between the two objects while still returning true.</param> /// <param name="objectA">The first object's location as a LocationValue.</param> /// <param name="objectB">The second object's location as a LocationValue.</param> /// <returns></returns> public static bool IsWithinRange(double range, LocationValue objectA, LocationValue objectB) { Vec3D objA = new Vec3D(objectA); Vec3D objB = new Vec3D(objectB); if (range > objA.ScalerDistanceTo(objB)) { return true; } return false; }
//Find obstructions //public static List<string> FindObstructions(List<string> allObstructions, Vec3D sensorPoint, Vec3D emitterPoint) //{//should pass a list of SimulationObjectProxies? // List<string> obstructionList = new List<string>(); // SimulationObject obj; // //do obstruction calculations // foreach (string region in allObstructions) // { // obj = bbc // Polygon3D reg = new Polygon3D( // } // return obstructionList; // //return a list of ACVs? //} /// <summary> /// This method determines if 2 objects are within a certain range. Returns true if /// the distance between the two objects is less than the range, otherwise returns false. Offers easy /// calculation of two LocationValue objects. /// </summary> /// <param name="range">The max distance that can be between the two objects while still returning true.</param> /// <param name="objectA">The first object's location as a LocationValue.</param> /// <param name="objectB">The second object's location as a LocationValue.</param> /// <returns></returns> public static bool IsWithinRange(double range, LocationValue objectA, LocationValue objectB) { Vec3D objA = new Vec3D(objectA); Vec3D objB = new Vec3D(objectB); if (range > objA.ScalerDistanceTo(objB)) { return(true); } return(false); }
public static bool SensorDoesLineCross(Polygon3D poly, Vec3D fromP, Vec3D toP) { if (fromP.Z < poly.bottom || fromP.Z > poly.top) { return(false); } if (toP.Z < poly.bottom || toP.Z > poly.top) { return(false); } return(Polygon2D.SensorDoesLineCross(poly.footprint, new Vec2D(fromP.X, fromP.Y), new Vec2D(toP.X, toP.Y))); }
public static bool DoesLineCross(Polygon3D poly, Vec3D fromP, Vec3D toP) { if (fromP.Z < poly.bottom || fromP.Z > poly.top) { return false; } if (toP.Z < poly.bottom || toP.Z > poly.top) { return false; } return Polygon2D.DoesLineCross(poly.footprint, new Vec2D(fromP.X, fromP.Y), new Vec2D(toP.X, toP.Y)); }
public static Vec3D FindIntersect(Polygon3D poly, Vec3D fromP, Vec3D toP) { Vec2D intersect = Polygon2D.FindIntersect(poly.footprint, new Vec2D(fromP.X, fromP.Y), new Vec2D(toP.X, toP.Y)); if (intersect != null) { return(new Vec3D(intersect.X, intersect.Y, fromP.Z)); } else { return(null); } }
public static Vec3D FindIntersect(Polygon3D poly, Vec3D fromP, Vec3D toP) { Vec2D intersect = Polygon2D.FindIntersect(poly.footprint, new Vec2D(fromP.X, fromP.Y), new Vec2D(toP.X, toP.Y)); if (intersect != null) { return new Vec3D(intersect.X, intersect.Y, fromP.Z); } else { return null; } }
//detection public static DetectedAttributeValue Detection(LocationValue sensingLocation, LocationValue emittingLocation, DataValue emittingObjectAttribute, List <ConeValue> sensingCones, Dictionary <string, double> emitters, List <SimulationObjectProxy> obstructions, ref Random random) { DetectedAttributeValue returnDAV = new DetectedAttributeValue(); Vec3D sensingPoint = new Vec3D(sensingLocation); Vec3D emittingPoint = new Vec3D(emittingLocation); Vec3D sensingDirection = new Vec3D(sensingPoint); //can't set to blank, just ignore. double coneAngle = 0.0; double angleBetweenSensorAndEmitter = 0.0; foreach (ConeValue cone in sensingCones) { sensingDirection.Set(cone.direction); Vec3D closestPoint = FindClosestPoint(sensingPoint, sensingDirection, emittingPoint); if (cone.extent > sensingPoint.ScalerDistanceTo(closestPoint)) { //p* is within the cone's extent. //determine if emitting point is within the spread of the cone. coneAngle = cone.spread * Math.PI / 180; // System.Math.Atan(emittingPoint.ScalerDistanceTo(closestPoint) / sensingPoint.ScalerDistanceTo(closestPoint));//should be cone.spread angleBetweenSensorAndEmitter = System.Math.Atan(emittingPoint.ScalerDistanceTo(closestPoint) / sensingPoint.ScalerDistanceTo(closestPoint)); if (coneAngle < angleBetweenSensorAndEmitter) { continue; //should go to next cone. } if (emitters.ContainsKey(cone.level)) {//emitter has an emission at the same level as the cone. //returnDAV = (DetectedAttributeValue)ObfuscateAttributeValue(emittingObjectAttribute, emitters[cone.level], ref random); returnDAV = (DetectedAttributeValue)FuzzAttributeValue(emittingObjectAttribute, emitters[cone.level], ref random); return(returnDAV); } else { //emitter does not emit the same level as the cone. //should this find next best, or just move on? } } } return(null); }
public Vec3D Add(Vec3D v2) { Vec3D r = new Vec3D(this); r.X += v2.X; r.Y += v2.Y; r.Z += v2.Z; return r; }
private List<SimulationObjectProxy> FindObstructions(Vec3D sensorPoint, Vec3D emitterPoint) { List<SimulationObjectProxy> obstructionList = new List<SimulationObjectProxy>(); //SimulationObjectProxy blocker; foreach (KeyValuePair<string, StateDB.ActiveRegion> br in obstructions) { if (Polygon3D.SensorDoesLineCross(br.Value.poly, sensorPoint, emitterPoint)) { obstructionList.Add(objectProxies[br.Key]); } } return obstructionList; }
public Vec3D VectorDistanceTo(Vec3D v2) { Vec3D r = new Vec3D(v2); r.X -= X; r.Y -= Y; r.Z -= Z; return r; }
/* private CapabilityValue.Effect FindCapabilityEffect(CapabilityValue cap, VulnerabilityValue vuln) { List<string> vulnNames = new List<string>(); foreach (VulnerabilityValue.Transition t in vuln.transitions) { foreach (VulnerabilityValue.TransitionCondition tc in t.conditions) { if (!vulnNames.Contains(tc.capability)) { vulnNames.Add(tc.capability); } } } foreach (CapabilityValue.Effect e in cap.effects) { if (vulnNames.Contains(e.name)) { return e; } } return null; }*/ private void TimeTick(SimulationEvent e) { if (objectProxies == null) { objectProxies = bbClient.GetObjectProxies(); } time = ((IntegerValue)e["Time"]).value; DataValue dv = null; SimulationObjectProxy obProx = null, targetProx = null; Vec3D myLoc; Vec3D targetLoc; string targetID; bool isWeapon = false; bool pursueStarted; CapabilityValue capabilities; VulnerabilityValue vulnerabilities; CapabilityValue.Effect effect; double distance; LocationValue location; foreach (string id in objectProxies.Keys) { obProx = objectProxies[id]; // update the StateDB info if (StateDB.physicalObjects[id].ownerID == "") { string owner = ((StringValue)obProx["OwnerID"].GetDataValue()).value; if (StateDB.decisionMakers.ContainsKey(owner)) { StateDB.physicalObjects[id].ownerID = owner; } } if (StateDB.physicalObjects[id].speciesName == "") { string speciesName = ((StringValue)obProx["ClassName"].GetDataValue()).value; StateDB.physicalObjects[id].speciesName = speciesName; } if (StateDB.physicalObjects[id].ownerID != "" && StateDB.physicalObjects[id].teamName == "") { if (StateDB.decisionMakers[StateDB.physicalObjects[id].ownerID].team != null) { StateDB.physicalObjects[id].teamName = StateDB.decisionMakers[StateDB.physicalObjects[id].ownerID].team.id; } } if (((StringValue)obProx["AttackState"].GetDataValue()).value == "BEING_ATTACKED") { continue; } AttackCollectionValue attCV = (AttackCollectionValue)obProx["CurrentAttacks"].GetDataValue(); if (attCV.GetCurrentSelfDefenseAttacks().Count == 0) //if (((StringValue)obProx["AttackTargetID"].GetDataValue()).value == "") { dv = obProx["SelfDefenseStartAttack"].GetDataValue(); ((BooleanValue)dv).value = false; obProx["SelfDefenseStartAttack"].SetDataValue(dv); dv = obProx["SelfDefenseCapability"].GetDataValue(); ((StringValue)dv).value = ""; obProx["SelfDefenseCapability"].SetDataValue(dv); dv = obProx["SelfDefenseTargetID"].GetDataValue(); ((StringValue)dv).value = ""; obProx["SelfDefenseTargetID"].SetDataValue(dv); } if (((BooleanValue)obProx["SelfDefenseStartAttack"].GetDataValue()).value == true) { continue; } isWeapon = ((BooleanValue)obProx["IsWeapon"].GetDataValue()).value; pursueStarted = ((BooleanValue)obProx["PursueStarted"].GetDataValue()).value; targetID = ((StringValue)obProx["PursueTargetID"].GetDataValue()).value; capabilities = (CapabilityValue)obProx["Capability"].GetDataValue(); if (isWeapon && pursueStarted && objectProxies.ContainsKey(targetID)) { targetProx = objectProxies[targetID]; location = (LocationValue)obProx["Location"].GetDataValue(); if (!location.exists) { continue; } myLoc = new Vec3D(location); location = (LocationValue)targetProx["Location"].GetDataValue(); if (!location.exists) { continue; } targetLoc = new Vec3D(location); distance = myLoc.ScalerDistanceTo(targetLoc); vulnerabilities = (VulnerabilityValue)targetProx["Vulnerability"].GetDataValue(); //string cap = FindCapability(capabilities, vulnerabilities); effect = SimUtility.FindCapabilityEffect(capabilities, vulnerabilities); if (effect != null && distance < effect.range) { dv = obProx["SelfDefenseStartAttack"].GetDataValue(); ((BooleanValue)dv).value = true; obProx["SelfDefenseStartAttack"].SetDataValue(dv); dv = obProx["SelfDefenseCapability"].GetDataValue(); ((StringValue)dv).value = effect.name; obProx["SelfDefenseCapability"].SetDataValue(dv); dv = obProx["SelfDefenseTargetID"].GetDataValue(); ((StringValue)dv).value = targetID; obProx["SelfDefenseTargetID"].SetDataValue(dv); } else if (effect == null && distance < 1) { distClient.PutEvent(SimUtility.BuildStateChangeEvent(ref simModel, time, id, "Dead")); } continue; } string ownerID = ((StringValue)obProx["OwnerID"].GetDataValue()).value; if (StateDB.decisionMakers.ContainsKey(ownerID)) { StateDB.DecisionMaker thisDM = StateDB.decisionMakers[ownerID]; List<string> targets = ((StringListValue)obProx["TargetsInRange"].GetDataValue()).strings; //if (targets.Count == 0) //{ // continue; //} foreach (string target in targets) { SimulationObjectProxy obProx2 = objectProxies[target]; string ownerID2 = ((StringValue)obProx2["OwnerID"].GetDataValue()).value; if (!StateDB.decisionMakers.ContainsKey(ownerID2)) { continue; } StateDB.DecisionMaker thatDM = StateDB.decisionMakers[ownerID2]; vulnerabilities = (VulnerabilityValue)obProx2["Vulnerability"].GetDataValue(); effect = SimUtility.FindCapabilityEffect(capabilities, vulnerabilities); if (effect != null && thisDM.isHostile(thatDM) && !thisDM.isHuman) { dv = obProx["SelfDefenseStartAttack"].GetDataValue(); ((BooleanValue)dv).value = true; obProx["SelfDefenseStartAttack"].SetDataValue(dv); dv = obProx["SelfDefenseCapability"].GetDataValue(); ((StringValue)dv).value = effect.name; obProx["SelfDefenseCapability"].SetDataValue(dv); dv = obProx["SelfDefenseTargetID"].GetDataValue(); ((StringValue)dv).value = target; obProx["SelfDefenseTargetID"].SetDataValue(dv); break; } } } } }
static public SimulationEvent BuildHistory_AttackerObjectReportEvent(ref SimulationModelInfo simModel, int time, string objectID, Vec3D location, string targetObjectID, Vec3D targetLocation, string capabilityName, int appliedIntensity) { SimulationEvent sc = SimulationEventFactory.BuildEvent(ref simModel, "History_AttackerObjectReport"); ((IntegerValue)sc["Time"]).value = time; ((StringValue)sc["ObjectID"]).value = objectID; sc["ObjectLocation"] = (DataValue)location.ToLocationValue(); ((StringValue)sc["TargetObjectID"]).value = targetObjectID; sc["TargetObjectLocation"] = (DataValue)targetLocation.ToLocationValue(); ((StringValue)sc["CapabilityName"]).value = capabilityName; ((IntegerValue)sc["AppliedIntensity"]).value = appliedIntensity; return sc; }
public void Set(Vec3D v) { X = v.X; Y = v.Y; Z = v.Z; }
public double ScalerDistanceTo(Vec3D v2) { return Math.Sqrt(Math.Pow(v2.X - X, 2) + Math.Pow(v2.Y - Y, 2) + Math.Pow(v2.Z - Z, 2)); }
private void MoveObject(SimulationEvent e) { //AD: Inserted a return here as all motion logic lives in the DIS adapter now. return; //TODO: adjust heading (current, expected, delta) //use radius math to calculate turn radius //objectProxies = bbClient.GetObjectProxies(); DataValue dv = null; string id = ((StringValue)e["ObjectID"]).value; SimulationObjectProxy obProx = objectProxies[id]; double throttle = 0; double maxSpeed = 0; double speedMultiplier = 0; Vec3D curVec = new Vec3D(0, 0, 0); Vec3D destVec = new Vec3D(0, 0, 0); Vec3D velVec = new Vec3D(0, 0, 0); dv = obProx["Location"].GetDataValue(); curVec.Set((LocationValue)dv); dv = obProx["MaximumSpeed"].GetDataValue(); maxSpeed = ((DoubleValue)dv).value; dv = e["DestinationLocation"]; destVec.Set((LocationValue)dv); obProx["DestinationLocation"].SetDataValue(dv); dv = e["Throttle"]; throttle = ((DoubleValue)dv).value; obProx["Throttle"].SetDataValue(dv); dv = obProx["ActiveRegionSpeedMultiplier"].GetDataValue(); speedMultiplier = ((DoubleValue)dv).value; velVec = curVec.VectorDistanceTo(destVec); velVec.Normalize(); velVec = velVec.Multiply(maxSpeed * throttle * speedMultiplier); obProx["Velocity"].SetDataValue(velVec.ToVelocityValue()); // System.Console.WriteLine("Object {0} Velocity={1}", id.ToString(), velVec.ToString()); }
private bool IsOnSea(Vec3D loc) { if (loc.Z > 0) { return false; } else { return !OnLandRegion(new Vec2D(loc.X, loc.Y)); } }
/// <summary> /// /// </summary> /// <param name="allObjectViews"></param> private void SenseAllObjects(ref Dictionary<string, Dictionary<string, AttributeCollectionValue>> allObjectsViews) { SimulationObjectProxy sensingProxy = null; SimulationObjectProxy targetProxy = null; Vec3D sensingLocation = null; Vec3D targetsLocation = null; LocationValue senLocation = null; LocationValue tarLocation = null; double distance = 0.0; SensorArrayValue sav = null; DataValue targetsAttribute = null; string ownerID = null; string objectType = null; DetectedAttributeValue detectedAttribute; AttributeCollectionValue singleAttributeCollection = null; bool isSensed = false; // The dictionary is constantly created in this method // Dictionary<string, AttributeCollectionValue> singleObjectView; //AD to improve this later: // for each object in the visible ObjectDistances collection // for each object after the current index // check for the index object's view of the nested object // check for the nested object's view of the index object //Possible hangup is the "All" emitter. int x = 0; //Each object senses each other object //foreach (string sensorObjectID in listOfObjectIDs) foreach (KeyValuePair<string, List<string>> networks in networkRosters) { if (!activeSensorNetworks[networks.Key]) continue; foreach (string sensorObjectID in networkObjects[networks.Key]) { sensingProxy = objectProxies[sensorObjectID]; objectType = sensingProxy.GetObjectType(); senLocation = sensingProxy["Location"].GetDataValue() as LocationValue; if (senLocation.exists) { ownerID = ((StringValue)sensingProxy["OwnerID"].GetDataValue()).value; singleObjectView = new Dictionary<string, AttributeCollectionValue>(); x++; //foreach (string targetObjectID in listOfObjectIDs) foreach (List<string> objects in networkObjects.Values) { if (objects.Contains(sensorObjectID)) { if (((EmitterValue)sensingProxy["Emitters"].GetDataValue()).emitters.ContainsKey("Invisible")) { continue; } string target = sensorObjectID; singleAttributeCollection = new AttributeCollectionValue(); foreach (KeyValuePair<string, AttributeInfo> simModelAtt in simModel.objectModel.objects[objectType].attributes) { if (!simModelAtt.Value.ownerObservable == true) continue; //if (!sensingProxy.GetKeys().Contains(simModelAtt.Key)) // continue; DataValue t = sensingProxy[simModelAtt.Key].GetDataValue(); if (t.dataType == "CustomAttributesType") { Dictionary<string, DataValue> copiedDict = CopyFromCustomAttributes(((CustomAttributesValue)t).attributes); t = new CustomAttributesValue(); ((CustomAttributesValue)t).attributes = copiedDict; } detectedAttribute = new DetectedAttributeValue(); detectedAttribute.stdDev = 100; detectedAttribute.value = DataValueFactory.BuildFromDataValue(t); AddAttributeToACV(ref singleAttributeCollection, simModelAtt.Key, detectedAttribute); }//end foreach sensable attribute if (!allObjectsViews.ContainsKey(sensorObjectID)) { allObjectsViews.Add(sensorObjectID, new Dictionary<string, AttributeCollectionValue>()); } if (!objectViews.ContainsKey(sensorObjectID)) { objectViews.Add(sensorObjectID, new ObjectsAttributeCollection()); } //update the global "allObjectViews". The return from UpdateObject is the collection of attributes //that have changed. These attributes are stored in allObjectsViews and then sent out //to users. AttributeCollectionValue changedAttributes = objectViews[sensorObjectID].UpdateObject(target, singleAttributeCollection); //if (changedAttributes != null && selectedRangeRingLevel != RangeRingLevels.DISABLED) //{ // CalculateRangeRings(ref changedAttributes, ref sensingProxy); //} if (changedAttributes != null) { allObjectsViews[sensorObjectID].Add(target, changedAttributes); } else//this is so there is at least the empty entry for the detected object so //you still know it is detected. { if (!allObjectsViews[sensorObjectID].ContainsKey(target)) { allObjectsViews[sensorObjectID].Add(target, new AttributeCollectionValue()); } } } else { foreach (string targetObjectID in objects) {//sensing and target objects are not the same targetProxy = objectProxies[targetObjectID]; tarLocation = targetProxy["Location"].GetDataValue() as LocationValue; if (tarLocation.exists) { EmitterValue emitters = targetProxy["Emitters"].GetDataValue() as EmitterValue; if (emitters.emitters.ContainsKey("All")) { //if an object has an all emitter, retrieve all attributes without sensing algorithm AttributeCollectionValue atts = new AttributeCollectionValue(); if (singleObjectView.ContainsKey(targetObjectID)) { atts = singleObjectView[targetObjectID]; } SenseAllAttributes(ref atts, targetProxy); singleObjectView[targetObjectID] = atts; isSensed = true; if (!allObjectsViews.ContainsKey(sensorObjectID)) { allObjectsViews.Add(sensorObjectID, new Dictionary<string, AttributeCollectionValue>()); } if (!objectViews.ContainsKey(sensorObjectID)) { objectViews.Add(sensorObjectID, new ObjectsAttributeCollection()); } //update the global "allObjectViews". The return from UpdateObject is the collection of attributes //that have changed. These attributes are stored in allObjectsViews and then sent out //to users. AttributeCollectionValue changedAttributes = objectViews[sensorObjectID].UpdateObject(targetObjectID, atts); //if (changedAttributes != null && selectedRangeRingLevel == RangeRingLevels.FULL) //{//the only way to sense a "target" here is for FULL ring display // CalculateRangeRings(ref changedAttributes, ref targetProxy); //} if (changedAttributes != null) { allObjectsViews[sensorObjectID].Add(targetObjectID, changedAttributes); } else//this is so there is at least the empty entry for the detected object so //you still know it is detected. { if (!allObjectsViews[sensorObjectID].ContainsKey(targetObjectID)) { allObjectsViews[sensorObjectID].Add(targetObjectID, new AttributeCollectionValue()); } } } else if (emitters.emitters.ContainsKey("Invisible")) { continue; } else {//object does not have an all emitter, continue to check each emitter value AttributeCollectionValue atts = new AttributeCollectionValue(); if (Omniscience) { if (singleObjectView.ContainsKey(targetObjectID)) { atts = singleObjectView[targetObjectID]; } SenseAllAttributes(ref atts, targetProxy); singleObjectView[targetObjectID] = atts; isSensed = true; if (!allObjectsViews.ContainsKey(sensorObjectID)) { allObjectsViews.Add(sensorObjectID, new Dictionary<string, AttributeCollectionValue>()); } if (!objectViews.ContainsKey(sensorObjectID)) { objectViews.Add(sensorObjectID, new ObjectsAttributeCollection()); } //update the global "allObjectViews". The return from UpdateObject is the collection of attributes //that have changed. These attributes are stored in allObjectsViews and then sent out //to users. AttributeCollectionValue changedAttributes = objectViews[sensorObjectID].UpdateObject(targetObjectID, atts); //if (changedAttributes != null && selectedRangeRingLevel == RangeRingLevels.FULL) //{//the only way to sense a "target" here is for FULL ring display // CalculateRangeRings(ref changedAttributes, ref targetProxy); //} if (changedAttributes != null) { allObjectsViews[sensorObjectID].Add(targetObjectID, changedAttributes); } else//this is so there is at least the empty entry for the detected object so //you still know it is detected. { if (!allObjectsViews[sensorObjectID].ContainsKey(targetObjectID)) { allObjectsViews[sensorObjectID].Add(targetObjectID, new AttributeCollectionValue()); } } continue; } sensingLocation = new Vec3D(senLocation); targetsLocation = new Vec3D(tarLocation); isSensed = false; distance = sensingLocation.ScalerDistanceTo(targetsLocation); sav = sensingProxy["Sensors"].GetDataValue() as SensorArrayValue; foreach (SensorValue sv in sav.sensors) { if (distance < sv.maxRange) { //Find obstructions List<SimulationObjectProxy> obstructions = FindObstructions(sensingLocation, targetsLocation); foreach (KeyValuePair<string, List<ConeValue>> kvp in sv.ranges) { //Key is the attribute being sensed, value is a list of cones if (kvp.Key == "All") { atts = new AttributeCollectionValue(); if (singleObjectView.ContainsKey(targetObjectID)) { atts = singleObjectView[targetObjectID]; } SenseAllAttributes(ref atts, targetProxy); singleObjectView[targetObjectID] = atts; isSensed = true; } else //not an All sensor, so run detection algorithm {//Added in main-line if (!emitters.emitters.ContainsKey(kvp.Key)) { continue; } //Custom attributes fix: DataValue currentDataValue; try { currentDataValue = targetProxy[kvp.Key].GetDataValue(); } catch { currentDataValue = targetProxy["CustomAttributes"].GetDataValue(); currentDataValue = ((CustomAttributesValue)currentDataValue)[kvp.Key]; //will throw an error here if object doesn't contain custom atts, or //if it doesnt contain the specified custom att. } bool isObstructed = false; foreach (SimulationObjectProxy reg in obstructions) { foreach (string attributeBlocked in ((StringListValue)reg["BlocksSensorTypes"].GetDataValue()).strings) { if (kvp.Key == attributeBlocked) { isObstructed = true; } } } if (isObstructed) { detectedAttribute = new DetectedAttributeValue(); detectedAttribute.value = DataValueFactory.BuildValue(currentDataValue.dataType); detectedAttribute.confidence = 0; //continue; } else { targetsAttribute = DataValueFactory.BuildFromDataValue(currentDataValue); //ev is emitters Dictionary<string, double> emitterCollection = emitters.emitters[kvp.Key]; detectedAttribute = new DetectedAttributeValue(); detectedAttribute = ObjectMath.Detection(senLocation, tarLocation, targetsAttribute, kvp.Value, emitterCollection, obstructions, ref randomGenerator); } if (detectedAttribute != null) { singleAttributeCollection = new AttributeCollectionValue(); if (singleObjectView.ContainsKey(targetObjectID)) { singleAttributeCollection = singleObjectView[targetObjectID]; } AddAttributeToACV(ref singleAttributeCollection, kvp.Key, detectedAttribute); isSensed = true; } } }//end foreach attribute in sensor //if the object has any attributes sensed, fill in some other info for the object's view. if (isSensed) { detectedAttribute = new DetectedAttributeValue(); detectedAttribute.stdDev = 100; detectedAttribute.value = targetProxy["ID"].GetDataValue(); if (singleAttributeCollection == null) { singleAttributeCollection = new AttributeCollectionValue(); } if (!singleObjectView.ContainsKey(targetObjectID)) { singleObjectView.Add(targetObjectID, singleAttributeCollection); } singleAttributeCollection = singleObjectView[targetObjectID]; AddAttributeToACV(ref singleAttributeCollection, "ID", detectedAttribute); detectedAttribute = new DetectedAttributeValue(); detectedAttribute.stdDev = 100; detectedAttribute.value = targetProxy["OwnerID"].GetDataValue(); AddAttributeToACV(ref singleAttributeCollection, "OwnerID", detectedAttribute); }//end if isSensed. } }//end foreach sensor in sensor array if (singleObjectView.ContainsKey(targetObjectID)) { AttributeCollectionValue attr = singleObjectView[targetObjectID]; if (!allObjectsViews.ContainsKey(sensorObjectID)) { allObjectsViews.Add(sensorObjectID, new Dictionary<string, AttributeCollectionValue>()); } if (!objectViews.ContainsKey(sensorObjectID)) { objectViews.Add(sensorObjectID, new ObjectsAttributeCollection()); } if (attr.attributes.ContainsKey("CustomAttributes")) { DataValue t = ((DetectedAttributeValue)attr["CustomAttributes"]).value; double conf = ((DetectedAttributeValue)attr["CustomAttributes"]).confidence; Dictionary<string, DataValue> copiedDict = CopyFromCustomAttributes(((CustomAttributesValue)t).attributes); t = new CustomAttributesValue(); ((CustomAttributesValue)t).attributes = copiedDict; attr.attributes.Remove("CustomAttributes"); attr.attributes.Add("CustomAttributes", DataValueFactory.BuildDetectedValue(t, Convert.ToInt32(conf))); } //update the global "allObjectViews". The return from UpdateObject is the collection of attributes //that have changed. These attributes are stored in allObjectsViews and then sent out //to users. AttributeCollectionValue changedAttributes = objectViews[sensorObjectID].UpdateObject(targetObjectID, attr); //if (changedAttributes != null && selectedRangeRingLevel == RangeRingLevels.FULL) //{//the only way to sense a "target" here is for FULL ring display // CalculateRangeRings(ref changedAttributes, ref targetProxy); //} if (changedAttributes != null) { allObjectsViews[sensorObjectID].Add(targetObjectID, changedAttributes); } else//this is so there is at least the empty entry for the detected object so //you still know it is detected. { if (!allObjectsViews[sensorObjectID].ContainsKey(targetObjectID)) { allObjectsViews[sensorObjectID].Add(targetObjectID, new AttributeCollectionValue()); } } } else { if (objectViews.ContainsKey(sensorObjectID)) { if (objectViews[sensorObjectID].ContainsObject(targetObjectID)) { objectViews[sensorObjectID].RemoveObject(targetObjectID); //if you once knew of this object, and now don't, remove it from object's view. } } } }//end emitter detection }//end if target is visible } } }//end foreach target object }//end if sensor is visible }//end of foreach sensing object }//end of Foreach sensor network //if (x > 0) // Console.Out.WriteLine("ViewPro: {0} objects were sensing at time {1}.", x, currentTick / 1000); }
private void RevealObject(SimulationEvent e) { //objectProxies = bbClient.GetObjectProxies(); // update my objects record AttributeCollectionValue atts = (AttributeCollectionValue)e["Attributes"]; if (e["ObjectID"] != null) { string id = ((StringValue)e["ObjectID"]).value; SimulationObjectProxy prox = null;// objectProxies[id]; prox = GetObjectProxy(id); if (prox == null) return; // initialize any object values I need to. foreach (string attname in atts.attributes.Keys) { if (prox.GetKeys().Contains(attname) && prox[attname].IsOwner()) { prox[attname].SetDataValue(atts[attname]); } } /* * If object is docked to parent, ignore location */ DataValue dv = prox["DockedToParent"].GetDataValue(); if (((BooleanValue)dv).value) { dv = prox["Location"].GetDataValue(); ((LocationValue)dv).exists = false; prox["Location"].SetDataValue(dv); } //Initialize collision shape DoubleValue size = (DoubleValue)prox["Size"].GetDataValue(); if (size.value > 0) { collisionShapes[id] = createRelativeCollisionShape(size.value); } else { if (collisionShapes.ContainsKey(id)) { collisionShapes.Remove(id); } } if (!atts.attributes.ContainsKey("Heading")) { //default heading is 0,1,0 for now, which should be heading 0, due north Vec3D defaultHeading = new Vec3D(0, 1, 0); double degHeading = 180 / Math.PI * Math.Atan2(defaultHeading.X, defaultHeading.Y); prox["Heading"].SetDataValue(DataValueFactory.BuildDouble(degHeading)); } else { } // TODO: Kill object if revealed inside an obstructing region } }
public Vec3D(Vec3D v) { X = v.X; Y = v.Y; Z = v.Z; }
static public SimulationEvent BuildHistory_AttackedObjectReportEvent(ref SimulationModelInfo simModel, int time, string objectID, Vec3D location, bool success, string newState) { SimulationEvent sc = SimulationEventFactory.BuildEvent(ref simModel, "History_AttackedObjectReport"); ((IntegerValue)sc["Time"]).value = time; ((StringValue)sc["ObjectID"]).value = objectID; sc["ObjectLocation"] = (DataValue)location.ToLocationValue(); ((BooleanValue)sc["AttackSuccess"]).value = success; ((StringValue)sc["NewState"]).value = newState; return sc; }
public Vec3D Subtract(Vec3D v2) { Vec3D r = new Vec3D(this); r.X -= v2.X; r.Y -= v2.Y; r.Z -= v2.Z; return r; }
private bool IsObstructed(Vec3D cur, Vec3D dest, String myID) { foreach (StateDB.ActiveRegion reg in StateDB.activeRegions.Values) { if (reg.blockingRegion && Polygon3D.DoesLineCross(reg.poly, cur, dest)) { return true; } } foreach (String id in collisionShapes.Keys) { if (id != myID) { SimulationObjectProxy obProx = objectProxies[id]; LocationValue loc = (LocationValue)obProx["Location"].GetDataValue(); if (loc.exists) { Polygon3D absShape = createAbsoluteCollisionShape(collisionShapes[id], loc); if (Polygon3D.DoesLineCross(absShape, cur, dest)) { return true; } } } } return false; }
private bool IsInObstruction(Vec3D cur) { foreach (StateDB.ActiveRegion reg in StateDB.activeRegions.Values) { if (reg.blockingRegion && Polygon3D.IsPointInside(reg.poly, cur)) { return true; } } return false; }
public Vec3D Multiply(double s) { Vec3D r = new Vec3D(this); r.X *= s; r.Y *= s; r.Z *= s; return r; }
public double ScalerDistanceTo(Vec3D v2) { return(Math.Sqrt(Math.Pow(v2.X - X, 2) + Math.Pow(v2.Y - Y, 2) + Math.Pow(v2.Z - Z, 2))); }
public static void UpdateObjectLocation(String objID, Vec3D loc) { if (_objectLocations.ContainsKey(objID)) { _objectLocations[objID].X = loc.X; _objectLocations[objID].Y = loc.Y; _objectLocations[objID].Z = loc.Z; } else { _objectLocations.Add(objID, new Vec3D(loc)); } double dist; foreach (String o in _objectLocations.Keys) { if (o == objID) continue; dist = _objectLocations[o].ScalerDistanceTo(loc); SetScalarDistanceBetweenTwoObjects(o, objID, dist); } UpdateOthersForNewLocation(objID); UpdateObjectsInSensorRange(objID); //might be a bit expensive to do this often }
static public SimulationEvent BuildHistory_SubplatformLaunchEvent(ref SimulationModelInfo simModel, int time, string objectID, string parentObjectID, Vec3D parentLocation, Vec3D launchDestinationLocation, bool isWeaponLaunch, string targetObjectID) { SimulationEvent sc = SimulationEventFactory.BuildEvent(ref simModel, "History_SubplatformLaunch"); ((IntegerValue)sc["Time"]).value = time; ((StringValue)sc["ObjectID"]).value = objectID; ((StringValue)sc["ParentObjectID"]).value = parentObjectID; sc["ParentObjectLocation"] = (DataValue)parentLocation.ToLocationValue(); sc["LaunchDestinationLocation"] = (DataValue)launchDestinationLocation.ToLocationValue(); ((BooleanValue)sc["IsWeaponLaunch"]).value = isWeaponLaunch; ((StringValue)sc["TargetObjectID"]).value = targetObjectID; return sc; }
private List<String> GetActiveRegions(Vec3D cur) { List<string> regions = new List<string>(); foreach (StateDB.ActiveRegion reg in StateDB.activeRegions.Values) { if (Polygon3D.IsPointInside(reg.poly, cur)) { regions.Add(reg.id); } } return regions; }
//detection public static DetectedAttributeValue Detection(LocationValue sensingLocation, LocationValue emittingLocation, DataValue emittingObjectAttribute, List<ConeValue> sensingCones, Dictionary<string, double> emitters, List<SimulationObjectProxy> obstructions, ref Random random) { DetectedAttributeValue returnDAV = new DetectedAttributeValue(); Vec3D sensingPoint = new Vec3D(sensingLocation); Vec3D emittingPoint = new Vec3D(emittingLocation); Vec3D sensingDirection = new Vec3D(sensingPoint); //can't set to blank, just ignore. double coneAngle = 0.0; double angleBetweenSensorAndEmitter = 0.0; foreach(ConeValue cone in sensingCones) { sensingDirection.Set(cone.direction); Vec3D closestPoint = FindClosestPoint(sensingPoint, sensingDirection, emittingPoint); if (cone.extent > sensingPoint.ScalerDistanceTo(closestPoint)) {//p* is within the cone's extent. //determine if emitting point is within the spread of the cone. coneAngle = cone.spread * Math.PI / 180;// System.Math.Atan(emittingPoint.ScalerDistanceTo(closestPoint) / sensingPoint.ScalerDistanceTo(closestPoint));//should be cone.spread angleBetweenSensorAndEmitter = System.Math.Atan(emittingPoint.ScalerDistanceTo(closestPoint) / sensingPoint.ScalerDistanceTo(closestPoint)); if (coneAngle < angleBetweenSensorAndEmitter) { continue; //should go to next cone. } if (emitters.ContainsKey(cone.level)) {//emitter has an emission at the same level as the cone. //returnDAV = (DetectedAttributeValue)ObfuscateAttributeValue(emittingObjectAttribute, emitters[cone.level], ref random); returnDAV = (DetectedAttributeValue)FuzzAttributeValue(emittingObjectAttribute, emitters[cone.level], ref random); return returnDAV; } else { //emitter does not emit the same level as the cone. //should this find next best, or just move on? } } } return null; }
private void TimeTick(SimulationEvent e) { int oldTime = time; DataValue dv = null; Vec3D landIntersect; Vec3D obstructionIntersect; Vec3D curLocVec = new Vec3D(0, 0, 0); Vec3D newLocVec = new Vec3D(0, 0, 0); Vec3D destVec = new Vec3D(0, 0, 0); Vec3D velVec = new Vec3D(0, 0, 0); Vec3D headingVector = new Vec3D(0, 0, 0); dv = e["Time"]; time = ((IntegerValue)dv).value; double dTime = ((double)(time - oldTime)) / 1000; SimulationObjectProxy obProx = null; SimulationObjectProxy parentProx = null; bool launchStarted, launchDone; int launchEndTime; bool pursueStarted; string pursueTargetID; string parentObjectID; ScoringDB.ActorFrame actorFrame = new ScoringDB.ActorFrame(); foreach (string id in objectProxies.Keys) { obProx = objectProxies[id]; //********************************* // Launch movement logic //********************************* #region Launch Logic launchStarted = ((BooleanValue)obProx["LaunchStarted"].GetDataValue()).value; launchDone = ((BooleanValue)obProx["LaunchDone"].GetDataValue()).value; pursueStarted = ((BooleanValue)obProx["PursueStarted"].GetDataValue()).value; pursueTargetID = ((StringValue)obProx["PursueTargetID"].GetDataValue()).value; if (launchStarted == false && launchDone == true) { dv = obProx["LaunchDone"].GetDataValue(); ((BooleanValue)dv).value = false; obProx["LaunchDone"].SetDataValue(dv); launchDone = false; } if (launchStarted == true && launchDone == false) { parentObjectID = ((StringValue)obProx["ParentObjectID"].GetDataValue()).value; parentProx = objectProxies[parentObjectID]; launchEndTime = ((IntegerValue)obProx["LaunchEndTime"].GetDataValue()).value; if (time >= launchEndTime) { Vec3D parentVec = new Vec3D((LocationValue)parentProx["Location"].GetDataValue()); dv = obProx["LaunchDestinationLocation"].GetDataValue(); Vec3D launchDestVec = new Vec3D((LocationValue)dv); bool sendMoveRequest = ((LocationValue)dv).exists; obProx["Location"].SetDataValue(parentVec.ToLocationValue()); //Now that location has been updated, set in helper library: ObjectDistances.UpdateObjectLocation(id, parentVec); dv = obProx["LaunchDone"].GetDataValue(); ((BooleanValue)dv).value = true; obProx["LaunchDone"].SetDataValue(dv); if (sendMoveRequest) { string userID = ((StringValue)obProx["OwnerID"].GetDataValue()).value; distClient.PutEvent(SimUtility.BuildMoveObjectRequestEvent(ref simModel, time, userID, id, launchDestVec, 1.0)); } if (((BooleanValue)obProx["LaunchIsWeapon"].GetDataValue()).value == true) { dv = obProx["PursueStarted"].GetDataValue(); ((BooleanValue)dv).value = true; obProx["PursueStarted"].SetDataValue(dv); pursueStarted = true; dv = obProx["LaunchWeaponTargetID"].GetDataValue(); pursueTargetID = ((StringValue)dv).value; dv = obProx["PursueTargetID"].GetDataValue(); ((StringValue)dv).value = pursueTargetID; obProx["PursueTargetID"].SetDataValue(dv); distClient.PutEvent(SimUtility.BuildSystemMessageEvent(ref simModel, time, ((StringValue)(obProx["OwnerID"].GetDataValue())).value, id + " has been launched from " + parentObjectID + " at " + pursueTargetID)); distClient.PutEvent(SimUtility.BuildHistory_SubplatformLaunchEvent(ref simModel, time, id, parentObjectID, parentVec, launchDestVec, true, pursueTargetID)); } else { distClient.PutEvent(SimUtility.BuildSystemMessageEvent(ref simModel, time, ((StringValue)(obProx["OwnerID"].GetDataValue())).value, id + " has been undocked from " + parentObjectID)); distClient.PutEvent(SimUtility.BuildHistory_SubplatformLaunchEvent(ref simModel, time, id, parentObjectID, parentVec, launchDestVec, false, "")); } } } #endregion #region Pursue Logic /*if (pursueStarted) { if (objectProxies.ContainsKey(pursueTargetID)) { dv = objectProxies[pursueTargetID]["Location"].GetDataValue(); String targetState = ((StringValue)objectProxies[pursueTargetID]["State"].GetDataValue()).value; if (!((LocationValue)dv).exists || targetState == "Dead") { //if my target is dead or not existant, kill this weapon too. obProx["PursueStarted"].SetDataValue(DataValueFactory.BuildBoolean(false)); obProx["PursueTargetID"].SetDataValue(DataValueFactory.BuildString(String.Empty)); distClient.PutEvent(SimUtility.BuildStateChangeEvent(ref simModel, time, id, "Dead")); continue; } destVec.Set((LocationValue)dv); obProx["DestinationLocation"].SetDataValue(destVec.ToLocationValue()); dv = obProx["Throttle"].GetDataValue(); ((DoubleValue)dv).value = 1; obProx["Throttle"].SetDataValue(dv); distClient.PutEvent(SimUtility.BuildHistory_PursueEvent(ref simModel, time, id, curLocVec, pursueTargetID, destVec)); } }*/ #endregion //********************************* // MoveObject logic //********************************* // /* // Ignore objects that don't have a location // dv = obProx["Location"].GetDataValue(); if (!((LocationValue)dv).exists) { continue; } curLocVec.Set((LocationValue)dv); //dv = obProx["Velocity"].GetDataValue(); //velVec.Set((VelocityValue)dv); dv = obProx["DestinationLocation"].GetDataValue(); if (!((LocationValue)dv).exists) { destVec.Set(curLocVec); obProx["DestinationLocation"].SetDataValue(destVec.ToLocationValue()); } else { destVec.Set((LocationValue)dv); } dv = obProx["Throttle"].GetDataValue(); double throttle = ((DoubleValue)dv).value; dv = obProx["MaximumSpeed"].GetDataValue(); double maxSpeed = ((DoubleValue)dv).value; // // If the object's throttle or maximum speed are zero, set velocity to (0,0,0) and // set the destination to the current location // if (throttle == 0 || maxSpeed == 0 || ((StringValue)obProx["State"].GetDataValue()).value == "Dead") { velVec.Set(0, 0, 0); obProx["Velocity"].SetDataValue(velVec.ToVelocityValue()); destVec.Set(curLocVec); obProx["DestinationLocation"].SetDataValue(destVec.ToLocationValue()); dv = obProx["Throttle"].GetDataValue(); ((DoubleValue)dv).value = 0; obProx["Throttle"].SetDataValue(dv); } */ // // Update what active regions the object is in. // StateDB.physicalObjects[id].activeRegions = GetActiveRegions(curLocVec); dv = obProx["InActiveRegions"].GetDataValue(); ((StringListValue)dv).strings = StateDB.physicalObjects[id].activeRegions; obProx["InActiveRegions"].SetDataValue(dv); double speedMultiplier = GetActiveRegionSpeedMultiplier(StateDB.physicalObjects[id].activeRegions); dv = obProx["ActiveRegionSpeedMultiplier"].GetDataValue(); if (((DoubleValue)dv).value != speedMultiplier) { ((DoubleValue)dv).value = speedMultiplier; obProx["ActiveRegionSpeedMultiplier"].SetDataValue(dv); //distClient.PutEvent(SimUtility.BuildActiveRegionSpeedMultiplierUpdateEvent(ref simModel, time, id)); distributor.viewProBackChannelEvents.Add(SimUtility.BuildActiveRegionSpeedMultiplierUpdateEvent(ref simModel, time, id)); } if (time % 1000 == 0) { actorFrame.objectID = id; actorFrame.speciesName = StateDB.physicalObjects[id].speciesName; actorFrame.ownerID = StateDB.physicalObjects[id].ownerID; actorFrame.activeRegions = StateDB.physicalObjects[id].activeRegions; ScoringDB.UpdateScore_ObjectExists(actorFrame); } // // Update the object's velocity based on its destinations, throttle, and maximum speed. // /* if (curLocVec.ScalerDistanceTo(destVec) > 0.01) { double degCurHeading = 0.0; double degDestHeading = 0.0; // headingVector = new Vec3D(((VelocityValue)obProx["Heading"].GetDataValue())); degCurHeading = ((DoubleValue)obProx["Heading"].GetDataValue()).value;//180 / Math.PI * Math.Atan2(headingVector.X, headingVector.Y); double tx = Math.Sin(degCurHeading / 180 * Math.PI);// /180*Math.PI; double ty = Math.Cos(degCurHeading / 180 * Math.PI);///180*Math.PI; headingVector = new Vec3D(tx, ty, 0); //TODO: Adjust velocity vector based on heading if (curLocVec.ScalerDistanceTo(destVec) >= (maxSpeed * throttle * dTime * speedMultiplier)) { velVec = headingVector; velVec = velVec.Multiply(maxSpeed * throttle * speedMultiplier); // // Update the object's location based on its velocity // newLocVec.X = curLocVec.X + (velVec.X * dTime); newLocVec.Y = curLocVec.Y + (velVec.Y * dTime); newLocVec.Z = curLocVec.Z + (velVec.Z * dTime); } else { velVec = destVec.Subtract(curLocVec); // // Update the object's location based on its velocity // newLocVec.X = curLocVec.X + (velVec.X); newLocVec.Y = curLocVec.Y + (velVec.Y); newLocVec.Z = curLocVec.Z + (velVec.Z); } //TODO: adjust position based on velocity vector obProx["Velocity"].SetDataValue(velVec.ToVelocityValue()); // // Update the object's location based on its velocity // -- AD: Moved up, as dTime was exponentially reducing object speed rather than stopping quickly. //newLocVec.X = curLocVec.X + (velVec.X * dTime); //newLocVec.Y = curLocVec.Y + (velVec.Y * dTime); //newLocVec.Z = curLocVec.Z + (velVec.Z * dTime); //TODO: Adjust heading if needed if (curLocVec.ScalerDistanceTo(destVec) >= (maxSpeed * throttle * dTime * speedMultiplier)) { headingVector = curLocVec.VectorDistanceTo(destVec); headingVector.Normalize(); //velVec = velVec.Multiply(maxSpeed * throttle * speedMultiplier); } else { headingVector = destVec.Subtract(curLocVec); headingVector.Normalize(); } degDestHeading = 180 / Math.PI * Math.Atan2(headingVector.X, headingVector.Y); double newDiff = 0.0; if (degDestHeading > degCurHeading) { newDiff = degDestHeading - degCurHeading; } else { newDiff = degCurHeading - degDestHeading; } if (degDestHeading < 0) degDestHeading = 360 + degDestHeading; if (degCurHeading < 0) degCurHeading = 360 + degCurHeading; if (degDestHeading != degCurHeading) { double deltaDegrees = _maxTurnAngle; double diff = Math.Abs(degDestHeading - degCurHeading); deltaDegrees = Math.Min(deltaDegrees, diff); if ((degDestHeading > degCurHeading && diff < 180) || (degDestHeading < degCurHeading && diff > 180)) { //add to heading degCurHeading += deltaDegrees; } else { //subtract from heading degCurHeading -= deltaDegrees; } degCurHeading = degCurHeading % 360; Vec3D newHeadingVector = new Vec3D(Math.Sin(degCurHeading / 180 * Math.PI), Math.Cos(degCurHeading / 180 * Math.PI), 0); headingVector = newHeadingVector; } else { } //obProx["Heading"].SetDataValue(headingVector.ToVelocityValue()); obProx["Heading"].SetDataValue(DataValueFactory.BuildDouble(degCurHeading)); Console.WriteLine(String.Format("Tick; New Location:({0},{1}); New Heading Vector:({2},{3}); Heading:{4}", newLocVec.X, newLocVec.Y, headingVector.X, headingVector.Y, degCurHeading)); //Console.WriteLine("New Location: {"+newLocVec.X+","+newLocVec.Y+"}"); //Console.WriteLine("New Velocity Vector: {" + velVec.X + "," + velVec.Y + "}"); // TODO: Do obstruction check here bool stopMotion = false; switch (obProx.GetObjectType()) { case "SeaObject": if (!IsOnSea(newLocVec)) { stopMotion = true; distClient.PutEvent(SimUtility.BuildSystemMessageEvent(ref simModel, time, ((StringValue)(obProx["OwnerID"].GetDataValue())).value, id + " has been blocked by land")); } break; case "LandObject": if (!IsOnLand(newLocVec)) { stopMotion = true; distClient.PutEvent(SimUtility.BuildSystemMessageEvent(ref simModel, time, ((StringValue)(obProx["OwnerID"].GetDataValue())).value, id + " has been blocked by sea")); } break; default: break; } if (IsObstructed(curLocVec, newLocVec, id)) { stopMotion = true; } if (!stopMotion) { curLocVec.Set(newLocVec); obProx["Location"].SetDataValue(curLocVec.ToLocationValue()); //Now that location has been updated, set in helper library: ObjectDistances.UpdateObjectLocation(id, curLocVec); } else { obProx["Location"].SetDataValue(curLocVec.ToLocationValue()); //Now that location has been updated, set in helper library: ObjectDistances.UpdateObjectLocation(id, curLocVec); destVec.Set(curLocVec); obProx["DestinationLocation"].SetDataValue(destVec.ToLocationValue()); distClient.PutEvent(SimUtility.BuildMoveDoneEvent(ref simModel, time, id, "Obstruction")); distributor.viewProBackChannelEvents.Add(SimUtility.BuildMoveDoneEvent(ref simModel, time, id, "Obstruction")); dv = obProx["Throttle"].GetDataValue(); ((DoubleValue)dv).value = 0; obProx["Throttle"].SetDataValue(dv); distClient.PutEvent(SimUtility.BuildSystemMessageEvent(ref simModel, time, ((StringValue)(obProx["OwnerID"].GetDataValue())).value, id + " was stopped by an obstruction")); } } else // if the object has reached its destination and is not pursuing, send MoveDone { velVec.Set(0, 0, 0); newLocVec.Set(destVec); obProx["Location"].SetDataValue(newLocVec.ToLocationValue()); //Now that location has been updated, set in helper library: ObjectDistances.UpdateObjectLocation(id, newLocVec); obProx["Velocity"].SetDataValue(velVec.ToVelocityValue()); if (!pursueStarted && throttle > 0) { // TODO: Make sure MoveDone is being sent correctly. distClient.PutEvent(SimUtility.BuildMoveDoneEvent(ref simModel, time, id, "ReachedDestination")); distributor.viewProBackChannelEvents.Add(SimUtility.BuildMoveDoneEvent(ref simModel, time, id, "ReachedDestination")); dv = obProx["Throttle"].GetDataValue(); ((DoubleValue)dv).value = 0; obProx["Throttle"].SetDataValue(dv); distClient.PutEvent(SimUtility.BuildSystemMessageEvent(ref simModel, time, ((StringValue)(obProx["OwnerID"].GetDataValue())).value, id + " has reached its destination")); } }*/ } }
static public SimulationEvent BuildHistory_PursueEvent(ref SimulationModelInfo simModel, int time, string objectID, Vec3D objectLocation, string targetObjectID, Vec3D targetLocation) { SimulationEvent sc = SimulationEventFactory.BuildEvent(ref simModel, "History_Pursue"); ((IntegerValue)sc["Time"]).value = time; ((StringValue)sc["ObjectID"]).value = objectID; sc["ObjectLocation"] = (DataValue)objectLocation.ToLocationValue(); ((StringValue)sc["TargetObjectID"]).value = targetObjectID; sc["TargetObjectLocation"] = (DataValue)targetLocation.ToLocationValue(); return sc; }