//----------------------------------------------------------------------- /// <summary> /// 查找交集 /// </summary> public void _calcIntersections() { mIntersectionsMap.Clear(); mIntersections.Clear(); //std::map<Ogre::Vector3, PathIntersection, Vector3Comparator> pointSet; std_map <Vector3, std_vector <PathCoordinate> > pointSet = new std_map <Vector3, std_vector <PathCoordinate> >(new Vector3Comparator()); // for (std::vector<Path>::iterator it = mPaths.begin(); it!= mPaths.end(); ++it) uint it_index = 0; foreach (var it in mPaths) { uint it_point_index = 0; //for (std::vector<Ogre::Vector3>::const_iterator it2 = it->getPoints().begin(); it2 != it->getPoints().end(); ++it2) foreach (var it2 in it._getPoints()) { //PathCoordinate pc(it-mPaths.begin(), it2-it->getPoints().begin()); PathCoordinate pc = new PathCoordinate(it_index, it_point_index); //if (pointSet.find(*it2)==pointSet.end()) if (!pointSet.ContainsKey(it2)) { std_vector <PathCoordinate> pi = new std_vector <PathCoordinate>(); pi.Add(pc); //pointSet[it2] = pi; pointSet.Add(it2, pi); } else { pointSet[it2].push_back(pc); } it_point_index++; } it_index++; } //for (std::map<Ogre::Vector3, PathIntersection, Vector3Comparator>::iterator it = pointSet.begin(); it != pointSet.end(); ++it) foreach (var it_ps in pointSet) { if (it_ps.Value.size() > 1) { foreach (var it2 in it_ps.Value) { //mIntersectionsMap[*it2] = it->second; if (mIntersectionsMap.ContainsKey(it2)) { mIntersectionsMap[it2] = it_ps.Value; } else { mIntersectionsMap.Add(it2, it_ps.Value); } } mIntersections.push_back(it_ps.Value); } } // }
//----------------------------------------------------------------------- /// <summary> /// 查找交集 /// </summary> public void _calcIntersections() { mIntersectionsMap.Clear(); mIntersections.Clear(); //std::map<Ogre::Vector3, PathIntersection, Vector3Comparator> pointSet; std_map<Vector3, std_vector<PathCoordinate>> pointSet = new std_map<Vector3, std_vector<PathCoordinate>>(new Vector3Comparator()); // for (std::vector<Path>::iterator it = mPaths.begin(); it!= mPaths.end(); ++it) uint it_index = 0; foreach (var it in mPaths) { uint it_point_index = 0; //for (std::vector<Ogre::Vector3>::const_iterator it2 = it->getPoints().begin(); it2 != it->getPoints().end(); ++it2) foreach (var it2 in it._getPoints()) { //PathCoordinate pc(it-mPaths.begin(), it2-it->getPoints().begin()); PathCoordinate pc = new PathCoordinate(it_index, it_point_index); //if (pointSet.find(*it2)==pointSet.end()) if (!pointSet.ContainsKey(it2)) { std_vector<PathCoordinate> pi = new std_vector<PathCoordinate>(); pi.Add(pc); //pointSet[it2] = pi; pointSet.Add(it2, pi); } else { pointSet[it2].push_back(pc); } it_point_index++; } it_index++; } //for (std::map<Ogre::Vector3, PathIntersection, Vector3Comparator>::iterator it = pointSet.begin(); it != pointSet.end(); ++it) foreach (var it_ps in pointSet) { if (it_ps.Value.size() > 1) { foreach (var it2 in it_ps.Value) { //mIntersectionsMap[*it2] = it->second; if (mIntersectionsMap.ContainsKey(it2)) { mIntersectionsMap[it2] = it_ps.Value; } else { mIntersectionsMap.Add(it2, it_ps.Value); } } mIntersections.push_back(it_ps.Value); } } // }
protected virtual void DoMobUpdate() { if (PathCoordinates == null || PathCoordinates.Count == 0) { PathCoordinates = GetNewPath(); } else { PathCoordinate pathCoordinate = PathCoordinates[0]; if (pathCoordinate == null) { PathCoordinates = null; } else { PathCoordinates.RemoveAt(0); // Get the next position in the path that is further than twice the width of the current entity double width = this.Width * 2.0; double widthSqr = width * width; Vector3?nextPosition = pathCoordinate.AsEntityPosition(this).ToVector(); while (nextPosition != null && nextPosition.Value.DistanceSquared(new Vector3(this.Position.X, nextPosition.Value.Y, this.Position.Z)) < widthSqr) { if (PathCoordinates.Count == 0) { nextPosition = null; PathCoordinates = null; } else { pathCoordinate = PathCoordinates[0]; PathCoordinates.RemoveAt(0); nextPosition = pathCoordinate.AsEntityPosition(this).ToVector(); } } IsJumping = false; if (nextPosition != null) { double currentY = Math.Floor(BoundingBox.Minimum.Y + 0.5); Vector3 difference = nextPosition.Value - new Vector3(this.Position.X, currentY, this.Position.Z); double newYaw = ((Math.Atan2(difference.Z, difference.X) * 180.0) / Math.PI) - 90.0; double yawMovement = (newYaw - Yaw); _forwardMovement = Speed; for (; yawMovement < -180F; yawMovement += 360F) { } for (; yawMovement >= 180F; yawMovement -= 360F) { } Yaw += yawMovement.Clamp(-30.0, 30.0); if (Target != null) { double xDiff = Target.Position.X - Position.X; double zDiff = Target.Position.Z - Position.Z; double previousYaw = Yaw; Yaw = Math.Atan2(zDiff, xDiff).ToDegrees() - 90.0; double turnDirection = ((previousYaw - Yaw)).ToRadians();// + 90.0).ToRadians(); _strafingMovement = -Math.Sin(turnDirection) * Speed * 1.0; _forwardMovement = Math.Cos(turnDirection) * Speed * 1.0; //Server.Logger.Log(LogLevel.Debug, "PrevYaw: {0}, NewYaw: {1}, Turn: {2}", previousYaw, Yaw, turnDirection); } if (difference.Y > 0.0) { IsJumping = true; } } if (Target != null) { this.FaceEntity(Target, 30, 30); //Server.Logger.Log(LogLevel.Debug, "FacingYaw: {0}", Yaw); } } _strafingMovement *= 0.98; _forwardMovement *= 0.98; #region Calculate Friction double blockFrictionFactor = 0.91; if (OnGround) { blockFrictionFactor = 0.55; StructBlock block = (StructBlock)World.GetBlock(UniversalCoords.FromAbsWorld(this.Position.X, this.Position.Y - 1, this.Position.Z)); if (block.Type > 0) { BlockBase blockInstance = BlockHelper.Instance.CreateBlockInstance(block.Type); if (blockInstance != null) { blockFrictionFactor = blockInstance.Slipperiness * 0.91; } } } double f3 = 0.163 / (blockFrictionFactor * blockFrictionFactor * blockFrictionFactor); double f4 = OnGround ? 1.0 * f3 : 0.02; #endregion ApplyStrafingToVelocity(_strafingMovement, _forwardMovement, f4); foreach (var e in World.GetEntitiesWithinBoundingBoxExcludingEntity(this, BoundingBox.Expand(new Vector3(0.2, 0.0, 0.2)))) { EntityBase entity = e as EntityBase; if (entity.Pushable) { entity.ApplyEntityCollision(this); } } } }
/// <summary> /// Returns "safe" coordinates 1 block (NSEW) from <paramref name="start"/> where they are not the first point, and the distance to end is less than <paramref name="maxDistance"/> /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="size"></param> /// <param name="maxDistance"></param> /// <returns></returns> private PathCoordinate[] GetPathOptions(PathCoordinate start, PathCoordinate end, Size size, double maxDistance) { int height = 0; if (CheckOffset(start.Coordinate.Offset(0, 1, 0), size) == 1) { height = 1; } List<PathCoordinate> pathOptions = new List<PathCoordinate>(); PathCoordinate eastPoint = GetSafeCoordinate(start.Coordinate.Offset(0, 0, 1), size, height); PathCoordinate northPoint = GetSafeCoordinate(start.Coordinate.Offset(-1, 0, 0), size, height); PathCoordinate southPoint = GetSafeCoordinate(start.Coordinate.Offset(1, 0, 0), size, height); PathCoordinate westPoint = GetSafeCoordinate(start.Coordinate.Offset(0, 0, -1), size, height); if (eastPoint != null && !eastPoint.Checked && eastPoint.DistanceTo(end) < maxDistance) pathOptions.Add(eastPoint); if (northPoint != null && !northPoint.Checked && northPoint.DistanceTo(end) < maxDistance) pathOptions.Add(northPoint); if (southPoint != null && !southPoint.Checked && southPoint.DistanceTo(end) < maxDistance) pathOptions.Add(southPoint); if (westPoint != null && !westPoint.Checked && westPoint.DistanceTo(end) < maxDistance) pathOptions.Add(westPoint); return pathOptions.ToArray(); }
private PathCoordinate GetCoordinateFromCacheOrAdd(UniversalCoords coordinate) { PathCoordinate result = null; if (!_coordinateCache.TryGetValue(coordinate, out result)) { result = new PathCoordinate(coordinate); _coordinateCache[coordinate] = result; } return result; }
private List<PathCoordinate> GeneratePath(PathCoordinate start, PathCoordinate end, Size size, double maxDistance) { SortedSet<PathCoordinate> sortedPath = new SortedSet<PathCoordinate>(new PathCoordinateDistanceToTargetComparer()); List<PathCoordinate> path = new List<PathCoordinate>(); _firstCoordinate = start; _firstCoordinate.DistanceToTarget = _firstCoordinate.DistanceTo(end); PathCoordinate currentCoordinate = start; int loopsLeft = 1000; while (currentCoordinate != null && currentCoordinate != end && loopsLeft > 0) { currentCoordinate.Checked = true; loopsLeft--; PathCoordinate[] pathOptions = GetPathOptions(currentCoordinate, end, size, maxDistance); foreach (var option in pathOptions) { double distance = currentCoordinate.DistanceFromStart + currentCoordinate.DistanceTo(option); bool existsInPath = sortedPath.Contains(option); if (!existsInPath || distance < option.DistanceFromStart) { option.PreviousCoordinate = currentCoordinate; if (existsInPath) { sortedPath.Remove(option); option.SetDistanceFromStartAndTarget(distance, option.DistanceTo(end)); sortedPath.Add(option); } else { option.SetDistanceFromStartAndTarget(distance, option.DistanceTo(end)); sortedPath.Add(option); } } } sortedPath.Remove(currentCoordinate); if (sortedPath.Count > 0) currentCoordinate = sortedPath.Min; else break; } if (currentCoordinate == null || currentCoordinate == _firstCoordinate) return null; // currentCoordinate is destination so walk up previous coordinates and add to list, then reverse List<PathCoordinate> result = new List<PathCoordinate> {currentCoordinate}; while (currentCoordinate.PreviousCoordinate != null) { result.Add(currentCoordinate.PreviousCoordinate); currentCoordinate = currentCoordinate.PreviousCoordinate; } result.Reverse(); return result; }