예제 #1
0
        //-----------------------------------------------------------------------
        /// <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);
                }
            }
            //
        }
예제 #2
0
        //-----------------------------------------------------------------------
        /// <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);
                }
            }
            //          
        }
예제 #3
0
        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);
                    }
                }
            }
        }
예제 #4
0
        /// <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();
        }
예제 #5
0
        private PathCoordinate GetCoordinateFromCacheOrAdd(UniversalCoords coordinate)
        {
            PathCoordinate result = null;

            if (!_coordinateCache.TryGetValue(coordinate, out result))
            {
                result = new PathCoordinate(coordinate);
                _coordinateCache[coordinate] = result;
            }

            return result;
        }
예제 #6
0
        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;
        }