public override void Enter(clsGroundAtom refGroundAtom) { // YD: subscribe to event handlers refGroundAtom.earthquakeStartedEventHandler += earthquakeStartedInStructureEventHandler; refGroundAtom.earthquakeEndedEventHandler += earthquakeEndedDefaultEventHandler; refGroundAtom.forcesHaveArrivedEventHandler += forcesHaveArrivedDefaultEventHandler; refGroundAtom.incapacitationEventHandler += incapacitationDefaultEventHandler; refGroundAtom.deathEventHandler += deathDefaultEventHandler; targetPosition = CalculateNextRandomPosition(5000, refGroundAtom.curr_X, refGroundAtom.curr_Y); }
private void exitBuilding(clsGroundAtom refGroundAtom) { double distanceToExit = TerrainService.MathEngine.CalcDistance(refGroundAtom.curr_X, refGroundAtom.curr_Y, targetPosition.x, targetPosition.y); double DeltaTimeSec = refGroundAtom.m_GameObject.m_GameManager.GroundCycleResolution * 0.001; double targetAzimuth = Util.Azimuth2Points(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetPosition.x, targetPosition.y); double stepDistanceInMeters = 1000 * (refGroundAtom.currentSpeed * DeltaTimeSec / 3600); TerrainService.Vector NewPosition = new TerrainService.Vector(); TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetAzimuth, stepDistanceInMeters, out NewPosition.x, out NewPosition.y); TerrainService.GeometryHelper.Edge CrossedEdge = new TerrainService.GeometryHelper.Edge(); TerrainService.shPoint[] Pnts = Structure.Points.ToArray(); bool isCross = TerrainService.GeometryHelper.GeometryMath.isPolygonBorderCross(refGroundAtom.curr_X, refGroundAtom.curr_Y, NewPosition.x, NewPosition.y, ref Pnts, ref CrossedEdge); // reached exit - go away from building, you don't want it to fall on you if (isCross) { // calculate displacement vector TerrainService.Vector currentDirection = NewPosition - new TerrainService.Vector(refGroundAtom.curr_X, refGroundAtom.curr_Y, 0); // calculate edge vector TerrainService.Vector edgePointVector0 = new TerrainService.Vector(CrossedEdge.org.x, CrossedEdge.org.y, 0); TerrainService.Vector edgePointVector1 = new TerrainService.Vector(CrossedEdge.dest.x, CrossedEdge.dest.y, 0); TerrainService.Vector edgeVector = edgePointVector1 - edgePointVector0; // now calculate the perpendicular to the edge TerrainService.Vector projectionOnEdge = edgeVector * (currentDirection * edgeVector) / (edgeVector * edgeVector); TerrainService.Vector perpendicular = currentDirection - projectionOnEdge; // and normalize it perpendicular.normalize(); // get the azimuth perpendicular to the edge double perpendicularAzimuth = Util.Azimuth2Points(0, 0, perpendicular.x, perpendicular.y) + Util.random.NextDouble() * 120 - 30; // distance to go away from building double distanceMeters = 15 * Util.random.NextDouble() + 10; TerrainService.Vector targetLocation = new TerrainService.Vector(); TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.curr_X, refGroundAtom.curr_Y, perpendicularAzimuth, distanceMeters, out targetLocation.x, out targetLocation.y); // decide according to earthquake status if (!refGroundAtom.m_GameObject.forcesHaveArrived()) { // refGroundAtom.clearStageTransitionEventSubscriptions(); refGroundAtom.forcesHaveArrivedEventHandler += forcesHaveArrivedDefaultEventHandler; refGroundAtom.earthquakeEndedEventHandler += earthquakeEndedDefaultEventHandler; clsActivityMovement goAwayActivity = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); refGroundAtom.ChangeState(new GO_AWAY_FROM_BUILDING_STATE(goAwayActivity, targetLocation, Structure, exitEdgeNumber)); return; } else { refGroundAtom.clearStageTransitionEventSubscriptions(); refGroundAtom.clearReevaluationEventSubscription(); refGroundAtom.forcesHaveArrivedEventHandler += forcesHaveArrivedDefaultEventHandler; refGroundAtom.earthquakeEndedEventHandler += earthquakeEndedDefaultEventHandler; refGroundAtom.reEvaluationEventHandler += reevaluationAfterForcesHaveArrivedEventHandler; clsActivityMovement barrierMovement = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); refGroundAtom.resetMovementData(); refGroundAtom.ChangeState(new GO_TO_POLICE_BARRIER_STATE(barrierMovement)); return; } } }
private void MoveInStructure(clsGroundAtom refGroundAtom, int DeltaTime) { double DeltaTimeSec = DeltaTime * 0.001; double dist = refGroundAtom.currentSpeed * DeltaTimeSec / 3600; double oldX = refGroundAtom.curr_X; double oldY = refGroundAtom.curr_Y; // YD - fixed bug where atoms in building travel way to fast than they should be. // Details: In the third line below addition of distance in meters to position in coordinates! //TerrainService.Vector vt = targetPosition - refGroundAtom.currPosition; //vt.normalize(); //TerrainService.Vector NewPosition = refGroundAtom.currPosition + (vt * dist); ////......... TerrainService.Vector vt = targetPosition - refGroundAtom.currPosition; double targetDist = TerrainService.MathEngine.CalcDistance(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetPosition.x, targetPosition.y); double targetAzimuth = Util.Azimuth2Points(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetPosition.x, targetPosition.y); TerrainService.Vector NewPosition = new TerrainService.Vector(); TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetAzimuth, 1000 * dist, out NewPosition.x, out NewPosition.y); // ---------------------------------------------------------------------------------------- // check if in collision clsGroundAtom collidingAtom = null; manageCollisions(refGroundAtom, NewPosition, out collidingAtom); TerrainService.GeometryHelper.Edge CrossedEdge = new TerrainService.GeometryHelper.Edge(); TerrainService.shPoint[] Pnts = Structure.Points.ToArray(); // step aside in case of collision if (!refGroundAtom.isCollision) { // draw avoidance side randomly to when collision will occur int random = Util.random.Next(2) * 2 - 1; refGroundAtom.Offset_Azimuth = 90 * random; } if (refGroundAtom.isCollision) { // choose side to step to according to social comparison theory clsGroundAtom mostSimilar = SocialComparison.findMostSimilarInStructure(refGroundAtom, Structure); if (mostSimilar != null) { TerrainService.Vector headingVector = new TerrainService.Vector(); headingVector.x = targetPosition.x - refGroundAtom.curr_X; headingVector.y = targetPosition.y - refGroundAtom.curr_Y; TerrainService.Vector vectorToMostSimilar = new TerrainService.Vector(); vectorToMostSimilar.x = mostSimilar.curr_X - refGroundAtom.curr_X; vectorToMostSimilar.y = mostSimilar.curr_Y - refGroundAtom.curr_Y; bool mostSimilarIsToTheLeft = (headingVector ^ vectorToMostSimilar).norm() > 0; if (mostSimilarIsToTheLeft) { refGroundAtom.Offset_Azimuth = 90; } else { refGroundAtom.Offset_Azimuth = -90; } } List <CollisionTime> collisions = refGroundAtom.Collisions; double azimuthToCollidingAtom = Util.Azimuth2Points(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, collidingAtom.currPosition.x, collidingAtom.currPosition.y); TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, azimuthToCollidingAtom + refGroundAtom.Offset_Azimuth, 1000 * dist, out NewPosition.x, out NewPosition.y); } bool isCross = TerrainService.GeometryHelper.GeometryMath.isPolygonBorderCross(refGroundAtom.curr_X, refGroundAtom.curr_Y, NewPosition.x, NewPosition.y, ref Pnts, ref CrossedEdge); if (isCross) { CrossedEdge.rot90(); TerrainService.Vector orig = new TerrainService.Vector(CrossedEdge.org.x, CrossedEdge.org.y, 0); TerrainService.Vector dest = new TerrainService.Vector(CrossedEdge.dest.x, CrossedEdge.dest.y, 0); TerrainService.Vector n = dest - orig; n.normalize(); TerrainService.Vector NewD = vt - 2 * (vt * n) * n; NewD.normalize(); TerrainService.Vector NewDirect = NewD * 5000; // YD: calculate new target position according to next waypoint and not randomly //targetPosition = NewDirect; targetPosition = CalculateNextWaypointPosition(refGroundAtom); // --- // YD: Bug fix for moving too fast in buildings //vt = targetPosition - refGroundAtom.currPosition; //vt.normalize(); //NewPosition = refGroundAtom.currPosition + (vt * dist); vt = targetPosition - refGroundAtom.currPosition; targetDist = TerrainService.MathEngine.CalcDistance(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetPosition.x, targetPosition.y) / 1000; targetAzimuth = Util.Azimuth2Points(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetPosition.x, targetPosition.y); TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetAzimuth, 1000 * dist, out NewPosition.x, out NewPosition.y); // --------------------------------------------------------------------------------- //refGroundAtom.currPosition = NewPosition; //refGroundAtom.curr_X = refGroundAtom.currPosition.x; //refGroundAtom.curr_Y = refGroundAtom.currPosition.y; // return; } refGroundAtom.currPosition = NewPosition; // YD: get current azimuth refGroundAtom.currentAzimuth = Util.Azimuth2Points(refGroundAtom.curr_X, refGroundAtom.curr_Y, NewPosition.x, NewPosition.y); refGroundAtom.curr_X = refGroundAtom.currPosition.x; refGroundAtom.curr_Y = refGroundAtom.currPosition.y; bool isIn = TerrainService.GeometryHelper.GeometryMath.isPointInPolygon(refGroundAtom.curr_X, refGroundAtom.curr_Y, ref Pnts); if (isIn == false) { System.Random Rnd = new Random(); while (true) { double vRnd = Rnd.NextDouble(); double randX = Structure.minX + (Structure.maxX - Structure.minX) * vRnd; vRnd = Rnd.NextDouble(); double randY = Structure.minY + (Structure.maxY - Structure.minY) * vRnd; bool inPolygon = TerrainService.GeometryHelper.GeometryMath.isPointInPolygon(randX, randY, ref Pnts); if (inPolygon == true) { refGroundAtom.curr_X = randX; refGroundAtom.curr_Y = randY; refGroundAtom.currPosition = new TerrainService.Vector(randX, randY, 0); // YD: calculate new target position according to next waypoint and not randomly //targetPosition = CalculateNextRandomPosition(5000, refGroundAtom.curr_X, refGroundAtom.curr_Y); targetPosition = CalculateNextWaypointPosition(refGroundAtom); // --- break; } } } // YD: since there are more than once structure, update possition according to the right structure's quadtree refGroundAtom.m_GameObject.getQuadTreeByStructure(Structure).PositionUpdate(refGroundAtom); }
public GO_AWAY_FROM_BUILDING_STATE(clsActivityMovement ActivityMovement, TerrainService.Vector targetPosition, clsPolygon Structure, int exitEdgeNumber) : base(ActivityMovement) { refActivityMovement = ActivityMovement; this.targetPosition = targetPosition; this.Structure = Structure; this.exitEdgeNumber = exitEdgeNumber; }
private void exitBuilding(clsGroundAtom refGroundAtom) { double distanceToExit = TerrainService.MathEngine.CalcDistance(refGroundAtom.curr_X, refGroundAtom.curr_Y, targetPosition.x, targetPosition.y); double DeltaTimeSec = refGroundAtom.m_GameObject.m_GameManager.GroundCycleResolution * 0.001; double targetAzimuth = Util.Azimuth2Points(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetPosition.x, targetPosition.y); double stepDistanceInMeters = 1000 * (refGroundAtom.currentSpeed * DeltaTimeSec / 3600); TerrainService.Vector NewPosition = new TerrainService.Vector(); TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetAzimuth, stepDistanceInMeters, out NewPosition.x, out NewPosition.y); TerrainService.GeometryHelper.Edge CrossedEdge = new TerrainService.GeometryHelper.Edge(); TerrainService.shPoint[] Pnts = Structure.Points.ToArray(); bool isCross = TerrainService.GeometryHelper.GeometryMath.isPolygonBorderCross(refGroundAtom.curr_X, refGroundAtom.curr_Y, NewPosition.x, NewPosition.y, ref Pnts, ref CrossedEdge); // reached exit - go away from building, you don't want it to fall on you if (isCross) { // calculate displacement vector TerrainService.Vector currentDirection = NewPosition - new TerrainService.Vector(refGroundAtom.curr_X, refGroundAtom.curr_Y, 0); // calculate edge vector TerrainService.Vector edgePointVector0 = new TerrainService.Vector(CrossedEdge.org.x, CrossedEdge.org.y, 0); TerrainService.Vector edgePointVector1 = new TerrainService.Vector(CrossedEdge.dest.x, CrossedEdge.dest.y, 0); TerrainService.Vector edgeVector = edgePointVector1 - edgePointVector0; // now calculate the perpendicular to the edge TerrainService.Vector projectionOnEdge = edgeVector * (currentDirection * edgeVector) / (edgeVector * edgeVector); TerrainService.Vector perpendicular = currentDirection - projectionOnEdge; // and normalize it perpendicular.normalize(); // get the azimuth perpendicular to the edge double perpendicularAzimuth = Util.Azimuth2Points(0, 0, perpendicular.x, perpendicular.y) + Util.random.NextDouble() * 120 - 30; // distance to go away from building double distanceMeters = 15 * Util.random.NextDouble() + 10; TerrainService.Vector targetLocation = new TerrainService.Vector(); TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.curr_X, refGroundAtom.curr_Y, perpendicularAzimuth, distanceMeters, out targetLocation.x, out targetLocation.y); clsActivityMovement goAwayActivity = RouteUtils.createActivityAndStart(refGroundAtom, (int)refGroundAtom.currentSpeed, null); refGroundAtom.ChangeState(new GO_AWAY_FROM_BUILDING_STATE(goAwayActivity, targetLocation, Structure, exitEdgeNumber)); return; } }
private void MoveInStructure(clsGroundAtom refGroundAtom,int DeltaTime) { double DeltaTimeSec = DeltaTime * 0.001; double dist = refGroundAtom.currentSpeed * DeltaTimeSec / 3600; double oldX = refGroundAtom.curr_X; double oldY = refGroundAtom.curr_Y; // YD - fixed bug where atoms in building travel way to fast than they should be. // Details: In the third line below addition of distance in meters to position in coordinates! //TerrainService.Vector vt = targetPosition - refGroundAtom.currPosition; //vt.normalize(); //TerrainService.Vector NewPosition = refGroundAtom.currPosition + (vt * dist); ////......... TerrainService.Vector vt = targetPosition - refGroundAtom.currPosition; double targetDist = TerrainService.MathEngine.CalcDistance(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetPosition.x, targetPosition.y); double targetAzimuth = Util.Azimuth2Points(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetPosition.x, targetPosition.y); TerrainService.Vector NewPosition = new TerrainService.Vector(); TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetAzimuth, 1000 * dist, out NewPosition.x, out NewPosition.y); // ---------------------------------------------------------------------------------------- // check if in collision clsGroundAtom collidingAtom = null; manageCollisions(refGroundAtom, NewPosition, out collidingAtom); TerrainService.GeometryHelper.Edge CrossedEdge = new TerrainService.GeometryHelper.Edge(); TerrainService.shPoint[] Pnts = Structure.Points.ToArray(); // step aside in case of collision if (!refGroundAtom.isCollision) { // draw avoidance side randomly to when collision will occur int random = Util.random.Next(2) * 2 - 1; refGroundAtom.Offset_Azimuth = 90 * random; } if (refGroundAtom.isCollision) { // choose side to step to according to social comparison theory clsGroundAtom mostSimilar = SocialComparison.findMostSimilarInStructure(refGroundAtom, Structure); if (mostSimilar != null) { TerrainService.Vector headingVector = new TerrainService.Vector(); headingVector.x = targetPosition.x - refGroundAtom.curr_X; headingVector.y = targetPosition.y - refGroundAtom.curr_Y; TerrainService.Vector vectorToMostSimilar = new TerrainService.Vector(); vectorToMostSimilar.x = mostSimilar.curr_X - refGroundAtom.curr_X; vectorToMostSimilar.y = mostSimilar.curr_Y - refGroundAtom.curr_Y; bool mostSimilarIsToTheLeft = (headingVector ^ vectorToMostSimilar).norm() > 0; if (mostSimilarIsToTheLeft) refGroundAtom.Offset_Azimuth = 90; else refGroundAtom.Offset_Azimuth = -90; } List<CollisionTime> collisions = refGroundAtom.Collisions; double azimuthToCollidingAtom = Util.Azimuth2Points(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, collidingAtom.currPosition.x, collidingAtom.currPosition.y); TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, azimuthToCollidingAtom + refGroundAtom.Offset_Azimuth, 1000 * dist, out NewPosition.x, out NewPosition.y); } bool isCross = TerrainService.GeometryHelper.GeometryMath.isPolygonBorderCross(refGroundAtom.curr_X, refGroundAtom.curr_Y, NewPosition.x, NewPosition.y, ref Pnts, ref CrossedEdge); if (isCross) { CrossedEdge.rot90(); TerrainService.Vector orig = new TerrainService.Vector(CrossedEdge.org.x, CrossedEdge.org.y,0); TerrainService.Vector dest = new TerrainService.Vector(CrossedEdge.dest.x, CrossedEdge.dest.y, 0); TerrainService.Vector n = dest - orig; n.normalize(); TerrainService.Vector NewD = vt - 2 * (vt * n) * n; NewD.normalize(); TerrainService.Vector NewDirect = NewD * 5000; // YD: calculate new target position according to next waypoint and not randomly //targetPosition = NewDirect; targetPosition = CalculateNextWaypointPosition(refGroundAtom); // --- // YD: Bug fix for moving too fast in buildings //vt = targetPosition - refGroundAtom.currPosition; //vt.normalize(); //NewPosition = refGroundAtom.currPosition + (vt * dist); vt = targetPosition - refGroundAtom.currPosition; targetDist = TerrainService.MathEngine.CalcDistance(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetPosition.x, targetPosition.y) / 1000; targetAzimuth = Util.Azimuth2Points(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetPosition.x, targetPosition.y); TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetAzimuth, 1000 * dist, out NewPosition.x, out NewPosition.y); // --------------------------------------------------------------------------------- //refGroundAtom.currPosition = NewPosition; //refGroundAtom.curr_X = refGroundAtom.currPosition.x; //refGroundAtom.curr_Y = refGroundAtom.currPosition.y; // return; } refGroundAtom.currPosition = NewPosition; // YD: get current azimuth refGroundAtom.currentAzimuth = Util.Azimuth2Points(refGroundAtom.curr_X, refGroundAtom.curr_Y, NewPosition.x, NewPosition.y); refGroundAtom.curr_X = refGroundAtom.currPosition.x; refGroundAtom.curr_Y = refGroundAtom.currPosition.y; bool isIn = TerrainService.GeometryHelper.GeometryMath.isPointInPolygon(refGroundAtom.curr_X, refGroundAtom.curr_Y, ref Pnts); if (isIn == false) { System.Random Rnd = new Random(); while (true) { double vRnd = Rnd.NextDouble(); double randX = Structure.minX + (Structure.maxX - Structure.minX) * vRnd; vRnd = Rnd.NextDouble(); double randY = Structure.minY + (Structure.maxY - Structure.minY) * vRnd; bool inPolygon = TerrainService.GeometryHelper.GeometryMath.isPointInPolygon(randX, randY, ref Pnts); if (inPolygon == true) { refGroundAtom.curr_X = randX; refGroundAtom.curr_Y = randY; refGroundAtom.currPosition = new TerrainService.Vector(randX, randY, 0); // YD: calculate new target position according to next waypoint and not randomly //targetPosition = CalculateNextRandomPosition(5000, refGroundAtom.curr_X, refGroundAtom.curr_Y); targetPosition = CalculateNextWaypointPosition(refGroundAtom); // --- break; } } } // YD: since there are more than once structure, update possition according to the right structure's quadtree refGroundAtom.m_GameObject.getQuadTreeByStructure(Structure).PositionUpdate(refGroundAtom); }
public override void Enter(clsGroundAtom refGroundAtom) { refGroundAtom.clearAllEventSubscriptions(); refGroundAtom.forcesHaveArrivedEventHandler += forcesHaveArrivedDefaultEventHandler; exitWaypoints = Structure.waypointGraph.findExitPath(refGroundAtom.currentStructureWaypoint); PolygonWaypoint exitWaypoint = exitWaypoints[exitWaypoints.Count() - 1]; exitEdgeNumber = exitWaypoint.edgeNum; targetPosition = new TerrainService.Vector(); targetPosition.x = exitWaypoints[waypointIndex].x; targetPosition.y = exitWaypoints[waypointIndex].y; waypointIndex++; }
public override void Enter(clsGroundAtom refGroundAtom) { targetPosition = new TerrainService.Vector(); double randomDistance = Util.random.NextDouble() * 10; double randomAzimuth = Util.random.NextDouble() * 360; TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, randomAzimuth, randomDistance, out targetPosition.x, out targetPosition.y); TerrainService.GeometryHelper.Edge CrossedEdge = new TerrainService.GeometryHelper.Edge(); TerrainService.shPoint[] Pnts = Structure.Points.ToArray(); bool isCross = TerrainService.GeometryHelper.GeometryMath.isPolygonBorderCross(refGroundAtom.curr_X, refGroundAtom.curr_Y, targetPosition.x, targetPosition.y, ref Pnts, ref CrossedEdge); if (isCross) { targetPosition.x = refGroundAtom.curr_X; targetPosition.y = refGroundAtom.curr_Y; } }
public override void Enter(clsGroundAtom refGroundAtom) { // subscribe event handlers refGroundAtom.earthquakeStartedEventHandler += earthquakeStartedInStructureEventHandler; refGroundAtom.earthquakeEndedEventHandler += earthquakeEndedDefaultEventHandler; refGroundAtom.forcesHaveArrivedEventHandler += forcesHaveArrivedDefaultEventHandler; refGroundAtom.incapacitationEventHandler += incapacitationDefaultEventHandler; refGroundAtom.deathEventHandler += deathDefaultEventHandler; if (nextWaypoint != null) { targetPosition = new TerrainService.Vector(); targetPosition.x = nextWaypoint.x; targetPosition.y = nextWaypoint.y; } else { targetPosition = CalculateNextWaypointPosition(refGroundAtom); } }
// YD: manage collisions like on sidewalk private void manageCollisions(clsGroundAtom refGroundAtom, TerrainService.Vector newPosition, out clsGroundAtom collidingAtom) { collidingAtom = null; List<CollisionTime> CollisionsToDelete = new List<CollisionTime>(); foreach (var v in refGroundAtom.Collisions) { if ((refGroundAtom.m_GameObject.Ex_clockDate - v.time).TotalSeconds > 2) { CollisionsToDelete.Add(v); } } foreach (var v in CollisionsToDelete) { refGroundAtom.Collisions.Remove(v); } refGroundAtom.isCollision = false; List<clsGroundAtom> colAtoms = refGroundAtom.m_GameObject.getQuadTreeByStructure(Structure).SearchEntities(newPosition.x, newPosition.y, 2 * clsGroundAtom.RADIUS, isPrecise: true); foreach (clsGroundAtom atom in colAtoms) { if (atom != refGroundAtom) { TerrainService.Vector vDest = new TerrainService.Vector(newPosition.x, newPosition.y, 0); TerrainService.Vector vMe = new TerrainService.Vector(refGroundAtom.curr_X, refGroundAtom.curr_Y, 0); TerrainService.Vector vCollision = new TerrainService.Vector(atom.curr_X, atom.curr_Y, 0); TerrainService.Vector MyDirection = vDest - vMe; MyDirection.normalize(); TerrainService.Vector CollisionDirection = vCollision - vMe; CollisionDirection.normalize(); double dot = MyDirection * CollisionDirection; if (dot >= 0.8)// 0.6) //Against Main Direction { // if (atom.Collisions.Contains(refGroundAtom.MyName)) continue; // Fix 03 if (atom.Collisions.Exists(v => v.name == refGroundAtom.MyName)) continue; if (atom.Collisions.Exists(v => v.name == refGroundAtom.MyName)) continue; //Fix 04 - New If double d = TerrainService.MathEngine.CalcDistance(newPosition.x, newPosition.y, atom.curr_X, atom.curr_Y); refGroundAtom.isCollision = true; CollisionTime cTime = new CollisionTime(); cTime.name = atom.MyName; cTime.time = refGroundAtom.m_GameObject.Ex_clockDate; refGroundAtom.Collisions.Add(cTime); collidingAtom = atom; break; } } } }
// YD: get next waypoint to go to in structure internal TerrainService.Vector CalculateNextWaypointPosition(clsGroundAtom refGroundAtom) { // next point is drawn randomly int numOfWaypointNeighbors = refGroundAtom.currentStructureWaypoint.neighbors.Count(); PolygonWaypoint nextWaypoint = refGroundAtom.currentStructureWaypoint.neighbors[Util.random.Next(numOfWaypointNeighbors)]; targetPosition = new TerrainService.Vector(); targetPosition.x = nextWaypoint.x; targetPosition.y = nextWaypoint.y; refGroundAtom.currentStructureWaypoint = nextWaypoint; refGroundAtom.currentAzimuth = Util.Azimuth2Points(refGroundAtom.curr_X, refGroundAtom.curr_Y, nextWaypoint.x, nextWaypoint.y); return targetPosition; }
internal TerrainService.Vector CalculateNextRandomPosition(double MaxRange, double Xcenter, double Ycenter) { double dist = 0; double MapX = 0; double MapY = 0; double azim = 360 * Util.random.NextDouble(); dist = MaxRange; //MaxRange * Util.random.NextDouble(); TerrainService.MathEngine.CalcProjectedLocationNew(Xcenter, Ycenter, azim, dist, out MapX, out MapY); TerrainService.Vector Position = new TerrainService.Vector(MapX, MapY, 0); return Position; }
public override void Execute(clsGroundAtom refGroundAtom) { List <CollisionTime> CollisionsToDelete = new List <CollisionTime>(); foreach (var v in refGroundAtom.Collisions) { if ((refGroundAtom.m_GameObject.Ex_clockDate - v.time).TotalSeconds > 2) { CollisionsToDelete.Add(v); } } foreach (var v in CollisionsToDelete) { refGroundAtom.Collisions.Remove(v); } // refGroundAtom.Collisions.ForEach(t=>(refGroundAtom.m_GameObject.Ex_clockDate-t.time).TotalSeconds>2) if (refActivityMovement.TimeTo < refGroundAtom.m_GameObject.Ex_clockDate) { refActivityMovement.isEnded = true; refActivityMovement.isActive = false; refGroundAtom.ChangeState(new ADMINISTRATIVE_STATE()); return; } if (refGroundAtom.currentRoute == null) { return; } if (refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) //-1) // refActivityMovement.RouteActivity.Points.Count()-1) { // Fix 01 Start int nl = refGroundAtom.currentRoute.arr_legs.Count; double xEnd = refGroundAtom.currentRoute.arr_legs[nl - 1].ToLongn; double yEnd = refGroundAtom.currentRoute.arr_legs[nl - 1].ToLatn; refGroundAtom.curr_X = xEnd; refGroundAtom.curr_Y = yEnd; // Fix 01 End refActivityMovement.isEnded = true; refActivityMovement.isActive = false; refGroundAtom.currentRoute = null; refGroundAtom.ChangeState(new ADMINISTRATIVE_STATE()); return; } double nextRoute_X = 0; double nextRoute_Y = 0; int nextLeg = 0; double X_Distination = 0; double Y_Distination = 0; double AzimDepl; refGroundAtom.VirtualMoveOnRoute(refGroundAtom.m_GameObject.m_GameManager.GroundCycleResolution, refGroundAtom.X_Route, refGroundAtom.Y_Route, out nextRoute_X, out nextRoute_Y, out nextLeg); double currentAzimuth = Util.Azimuth2Points(refGroundAtom.X_Route, refGroundAtom.Y_Route, nextRoute_X, nextRoute_Y); bool isRight = true; // Yinon Douchan: Collision management bool isLeft = true; refGroundAtom.currentAzimuth = currentAzimuth; // ----------------------------------- // refGroundAtom.Collisions.Clear(); Lab1 :; refGroundAtom.isCollision = false; // Fix 02 if (refGroundAtom.Offset_Azimuth != 0.0 || refGroundAtom.Offset_Distance!=0.0) if (refGroundAtom.Offset_Distance != 0.0) { AzimDepl = currentAzimuth + refGroundAtom.Offset_Azimuth; if (AzimDepl >= 360) { AzimDepl = AzimDepl - 360; } TerrainService.MathEngine.CalcProjectedLocationNew(nextRoute_X, nextRoute_Y, AzimDepl, refGroundAtom.Offset_Distance, out X_Distination, out Y_Distination);//, true); } else { X_Distination = nextRoute_X; Y_Distination = nextRoute_Y; } List <clsGroundAtom> colAtoms = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(X_Distination, Y_Distination, refGroundAtom.collisionRadius, isPrecise: true); // List<clsGroundAtom> colAtoms = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(X_Distination, refGroundAtom.curr_Y, clsGroundAtom.OFFSET_IN_COLLISION, isPrecise: true); foreach (clsGroundAtom atom in colAtoms) { if (atom != refGroundAtom) { TerrainService.Vector vDest = new TerrainService.Vector(X_Distination, Y_Distination, 0); TerrainService.Vector vMe = new TerrainService.Vector(refGroundAtom.curr_X, refGroundAtom.curr_Y, 0); TerrainService.Vector vCollision = new TerrainService.Vector(atom.curr_X, atom.curr_Y, 0); TerrainService.Vector MyDirection = vDest - vMe; MyDirection.normalize(); TerrainService.Vector CollisionDirection = vCollision - vMe; CollisionDirection.normalize(); double dot = MyDirection * CollisionDirection; if (dot >= 0.8)// 0.6) //Against Main Direction { // if (atom.Collisions.Contains(refGroundAtom.MyName)) continue; // Fix 03 if (atom.Collisions.Exists(v => v.name == refGroundAtom.MyName)) continue; if (atom.Collisions.Exists(v => v.name == refGroundAtom.MyName)) { continue; } //Fix 04 - New If double d = TerrainService.MathEngine.CalcDistance(X_Distination, Y_Distination, atom.curr_X, atom.curr_Y); refGroundAtom.isCollision = true; CollisionTime cTime = new CollisionTime(); cTime.name = atom.MyName; cTime.time = refGroundAtom.m_GameObject.Ex_clockDate; refGroundAtom.Collisions.Add(cTime); break; } } } if (refGroundAtom.isCollision) { refGroundAtom.Offset_Azimuth = 90; // Yinon Douchan: Modified collision handling // check if I cannot go right or cannot go left if ((refGroundAtom.Offset_Distance + clsGroundAtom.OFFSET_IN_COLLISION) > clsGroundAtom.MAX_OFFSET) { isRight = false; } if ((refGroundAtom.Offset_Distance - clsGroundAtom.OFFSET_IN_COLLISION) < -clsGroundAtom.MAX_OFFSET) { isLeft = false; } if (isRight && !isLeft) { // can only evade right refGroundAtom.Offset_Distance += clsGroundAtom.OFFSET_IN_COLLISION; } else if (isLeft && !isRight) { // can only evade left refGroundAtom.Offset_Distance -= clsGroundAtom.OFFSET_IN_COLLISION; } else if (isLeft && isRight) { // decide whether to turn right or left based on social comparison to most similar clsGroundAtom mostSimilar = SocialComparison.findMostSimilarByDistanceAndAzimuth(refGroundAtom); if (mostSimilar != null) { SocialComparison.setOffsetTowardsMostSimilar(refGroundAtom, mostSimilar); } else { // no similar agent - pick a side randomly if (Util.random.NextDouble() > 0.5) { refGroundAtom.Offset_Distance += clsGroundAtom.OFFSET_IN_COLLISION; } else { refGroundAtom.Offset_Distance -= clsGroundAtom.OFFSET_IN_COLLISION; } } } if (refGroundAtom.Offset_Distance < -clsGroundAtom.MAX_OFFSET) { refGroundAtom.Offset_Distance = -clsGroundAtom.MAX_OFFSET; refGroundAtom.Offset_Azimuth = 0; return; } else if (refGroundAtom.Offset_Distance > clsGroundAtom.MAX_OFFSET) { refGroundAtom.Offset_Distance = clsGroundAtom.MAX_OFFSET; refGroundAtom.Offset_Azimuth = 0; return; } // refGroundAtom.Offset_Distance += clsGroundAtom.OFFSET_IN_COLLISION;// 2*clsGroundAtom.RADIUS; if (refGroundAtom.Offset_Distance < 0) { refGroundAtom.Offset_Azimuth = 180 - refGroundAtom.Offset_Azimuth; } // -------------------------------------------------------------------------- // Yinon Douchan: Commented out - Why are you assigning offsetted position to route position? This caused bugs in movement //nextRoute_X = X_Distination; //nextRoute_Y = Y_Distination; // ------------------------------------------------------------------------------------ // AzimDepl = currentAzimuth + refGroundAtom.Offset_Azimuth; // if (AzimDepl >= 360) AzimDepl = AzimDepl - 360; // TerrainService.MathEngine.CalcProjectedLocationNew(X_Distination, Y_Distination, AzimDepl, refGroundAtom.Offset_Distance, out X_Distination, out Y_Distination);//, true); // Yinon Douchan: Commented out - This caused the simulator to enter an endless loop //goto Lab1; // --------------------------------------------------------------------------------- //AzimDepl = currentAzimuth + refGroundAtom.Offset_Azimuth; //if (AzimDepl >= 360) AzimDepl = AzimDepl - 360; } else { refGroundAtom.X_Route = nextRoute_X; refGroundAtom.Y_Route = nextRoute_Y; refGroundAtom.currentLeg = nextLeg; refGroundAtom.X_Distination = X_Distination; refGroundAtom.Y_Distination = Y_Distination; refGroundAtom.MoveToDestination(refGroundAtom.m_GameObject.m_GameManager.GroundCycleResolution); } //List<clsGroundAtom> colAtoms = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(refGroundAtom.curr_X, refGroundAtom.curr_Y, 10, isPrecise: true); //foreach (clsGroundAtom atom in colAtoms) //{ // if(atom!=refGroundAtom) // { // refGroundAtom.isCollision = true; // break; // } //} //if (refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) //-1) // refActivityMovement.RouteActivity.Points.Count()-1) // { // refActivityMovement.isEnded = true; // refActivityMovement.isActive = false; // refGroundAtom.currentRoute = null; // refGroundAtom.ChangeState(new ADMINISTRATIVE_STATE()); // return; // } //else //{ // refGroundAtom.Move(refGroundAtom.m_GameObject.m_GameManager.GroundCycleResolution); //} }
public override void Execute(clsGroundAtom refGroundAtom) { List<CollisionTime> CollisionsToDelete=new List<CollisionTime>(); foreach(var v in refGroundAtom.Collisions) { if((refGroundAtom.m_GameObject.Ex_clockDate-v.time).TotalSeconds>2) { CollisionsToDelete.Add(v); } } foreach (var v in CollisionsToDelete) { refGroundAtom.Collisions.Remove(v); } // refGroundAtom.Collisions.ForEach(t=>(refGroundAtom.m_GameObject.Ex_clockDate-t.time).TotalSeconds>2) if(refActivityMovement.TimeTo<refGroundAtom.m_GameObject.Ex_clockDate) { refActivityMovement.isEnded = true; refActivityMovement.isActive = false; refGroundAtom.ChangeState(new ADMINISTRATIVE_STATE()); return; } if (refGroundAtom.currentRoute == null) return; if ( refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) //-1) // refActivityMovement.RouteActivity.Points.Count()-1) { // Fix 01 Start int nl = refGroundAtom.currentRoute.arr_legs.Count; double xEnd = refGroundAtom.currentRoute.arr_legs[nl - 1].ToLongn; double yEnd = refGroundAtom.currentRoute.arr_legs[nl - 1].ToLatn; refGroundAtom.curr_X = xEnd; refGroundAtom.curr_Y = yEnd; // Fix 01 End refActivityMovement.isEnded = true; refActivityMovement.isActive = false; refGroundAtom.currentRoute = null; refGroundAtom.ChangeState(new ADMINISTRATIVE_STATE()); return; } double nextRoute_X = 0; double nextRoute_Y = 0; int nextLeg = 0; double X_Distination = 0; double Y_Distination = 0; double AzimDepl; refGroundAtom.VirtualMoveOnRoute(refGroundAtom.m_GameObject.m_GameManager.GroundCycleResolution, refGroundAtom.X_Route, refGroundAtom.Y_Route, out nextRoute_X, out nextRoute_Y,out nextLeg); double currentAzimuth = Util.Azimuth2Points(refGroundAtom.X_Route, refGroundAtom.Y_Route, nextRoute_X, nextRoute_Y); bool isRight = true; // Yinon Douchan: Collision management bool isLeft = true; refGroundAtom.currentAzimuth = currentAzimuth; // ----------------------------------- // refGroundAtom.Collisions.Clear(); Lab1: ; refGroundAtom.isCollision = false; // Fix 02 if (refGroundAtom.Offset_Azimuth != 0.0 || refGroundAtom.Offset_Distance!=0.0) if (refGroundAtom.Offset_Distance != 0.0) { AzimDepl = currentAzimuth + refGroundAtom.Offset_Azimuth; if (AzimDepl >= 360) AzimDepl = AzimDepl - 360; TerrainService.MathEngine.CalcProjectedLocationNew(nextRoute_X, nextRoute_Y, AzimDepl, refGroundAtom.Offset_Distance, out X_Distination, out Y_Distination);//, true); } else { X_Distination = nextRoute_X; Y_Distination = nextRoute_Y; } List<clsGroundAtom> colAtoms = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(X_Distination, Y_Distination, 2 * clsGroundAtom.RADIUS, isPrecise: true); // List<clsGroundAtom> colAtoms = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(X_Distination, refGroundAtom.curr_Y, clsGroundAtom.OFFSET_IN_COLLISION, isPrecise: true); foreach (clsGroundAtom atom in colAtoms) { if (atom != refGroundAtom) { TerrainService.Vector vDest= new TerrainService.Vector(X_Distination, Y_Distination, 0); TerrainService.Vector vMe = new TerrainService.Vector(refGroundAtom.curr_X, refGroundAtom.curr_Y, 0); TerrainService.Vector vCollision = new TerrainService.Vector(atom.curr_X, atom.curr_Y, 0); TerrainService.Vector MyDirection = vDest - vMe; MyDirection.normalize(); TerrainService.Vector CollisionDirection = vCollision - vMe; CollisionDirection.normalize(); double dot = MyDirection * CollisionDirection; if (dot >=0.8)// 0.6) //Against Main Direction { // if (atom.Collisions.Contains(refGroundAtom.MyName)) continue; // Fix 03 if (atom.Collisions.Exists(v => v.name == refGroundAtom.MyName)) continue; if (atom.Collisions.Exists(v => v.name == refGroundAtom.MyName)) continue; //Fix 04 - New If double d = TerrainService.MathEngine.CalcDistance(X_Distination, Y_Distination, atom.curr_X, atom.curr_Y); refGroundAtom.isCollision = true; CollisionTime cTime = new CollisionTime(); cTime.name = atom.MyName; cTime.time = refGroundAtom.m_GameObject.Ex_clockDate; refGroundAtom.Collisions.Add(cTime); break; } } } if(refGroundAtom.isCollision) { refGroundAtom.Offset_Azimuth = 90; // Yinon Douchan: Modified collision handling // check if I cannot go right or cannot go left if ((refGroundAtom.Offset_Distance + clsGroundAtom.OFFSET_IN_COLLISION) > clsGroundAtom.MAX_OFFSET) isRight = false; if ((refGroundAtom.Offset_Distance - clsGroundAtom.OFFSET_IN_COLLISION) < -clsGroundAtom.MAX_OFFSET) isLeft = false; if (isRight && !isLeft) { // can only evade right refGroundAtom.Offset_Distance += clsGroundAtom.OFFSET_IN_COLLISION; } else if (isLeft && !isRight) { // can only evade left refGroundAtom.Offset_Distance -= clsGroundAtom.OFFSET_IN_COLLISION; } else if (isLeft && isRight) { // decide whether to turn right or left based on social comparison to most similar clsGroundAtom mostSimilar = SocialComparison.findMostSimilar(refGroundAtom); if (mostSimilar != null) { SocialComparison.setOffsetTowardsMostSimilar(refGroundAtom, mostSimilar); } else { // no similar agent - pick a side randomly if (Util.random.NextDouble() > 0.5) { refGroundAtom.Offset_Distance += clsGroundAtom.OFFSET_IN_COLLISION; } else { refGroundAtom.Offset_Distance -= clsGroundAtom.OFFSET_IN_COLLISION; } } } if (refGroundAtom.Offset_Distance < -clsGroundAtom.MAX_OFFSET) { refGroundAtom.Offset_Distance = -clsGroundAtom.MAX_OFFSET; refGroundAtom.Offset_Azimuth = 0; return; } else if (refGroundAtom.Offset_Distance > clsGroundAtom.MAX_OFFSET) { refGroundAtom.Offset_Distance = clsGroundAtom.MAX_OFFSET; refGroundAtom.Offset_Azimuth = 0; return; } // refGroundAtom.Offset_Distance += clsGroundAtom.OFFSET_IN_COLLISION;// 2*clsGroundAtom.RADIUS; if (refGroundAtom.Offset_Distance < 0) { refGroundAtom.Offset_Azimuth = 180 - refGroundAtom.Offset_Azimuth; } // -------------------------------------------------------------------------- // Yinon Douchan: Commented out - Why are you assigning offsetted position to route position? This caused bugs in movement //nextRoute_X = X_Distination; //nextRoute_Y = Y_Distination; // ------------------------------------------------------------------------------------ // AzimDepl = currentAzimuth + refGroundAtom.Offset_Azimuth; // if (AzimDepl >= 360) AzimDepl = AzimDepl - 360; // TerrainService.MathEngine.CalcProjectedLocationNew(X_Distination, Y_Distination, AzimDepl, refGroundAtom.Offset_Distance, out X_Distination, out Y_Distination);//, true); // Yinon Douchan: Commented out - This caused the simulator to enter an endless loop //goto Lab1; // --------------------------------------------------------------------------------- //AzimDepl = currentAzimuth + refGroundAtom.Offset_Azimuth; //if (AzimDepl >= 360) AzimDepl = AzimDepl - 360; } else { refGroundAtom.X_Route = nextRoute_X; refGroundAtom.Y_Route = nextRoute_Y; refGroundAtom.currentLeg = nextLeg; refGroundAtom.X_Distination = X_Distination; refGroundAtom.Y_Distination = Y_Distination; refGroundAtom.MoveToDestination(refGroundAtom.m_GameObject.m_GameManager.GroundCycleResolution); } //List<clsGroundAtom> colAtoms = refGroundAtom.m_GameObject.m_GameManager.QuadTreeGroundAtom.SearchEntities(refGroundAtom.curr_X, refGroundAtom.curr_Y, 10, isPrecise: true); //foreach (clsGroundAtom atom in colAtoms) //{ // if(atom!=refGroundAtom) // { // refGroundAtom.isCollision = true; // break; // } //} //if (refGroundAtom.currentLeg > refGroundAtom.currentRoute.arr_legs.Count) //-1) // refActivityMovement.RouteActivity.Points.Count()-1) // { // refActivityMovement.isEnded = true; // refActivityMovement.isActive = false; // refGroundAtom.currentRoute = null; // refGroundAtom.ChangeState(new ADMINISTRATIVE_STATE()); // return; // } //else //{ // refGroundAtom.Move(refGroundAtom.m_GameObject.m_GameManager.GroundCycleResolution); //} }