Example #1
0
        // Update is called once per frame
        void Update()
        {
            if (pathOn != null)
            {
                float distToTravel;
                if (acceleration < 0f && speed < (-acceleration) * Time.deltaTime)
                {
                    distToTravel = speed * speed / (2 * (-acceleration));
                }
                else
                {
                    distToTravel = speed * Time.deltaTime + 0.5f * acceleration * Time.deltaTime * Time.deltaTime;
                }
                speed += Time.deltaTime * acceleration;
                speed  = Mathf.Max(0f, speed);

                distTraveledOnSeg += distToTravel;
                bool termination;
                int  nextSeg, nextLane;
                Pair <Road, float> nextInfo = pathOn.travelAlong(currentSeg, currentParam, distToTravel, laneOn, out nextSeg, out nextLane, out termination);

                if (termination)
                {
                    VhCtrlOfCurrentSeg.VehicleLeave(this, laneOn);

                    stopEvent.Invoke();

                    Reset();
                    return;
                }

                Road roadOn = nextInfo.First;
                currentParam = nextInfo.Second;

                if (currentSeg != nextSeg)
                {
                    VhCtrlOfCurrentSeg.VehicleLeave(this, laneOn);
                    distTraveledOnSeg = distToTravel;
                    laneOn            = nextLane;
                    currentSeg        = nextSeg;

                    VhCtrlOfCurrentSeg.VehicleEnter(this, laneOn);
                }

                if (!Algebra.isclose(rightOffset, 0f))
                {
                    float lateralAcc = (lateralSpeedMagnitude * lateralSpeedMagnitude > 2 * lateralMaxAcc * Mathf.Abs(rightOffset)) ?
                                       -0.98f * lateralMaxAcc : lateralMaxAcc;

                    lateralSpeedMagnitude = Mathf.Max(lateralSpeedMagnitude + lateralAcc * Time.deltaTime, 0f);

                    rightOffset = Mathf.Sign(rightOffset) * Mathf.Max(Mathf.Abs(rightOffset) - lateralSpeedMagnitude * Time.deltaTime, 0f);
                }
                else
                {
                    lateralSpeedMagnitude = 0f;
                }

                transform.position = roadOn.at(currentParam, usebuff: true) +
                                     roadOn.rightNormal(currentParam, usebuff: true) * (roadOn.getLaneCenterOffset(laneOn, headingOfCurrentSeg) + rightOffset);

                transform.rotation = headingOfCurrentSeg ?
                                     Quaternion.LookRotation(roadOn.frontNormal(currentParam, usebuff: true), roadOn.upNormal(currentParam, usebuff: true)) :
                                     Quaternion.LookRotation(-roadOn.frontNormal(currentParam, usebuff: true), roadOn.upNormal(currentParam, usebuff: true));

                if (rightOffset != 0f)
                {
                    if (headingOfCurrentSeg)
                    {
                        transform.Rotate(roadOn.upNormal(currentParam, usebuff: true), -Mathf.Sign(rightOffset) * Mathf.Atan(lateralSpeedMagnitude / Mathf.Max(speed, 0.2f)) * Mathf.Rad2Deg);
                    }
                    else
                    {
                        transform.Rotate(roadOn.upNormal(currentParam, usebuff: true), Mathf.Sign(rightOffset) * Mathf.Atan(lateralSpeedMagnitude / Mathf.Max(speed, 0.2f)) * Mathf.Rad2Deg);
                    }
                }

                wheelRotation = (wheelRotation + distToTravel / wheeRadius * Mathf.Rad2Deg) % 360;
                /*TODO: calculate wheel radius*/
                transform.GetChild(0).GetChild(1).localRotation     = transform.GetChild(0).GetChild(2).localRotation =
                    transform.GetChild(0).GetChild(3).localRotation = transform.GetChild(0).GetChild(4).localRotation =
                        Quaternion.Euler(wheelRotation, 0f, 0f);
            }
        }
Example #2
0
        Road generateVirtualRoad(int i1, int i2)
        {
            Road r1 = connection[i1];
            Road r2 = connection[i2];

            if (outLaneRange[i1, i2] == null)
            {
                return(null);
            }
            int loOutLaneNum = outLaneRange[i1, i2].First;
            int hiOutLaneNum = outLaneRange[i1, i2].Second;

            int loInLaneNum = inLaneRange[i2, i1].First;
            int hiInLaneNum = inLaneRange[i2, i1].Second;

            Debug.Assert(hiOutLaneNum - loOutLaneNum == hiInLaneNum - loInLaneNum);

            float r1_margin = startof(r1.curve) ? r1.margin0Param : r1.margin1Param;
            float r2_margin = startof(r2.curve) ? r2.margin0Param : r2.margin1Param;

            float   r1_radiOffset = 0.5f * (r1.getLaneCenterOffset(loOutLaneNum, !startof(r1.curve)) + r1.getLaneCenterOffset(hiOutLaneNum, !startof(r1.curve)));
            float   r2_radiOffset = 0.5f * (r2.getLaneCenterOffset(loInLaneNum, startof(r2.curve)) + r2.getLaneCenterOffset(hiInLaneNum, startof(r2.curve)));
            Vector3 r1_endPos     = r1.at(r1_margin) + r1.rightNormal(r1_margin) * r1_radiOffset;
            Vector3 r2_endPos     = r2.at(r2_margin) + r2.rightNormal(r2_margin) * r2_radiOffset;

            List <string> virtualRoadLaneCfg   = new List <string>();
            int           virtualRoadLaneCount = hiOutLaneNum - loOutLaneNum + 1;

            for (int i = 0; i != virtualRoadLaneCount; ++i)
            {
                virtualRoadLaneCfg.Add("lane");
                if (i != virtualRoadLaneCount - 1)
                {
                    virtualRoadLaneCfg.Add("dash_white");
                }
            }

            Vector2 r1_direction = startof(r1.curve) ? -r1.curve.direction_2d(r1_margin) : r1.curve.direction_2d(r1_margin);
            Vector2 r2_direction = startof(r2.curve) ? -r2.curve.direction_2d(r2_margin) : r2.curve.direction_2d(r2_margin);

            if (Geometry.Parallel(r1_direction, r2_direction))
            {
                /*TODO: perform a U turn when r1 = r2*/
                if (Algebra.isRoadNodeClose(r1_endPos, r2_endPos))
                {
                    /*exact same lane config for neighbors, just go straight*/
                    return(null);
                }
                //return new Road(Line.TryInit(r1_endPos, r2_endPos), virtualRoadLaneCfg, _noEntity: true);
                return(createNoEntityRoadIfNotNull(Line.TryInit(r1_endPos, r2_endPos), virtualRoadLaneCfg));
            }
            else
            {
                Curve          l1 = Line.TryInit(Algebra.toVector2(r1_endPos), Algebra.toVector2(r1_endPos) + Algebra.InfLength * r1_direction, r1_endPos.y, r1_endPos.y);
                Curve          l2 = Line.TryInit(Algebra.toVector2(r2_endPos), Algebra.toVector2(r2_endPos) + Algebra.InfLength * r2_direction, r2_endPos.y, r2_endPos.y);
                List <Vector3> intereSectionPoint = Geometry.curveIntersect(l1, l2);
                if (intereSectionPoint.Count == 1)
                {
                    //return new Road(Bezeir.TryInit(r1_endPos, intereSectionPoint.First(), r2_endPos), virtualRoadLaneCfg, _noEntity: true);
                    return(createNoEntityRoadIfNotNull(Bezeir.TryInit(r1_endPos, intereSectionPoint.First(), r2_endPos), virtualRoadLaneCfg));
                }
                else
                {
                    //return new Road(Line.TryInit(r1_endPos, r2_endPos), virtualRoadLaneCfg, _noEntity: true);
                    return(createNoEntityRoadIfNotNull(Line.TryInit(r1_endPos, r2_endPos), virtualRoadLaneCfg));
                }
            }
        }
Example #3
0
        public void Update()
        {
            clearAngleDrawing();
            laneConfig = GameObject.FindWithTag("UI/laneconfig").GetComponent <LaneConfigPanelBehavior>().laneconfigresult;
            interestedApproxLines.Clear();

            if (pointer >= 1)
            {
                interestedApproxLines.Add(Line.TryInit(controlPoint[pointer - 1] + Vector3.back * Algebra.InfLength, controlPoint[pointer - 1] + Vector3.forward * Algebra.InfLength));
                interestedApproxLines.Add(Line.TryInit(controlPoint[pointer - 1] + Vector3.left * Algebra.InfLength, controlPoint[pointer - 1] + Vector3.right * Algebra.InfLength));
                if (targetRoad != null && !Algebra.isProjectionClose(controlPoint[pointer - 1], targetRoad.curve.AttouchPoint(controlPoint[pointer - 1])))
                {
                    interestedApproxLines.Add(Line.TryInit(controlPoint[pointer - 1], targetRoad.curve.AttouchPoint(controlPoint[pointer - 1])));
                }
            }

            if (indicatorType == IndicatorType.none)
            {
                nodeIndicator.transform.localScale = Vector3.zero;
            }

            if (controlPoint[pointer].x != Vector3.negativeInfinity.x && indicatorType != IndicatorType.none)
            {
                Vector3 adjustedAttach;
                if (targetRoad != null)
                {
                    adjustedAttach = targetRoad.at(targetRoad.curve.paramOf(targetRoad.curve.AttouchPoint(controlPoint[pointer])).Value);
                }
                else
                {
                    adjustedAttach = controlPoint[pointer];
                }
                nodeIndicator.transform.position   = new Vector3(adjustedAttach.x, adjustedAttach.y / 2 + 0.1f, adjustedAttach.z);
                nodeIndicator.transform.localScale = new Vector3(1.5f, Mathf.Max(1f, adjustedAttach.y / 2), 1.5f);

                if (indicatorType == IndicatorType.line)
                {
                    if (pointer == 1)
                    {
                        Destroy(roadIndicator);
                        addAngleDrawing(controlPoint[1], controlPoint[0]);
                        addAngleDrawing(controlPoint[0], controlPoint[1]);

                        Road cp0_targetRoad;
                        roadManager.approxNodeToExistingRoad(controlPoint[0], out cp0_targetRoad);
                        if (cp0_targetRoad != null)
                        {
                            //perpendicular
                            interestedApproxLines.Add(Line.TryInit(controlPoint[0], controlPoint[0] + Algebra.angle2dir_3d(cp0_targetRoad.curve.Angle_2d((float)cp0_targetRoad.curve.paramOf(controlPoint[0])) + Mathf.PI / 2) * Algebra.InfLength));
                            interestedApproxLines.Add(Line.TryInit(controlPoint[0], controlPoint[0] + Algebra.angle2dir_3d(cp0_targetRoad.curve.Angle_2d((float)cp0_targetRoad.curve.paramOf(controlPoint[0])) - Mathf.PI / 2) * Algebra.InfLength));
                            //extension
                            if (Algebra.isclose(cp0_targetRoad.curve.at_ending(true), controlPoint[0]))
                            {
                                Node crossingRoad;
                                roadManager.findNodeAt(cp0_targetRoad.curve.at_ending(true), out crossingRoad);
                                Debug.Assert(crossingRoad != null);
                                interestedApproxLines.AddRange(crossingRoad.directionalLines(Algebra.InfLength, reverse: true));
                            }
                            else
                            {
                                if (Algebra.isclose(cp0_targetRoad.curve.at_ending(false), controlPoint[0]))
                                {
                                    Node crossingRoad;
                                    roadManager.findNodeAt(cp0_targetRoad.curve.at_ending(false), out crossingRoad);
                                    Debug.Assert(crossingRoad != null);
                                    interestedApproxLines.AddRange(crossingRoad.directionalLines(Algebra.InfLength, reverse: true));
                                }
                            }
                        }

                        if (!Algebra.isProjectionClose(controlPoint[0], controlPoint[1]))
                        {
                            roadIndicator = Instantiate(roadIndicatorPrefab, transform);
                            RoadRenderer roadConfigure = roadIndicator.GetComponent <RoadRenderer>();
                            roadConfigure.generate(Line.TryInit(controlPoint[0], controlPoint[1]), laneConfig);
                        }
                    }

                    if (pointer == 2)
                    {
                        roadManager.addRoad(Line.TryInit(controlPoint[0], controlPoint[1]), laneConfig);
                        reset();
                    }
                }
                if (indicatorType == IndicatorType.bezeir)
                {
                    if (pointer == 1)
                    {
                        Destroy(roadIndicator);
                        addAngleDrawing(controlPoint[1], controlPoint[0]);
                        addAngleDrawing(controlPoint[0], controlPoint[1]);
                        interestedApproxLines.Add(Line.TryInit(controlPoint[0] + Vector3.back * Algebra.InfLength, controlPoint[0] + Vector3.forward * Algebra.InfLength));
                        interestedApproxLines.Add(Line.TryInit(controlPoint[0] + Vector3.left * Algebra.InfLength, controlPoint[0] + Vector3.right * Algebra.InfLength));

                        Road cp0_targetRoad;
                        roadManager.approxNodeToExistingRoad(controlPoint[0], out cp0_targetRoad);
                        if (cp0_targetRoad != null)
                        {
                            interestedApproxLines.Add(Line.TryInit(controlPoint[0], controlPoint[0] + Algebra.angle2dir_3d(cp0_targetRoad.curve.Angle_2d((float)cp0_targetRoad.curve.paramOf(controlPoint[0])) + Mathf.PI / 2) * Algebra.InfLength));
                            interestedApproxLines.Add(Line.TryInit(controlPoint[0], controlPoint[0] + Algebra.angle2dir_3d(cp0_targetRoad.curve.Angle_2d((float)cp0_targetRoad.curve.paramOf(controlPoint[0])) - Mathf.PI / 2) * Algebra.InfLength));
                            if (Algebra.isclose(cp0_targetRoad.curve.at_ending(true), controlPoint[0]))
                            {
                                Node crossingRoad;
                                roadManager.findNodeAt(cp0_targetRoad.curve.at_ending(true), out crossingRoad);
                                Debug.Assert(crossingRoad != null);
                                interestedApproxLines.AddRange(crossingRoad.directionalLines(Algebra.InfLength, reverse: true));
                            }
                            else
                            {
                                if (Algebra.isclose(cp0_targetRoad.curve.at_ending(false), controlPoint[0]))
                                {
                                    Node crossingRoad;
                                    roadManager.findNodeAt(cp0_targetRoad.curve.at_ending(false), out crossingRoad);
                                    Debug.Assert(crossingRoad != null);
                                    interestedApproxLines.AddRange(crossingRoad.directionalLines(Algebra.InfLength, reverse: true));
                                }
                            }
                        }

                        if (!Algebra.isProjectionClose(controlPoint[0], controlPoint[1]))
                        {
                            roadIndicator = Instantiate(roadIndicatorPrefab, transform);
                            RoadRenderer roadConfigure = roadIndicator.GetComponent <RoadRenderer>();
                            roadConfigure.generate(Line.TryInit(controlPoint[0], controlPoint[1]), laneConfig);
                        }
                    }

                    if (pointer == 2)
                    {
                        if (!Geometry.Parallel(controlPoint[1] - controlPoint[0], controlPoint[2] - controlPoint[1]) &&
                            !Algebra.isRoadNodeClose(controlPoint[2], controlPoint[1]))
                        {
                            Destroy(roadIndicator);
                            addAngleDrawing(controlPoint[2], controlPoint[1]);

                            roadIndicator = Instantiate(roadIndicatorPrefab, transform);
                            RoadRenderer roadConfigure = roadIndicator.GetComponent <RoadRenderer>();
                            roadConfigure.generate(Bezeir.TryInit(controlPoint[0], controlPoint[1], controlPoint[2]), laneConfig);
                        }
                    }

                    if (pointer == 3)
                    {
                        if (!Geometry.Parallel(controlPoint[1] - controlPoint[0], controlPoint[2] - controlPoint[1]) &&
                            !Algebra.isRoadNodeClose(controlPoint[2], controlPoint[1]))
                        {
                            roadManager.addRoad(Bezeir.TryInit(controlPoint[0], controlPoint[1], controlPoint[2]), laneConfig);
                            reset();
                        }
                        else
                        {
                            pointer = 2;
                        }
                    }
                }

                if (indicatorType == IndicatorType.arc)
                {
                    if (pointer == 1)
                    {
                        Road cp0_targetRoad;
                        roadManager.approxNodeToExistingRoad(controlPoint[0], out cp0_targetRoad);
                        if (cp0_targetRoad != null)
                        {
                            addAngleDrawing(controlPoint[0], controlPoint[1]);

                            if (Algebra.isclose(cp0_targetRoad.curve.at_ending(true), controlPoint[0]))
                            {
                                interestedApproxLines.Add(Line.TryInit(controlPoint[0], controlPoint[0] + Algebra.angle2dir_3d(cp0_targetRoad.curve.Angle_2d(0f) + Mathf.PI / 2) * Algebra.InfLength));
                                interestedApproxLines.Add(Line.TryInit(controlPoint[0], controlPoint[0] + Algebra.angle2dir_3d(cp0_targetRoad.curve.Angle_2d(0f) - Mathf.PI / 2) * Algebra.InfLength));
                                Node crossingRoad;
                                roadManager.findNodeAt(cp0_targetRoad.curve.at_ending(true), out crossingRoad);
                                Debug.Assert(crossingRoad != null);
                                interestedApproxLines.AddRange(crossingRoad.directionalLines(Algebra.InfLength, reverse: true));
                            }
                            else
                            {
                                if (Algebra.isclose(cp0_targetRoad.curve.at_ending(false), controlPoint[0]))
                                {
                                    interestedApproxLines.Add(Line.TryInit(controlPoint[0], controlPoint[0] + Algebra.angle2dir_3d(cp0_targetRoad.curve.Angle_2d(1f) + Mathf.PI / 2) * Algebra.InfLength));
                                    interestedApproxLines.Add(Line.TryInit(controlPoint[0], controlPoint[0] + Algebra.angle2dir_3d(cp0_targetRoad.curve.Angle_2d(1f) - Mathf.PI / 2) * Algebra.InfLength));
                                    Node crossingRoad;
                                    roadManager.findNodeAt(cp0_targetRoad.curve.at_ending(false), out crossingRoad);
                                    Debug.Assert(crossingRoad != null);
                                    interestedApproxLines.AddRange(crossingRoad.directionalLines(Algebra.InfLength, reverse: true));
                                }
                            }
                        }

                        /*ind[0] is start, ind[1] isorigin*/
                        Destroy(roadIndicator);
                        if (!Algebra.isProjectionClose(controlPoint[0], controlPoint[1]))
                        {
                            roadIndicator = Instantiate(roadIndicatorPrefab, transform);
                            RoadRenderer roadConfigure = roadIndicator.GetComponent <RoadRenderer>();
                            roadConfigure.generate(Line.TryInit(controlPoint[1], controlPoint[0]), laneConfig);
                            if (!Algebra.isclose(controlPoint[1], controlPoint[0]))
                            {
                                roadConfigure.generate(Arc.TryInit(controlPoint[1], controlPoint[0], 1.999f * Mathf.PI), laneConfig);
                            }
                        }
                    }

                    if (pointer == 2)
                    {
                        Vector3 basedir    = controlPoint[0] - controlPoint[1];
                        Vector3 towardsdir = controlPoint[2] - controlPoint[1];
                        interestedApproxLines.Add(Arc.TryInit(controlPoint[1], controlPoint[0], Mathf.PI * 1.999f));
                        if (!Algebra.isProjectionClose(Vector3.zero, towardsdir) && !Algebra.isProjectionClose(controlPoint[1], controlPoint[0]) && !Geometry.Parallel(basedir, towardsdir))
                        {
                            Destroy(roadIndicator);
                            roadIndicator = Instantiate(roadIndicatorPrefab, transform);
                            RoadRenderer roadConfigure = roadIndicator.GetComponent <RoadRenderer>();
                            roadConfigure.generate(Arc.TryInit(Algebra.toVector2(controlPoint[1]), Algebra.toVector2(controlPoint[0]),
                                                               Mathf.Deg2Rad * Vector2.SignedAngle(Algebra.toVector2(basedir), Algebra.toVector2(towardsdir)),
                                                               controlPoint[0].y, controlPoint[2].y), laneConfig);
                            roadConfigure.generate(Arc.TryInit(controlPoint[1], controlPoint[1] + Vector3.right, 1.999f * Mathf.PI), laneConfig);
                        }
                    }

                    if (pointer == 3)
                    {
                        Vector3 basedir    = controlPoint[0] - controlPoint[1];
                        Vector3 towardsdir = controlPoint[2] - controlPoint[1];
                        if (Algebra.isclose(0, towardsdir.magnitude))
                        {
                            pointer = 2;
                        }
                        else
                        {
                            roadManager.addRoad(Arc.TryInit(Algebra.toVector2(controlPoint[1]), Algebra.toVector2(controlPoint[0]), Mathf.Deg2Rad * Vector2.SignedAngle(Algebra.toVector2(basedir), Algebra.toVector2(towardsdir)),
                                                            controlPoint[0].y, controlPoint[2].y), laneConfig);
                            reset();
                        }
                    }
                }

                if (indicatorType == IndicatorType.delete)
                {
                    if (pointer == 0)
                    {
                        Destroy(roadIndicator);

                        if (targetRoad != null)
                        {
                            roadIndicator = Instantiate(roadIndicatorPrefab, transform);
                            RoadRenderer roadConfigure = roadIndicator.GetComponent <RoadRenderer>();
                            roadConfigure.generate(targetRoad.marginedOutCurve, new List <string> {
                                "removal_" + targetRoad.width
                            });
                        }
                    }
                    else
                    {
                        if (targetRoad != null)
                        {
                            roadManager.deleteRoad(targetRoad);
                            reset();
                        }
                        else
                        {
                            pointer = 0;
                        }
                    }
                }
            }
        }