// get the atom with the highest Sim() value to me in a structure public static clsGroundAtom findMostSimilarInStructure(clsGroundAtom me, clsPolygon structure) { // find most similar only in this agent's public space List <clsGroundAtom> comparisonAtoms = me.m_GameObject.getQuadTreeByStructure(structure).SearchEntities(me.curr_X, me.curr_Y, me.proxemics.publicSpace, isPrecise: true); return(findMostSimilarFromGroup(me, comparisonAtoms)); }
public static void CheckNextMission(clsGroundAtom refGroundAtom) { List <clsActivityBase> Activites = null; refGroundAtom.m_GameObject.m_GroundActivities.TryGetValue(refGroundAtom.GUID, out Activites); if (Activites == null) { return; } clsActivityBase ActivityFound = null; foreach (clsActivityBase Activity in Activites) { if (Activity.isEnded == false) { if (Activity.TimeFrom <= refGroundAtom.m_GameObject.Ex_clockDate && refGroundAtom.m_GameObject.Ex_clockDate < Activity.TimeTo) { ActivityFound = Activity; break; } } } if (ActivityFound != null) { switch (ActivityFound.ActivityType) { case enumActivity.MovementActivity: // Yinon Douchan: changed to new state refGroundAtom.ChangeState(new REGULAR_MOVEMENT_STATE(ActivityFound as clsActivityMovement)); // ----------------------------------------- break; } } }
// get the atom with the highest Sim() value to me public static clsGroundAtom findMostSimilarByDistanceAndAzimuth(clsGroundAtom me) { // find most similar only in this agent's public space List <clsGroundAtom> comparisonAtoms = me.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(me.curr_X, me.curr_Y, me.proxemics.publicSpace, isPrecise: true); return(findMostSimilarFromGroup(me, comparisonAtoms)); }
// get the atom with the highest Sim() value public static clsGroundAtom findMostSimilarFromGroup(clsGroundAtom me, List <clsGroundAtom> others) { if (others == null || others.Count == 0) { return(null); } double maxSimilarityValue = Double.MinValue; clsGroundAtom mostSimilarAtom = null; foreach (clsGroundAtom other in others) { // why compare to myself? why on earth compare myself to someone who can't move or is dead? if (other == me || other.healthStatus.isDead || other.healthStatus.isIncapacitated) { continue; } double similarity = calculateSimilarity(me, other); if (similarity >= maxSimilarityValue && similarity > SMIN && similarity < SMAX) { maxSimilarityValue = similarity; mostSimilarAtom = other; } } return(mostSimilarAtom); }
public static double calculateSimilarity(clsGroundAtom me, clsGroundAtom other) { double distanceReciproc = 1 / TerrainService.MathEngine.CalcDistance(me.curr_X, me.curr_Y, other.curr_X, other.curr_Y); if (Util.getAzimuthDifferenceDegrees(me.currentAzimuth, other.currentAzimuth) > SAME_DIRECTION_MARGIN_DEGREES) { return 0; } if (distanceReciproc > 1) return 0; else return 2 + 2 * distanceReciproc; }
public static void correctBehaviorToMostSimilar(clsGroundAtom me, clsGroundAtom mostSimilar, double baselineSpeed) { // for now correct speed and azimuth towards most similar double speedDifference = me.currentSpeed - mostSimilar.currentSpeed; double distance = TerrainService.MathEngine.CalcDistance(me.curr_X, me.curr_Y, mostSimilar.curr_X, mostSimilar.curr_Y); double minDistance = me.getSocialDistance(); // minimal distance based on proxemics double maxDistance = 5; // above 5 meters is far enough to have the same drive to minimize distance // gains per second of simulation double speedGain = 1 + 0.1 * (Math.Min(5, distance) - minDistance) * (double)me.m_GameObject.m_GameManager.GroundCycleResolution / 1000f; me.currentSpeed = speedGain * mostSimilar.currentSpeed; // don't go too fast in relation to the speed of who you compare to, you're not Usain Bolt me.currentSpeed = Math.Min(me.currentSpeed, Math.Min(2 * baselineSpeed, 2 * mostSimilar.currentSpeed)); }
// get the atom with the highest Sim() value public static clsGroundAtom findMostSimilarFromGroup(clsGroundAtom me, List<clsGroundAtom> others) { if (others == null || others.Count == 0) return null; double maxSimilarityValue = Double.MinValue; clsGroundAtom mostSimilarAtom = null; foreach (clsGroundAtom other in others) { if (other == me) continue; double similarity = calculateSimilarity(me, other); if (similarity >= maxSimilarityValue && similarity > SMIN && similarity < SMAX) { maxSimilarityValue = similarity; mostSimilarAtom = other; } } return mostSimilarAtom; }
public static void setOffsetTowardsMostSimilar(clsGroundAtom me, clsGroundAtom mostSimilar) { // set offset towards most similar atom if (mostSimilar.Offset_Distance - me.Offset_Distance > 0) { me.Offset_Distance += clsGroundAtom.OFFSET_IN_COLLISION; } else if (mostSimilar.Offset_Distance - me.Offset_Distance < 0) { me.Offset_Distance -= clsGroundAtom.OFFSET_IN_COLLISION; } else { // if most similar has the same offset like me choose a side randomly if (Util.random.NextDouble() > 0.5) { me.Offset_Distance += clsGroundAtom.OFFSET_IN_COLLISION; } else { me.Offset_Distance -= clsGroundAtom.OFFSET_IN_COLLISION; } } }
public static double calculateSimilarity(clsGroundAtom me, clsGroundAtom other) { // first factor: distance - the closer an entity is, the more similar. double distanceReciproc = 1 / TerrainService.MathEngine.CalcDistance(me.curr_X, me.curr_Y, other.curr_X, other.curr_Y); // second factor: difference in heading. If it is heading towards me it is similar, if it is not heading towards me, it is not. // important: We chose a binary threshold for this yet we think it needs to be soft if (Util.getAzimuthDifferenceDegrees(me.currentAzimuth, other.currentAzimuth) > SAME_DIRECTION_MARGIN_DEGREES) { return(0); } // sim value for gender double genderSimilarity = (me.gender == other.gender ? 1 : 0) * me.genderBiasFactor; if (distanceReciproc > 1) { return(0); } else { return(2 + DISTANCE_WEIGHT * distanceReciproc + GENDER_BIAS_WEIGHT * genderSimilarity); } }
public void RefreshActivity(GeneralActivityDTO ActivityDTO) { AtomBase GroundAtombase = null; GroundAtomObjectCollection.TryGetValue(ActivityDTO.Atom.UnitGuid, out GroundAtombase); if (GroundAtombase == null) { clsGroundAtom GroundAtom = new clsGroundAtom(this); GroundAtom.MyName = ActivityDTO.Atom.UnitName; GroundAtom.GUID = ActivityDTO.Atom.UnitGuid; GroundAtom.curr_X = ActivityDTO.Atom.Location.x; GroundAtom.curr_Y = ActivityDTO.Atom.Location.y; GroundAtomObjectCollection.TryAdd(GroundAtom.GUID, GroundAtom); NotifyClientsEndCycleArgs args = new NotifyClientsEndCycleArgs(); args = new NotifyClientsEndCycleArgs(); args.Transport2Client.Ex_clockDate = Ex_clockDate; // args.Transport2Client.ExClockRatioSpeed = m_GameManager.ExClockRatioSpeed; args.Transport2Client.AtomObjectType = 2; args.Transport2Client.AtomObjectCollection = PrepareGroundCommonProperty(); args.Transport2Client.ManagerStatus = m_GameManager.ManagerStatus; m_GameManager.NotifyClientsEndCycle(args); } }
public AtomData DeployFormationFromTree(DeployedFormation deployFormation) { if (GroundAtomObjectCollection.ContainsKey(deployFormation.formation.GUID)) return null; AtomData atom = new AtomData(); atom.Location = new DPoint(deployFormation.x, deployFormation.y); atom.UnitGuid = deployFormation.formation.GUID; atom.UnitName = deployFormation.formation.Identification; TDS.DAL.AtomsDB.AddAtom(atom); clsGroundAtom GroundAtom = new clsGroundAtom(this); GroundAtom.MyName = atom.UnitName; GroundAtom.GUID = atom.UnitGuid; GroundAtom.curr_X = atom.Location.x; GroundAtom.curr_Y = atom.Location.y; GroundAtomObjectCollection.TryAdd(GroundAtom.GUID, GroundAtom); m_GameManager.QuadTreeGroundAtom.PositionUpdate(GroundAtom); NotifyClientsEndCycleArgs args = new NotifyClientsEndCycleArgs(); args = new NotifyClientsEndCycleArgs(); args.Transport2Client.Ex_clockDate = Ex_clockDate; // args.Transport2Client.ExClockRatioSpeed = m_GameManager.ExClockRatioSpeed; args.Transport2Client.AtomObjectType = 2; args.Transport2Client.AtomObjectCollection = PrepareGroundCommonProperty(); args.Transport2Client.ManagerStatus = m_GameManager.ManagerStatus; m_GameManager.NotifyClientsEndCycle(args); return atom; }
private void GroundAtomsInit() { GroundAtomObjectCollection = new ConcurrentDictionary<string, AtomBase>(); IEnumerable<AtomData> atoms = TDS.DAL.AtomsDB.GetAllAtoms(); if (atoms == null) return; foreach(AtomData atom in atoms) { clsGroundAtom GroundAtom = new clsGroundAtom(this); GroundAtom.MyName = atom.UnitName; GroundAtom.GUID = atom.UnitGuid; GroundAtom.X_Route = atom.Location.x; GroundAtom.Y_Route = atom.Location.y; GroundAtom.curr_X = atom.Location.x; GroundAtom.curr_Y = atom.Location.y; GroundAtomObjectCollection.TryAdd(GroundAtom.GUID, GroundAtom); m_GameManager.QuadTreeGroundAtom.PositionUpdate(GroundAtom); //VH GroundAtom.ChangeState(new ADMINISTRATIVE_STATE()); } }
private clsGroundAtom[] randomizeAtomsOnSidewalks(int Qty) { DPoint[] travelCoordinates = getRegularMovementCoordinates(); clsGroundAtom[] atoms = new clsGroundAtom[Qty]; for (int i = 0; i < atoms.Count(); i++) { atoms[i] = new clsGroundAtom(this); // init ID related fields atoms[i].MyName = "Sidewalk" + i; atoms[i].GUID = Util.CretaeGuid(); // init starting point int startLocationIndex = Util.random.Next(travelCoordinates.Count()); int minutes = Util.random.Next(1); int seconds = Util.random.Next(1, 60); int endLocationIndex = Util.random.Next(travelCoordinates.Count() - 1); // make sure start and end location indices are not the same if (startLocationIndex == endLocationIndex) endLocationIndex++; Route route = RouteUtils.typRouteToRoute(travelRoutes[startLocationIndex, endLocationIndex]); // init activity clsActivityMovement activity = RouteUtils.createActivityAndStart(atoms[i], Util.random.Next(3, 11), route); activity.TimeFrom = DateTime.Now.AddMinutes(minutes).AddSeconds(seconds); List<clsActivityBase> activities = new List<clsActivityBase>(); activities.Add(activity); m_GroundActivities.Add(atoms[i].GUID, activities); atoms[i].currentStartWaypoint = startLocationIndex; atoms[i].currentEndWaypoint = endLocationIndex; atoms[i].curr_X = travelRoutes[startLocationIndex, endLocationIndex].arr_legs.ElementAt(0).FromLongn; atoms[i].curr_Y = travelRoutes[startLocationIndex, endLocationIndex].arr_legs.ElementAt(0).FromLatn; atoms[i].X_Route = atoms[i].curr_X; atoms[i].Y_Route = atoms[i].curr_Y; atoms[i].currPosition = new TerrainService.Vector(atoms[i].curr_X, atoms[i].curr_Y, 0); // add atom to collection GroundAtomObjectCollection.TryAdd(atoms[i].GUID, atoms[i]); // update atom position m_GameManager.QuadTreeGroundAtom.PositionUpdate(atoms[i]); // set state atoms[i].ChangeState(new ADMINISTRATIVE_STATE()); } return atoms; }
public PointData lookForClosestRouteToBarrier(clsGroundAtom refGroundAtom, Barrier barrier) { double minDistance = Double.PositiveInfinity; DPoint minPoint = null; foreach (DPoint point in routesToBarriersDataMap.Keys) { double distanceFromAtom = TerrainService.MathEngine.CalcDistance(refGroundAtom.curr_X, refGroundAtom.curr_Y, point.x, point.y); int barrierIndex = routesToBarriersDataMap[point].routeIndex2; if (distanceFromAtom < minDistance && barriers[barrierIndex] == barrier) { minDistance = distanceFromAtom; minPoint = point; } } return routesToBarriersDataMap[minPoint]; }
public PointData lookForClosestRegularRoute(clsGroundAtom refGroundAtom) { double minDistance = Double.PositiveInfinity; DPoint minPoint = null; foreach (DPoint point in pointDataMap.Keys) { double distanceFromAtom = TerrainService.MathEngine.CalcDistance(refGroundAtom.curr_X, refGroundAtom.curr_Y, point.x, point.y); if (distanceFromAtom < minDistance) { minDistance = distanceFromAtom; minPoint = point; } } return pointDataMap[minPoint]; }
private clsGroundAtom[] RandomizeAtomsInArea(clsPolygon Structure, ref QuadTree<clsGroundAtom> quadTree, int Qty) { double minX = double.MaxValue; double maxX = 0; double minY = double.MaxValue; double maxY = 0; IEnumerable<TerrainService.shPoint> PolPnts = Structure.Points; clsGroundAtom[] Atoms = new clsGroundAtom[Qty]; System.Random Rnd = new Random(); foreach(var pnt in PolPnts) { if (pnt.x > maxX) maxX = pnt.x; if (pnt.x < minX) minX = pnt.x; if (pnt.y > maxY) maxY = pnt.y; if (pnt.y < minY) minY = pnt.y; } DAreaRect rect = new DAreaRect(minX, minY, maxX, maxY); quadTree = new QuadTree<clsGroundAtom>(rect, 0, null); for (int i = 0; i < Qty; i++) { double vRnd = Rnd.NextDouble(); double randX = minX + (maxX - minX) * vRnd; vRnd = Rnd.NextDouble(); double randY = minY + (maxY - minY) * vRnd; // choose a random waypoint between rooms and corridors List<PolygonWaypoint> roomsAndCorridors = new List<PolygonWaypoint>(); roomsAndCorridors.AddRange(Structure.waypointGraph.rooms); roomsAndCorridors.AddRange(Structure.waypointGraph.corridors); int randomWaypointIndex = Rnd.Next(roomsAndCorridors.Count()); PolygonWaypoint waypoint = roomsAndCorridors[randomWaypointIndex]; TerrainService.shPoint[] Pnts=PolPnts.ToArray(); while (true) { bool inPolygon =TerrainService.GeometryHelper.GeometryMath.isPointInPolygon(randX, randY,ref Pnts); if (inPolygon == true) { clsGroundAtom GroundAtom = new clsGroundAtom(this); GroundAtom = new clsGroundAtom(this); GroundAtom.GUID = Util.CretaeGuid(); GroundAtom.MyName = GroundAtom.GUID; // YD: generate position by waypoints and not randomly //GroundAtom.curr_X = randX; //GroundAtom.curr_Y = randY; //GroundAtom.currPosition = new TerrainService.Vector(randX, randY, 0); GroundAtom.curr_X = waypoint.x; GroundAtom.curr_Y = waypoint.y; GroundAtom.currPosition = new TerrainService.Vector(waypoint.x, waypoint.y, 0); GroundAtom.currentStructureWaypoint = waypoint; GroundAtom.currentAzimuth = Util.Azimuth2Points(GroundAtom.curr_X, GroundAtom.curr_Y, GroundAtom.currentStructureWaypoint.x, GroundAtom.currentStructureWaypoint.y); // set speed randomly and not fixed GroundAtom.currentSpeed = Rnd.Next(3, 8); Atoms[i] = GroundAtom; GroundAtomObjectCollection.TryAdd(GroundAtom.GUID, GroundAtom); GroundAtom.ChangeState(new REGULAR_MOVEMENT_IN_STRUCTURE_STATE(Structure, GroundAtom.currentStructureWaypoint)); m_GameManager.QuadTreeStructure1GroundAtom.PositionUpdate(GroundAtom); break; } else { vRnd = Rnd.NextDouble(); randX = minX + (maxX - minX) * vRnd; vRnd = Rnd.NextDouble(); randY = minY + (maxY - minY) * vRnd; } } } return Atoms; }
// get the atom with the highest Sim() value to me public static clsGroundAtom findMostSimilar(clsGroundAtom me) { List<clsGroundAtom> comparisonAtoms = me.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(me.curr_X, me.curr_Y, COMPARISON_RADIUS, isPrecise: true); return findMostSimilarFromGroup(me, comparisonAtoms); }
public static void CheckNextMission(clsGroundAtom refGroundAtom) { List<clsActivityBase> Activites = null; refGroundAtom.m_GameObject.m_GroundActivities.TryGetValue(refGroundAtom.GUID, out Activites); if (Activites == null) return; clsActivityBase ActivityFound = null; foreach (clsActivityBase Activity in Activites) { if (Activity.isEnded == false ) { if (Activity.TimeFrom <= refGroundAtom.m_GameObject.Ex_clockDate && refGroundAtom.m_GameObject.Ex_clockDate < Activity.TimeTo) { ActivityFound = Activity; break; } } } if(ActivityFound != null) { switch(ActivityFound.ActivityType) { case enumActivity.MovementActivity: // Yinon Douchan: changed to new state refGroundAtom.ChangeState(new REGULAR_MOVEMENT_STATE(ActivityFound as clsActivityMovement)); // ----------------------------------------- break; } } }
// get the atom with the highest Sim() value to me in a structure public static clsGroundAtom findMostSimilarInStructure(clsGroundAtom me, clsPolygon structure) { List<clsGroundAtom> comparisonAtoms = me.m_GameObject.getQuadTreeByStructure(structure).SearchEntities(me.curr_X, me.curr_Y, COMPARISON_RADIUS, isPrecise: true); return findMostSimilarFromGroup(me, comparisonAtoms); }