Пример #1
0
 // Constructor to create clone copy
 public LBRoad(LBRoad lbRoad)
 {
     if (lbRoad == null)
     {
         SetClassDefaults();
     }
     else
     {
         isSelected   = lbRoad.isSelected;
         isReversed   = lbRoad.isReversed;
         roadName     = lbRoad.roadName;
         roadTypeDesc = lbRoad.roadTypeDesc;
         roadWidth    = lbRoad.roadWidth;
         roadLength   = lbRoad.roadLength;
         centreSpline = lbRoad.centreSpline;
         leftSpline   = lbRoad.leftSpline;
         rightSpline  = lbRoad.rightSpline;
         markerSpline = lbRoad.markerSpline;
     }
 }
        /// <summary>
        /// Get the splines for filtered roads matching on road name.
        /// Assumes road names are unique in the ER road network
        /// </summary>
        private void GetERSplineForRoads()
        {
            LBRoad lbRoadToUpdate = null;

            if (filteredRoadList == null)
            {
                filteredRoadList = new List <LBRoad>(numAllRoads + 20);
            }
            for (int i = 0; i < numFilteredRoads; i++)
            {
                lbRoadToUpdate = filteredRoadList[i];

                if (lbRoadToUpdate.isSelected)
                {
                    lbRoadToUpdate.centreSpline = LBIntegration.GetERRoadSplinePoints(lbRoadToUpdate, LBRoad.SplineType.CentreSpline, splinePointFilterSize);
                    lbRoadToUpdate.leftSpline   = LBIntegration.GetERRoadSplinePoints(lbRoadToUpdate, LBRoad.SplineType.LeftSpline, splinePointFilterSize);
                    lbRoadToUpdate.rightSpline  = LBIntegration.GetERRoadSplinePoints(lbRoadToUpdate, LBRoad.SplineType.RightSpline, splinePointFilterSize);

                    //Debug.Log("[DEBUG] GetERSplineForRoads: " + lbRoadToUpdate.roadName + " points: " + lbRoadToUpdate.leftSpline.Length);
                }
            }
        }
        private void OnGUI()
        {
            #region Initialise

            defaultEditorLabelWidth = EditorGUIUtility.labelWidth;
            defaultEditorFieldWidth = EditorGUIUtility.fieldWidth;

            //if (labelFieldRichText == null)
            {
                labelFieldRichText          = new GUIStyle("Label");
                labelFieldRichText.richText = true;
            }

            // Overide default styles
            EditorStyles.foldout.fontStyle = FontStyle.Bold;

            // When using a no-label foldout, don't forget to set the global
            // EditorGUIUtility.fieldWidth to a small value like 15, then back
            // to the original afterward.
            foldoutStyleNoLabel            = new GUIStyle(EditorStyles.foldout);
            foldoutStyleNoLabel.fixedWidth = 0.01f;
            #endregion

            GUILayout.BeginVertical("HelpBox");

            EditorGUILayout.HelpBox("The LB Path Importer will help you import Group Object Paths from an external source (e.g. EasyRoads3D) [EXPERIMENTAL]", MessageType.Info, true);
            EditorGUIUtility.labelWidth = 100f;
            landscape = (LBLandscape)EditorGUILayout.ObjectField(landscapeContent, landscape, typeof(LBLandscape), true);
            EditorGUIUtility.labelWidth = defaultEditorLabelWidth;

            EditorGUILayout.Space();

            #region Import - EasyRoads

            currentBgndColor    = GUI.backgroundColor;
            GUI.backgroundColor = GUI.backgroundColor * (EditorGUIUtility.isProSkin ? 0.7f : 1.3f);
            GUILayout.BeginVertical(EditorStyles.helpBox);
            GUI.backgroundColor = currentBgndColor;
            EditorGUILayout.LabelField("<color=" + txtColourName + "><b>Import from EasyRoads3D</b></color>", labelFieldRichText);

            #if LB_EDITOR_ER3
            GUILayout.BeginHorizontal();
            if (GUILayout.Button(erGetRoadsBtnContent, GUILayout.MaxWidth(100f)))
            {
                GetRoadList();
                GetFilteredRoadList();
            }
            if (GUILayout.Button(erClearRoadsBtnContent, GUILayout.MaxWidth(100f)))
            {
                if (roadList != null)
                {
                    roadList.Clear();
                }
                if (filteredRoadList != null)
                {
                    filteredRoadList.Clear();
                }
                if (roadTypeList != null)
                {
                    roadTypeList.Clear();
                }
                numAllRoads      = 0;
                numFilteredRoads = 0;
                numAllRoadTypes  = 0;
            }
            GUILayout.EndHorizontal();
            #else
            EditorGUILayout.HelpBox("EasyRoads3D v3.x does not appear to be installed", MessageType.Info, true);
            #endif
            #endregion

            EditorGUILayout.LabelField("Roads (all): " + numAllRoads.ToString("###0"));
            EditorGUILayout.LabelField("Roads (filtered): " + numFilteredRoads.ToString("###0"));
            EditorGUILayout.Space();

            EditorGUILayout.LabelField("<color=" + txtColourName + "><b>Copy Filtered Roads to LB Group</b></color>", labelFieldRichText);
            if (landscape == null)
            {
                EditorGUILayout.HelpBox("Select a landscape to export roads to Group Object Paths", MessageType.Info, true);
            }
            else
            {
                List <LBGroup> groupList = landscape.lbGroupList.FindAll(grp => grp.lbGroupType == LBGroup.LBGroupType.Uniform);

                int numUniformGroups = groupList == null ? 0 : groupList.Count;

                GetGroupNameList();

                if (numUniformGroups == 0)
                {
                    EditorGUILayout.HelpBox("There are no Uniform Groups in the landscape", MessageType.Info, true);
                }
                else
                {
                    EditorGUI.BeginChangeCheck();
                    GUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Target Group", GUILayout.Width(90f));
                    if (groupLookupIndex > numGroupNames - 1)
                    {
                        groupLookupIndex = -1; lbGroupTarget = null;
                    }
                    ;
                    groupLookupIndex = EditorGUILayout.Popup(groupLookupIndex, groupNameList.ToArray());
                    GUILayout.EndHorizontal();
                    if (EditorGUI.EndChangeCheck())
                    {
                        // Attempt to get the actual LBGroup instance
                        if (groupLookupIndex < 0 || groupLookupIndex > numGroupNames - 1)
                        {
                            lbGroupTarget = null;
                        }
                        else
                        {
                            string groupName = groupNameList[groupLookupIndex];
                            if (string.IsNullOrEmpty(groupName))
                            {
                                lbGroupTarget = null;
                            }
                            else if (groupName.Length < 7)
                            {
                                lbGroupTarget = null;
                            }
                            else
                            {
                                // Extract the group number out of the group name string
                                int nextSpace = groupName.IndexOf(" ", 6);
                                if (nextSpace < 7)
                                {
                                    lbGroupTarget = null;
                                }
                                else
                                {
                                    int grpNumber = -1;
                                    int.TryParse(groupName.Substring(6, nextSpace - 6), out grpNumber);
                                    if (grpNumber >= 0)
                                    {
                                        lbGroupTarget = landscape.lbGroupList[grpNumber - 1];
                                        //Debug.Log("[DEBUG: group " + lbGroupTarget == null ? "uknown" : lbGroupTarget.groupName);
                                    }
                                }
                            }
                        }
                    }

                    // If user has deleted a Group which was previously selected in the Path Importer, remove this as the target
                    if (groupLookupIndex < 0 && lbGroupTarget != null)
                    {
                        lbGroupTarget = null;
                    }

                    #if LB_EDITOR_ER3
                    splinePointFilterSize = EditorGUILayout.IntSlider(erSplinePointSizeContent, splinePointFilterSize, 1, 50);
                    #endif

                    GUILayout.BeginHorizontal();
                    if (GUILayout.Button(copyRoadsBtnContent, GUILayout.MaxWidth(100f)))
                    {
                        if (lbGroupTarget != null)
                        {
                            #if LB_EDITOR_ER3
                            GetERSplineForRoads();
                            #endif
                            CopyRoads(false);
                        }
                        else
                        {
                            EditorUtility.DisplayDialog("Copy Roads to Group", "You need to select a Target (Uniform) Group first", "Got it!");
                        }
                    }
                    if (GUILayout.Button(updateRoadsBtnContent, GUILayout.MaxWidth(100f)))
                    {
                        if (lbGroupTarget != null)
                        {
                            #if LB_EDITOR_ER3
                            GetERSplineForRoads();
                            #endif
                            CopyRoads(true);
                        }
                        else
                        {
                            EditorUtility.DisplayDialog("Update Roads in Group", "You need to select a Target (Uniform) Group first", "Got it!");
                        }
                    }
                    GUILayout.EndHorizontal();
                }
                //landscape.lbGroupList.Exists(grp => grp.showGroupsInScene == true);
            }

            EditorGUILayout.Space();

            scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);

            #region Filtering

            GUILayout.BeginHorizontal();
            // A Foldout with no label must have a style fixedWidth of low non-zero value, and have a small (global) fieldWidth.
            EditorGUIUtility.fieldWidth = 17f;
            isShowFilterList            = EditorGUILayout.Foldout(isShowFilterList, "", foldoutStyleNoLabel);
            EditorGUIUtility.fieldWidth = defaultEditorFieldWidth;
            EditorGUI.BeginChangeCheck();
            isFilterByRoadType = EditorGUILayout.Toggle(filterByRoadTypeContent, isFilterByRoadType);
            GUILayout.EndHorizontal();
            if (EditorGUI.EndChangeCheck())
            {
                GetFilteredRoadList();
            }

            if (isFilterByRoadType)
            {
                if (roadTypeList == null)
                {
                    roadTypeList = new List <LBRoadType>(20);
                }
                if (isShowFilterList)
                {
                    for (int rt = 0; rt < numAllRoadTypes; rt++)
                    {
                        lbRoadType = roadTypeList[rt];
                        if (lbRoadType != null)
                        {
                            GUILayout.BeginHorizontal();
                            EditorGUI.BeginChangeCheck();
                            lbRoadType.isSelected = EditorGUILayout.Toggle(lbRoadType.isSelected, GUILayout.Width(colSelectorWidth));
                            GUILayout.Label(lbRoadType.roadTypeDesc);
                            GUILayout.EndHorizontal();
                            if (EditorGUI.EndChangeCheck())
                            {
                                GetFilteredRoadList();
                            }
                        }
                    }
                }
            }

            EditorGUILayout.Space();

            #endregion

            #region Display Filtered Road List

            // Header
            GUILayout.BeginHorizontal();
            EditorGUI.BeginChangeCheck();
            isSelectAllFilteredRoads = EditorGUILayout.Toggle(isSelectAllFilteredRoads, GUILayout.Width(colSelectorWidth));
            if (EditorGUI.EndChangeCheck())
            {
                SelectFilteredRoads(isSelectAllFilteredRoads);
            }
            EditorGUILayout.LabelField("<color=" + txtColourName + "><b>Road Type</b></color>", labelFieldRichText, GUILayout.Width(colRoadTypeWidth));
            EditorGUILayout.LabelField("<color=" + txtColourName + "><b>Road Name</b></color>", labelFieldRichText, GUILayout.Width(colRoadNameWidth));
            GUILayout.EndHorizontal();

            for (int i = 0; i < numFilteredRoads; i++)
            {
                if (i > 200)
                {
                    if (i != numFilteredRoads - 1)
                    {
                        continue;
                    }
                    else
                    {
                        GUILayout.Label("..");
                    }
                }

                lbRoad = filteredRoadList[i];

                if (lbRoad != null)
                {
                    // Display the selectable road
                    GUILayout.BeginHorizontal();
                    //if (GUILayout.Button(new GUIContent("v", "Move road down in the list"), buttonCompact, GUILayout.MaxWidth(20f)))
                    //{
                    //    lbRoadMoveDown = new LBRoad(lbRoad);
                    //    lbRoadMovePos = i;
                    //}
                    lbRoad.isSelected = EditorGUILayout.Toggle(lbRoad.isSelected, GUILayout.Width(colSelectorWidth));
                    //GUILayout.Label(new GUIContent("R", "Reverse direction of path for this road"), GUILayout.Width(12f));
                    //lbRoad.isReversed = EditorGUILayout.Toggle(lbRoad.isReversed, GUILayout.Width(20f));
                    GUILayout.Label(lbRoad.roadTypeDesc, GUILayout.Width(colRoadTypeWidth));
                    GUILayout.Label(lbRoad.roadName, GUILayout.Width(colRoadNameWidth));
                    GUILayout.EndHorizontal();
                }
            }

            #endregion

            GUILayout.EndVertical();

            EditorGUILayout.EndScrollView();
            GUILayout.EndVertical();
        }
        /// <summary>
        /// Copy selected filtered roads to a Uniform Group.
        ///
        /// </summary>
        /// <param name="isUpdateExisting"></param>
        private void CopyRoads(bool isUpdateExisting)
        {
            if (lbGroupTarget != null)
            {
                LBRoad        lbRoadToCopy = null;
                LBGroupMember lbGroupMember = null;
                Vector2       leftSplinePt2D = Vector2.zero, rightSplinePt2D = Vector2.zero;
                bool          useWidth = false;
                bool          addNew   = false;

                if (filteredRoadList == null)
                {
                    filteredRoadList = new List <LBRoad>(numAllRoads + 20);
                }
                for (int i = 0; i < numFilteredRoads; i++)
                {
                    lbRoadToCopy = filteredRoadList[i];

                    //Debug.Log("[DEBUG] CopyRoads: " + lbRoadToCopy.roadName + " points: " + lbRoadToCopy.centreSpline.Length);

                    if (lbRoadToCopy.isSelected)
                    {
                        lbGroupMember = null;
                        addNew        = false;

                        // Validate that road has a matching left and right spline, else turn off useWidth.
                        int numPathPoints = lbRoadToCopy.centreSpline == null ? 0 : lbRoadToCopy.centreSpline.Length;
                        useWidth = lbRoadToCopy.leftSpline != null && lbRoadToCopy.rightSpline != null && lbRoadToCopy.centreSpline != null && numPathPoints == lbRoadToCopy.leftSpline.Length;

                        if (isUpdateExisting)
                        {
                            // Find a matching group member
                            lbGroupMember = lbGroupTarget.groupMemberList.Find(gm => gm.lbMemberType == LBGroupMember.LBMemberType.ObjPath && gm.lbObjPath != null && gm.lbObjPath.pathName == lbRoadToCopy.roadName);
                            if (lbGroupMember != null)
                            {
                                //Debug.Log("[DEBUG] found " + lbGroupMember.lbObjPath.pathName);

                                // Clear out the old points data
                                lbGroupMember.lbObjPath.showPathInScene = false;
                                lbGroupMember.lbObjPath.selectedList.Clear();
                                lbGroupMember.lbObjPath.positionList.Clear();
                                lbGroupMember.lbObjPath.pathPointList.Clear();
                                if (lbGroupMember.lbObjPath.widthList != null)
                                {
                                    lbGroupMember.lbObjPath.widthList.Clear();
                                }
                                else
                                {
                                    lbGroupMember.lbObjPath.widthList = new List <float>(numPathPoints);
                                }

                                // If useWidth was enabled but now shouldn't be, turn it off
                                if (lbGroupMember.lbObjPath.useWidth && !useWidth)
                                {
                                    // Disable use width
                                    lbGroupMember.lbObjPath.EnablePathWidth(false, true);
                                }
                            }
                            //else { Debug.Log("[DEBUG] " + lbRoadToCopy.roadName + " not found"); }
                        }

                        // Create a new Group Member if required
                        if (lbGroupMember == null)
                        {
                            lbGroupMember = new LBGroupMember();
                            lbGroupMember.lbMemberType = LBGroupMember.LBMemberType.ObjPath;
                            lbGroupMember.lbObjPath    = new LBObjPath();
                            if (lbGroupMember.lbObjPath != null)
                            {
                                lbGroupMember.lbObjPath.pathName = lbRoadToCopy.roadName;
                                lbGroupMember.lbObjPath.useWidth = useWidth;
                                lbGroupMember.lbObjPath.showDefaultSeriesInEditor = false;
                                addNew = true;
                            }
                        }

                        if (lbGroupMember != null)
                        {
                            if (lbGroupMember.lbObjPath != null)
                            {
                                lbGroupMember.showInEditor = false;

                                //Debug.Log("[DEBUG] CopyRoads: " + lbRoadToCopy.roadName + " points: " + numPathPoints);

                                lbGroupMember.lbObjPath.positionList.AddRange(lbRoadToCopy.centreSpline);
                                if (useWidth)
                                {
                                    lbGroupMember.lbObjPath.positionListLeftEdge.AddRange(lbRoadToCopy.leftSpline);
                                    lbGroupMember.lbObjPath.positionListRightEdge.AddRange(lbRoadToCopy.rightSpline);
                                }

                                for (int ptIdx = 0; ptIdx < numPathPoints; ptIdx++)
                                {
                                    lbGroupMember.lbObjPath.pathPointList.Add(new LBPathPoint());
                                    if (lbGroupMember.lbObjPath.useWidth)
                                    {
                                        // Calculate the 2D distance between the left and right splines. Currently Object Paths are flat
                                        // although they will support this in the future. Currently the Object Path rotation is only for objects on the path.
                                        leftSplinePt2D.x = lbRoadToCopy.leftSpline[ptIdx].x;
                                        leftSplinePt2D.y = lbRoadToCopy.leftSpline[ptIdx].z;

                                        rightSplinePt2D.x = lbRoadToCopy.rightSpline[ptIdx].x;
                                        rightSplinePt2D.y = lbRoadToCopy.rightSpline[ptIdx].z;

                                        lbGroupMember.lbObjPath.widthList.Add(Vector2.Distance(leftSplinePt2D, rightSplinePt2D));
                                    }
                                }

                                lbGroupMember.lbObjPath.showPathInScene = true;

                                if (addNew)
                                {
                                    lbGroupTarget.groupMemberList.Add(lbGroupMember);
                                }

                                //Debug.Log("[DEBUG] " + lbGroupTarget.groupName);
                            }
                        }
                    }
                }
            }
        }