예제 #1
0
		public void AddPoints(PathPoint[] _points){

            List<PathPoint> points = FilterPoints(_points);

            lastPoint = points[0].pos;


            for (int i = 0; i < points.Count - 1; i++)
            {

                Debug.DrawLine(points[i].pos, points[i].pos + Vector3.up, points[i].guessed ? Color.cyan : Color.blue, 20000);

                Debug.DrawLine(points[i].pos, points[i].pos + points[i].forwards, Color.green, 20000);
                Debug.DrawLine(points[i].pos, points[i].pos + points[i].backwards, Color.grey, 20000);

                

                PathPoint thisPoint = points[i];
                PathPoint nextPoint = points[i + 1];

                
               // Log.debug(i + ":" + "Angle:" + Vector3.Angle(thisPoint.normal, nextPoint.normal) + " Magnitude: " + (thisPoint.pos - nextPoint.pos).magnitude);
                                

                Vector3 thisPointPos = thisPoint.pos;
                Vector3 nextPointPos = nextPoint.pos;

                float angle = Vector3.Angle(thisPoint.forwards, nextPoint.forwards);
                float segementLength = (thisPointPos - nextPointPos).magnitude;

                if (thisPoint.forwards.magnitude > maxNormalSize)
                    thisPoint.forwards = thisPoint.forwards.normalized * maxNormalSize;

                if (thisPoint.backwards.magnitude > maxNormalSize)
                    thisPoint.backwards = thisPoint.backwards.normalized * maxNormalSize;

                Vector3 p0 = thisPointPos;
                Vector3 p1 = thisPointPos + thisPoint.forwards * normalScaleFactor;
                Vector3 p2 = nextPointPos + nextPoint.backwards * normalScaleFactor;

                //Seperate logic for tight turns
                if (segementLength < 30.0f)
                {
                    p1 = thisPointPos + thisPoint.forwards.normalized * segementLength * tightNormalScaleFactor;
                    p2 = nextPointPos + nextPoint.backwards.normalized * segementLength * tightNormalScaleFactor;
                }

                

                Vector3 p3 = nextPointPos;

             //   Debug.DrawLine(p0, p1, Color.cyan, 2000);
             //   Debug.DrawLine(p2, p3, Color.cyan, 2000);
                                              
                
                //First calculate the real length of the spline with a rough calulation
                float realLength = 0;
                float maxAngle = 0;
                for (float a = 0; a < 1.0f; a += 0.1f)
                {
                    Vector3 pointA = Beizer.CalculateBezierPoint(a, p0, p1, p2, p3);
                    Vector3 pointB = Beizer.CalculateBezierPoint(a + 0.2f, p0, p1, p2, p3);

                    float ang = Vector3.Angle(pointB-p0, p1-p0);
                    if (ang > maxAngle) {
                        maxAngle = ang;
                    }

                    realLength += (pointA - pointB).magnitude;
                }

                if (realLength > pathBreakThreshold)
                {
                    AddVertexPair(thisPoint.pos, thisPoint.forwards.normalized, false);
                    AddEndStop(thisPoint.pos, thisPoint.forwards.normalized, true);
                    AddEndStop(nextPoint.pos, nextPoint.forwards.normalized, false);
                    AddVertexPair(nextPoint.pos, nextPoint.forwards.normalized);

                    continue;
                }


                // Make each segment tile a whole number of texture repeats so that
                // overlaping paths line up
                int textureRepeats = (int)Math.Floor(realLength / (width * 4));

                textureOffset = (float)Math.Round(textureOffset);

                //Aim to keep a fixed size for each quad, increaing the number the more it curves
                int steps = (int)Math.Floor(realLength / 20.0f + maxAngle / 3.0f) + 1;
                float step = 1.0f / steps;
                for (float a = 0; a < 1.0f; a += step)
                {
                    Vector3 point = Beizer.CalculateBezierPoint(a, p0, p1, p2, p3);
                    Vector3 pointB = Beizer.CalculateBezierPoint(a+step, p0, p1, p2, p3);
                    Vector3 fwd = (pointB - point).normalized;

                    Debug.DrawLine(point+ Vector3.up, point + Vector3.up + fwd, Color.green, 2000);

                    AddVertexPair(point, fwd);

                    textureOffset += step * textureRepeats; 

                }

            }


            //End the last segement
            AddVertexPair(points[points.Count - 1].pos, points[points.Count - 1].forwards.normalized, false);

			//GenerateIndiciesAsLineStrip ();

            AddEndStop(points[0].pos, points[0].forwards.normalized, false);
            AddEndStop(points[points.Count - 1].pos, points[points.Count - 1].forwards.normalized, true);
		}
        private GameObject CreatePathGameobject(string type, PathPoint[] positions)
        {
            lineMaterial.color = new Color(1, 0, 0, 1);

            PathMeshBuilder pb = new PathMeshBuilder();

            if (type == "Citizen/Foot" || type == "Citizen/Cycle")
            {
                //Citizens have much tighter paths, to remove duplicate points so much
                //pb.duplicatePointThreshold = 0.0f;
                pb.tightNormalScaleFactor = 0.05f;
                pb.pathBreakThreshold = 300.0f;  //If a path segemnt is longer than this they are riding a bus/metro/train
                pb.maxNormalSize = 30.0f;
            }

            pb.AddPoints(positions);

            Mesh m = pb.GetMesh();
            GameObject go = new GameObject(); ;
            go.AddComponent<MeshFilter>();
            go.AddComponent<MeshRenderer>();
            go.GetComponent<MeshFilter>().mesh = m;
            go.GetComponent<MeshFilter>().sharedMesh = m;
            go.GetComponent<MeshRenderer>().material = lineMaterial;
            go.transform.localPosition = new Vector3(0, 3, 0);

            go.SetActive(Config.instance.IsTypeVisible(type));

            return go;
        }
        PathPoint[] GatherPathVerticies(uint pathID, bool isPed = false)
        {
            List<PathPoint> path = new List<PathPoint>();

            NetSegment[] segments = netMan.m_segments.m_buffer;
            NetNode[] nodes = netMan.m_nodes.m_buffer;
            NetLane[] lanes = Singleton<NetManager>.instance.m_lanes.m_buffer;

            PathUnit[] paths = Singleton<PathManager>.instance.m_pathUnits.m_buffer;
            uint segment = paths[pathID].GetPosition(0).m_segment;
            uint startNode;
            startNode = segments[segment].m_startNode;

            PathUnit.Position[] positions = GatherPathPositions(pathID, isPed);

            //Log.debug("Generating verticies...");

            PathPoint lastPoint = new PathPoint();

            for (int i = 0; i < positions.Length; i++) {

                Vector3 pv, dir;
                PathPoint newPoint = new PathPoint();

                uint laneId = PathManager.GetLaneID(positions[i]);

                //Put the destination market on the road not the sidewalk
                if (i == positions.Length - 1) {
                    laneId = lastPoint.laneId;
                }

                lanes[laneId].CalculatePositionAndDirection(positions[i].m_offset / 255.0f,out pv, out dir);

                newPoint.laneId = laneId;
                newPoint.guessed = false;
                newPoint.pos = pv;
                newPoint.forwards = (positions[i].m_offset < 128) ? -dir : dir;
                newPoint.backwards = -newPoint.forwards;

                //Point is contining a curve
                if ((lastPoint.pos - newPoint.pos).magnitude < 5.0f)
                {
                    newPoint.backwards = -lastPoint.forwards;
                }

                newPoint.segmentId = positions[i].m_segment;

                path.Add(newPoint);
                lastPoint = newPoint;

                if (i < positions.Length - 2) {
                    if (positions[i].m_segment != positions[i + 1].m_segment) {

                        newPoint = new PathPoint();

                        PathUnit.Position nextPos = positions[i + 1];
                        laneId = PathManager.GetLaneID(nextPos);

                        Vector3 pvA, dirA, pvB,dirB;
                        lanes[laneId].CalculatePositionAndDirection(0, out pvA, out dirA);
                        lanes[laneId].CalculatePositionAndDirection(1, out pvB, out dirB);

                        //Skip when not a junction;
                        if (pvA == pv || pvB == pv)
                            continue;

                        newPoint.guessed = true;
                        newPoint.laneId = laneId;

                        //Find the closest lane end of the next segment
                        if ((pvA - pv).magnitude < (pvB - pv).magnitude)
                        {
                            newPoint.pos = pvA;
                            newPoint.forwards = dirA;
                            newPoint.backwards = -dirA;
                        }
                        else
                        {
                            newPoint.pos = pvB;
                            newPoint.forwards = -dirB;
                            newPoint.backwards = dirB;
                        }

                        newPoint.segmentId = positions[i + 1].m_segment;

                        path.Add(newPoint);
                        lastPoint = newPoint;

                    }
                }

            }

            return path.ToArray();
        }
        public void AddPoints(PathPoint[] _points)
        {
            List<PathPoint> points = FilterPoints(_points);

            lastPoint = points[0].pos;

            for (int i = 0; i < points.Count - 1; i++)
            {

                Debug.DrawLine(points[i].pos, points[i].pos + Vector3.up, points[i].guessed ? Color.cyan : Color.blue, 20000);

                Debug.DrawLine(points[i].pos, points[i].pos + points[i].forwards, Color.green, 20000);
                Debug.DrawLine(points[i].pos, points[i].pos + points[i].backwards, Color.grey, 20000);

                PathPoint thisPoint = points[i];
                PathPoint nextPoint = points[i + 1];

               // Log.debug(i + ":" + "Angle:" + Vector3.Angle(thisPoint.normal, nextPoint.normal) + " Magnitude: " + (thisPoint.pos - nextPoint.pos).magnitude);

                Vector3 thisPointPos = thisPoint.pos;
                Vector3 nextPointPos = nextPoint.pos;

                float angle = Vector3.Angle(thisPoint.forwards, nextPoint.forwards);
                float segementLength = (thisPointPos - nextPointPos).magnitude;

                if (thisPoint.forwards.magnitude > maxNormalSize)
                    thisPoint.forwards = thisPoint.forwards.normalized * maxNormalSize;

                if (thisPoint.backwards.magnitude > maxNormalSize)
                    thisPoint.backwards = thisPoint.backwards.normalized * maxNormalSize;

                Vector3 p0 = thisPointPos;
                Vector3 p1 = thisPointPos + thisPoint.forwards * normalScaleFactor;
                Vector3 p2 = nextPointPos + nextPoint.backwards * normalScaleFactor;

                //Seperate logic for tight turns
                if (segementLength < 30.0f)
                {
                    p1 = thisPointPos + thisPoint.forwards.normalized * segementLength * tightNormalScaleFactor;
                    p2 = nextPointPos + nextPoint.backwards.normalized * segementLength * tightNormalScaleFactor;
                }

                Vector3 p3 = nextPointPos;

             //   Debug.DrawLine(p0, p1, Color.cyan, 2000);
             //   Debug.DrawLine(p2, p3, Color.cyan, 2000);

                //First calculate the real length of the spline with a rough calulation
                float realLength = 0;
                float maxAngle = 0;
                for (float a = 0; a < 1.0f; a += 0.1f)
                {
                    Vector3 pointA = Beizer.CalculateBezierPoint(a, p0, p1, p2, p3);
                    Vector3 pointB = Beizer.CalculateBezierPoint(a + 0.2f, p0, p1, p2, p3);

                    float ang = Vector3.Angle(pointB-p0, p1-p0);
                    if (ang > maxAngle) {
                        maxAngle = ang;
                    }

                    realLength += (pointA - pointB).magnitude;
                }

                if (realLength > pathBreakThreshold)
                {
                    AddVertexPair(thisPoint.pos, thisPoint.forwards.normalized, false);
                    AddEndStop(thisPoint.pos, thisPoint.forwards.normalized, true);
                    AddEndStop(nextPoint.pos, nextPoint.forwards.normalized, false);
                    AddVertexPair(nextPoint.pos, nextPoint.forwards.normalized);

                    continue;
                }

                // Make each segment tile a whole number of texture repeats so that
                // overlaping paths line up
                int textureRepeats = (int)Math.Floor(realLength / (width * 4));

                textureOffset = (float)Math.Round(textureOffset);

                //Aim to keep a fixed size for each quad, increaing the number the more it curves
                int steps = (int)Math.Floor(realLength / 20.0f + maxAngle / 3.0f) + 1;
                float step = 1.0f / steps;
                for (float a = 0; a < 1.0f; a += step)
                {
                    Vector3 point = Beizer.CalculateBezierPoint(a, p0, p1, p2, p3);
                    Vector3 pointB = Beizer.CalculateBezierPoint(a+step, p0, p1, p2, p3);
                    Vector3 fwd = (pointB - point).normalized;

                    Debug.DrawLine(point+ Vector3.up, point + Vector3.up + fwd, Color.green, 2000);

                    AddVertexPair(point, fwd);

                    textureOffset += step * textureRepeats;

                }

            }

            //End the last segement
            AddVertexPair(points[points.Count - 1].pos, points[points.Count - 1].forwards.normalized, false);

            //GenerateIndiciesAsLineStrip ();

            AddEndStop(points[0].pos, points[0].forwards.normalized, false);
            AddEndStop(points[points.Count - 1].pos, points[points.Count - 1].forwards.normalized, true);
        }
        public List<PathPoint> FilterPoints(PathPoint[] points)
        {
            List<PathPoint> o = new List<PathPoint>();

            int j = 0;
            for (int i = 0; i < points.Length -1; i++)
            {
                if ((points[j].pos - points[i].pos).magnitude < duplicatePointThreshold)
                    continue;

                // KLUDGE: Filter out tight U-Turns
                if (
                    i > points.Length - 4
                    && (Vector3.Angle(points[j].forwards, points[i].forwards) > 170.0f)
                    && (points[j].pos - points[i].pos).magnitude < duplicatePointThreshold
                )
                    continue;

                j = i;
                o.Add(points[i]);
            }

            points[points.Length - 1].forwards = Vector3.zero;// points[points.Length - 1].pos - points[j].pos;

            o.Add(points[points.Length - 1]);
            return o;
        }
예제 #6
0
        PathPoint[] GatherPathVerticies(uint pathID, bool isPed = false)
        {
            List <PathPoint> path = new List <PathPoint>();

            NetSegment[] segments = netMan.m_segments.m_buffer;
            NetNode[]    nodes    = netMan.m_nodes.m_buffer;
            NetLane[]    lanes    = Singleton <NetManager> .instance.m_lanes.m_buffer;

            PathUnit[] paths   = Singleton <PathManager> .instance.m_pathUnits.m_buffer;
            uint       segment = paths[pathID].GetPosition(0).m_segment;
            uint       startNode;

            startNode = segments[segment].m_startNode;


            PathUnit.Position[] positions = GatherPathPositions(pathID, isPed);

            //Log.debug("Generating verticies...");

            PathPoint lastPoint = new PathPoint();

            for (int i = 0; i < positions.Length; i++)
            {
                Vector3   pv, dir;
                PathPoint newPoint = new PathPoint();

                uint laneId = PathManager.GetLaneID(positions[i]);

                //Put the destination market on the road not the sidewalk
                if (i == positions.Length - 1)
                {
                    laneId = lastPoint.laneId;
                }

                lanes[laneId].CalculatePositionAndDirection(positions[i].m_offset / 255.0f, out pv, out dir);

                newPoint.laneId    = laneId;
                newPoint.guessed   = false;
                newPoint.pos       = pv;
                newPoint.forwards  = (positions[i].m_offset < 128) ? -dir : dir;
                newPoint.backwards = -newPoint.forwards;

                //Point is contining a curve
                if ((lastPoint.pos - newPoint.pos).magnitude < 5.0f)
                {
                    newPoint.backwards = -lastPoint.forwards;
                }

                newPoint.segmentId = positions[i].m_segment;

                path.Add(newPoint);
                lastPoint = newPoint;

                if (i < positions.Length - 2)
                {
                    if (positions[i].m_segment != positions[i + 1].m_segment)
                    {
                        newPoint = new PathPoint();

                        PathUnit.Position nextPos = positions[i + 1];
                        laneId = PathManager.GetLaneID(nextPos);

                        Vector3 pvA, dirA, pvB, dirB;
                        lanes[laneId].CalculatePositionAndDirection(0, out pvA, out dirA);
                        lanes[laneId].CalculatePositionAndDirection(1, out pvB, out dirB);

                        //Skip when not a junction;
                        if (pvA == pv || pvB == pv)
                        {
                            continue;
                        }

                        newPoint.guessed = true;
                        newPoint.laneId  = laneId;

                        //Find the closest lane end of the next segment
                        if ((pvA - pv).magnitude < (pvB - pv).magnitude)
                        {
                            newPoint.pos       = pvA;
                            newPoint.forwards  = dirA;
                            newPoint.backwards = -dirA;
                        }
                        else
                        {
                            newPoint.pos       = pvB;
                            newPoint.forwards  = -dirB;
                            newPoint.backwards = dirB;
                        }

                        newPoint.segmentId = positions[i + 1].m_segment;

                        path.Add(newPoint);
                        lastPoint = newPoint;
                    }
                }
            }

            return(path.ToArray());
        }