/// <summary>
        /// Build a list of the Group names in the landscape
        /// </summary>
        private void GetGroupNameList()
        {
            if (groupNameList == null)
            {
                groupNameList = new List <string>(20);
            }
            else
            {
                groupNameList.Clear();
            }

            LBGroup lbGroup = null;

            if (landscape != null)
            {
                int numGroups = landscape.lbGroupList == null ? 0 : landscape.lbGroupList.Count;

                for (int gIdx = 0; gIdx < numGroups; gIdx++)
                {
                    lbGroup = landscape.lbGroupList[gIdx];

                    if (lbGroup.lbGroupType == LBGroup.LBGroupType.Uniform)
                    {
                        groupNameList.Add("Group " + (gIdx + 1) + " " + lbGroup.groupName);
                    }
                }
            }

            // Refresh the number of names in the list for faster lookup
            numGroupNames = groupNameList == null ? 0 : groupNameList.Count;
        }
        /// <summary>
        /// Remove any existing Location objects from the landscape. Only add back in ones from the selected group.
        /// This assumes only one group can be displayed for the current landscape.
        /// </summary>
        /// <param name="landscape"></param>
        /// <param name="lbGroupLocation"></param>
        /// <param name="showErrors"></param>
        public static void RefreshLocationsInScene(LBLandscape landscape, LBGroup lbGroupLocation, Material locationMaterial, bool showErrors)
        {
            string methodName = "LBGroupLocationItem.RefreshLocationsInScene";

            // Basic validation
            if (landscape == null)
            {
                if (showErrors)
                {
                    Debug.LogWarning("ERROR: " + methodName + " landscape is null");
                }
            }
            else
            {
                RemoveLocationsFromScene(landscape, showErrors);

                if (lbGroupLocation == null)
                {
                    if (showErrors)
                    {
                        Debug.LogWarning("ERROR: " + methodName + " lbGroupLocation is null");
                    }
                }
                else
                {
                    int numLocations = (lbGroupLocation.positionList == null ? 0 : lbGroupLocation.positionList.Count);

                    for (int i = 0; i < numLocations; i++)
                    {
                        CreateLocationItemInScene(landscape, lbGroupLocation, locationMaterial, lbGroupLocation.positionList[i] + landscape.start, lbGroupLocation.isFixedRotation ? lbGroupLocation.rotationYList[i] : 0f, i + 1, showErrors);
                    }
                }
            }
        }
Example #3
0
        public void InitialiseMemberProximity()
        {
            proximityMemberCellsListWidth = 1;
            if (isGroupDesignerEnabled)
            {
                // Set proximityMemberCellsListWidth dynamically based on group radius and 2x the maximum proximity
                proximityMemberCellsListWidth = (int)(activeGroupList[0].maxClearingRadius / LBGroup.GetMaxMemberProximityExtent(activeGroupList));
            }
            else
            {
                // Set proximityMemberCellsListWidth dynamically based on landscape width and 2x the maximum proximity
                proximityMemberCellsListWidth = (int)(landscapeWidth * 0.5f / LBGroup.GetMaxMemberProximityExtent(activeGroupList));
            }

            if (proximityMemberCellsListWidth > 100)
            {
                proximityMemberCellsListWidth = 100;
            }
            if (proximityMemberCellsListWidth < 1)
            {
                proximityMemberCellsListWidth = 1;
            }
            // Populate proximity lists
            totalProximityMemberCells = proximityMemberCellsListWidth * proximityMemberCellsListWidth;
            objectProximitiesList     = new List <LBObjectProximity> [totalProximityMemberCells];
            for (int i = 0; i < totalProximityMemberCells; i++)
            {
                objectProximitiesList[i] = new List <LBObjectProximity>();
            }
            // Initialise proximity variables
            thisObjectProximityCellIndex = 0;
            proximityMemberCellXCoord    = 0;
            proximityMemberCellZCoord    = 0;
            thisObjectProximitiesList    = new List <LBObjectProximity>();
        }
Example #4
0
        public void InitialiseGrassArrays()
        {
            isRemoveGrassPresent     = LBGroup.IsRemoveGrassPresent(activeGroupList);
            isGrassPopulationPresent = LBGroup.IsPopulateGrassPresent(activeGroupList);

            // A grass array needs to be size of the sum of all grass arrays in each terrain
            terrainDetailResolution  = lbGroupParams.landscape.GetLandscapeTerrainDetailResolution();
            grassArrayCellsListWidth = numTerrainsWide * terrainDetailResolution;

            totalGrassArrayCells = grassArrayCellsListWidth * grassArrayCellsListWidth;
            // Grass removal array: 255 = previous grass strengh, 0 = all grass removed
            initialGrassRemovalArray = new byte[totalGrassArrayCells];
            finalGrassRemovalArray   = new byte[totalGrassArrayCells];
            // Find out how many grass addition arrays we need, then pack them all into a single array
            grassAdditionArraySize = lbGroupParams.landscape.GetNumTerrainGrassList * totalGrassArrayCells;
            grassAdditionArray     = new byte[grassAdditionArraySize];
            // Set defaults for each array
            for (int i = 0; i < totalGrassArrayCells; i++)
            {
                initialGrassRemovalArray[i] = 255; finalGrassRemovalArray[i] = 255;
            }
            for (int i = 0; i < grassAdditionArraySize; i++)
            {
                grassAdditionArray[i] = 0;
            }
            // Calculate the size in metres of each cell
            grassArrayCellSize = lbGroupParams.landscape.size.x / grassArrayCellsListWidth;
            // Initialise grass array variables
            thisGrassArrayCellIndex      = 0;
            grassArrayCellXCoord         = 0;
            grassArrayCellZCoord         = 0;
            grassAreaRadius              = 0;
            grassAreaNoBlendRadius       = 0f;
            grassAreaCentreXIndex        = 0;
            grassAreaCentreZIndex        = 0;
            grassAreaMinXIndex           = 0;
            grassAreaMaxXIndex           = 0;
            grassAreaMinZIndex           = 0;
            grassAreaMaxZIndex           = 0;
            grassAdditionArrayIndexShift = 0;
            // Initialise grass removal variables
            grassRemovalBlendFactor = 0f;
            grassRemovalDist        = 0f;
            // Initialise grass population variables
            grassPlacementDist         = 0f;
            grassPopulationBlendFactor = 0f;
            grassNoiseValue            = 0f;

            terrainGrassList     = lbGroupParams.landscape.TerrainGrassList();
            terrainGrassListSize = terrainGrassList == null ? 0 : terrainGrassList.Count;
            grsIdx = 0;

            // The Group-level Grass option tab contains GUIDs that reference LBTerrainGrass instances in the
            // landscape class terrainGrassList. These are LBTerrainGrass instances that have been applied
            // to the landscape. Some LBTerrainGrass instances may be disabled or don't have a valid grass texture.
            // This list contains the matching index of the Grass Tab's LBTerrainGrass in the
            // array of unique detailPrototypes for all terrains.
            terrainGrassArrayIndexList = new List <int>(new int[terrainGrassListSize]);
        }
        /// <summary>
        /// Create a gameobject in the GroupDesigner that can be used to track location and size
        /// of SubGroups. Currently it assumes they are spawned from a Object Path in the parent
        /// Clearing Group. The LBPrefabItem component type may need to be changed for subgroups
        /// not created from an Object Path.
        /// </summary>
        /// <param name="parentTfrm"></param>
        /// <param name="parentGroup"></param>
        /// <param name="parentGroupMember"></param>
        /// <param name="subGroup"></param>
        /// <param name="subGroupPosition"></param>
        /// <param name="subGroupRotation"></param>
        /// <param name="subGroupRadius"></param>
        /// <param name="regionIdx"></param>
        /// <returns></returns>
        public static LBGroupDesignerItem CreateSubGroupItem(Transform parentTfrm, LBGroup parentGroup, LBGroupMember parentGroupMember, LBGroup subGroup, Vector3 subGroupPosition, Vector3 subGroupRotation, float subGroupRadius, int regionIdx)
        {
            LBGroupDesignerItem lbGroupDesignerItem = null;

            if (parentGroup != null && parentTfrm != null && subGroup != null)
            {
                // [DESIGNER] (parentGroupName.subgroup:subGroupName.regionnumber)
                GameObject subGroupGO = new GameObject("[DESIGNER] (" + (string.IsNullOrEmpty(parentGroup.groupName) ? "ParentGroup" : parentGroup.groupName) + ".subgroup:" + (string.IsNullOrEmpty(subGroup.groupName) ? "SubGroup" : subGroup.groupName) + "." + (regionIdx + 1) + ")");

                if (subGroupGO != null)
                {
                    Quaternion rotation = Quaternion.Euler(subGroupRotation);
                    subGroupGO.transform.SetPositionAndRotation(subGroupPosition, rotation);
                    subGroupGO.transform.SetParent(parentTfrm);
                    lbGroupDesignerItem = subGroupGO.AddComponent <LBGroupDesignerItem>();
                    if (lbGroupDesignerItem != null)
                    {
                        lbGroupDesignerItem.isSubGroup     = true;
                        lbGroupDesignerItem.SubGroupGUID   = subGroup == null ? string.Empty : subGroup.GUID;
                        lbGroupDesignerItem.position       = subGroupPosition;
                        lbGroupDesignerItem.rotation       = rotation;
                        lbGroupDesignerItem.subGroupRadius = subGroupRadius;
                        lbGroupDesignerItem.FindGroupDesigner();

                        if (parentGroupMember != null)
                        {
                            lbGroupDesignerItem.objPathGroupMemberGUID = parentGroupMember.GUID;
                            lbGroupDesignerItem.isObjPathMember        = parentGroupMember.lbMemberType == LBGroupMember.LBMemberType.ObjPath;
                        }
                        else
                        {
                            lbGroupDesignerItem.objPathGroupMemberGUID = string.Empty;
                            lbGroupDesignerItem.isObjPathMember        = false;
                        }
                    }

                    LBPrefabItem lbPrefabItem = subGroupGO.AddComponent <LBPrefabItem>();
                    if (lbPrefabItem != null)
                    {
                        lbPrefabItem.prefabItemType = LBPrefabItem.PrefabItemType.ObjPathDesignerPrefab;
                        // Add the GUID of the object path GroupMember so that we can track them in the scene
                        // It lets us enable/disable existing prefabs when using the Object Path Designer
                        // If this Group is being spawned from a parent group, assign the member GUID from that parent instead
                        // of using the current member GUID. This ensures that the Designers can disable and enable the correct gameobject
                        // for subgroups.
                        lbPrefabItem.groupMemberGUID = parentGroupMember != null ? parentGroupMember.GUID : subGroup.GUID;
                    }
                }
            }

            return(lbGroupDesignerItem);
        }
Example #6
0
 private void BClear_Click(object sender, EventArgs e)
 {
     T.Module(MethodBase.GetCurrentMethod().Name);
     filterText    = string.Empty;
     TBFilter.Text = string.Empty;
     if (LBGroup.SelectedIndex > -1 && LBGroup.GetSelected(LBGroup.SelectedIndex))
     {
         var result = GetLogItems(LBGroup.SelectedItem.ToString());
         result             = result.OrderByDescending(x => x.Stamp).ToList();
         dgvLogs.DataSource = result;
     }
     T.Module();
 }
Example #7
0
        private void Form1_Load(object sender, EventArgs e)
        {
            T.Module(MethodBase.GetCurrentMethod().Name);
            var folderGroups = config.Retrieve("folder.groups");

            if (folderGroups.Length == 0)
            {
                Environment.Exit(0);
            }
            List <string> folderGroupList = folderGroups.Split(' ').ToList <string>();

            folderGroupList.Sort();
            T.Inform("folderGroups", folderGroups);
            LBGroup.DataSource = folderGroupList;
            LBGroup.SetSelected(0, false);
            T.Module();
        }
Example #8
0
        private void OnEnable()
        {
            lbGroupDesignerItem = (LBGroupDesignerItem)target;
            if (lbGroupDesignerItem != null)
            {
                lbGroupDesignerItem.position = lbGroupDesignerItem.transform.position;
                lbGroupDesignerItem.rotation = lbGroupDesignerItem.transform.rotation;
                lbGroupDesignerItem.scale    = lbGroupDesignerItem.transform.localScale;

                // Get a reference to the group from the designer.
                if (lbGroupDesignerItem.lbGroupDesigner != null)
                {
                    lbGroup = lbGroupDesignerItem.lbGroupDesigner.lbGroup;
                }

                prevPosition = lbGroupDesignerItem.position;
            }
        }
        /// <summary>
        /// Find all the manual clearing location objects in the scene, filter them by a group, and set their size.
        /// </summary>
        /// <param name="landscape"></param>
        /// <param name="lbGroupLocation"></param>
        /// <param name="showErrors"></param>
        public static void RefreshLocationSizesInScene(LBLandscape landscape, LBGroup lbGroupLocation, bool showErrors)
        {
            string methodName = "LBGroupLocationItem.RefreshLocationSizesInScene";

            // Basic validation
            if (landscape == null)
            {
                if (showErrors)
                {
                    Debug.LogWarning("ERROR: " + methodName + " landscape is null");
                }
            }
            else
            {
                if (lbGroupLocation == null)
                {
                    if (showErrors)
                    {
                        Debug.LogWarning("ERROR: " + methodName + " lbGroupLocation is null");
                    }
                }
                else
                {
                    List <LBGroupLocationItem> lbGroupLocationItemList = new List <LBGroupLocationItem>();

                    landscape.GetComponentsInChildren(lbGroupLocationItemList);

                    // Update the size of all the current location items in the scene for this landscape
                    if (lbGroupLocationItemList != null)
                    {
                        lbGroupLocationItemList.RemoveAll(locItem => locItem.lbGroup.groupName != lbGroupLocation.groupName);

                        int numItems = lbGroupLocationItemList.Count;
                        for (int i = 0; i < numItems; i++)
                        {
                            LBGroupLocationItem lbGroupLocationItem = lbGroupLocationItemList[i];
                            lbGroupLocationItem.transform.localScale = new Vector3(lbGroupLocation.maxClearingRadius * 2f, 0.1f, lbGroupLocation.maxClearingRadius * 2f);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Refresh the number of zones in all location items in the scene for this a group.
        /// Typically called when manual clearing groups are being edited, and the number of zones is changed.
        /// </summary>
        /// <param name="landscape"></param>
        /// <param name="lbGroupLocation"></param>
        /// <param name="showErrors"></param>
        public static void RefreshLocationZonesInScene(LBLandscape landscape, LBGroup lbGroupLocation, bool showErrors)
        {
            string methodName = "LBGroupLocationItem.RefreshLocationZonesInScene";

            // Basic validation
            if (landscape == null)
            {
                if (showErrors)
                {
                    Debug.LogWarning("ERROR: " + methodName + " landscape is null");
                }
            }
            else
            {
                if (lbGroupLocation == null)
                {
                    if (showErrors)
                    {
                        Debug.LogWarning("ERROR: " + methodName + " lbGroupLocation is null");
                    }
                }
                else
                {
                    List <LBGroupLocationItem> lbGroupLocationItemList = new List <LBGroupLocationItem>();

                    landscape.GetComponentsInChildren(lbGroupLocationItemList);

                    // Update the zone count for all the current location items in the scene for this group
                    if (lbGroupLocationItemList != null)
                    {
                        lbGroupLocationItemList.RemoveAll(locItem => locItem.lbGroup.GUID != lbGroupLocation.GUID);

                        int numItems = lbGroupLocationItemList.Count;
                        for (int i = 0; i < numItems; i++)
                        {
                            LBGroupLocationItem lbGroupLocationItem = lbGroupLocationItemList[i];
                            lbGroupLocationItem.numZones = lbGroupLocation.zoneList == null ? 0 : lbGroupLocation.zoneList.Count;
                        }
                    }
                }
            }
        }
        public LBObjPathParameters()
        {
            landscape            = null;
            lbGroupOwner         = null;
            lbGroupMemberOwner   = null;
            prefabItemType       = LBPrefabItem.PrefabItemType.ObjPathPrefab;
            showErrors           = false;
            showProgress         = false;
            showProgressDelegate = null;
            clearingRotationY    = 0f;

            lbGroupMember     = null;
            prefab            = null;
            pathPoint         = Vector3.zero;
            distanceAlongPath = 0f;
            parentTfm         = null;
            terrainDataArray  = new TerrainData[0];
            terrainRectsArray = new Rect[0];
            terrainHeight     = 1000f;
        }
Example #12
0
        public void InitialiseTextureArrays()
        {
            isTexturingPresent        = LBGroup.IsApplyTexturesPresent(activeGroupList);
            isObjPathTexturingPresent = LBGroup.IsApplyObjPathTexturesPresent(activeGroupList) && !isGroupDesignerEnabled;

            // A texture array needs to be size of the sum of all alphamap arrays in each terrain
            terrainAlphamapResolution  = lbGroupParams.landscape.GetLandscapeTerrainAlphaMapResolution();
            textureArrayCellsListWidth = numTerrainsWide * terrainAlphamapResolution;

            totalTextureArrayCells = textureArrayCellsListWidth * textureArrayCellsListWidth;
            // Texture array: 255 = add highest strength, 0 = add nothing
            // Find out how many texture arrays we need, then pack them all into a single array
            // NOTE: This may cause issues for Imported Terrains with different textures in each terrain.
            totalTextureAdditionArrays = lbGroupParams.landscape.GetNumActiveTerrainTextures(true);
            textureAdditionArraySize   = totalTextureAdditionArrays * totalTextureArrayCells;
            textureAdditionArray       = new byte[textureAdditionArraySize];
            // Set defaults for each array
            for (int i = 0; i < textureAdditionArraySize; i++)
            {
                textureAdditionArray[i] = 0;
            }
            // Calculate the size in metres of each cell
            textureArrayCellSize = lbGroupParams.landscape.size.x / textureArrayCellsListWidth;
            // Initialise texture array variables
            thisTextureArrayCellIndex      = 0;
            textureArrayCellXCoord         = 0;
            textureArrayCellZCoord         = 0;
            textureAreaRadius              = 0;
            textureAreaNoBlendRadius       = 0f;
            textureAreaCentreXIndex        = 0;
            textureAreaCentreZIndex        = 0;
            textureAreaMinXIndex           = 0;
            textureAreaMaxXIndex           = 0;
            textureAreaMinZIndex           = 0;
            textureAreaMaxZIndex           = 0;
            textureAdditionArrayIndexShift = 0;
            // Initialise texture placement variables
            texturePlacementDist = 0f;
            textureBlendFactor   = 0f;

            terrainTextureList     = lbGroupParams.landscape.TerrainTexturesList();
            terrainTextureListSize = terrainTextureList == null ? 0 : terrainTextureList.Count;
            txIdx = 0;

            // The Group-level Tex option tab contains GUIDs that reference LBTerrainTexture instances in the
            // landscape class terrainTexturesList. These are LBTerrainTexture instances that have been applied
            // to the landscape. Some LBTerrainTexture instances may be disabled or don't have a valid Texture2D.
            // This list contains the matching index of the Texturing Tab's LBTerrainTexture in the
            // array of unique splatPrototypes for all terrains.
            terrainTextureArrayIndexList = new List <int>(new int[terrainTextureListSize]);

            // Fill the lookup array with -ve numbers to show there is no matching splatprototype to begin with
            for (int txArrayIdx = 0; txArrayIdx < terrainTextureListSize; txArrayIdx++)
            {
                terrainTextureArrayIndexList[txArrayIdx] = -1;
            }

            if ((isTexturingPresent || isObjPathTexturingPresent) && terrainTextureList != null)
            {
                // Get a list of unique textures from the terrain data
                for (int t = 0; t < numTerrains; t++)
                {
                    #if UNITY_2018_3_OR_NEWER
                    List <LBTerrainTexture> splatTextures = LBTerrainTexture.ToLBTerrainTextureList(terrainDataArray[t].terrainLayers);
                    #else
                    List <LBTerrainTexture> splatTextures = LBTerrainTexture.ToLBTerrainTextureList(terrainDataArray[t].splatPrototypes);
                    #endif

                    if (splatTextures != null)
                    {
                        for (txIdx = 0; txIdx < terrainTextureListSize; txIdx++)
                        {
                            // Skip textures that have already been matched
                            if (terrainTextureArrayIndexList[txIdx] < 0)
                            {
                                LBTerrainTexture lbTerrainTexture = terrainTextureList[txIdx];

                                // Attempt to match this Texture with a splatPrototype
                                // Check for tinted textures
                                //int splatIdx = splatTextures.FindIndex(stx => stx.texture == (lbTerrainTexture.isTinted ? lbTerrainTexture.tintedTexture : lbTerrainTexture.texture) &&
                                int splatIdx = splatTextures.FindIndex(stx => lbTerrainTexture.CompareToTexture2D(stx.texture) &&
                                                                       stx.normalMap == lbTerrainTexture.normalMap &&
                                                                       stx.smoothness == lbTerrainTexture.smoothness &&
                                                                       stx.metallic == lbTerrainTexture.metallic &&
                                                                       stx.tileSize == lbTerrainTexture.tileSize);

                                if (splatIdx >= 0)
                                {
                                    // Add this splatPrototype index to the array of LBTerrainTexture indexes
                                    // This will enable us to tell which splatPrototype (if any) matches the current LBTerrainTexture
                                    terrainTextureArrayIndexList[txIdx] = splatIdx;
                                }
                            }
                        }
                    }
                }
            }
        }
        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();
        }
Example #14
0
        /// <summary>
        /// Attempt to convert Mesh/Prefabs to Uniform Groups
        /// </summary>
        /// <param name="landscape"></param>
        public static void ConvertMeshesToGroups(LBLandscape landscape)
        {
            string methodName = "LBUpdate.ConvertMeshesToGroups";

            if (landscape == null)
            {
                Debug.LogWarning("ERROR: " + methodName + " - landscape is null. Please Report.");
            }
            else if (landscape.landscapeMeshList != null && landscape.lbGroupList != null)
            {
                List <LBGroup> convertedGroupList = new List <LBGroup>();

                int numMeshes = landscape.landscapeMeshList.Count;

                for (int mIdx = 0; mIdx < numMeshes; mIdx++)
                {
                    LBLandscapeMesh lMesh = landscape.landscapeMeshList[mIdx];

                    if (lMesh.isDisabled)
                    {
                        Debug.Log("INFO: " + methodName + " skipping disabled Mesh " + (mIdx + 1));
                    }
                    else if (lMesh.meshPlacingMode == LBLandscapeMesh.MeshPlacingMode.Map || lMesh.meshPlacingMode == LBLandscapeMesh.MeshPlacingMode.HeightInclinationMap)
                    {
                        Debug.Log("INFO: " + methodName + " cannot convert Mesh " + (mIdx + 1) + " as it contains a Map texture. Recommendation: use a Stencil Layer instead");
                    }
                    else if (!lMesh.usePrefab)
                    {
                        Debug.Log("INFO: " + methodName + " cannot convert Mesh " + (mIdx + 1) + " as Groups only support prefabs.");
                    }
                    else if (lMesh.isClustered)
                    {
                        Debug.Log("INFO: " + methodName + " cannot convert Mesh " + (mIdx + 1) + " as source has Clusters enabled. Recommendation: Create a Procedural Clearing to replace this Mesh/Prefab.");
                    }
                    else
                    {
                        LBGroup       lbGroup       = null;
                        LBGroupMember lbGroupMember = null;

                        // If this is the first group always create a new one
                        if (convertedGroupList.Count == 0)
                        {
                            lbGroup = new LBGroup();
                            if (lbGroup != null)
                            {
                                lbGroup.showInEditor = false;
                                lbGroup.groupName    = "converted group " + (convertedGroupList.Count + 1).ToString("000");
                                lbGroup.lbGroupType  = LBGroup.LBGroupType.Uniform;
                                lbGroup.filterList   = GetSupportedMeshFilters(lMesh.filterList);
                                convertedGroupList.Add(lbGroup);
                            }
                        }
                        else
                        {
                            // Find a compatible group, else create a new one
                            List <LBFilter> supportedMeshFilterList = GetSupportedMeshFilters(lMesh.filterList);
                            int             numThisMeshFilters      = (supportedMeshFilterList == null ? 0 : supportedMeshFilterList.Count);

                            // Find a group with the same filters
                            for (int grpIdx = 0; grpIdx < convertedGroupList.Count; grpIdx++)
                            {
                                LBGroup searchGroup = convertedGroupList[grpIdx];

                                List <LBFilter> groupFilterList     = searchGroup.filterList;
                                int             numThisGroupFilters = (groupFilterList == null ? 0 : groupFilterList.Count);

                                if (numThisMeshFilters == 0 && numThisGroupFilters == 0)
                                {
                                    lbGroup = searchGroup; break;
                                }
                                else if (numThisMeshFilters == numThisGroupFilters)
                                {
                                    // Assume they match
                                    bool isMatch = true;
                                    for (int fIdx = 0; fIdx < numThisGroupFilters; fIdx++)
                                    {
                                        if (groupFilterList[fIdx].filterType != supportedMeshFilterList[fIdx].filterType)
                                        {
                                            isMatch = false; break;
                                        }
                                        else if (groupFilterList[fIdx].lbStencilGUID != supportedMeshFilterList[fIdx].lbStencilGUID)
                                        {
                                            isMatch = false; break;
                                        }
                                        else if (groupFilterList[fIdx].lbStencilLayerGUID != supportedMeshFilterList[fIdx].lbStencilLayerGUID)
                                        {
                                            isMatch = false; break;
                                        }
                                    }
                                    if (isMatch)
                                    {
                                        lbGroup = searchGroup; break;
                                    }
                                }
                            }

                            // If no suitable group was found, add a new one
                            if (lbGroup == null)
                            {
                                lbGroup = new LBGroup();
                                lbGroup.showInEditor = false;
                                lbGroup.groupName    = "converted group " + (convertedGroupList.Count + 1).ToString("000");
                                lbGroup.lbGroupType  = LBGroup.LBGroupType.Uniform;
                                lbGroup.filterList   = GetSupportedMeshFilters(lMesh.filterList);
                                convertedGroupList.Add(lbGroup);
                            }
                        }

                        if (lbGroup == null)
                        {
                            Debug.Log("INFO: " + methodName + " could not create a new LBGroup. Please Report");
                        }
                        else
                        {
                            lbGroupMember = new LBGroupMember();
                            if (lbGroupMember == null)
                            {
                                Debug.Log("INFO: " + methodName + " could not create a new LBGroupMember. Please Report");
                            }
                            else
                            {
                                lbGroupMember.showInEditor = false;

                                CopyMeshToGroupMember(lMesh, lbGroup, lbGroupMember);

                                lbGroup.groupMemberList.Add(lbGroupMember);

                                // Disable migrated mesh/prefab items
                                lMesh.isDisabled = true;
                            }
                        }
                    }
                }

                if (convertedGroupList.Count > 0)
                {
                    landscape.lbGroupList.AddRange(convertedGroupList);
                }
            }
        }
Example #15
0
        private static void CopyMeshToGroupMember(LBLandscapeMesh lMesh, LBGroup lbGroup, LBGroupMember lbGroupMember)
        {
            if (lMesh != null && lbGroup != null && lbGroupMember != null)
            {
                if (lMesh.meshPlacingMode != LBLandscapeMesh.MeshPlacingMode.ConstantInfluence || lMesh.minScale != 1f || lMesh.maxScale != 1f)
                {
                    // This may not the first member of the group so need to check if we need to override group defaults

                    // The first member of a group sets the group-level default settings
                    if (lbGroup.groupMemberList.Count < 1)
                    {
                        lbGroupMember.isGroupOverride = false;
                        lbGroup.minScale       = lMesh.minScale;
                        lbGroup.maxScale       = lMesh.maxScale;
                        lbGroup.minHeight      = lMesh.minHeight;
                        lbGroup.maxHeight      = lMesh.maxHeight;
                        lbGroup.minInclination = lMesh.minInclination;
                        lbGroup.maxInclination = lMesh.maxInclination;
                    }
                    // Does this member have the same rules as the group it will be placed into?
                    else if (lMesh.minScale != lbGroup.minScale || lMesh.maxScale != lbGroup.maxScale ||
                             lMesh.minHeight != lbGroup.minHeight || lMesh.maxHeight != lbGroup.maxHeight ||
                             lMesh.minInclination != lbGroup.minInclination || lMesh.maxInclination != lbGroup.maxInclination)
                    {
                        lbGroupMember.isGroupOverride = true;

                        lbGroupMember.minScale       = lMesh.minScale;
                        lbGroupMember.maxScale       = lMesh.maxScale;
                        lbGroupMember.minHeight      = lMesh.minHeight;
                        lbGroupMember.maxHeight      = lMesh.maxHeight;
                        lbGroupMember.minInclination = lMesh.minInclination;
                        lbGroupMember.maxInclination = lMesh.maxInclination;
                    }
                    else
                    {
                        // Member rules are the same as the Group, so no need to override group-level defaults
                        lbGroupMember.isGroupOverride = false;
                    }
                }

                lbGroupMember.prefab     = lMesh.prefab;
                lbGroupMember.prefabName = lMesh.prefabName;

                lbGroupMember.modelOffsetX = lMesh.offset.x;
                lbGroupMember.modelOffsetY = 0f;
                lbGroupMember.modelOffsetZ = lMesh.offset.z;

                lbGroupMember.randomiseOffsetY = false;
                lbGroupMember.minOffsetY       = lMesh.offset.y;
                lbGroupMember.maxOffsetY       = lbGroupMember.minOffsetY;

                lbGroupMember.randomiseRotationY = lMesh.randomiseYRotation;
                if (lMesh.randomiseYRotation)
                {
                    lbGroupMember.startRotationY = 0f;
                    lbGroupMember.endRotationY   = 359.9f;
                }
                else
                {
                    lbGroupMember.startRotationY = lMesh.fixedYRotation;
                    lbGroupMember.endRotationY   = lMesh.fixedYRotation;
                }
                lbGroupMember.randomiseRotationXZ = false;
                lbGroupMember.rotationX           = lMesh.XRotation;
                lbGroupMember.endRotationX        = lMesh.XRotation;
                lbGroupMember.rotationZ           = lMesh.ZRotation;
                lbGroupMember.endRotationZ        = lMesh.ZRotation;

                lbGroupMember.isCombineMesh            = lMesh.isCombineMesh;
                lbGroupMember.isKeepPrefabConnection   = lMesh.isKeepPrefabConnection;
                lbGroupMember.isCreateCollider         = lMesh.isCreateCollider;
                lbGroupMember.isRemoveEmptyGameObjects = lMesh.isRemoveEmptyGameObjects;

                lbGroupMember.useNoise             = lMesh.useNoise;
                lbGroupMember.noiseTileSize        = lMesh.noiseTileSize;
                lbGroupMember.noisePlacementCutoff = lMesh.meshPlacementCutoff;

                lbGroupMember.maxPrefabSqrKm    = lMesh.maxMeshes;
                lbGroupMember.maxPrefabPerGroup = 10000;

                // Slightly incompatible as old mesh is centre to centre distance
                // mesh.minProximity can be 0.0, while lbGroupMember.proximityExtent currently must be > 0.01.
                lbGroupMember.proximityExtent = lMesh.minProximity;

                lbGroupMember.isTerrainAligned = lMesh.isTerrainAligned;

                lbGroupMember.isTerrainFlattened  = lMesh.isTerrainFlattened;
                lbGroupMember.flattenBlendRate    = lMesh.flattenBlendRate;
                lbGroupMember.flattenDistance     = lMesh.flattenDistance;
                lbGroupMember.flattenHeightOffset = lMesh.flattenHeightOffset;

                lbGroupMember.minGrassProximity = lMesh.minGrassProximity;
                lbGroupMember.isRemoveTree      = true;
                lbGroupMember.minTreeProximity  = lMesh.minTreeProximity;
            }
        }
        /// <summary>
        /// Add a new Location object and script to the scene. Append the location
        /// </summary>
        /// <param name="landscape"></param>
        /// <param name="lbGroupLocation"></param>
        /// <param name="showErrors"></param>
        /// <returns></returns>
        public static LBGroupLocationItem AddNewLocationToScene(LBLandscape landscape, LBGroup lbGroupLocation, Vector2 mousePosition, Camera svCamera, bool showErrors)
        {
            LBGroupLocationItem lbGroupLocationItem = null;
            string methodName = "LBGroupLocationItem.AddNewLocationToScene";

            // Basic validation
            if (landscape == null)
            {
                if (showErrors)
                {
                    Debug.LogWarning("ERROR: " + methodName + " landscape is null");
                }
            }
            else if (lbGroupLocation == null)
            {
                if (showErrors)
                {
                    Debug.LogWarning("ERROR: " + methodName + " lbGroupLocation is null");
                }
            }
            else
            {
                Vector3 locationPoint = Vector3.zero;

                locationPoint = LBEditorHelper.GetLandscapePositionFromMouse(landscape, mousePosition, false, true);
                if (locationPoint.x != 0 && locationPoint.z != 0)
                {
                    //Debug.Log("[DEBUG] locationPoint " + locationPoint + " mousePos: " + mousePosition);

                    Material locationMaterial = null;
                    locationMaterial = LBEditorHelper.GetMaterialFromAssets(LBSetup.materialsFolder, "LBLocation.mat");

                    lbGroupLocationItem = CreateLocationItemInScene(landscape, lbGroupLocation, locationMaterial, locationPoint, 0f, lbGroupLocation.positionList.Count + 1, showErrors);

                    if (lbGroupLocationItem != null)
                    {
                        lbGroupLocationItem.lbGroup.positionList.Add(locationPoint - landscape.start);
                        if (lbGroupLocationItem.lbGroup.isFixedRotation)
                        {
                            lbGroupLocationItem.lbGroup.rotationYList.Add(0f);
                        }
                        LBEditorHelper.RepaintLBW();
                    }
                }
            }

            return(lbGroupLocationItem);
        }
Example #17
0
        public void InitialiseTreeProximity(string methodName)
        {
            // Set proximityTreeCellsListWidth dynamically based on landscape width and 2x the maximum tree proximity
            // Populate proximity lists
            proximityTreeCellsListWidth = (int)(landscapeWidth * 0.5f / LBGroup.GetMaxMemberTreeProximity(activeGroupList));
            if (proximityTreeCellsListWidth > 100)
            {
                proximityTreeCellsListWidth = 100;
            }
            if (proximityTreeCellsListWidth < 1)
            {
                proximityTreeCellsListWidth = 1;
            }

            totalProximityTreeCells = proximityTreeCellsListWidth * proximityTreeCellsListWidth;
            treeProximitiesList     = new List <LBObjectProximity> [totalProximityTreeCells];
            for (int i = 0; i < totalProximityTreeCells; i++)
            {
                treeProximitiesList[i] = new List <LBObjectProximity>();
            }
            // Initialise proximity variables
            thisTreeProximityCellIndex = 0;
            proximityTreeCellXCoord    = 0;
            proximityTreeCellZCoord    = 0;
            // Calculate the size in metres of each cell
            proximityTreeCellSize           = lbGroupParams.landscape.size.x / proximityTreeCellsListWidth;
            proximityTreeCellMinXCoord      = 0;
            proximityTreeCellMaxXCoord      = 0;
            proximityTreeCellMinZCoord      = 0;
            proximityTreeCellMaxZCoord      = 0;
            proximityTreeCellBlockHalfWidth = 0;
            thisTreeProximitiesList         = new List <LBObjectProximity>();
            // Populate tree positions
            for (int i = 0; i < numTerrains; i++)
            {
                // Get and initialise terrain info
                Terrain tTerrain = landscapeTerrains[i];
                if (tTerrain == null)
                {
                    Debug.LogWarning("ERROR " + methodName + " - terrain " + i.ToString() + " is invalid or could not be found. Please Report.");
                }
                else
                {
                    TerrainData tTerrainData = tTerrain.terrainData;
                    if (tTerrainData == null)
                    {
                        Debug.LogWarning("ERROR " + methodName + " - some terrain data is invalid or could not be found. Please Report.");
                    }
                    else
                    {
                        // Get the position of the terrain relative to the landscape
                        Vector3 tTerrainPos = tTerrain.transform.position;
                        // Get the trees array
                        TreeInstance[] terrainTreesArray       = tTerrainData.treeInstances;
                        int            terrainTreesArrayLength = terrainTreesArray.Length;
                        // Initialise tree variables
                        Vector3      tTreeWorldPos      = Vector3.zero;
                        Vector3      tTreeLandscapePos  = Vector3.zero;
                        Vector2      tTreeNormalisedPos = Vector2.zero;
                        TreeInstance terrainTreeInstance;
                        for (int t = 0; t < terrainTreesArrayLength; t++)
                        {
                            terrainTreeInstance = terrainTreesArray[t];
                            // Get landscape position of the tree
                            tTreeWorldPos     = Vector3.Scale(terrainTreeInstance.position, tTerrainData.size) + tTerrainPos;
                            tTreeLandscapePos = tTreeWorldPos - landscapePosition;
                            // Get normalised position of the tree
                            tTreeNormalisedPos.x = tTreeLandscapePos.x / landscapeWidth;
                            tTreeNormalisedPos.y = tTreeLandscapePos.z / landscapeLength;
                            // Find which cell we are in
                            proximityTreeCellXCoord = (int)(tTreeNormalisedPos.x * proximityTreeCellsListWidth);
                            proximityTreeCellZCoord = (int)(tTreeNormalisedPos.y * proximityTreeCellsListWidth);
                            if (proximityTreeCellXCoord >= proximityTreeCellsListWidth)
                            {
                                proximityTreeCellXCoord = proximityTreeCellsListWidth - 1;
                            }
                            if (proximityTreeCellZCoord >= proximityTreeCellsListWidth)
                            {
                                proximityTreeCellZCoord = proximityTreeCellsListWidth - 1;
                            }
                            thisTreeProximityCellIndex = proximityTreeCellXCoord + (proximityTreeCellZCoord * proximityTreeCellsListWidth);
                            if (thisTreeProximityCellIndex < 0)
                            {
                                thisTreeProximityCellIndex = 0;
                            }
                            else if (thisTreeProximityCellIndex >= totalProximityTreeCells)
                            {
                                thisTreeProximityCellIndex = totalProximityTreeCells - 1;
                            }
                            // Add this tree position to the cell
                            treeProximitiesList[thisTreeProximityCellIndex].Add(new LBObjectProximity(tTreeLandscapePos, 0f, (short)i, t));
                        }
                    }
                }
            }
            // Initialise variables for removing trees
            treesToRemoveList     = new List <LBObjectProximity>();
            thisTreesToRemoveList = new List <LBObjectProximity>();
        }
        /// <summary>
        /// Create and initialise a location of a manual group in the scene.
        /// </summary>
        /// <param name="landscape"></param>
        /// <param name="lbGroupLocation"></param>
        /// <param name="locationMaterial"></param>
        /// <param name="locationPos"></param>
        /// <param name="locationYRotation"></param>
        /// <param name="locationNumber"></param>
        /// <param name="showErrors"></param>
        /// <returns></returns>
        private static LBGroupLocationItem CreateLocationItemInScene(LBLandscape landscape, LBGroup lbGroupLocation, Material locationMaterial, Vector3 locationPos, float locationYRotation, int locationNumber, bool showErrors)
        {
            LBGroupLocationItem lbGroupLocationItem = null;
            string methodName = "LBGroupLocationItem.CreateLocationItemInScene";

            GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);

            if (cylinder != null)
            {
                lbGroupLocationItem = cylinder.AddComponent <LBGroupLocationItem>();
                if (lbGroupLocationItem == null)
                {
                    DestroyImmediate(cylinder);
                    if (showErrors)
                    {
                        Debug.LogWarning("ERROR: " + methodName + " could not add LBGroupLocationItem to location gameobject. Please Report.");
                    }
                }
                else
                {
                    lbGroupLocationItem.lbGroup = lbGroupLocation;
                    cylinder.name = lbGroupLocation.groupName + "_loc" + locationNumber.ToString("0000");
                    cylinder.transform.SetPositionAndRotation(locationPos, Quaternion.Euler(0f, locationYRotation, 0f));
                    cylinder.transform.localScale = new Vector3(lbGroupLocation.maxClearingRadius * 2f, 0.1f, lbGroupLocation.maxClearingRadius * 2f);
                    MeshRenderer mRen = cylinder.GetComponent(typeof(MeshRenderer)) as MeshRenderer;
                    if (mRen != null)
                    {
                        // Disable casting and receive shadows
                        mRen.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
                        mRen.receiveShadows    = false;
                        if (locationMaterial != null)
                        {
                            mRen.sharedMaterial = locationMaterial;
                        }
                    }

                    // Remove capsule collider
                    Component collider = cylinder.GetComponent(typeof(Collider));
                    if (collider != null)
                    {
                        DestroyImmediate(collider);
                    }

                    cylinder.transform.SetParent(landscape.transform);

                    lbGroupLocationItem.rotationY = locationYRotation;
                    // Get the number of zones so that they can be shown in OnDrawGizmos
                    lbGroupLocationItem.numZones = lbGroupLocation.zoneList == null ? 0 : lbGroupLocation.zoneList.Count;

                    lbGroupLocationItem.isInitialised = true;
                }
            }
            return(lbGroupLocationItem);
        }
Example #19
0
        private void OnSceneGUI()
        {
            if (EditorApplication.isPlayingOrWillChangePlaymode)
            {
                return;
            }

            Event current = Event.current;

            if (current != null)
            {
                if (lbGroupLocationItem == null)
                {
                    return;
                }
                else if (lbGroup == null)
                {
                    lbGroup = lbGroupLocationItem.lbGroup; if (lbGroup == null)
                    {
                        return;
                    }
                }

                bool isLeftButton  = (current.button == 0);
                bool isRightButton = (current.button == 1);

                tryPosition = lbGroupLocationItem.transform.position;

                // Clamp position of clearing
                if (tryPosition.x < landscapeBounds.xMin || tryPosition.x > landscapeBounds.xMax || tryPosition.z < landscapeBounds.yMin || tryPosition.z > landscapeBounds.yMax)
                {
                    lbGroupLocationItem.transform.position = prevPosition;
                }

                // Update prevPostion with the current position
                prevPosition = lbGroupLocationItem.transform.position;

                prevPosition.y = LBLandscapeTerrain.GetHeight(landscape, new Vector2(prevPosition.x, prevPosition.z), false) + landscape.start.y;
                // Snap the clearing location to the terrain height at this point
                lbGroupLocationItem.transform.position = prevPosition;

                if (current.type == EventType.MouseDown && isRightButton)
                {
                    #region Display the Context-sensitive menu
                    // NOTE: The Context Menu that is display when a location is NOT selected, can be found
                    // in LandscapeBuilderWindow.SceneGUI(SceneView sv)

                    GenericMenu menu = new GenericMenu();
                    menu.AddItem(new GUIContent("Delete Postion"), false, DeleteLocation);
                    menu.AddSeparator("");
                    menu.AddItem(new GUIContent("Delete ALL"), false, DeleteAll);
                    menu.AddSeparator("");
                    menu.AddItem(new GUIContent("Unselect"), false, () => { Selection.activeObject = null; });
                    // The Cancel option is not really necessary as use can just click anywhere else. However, it may help some users.
                    menu.AddItem(new GUIContent("Cancel"), false, () => { });
                    menu.ShowAsContext();
                    current.Use();
                    #endregion
                }
                // Record the starting positions
                else if (current.type == EventType.MouseDown && isLeftButton && landscape != null)
                {
                    lbGroupLocationItem.position  = lbGroupLocationItem.transform.position - landscape.start;
                    lbGroupLocationItem.rotationY = lbGroupLocationItem.transform.rotation.eulerAngles.y;
                }
                else if (current.type == EventType.MouseUp && isLeftButton)
                {
                    if (lbGroup.isFixedRotation)
                    {
                        #if UNITY_2017_3_OR_NEWER
                        if (Tools.current == Tool.Rotate || Tools.current == Tool.Transform)
                        #else
                        if (Tools.current == Tool.Rotate)
                        #endif
                        {
                            // Locate the first matching clearing position
                            // Only check x,z axis as the y-axis may be slightly wrong
                            int idx = lbGroup.positionList.FindIndex(pos => pos.x == lbGroupLocationItem.position.x && pos.z == lbGroupLocationItem.position.z);

                            if (idx > -1)
                            {
                                // update with the new rotation
                                lbGroupLocationItem.rotationY          = lbGroupLocationItem.transform.rotation.eulerAngles.y;
                                lbGroup.rotationYList[idx]             = lbGroupLocationItem.rotationY;
                                lbGroupLocationItem.transform.rotation = Quaternion.Euler(0f, lbGroupLocationItem.rotationY, 0f);
                                // Update the LB Editor Windows
                                LBEditorHelper.RepaintEditorWindow(typeof(LandscapeBuilderWindow));
                            }
                        }
                    }


                    #if UNITY_2017_3_OR_NEWER
                    if ((Tools.current == Tool.Move || Tools.current == Tool.Transform) && landscape != null)
                    #else
                    if (Tools.current == Tool.Move && landscape != null)
                    #endif
                    {
                        // Locate the first matching clearing position
                        // Only check x,z axis as the y-axis may be slightly wrong
                        int idx = lbGroup.positionList.FindIndex(pos => pos.x == lbGroupLocationItem.position.x && pos.z == lbGroupLocationItem.position.z);

                        if (idx > -1)
                        {
                            // update it with the new position
                            lbGroup.positionList[idx] = lbGroupLocationItem.transform.position - landscape.start;
                        }
                    }

                    #if UNITY_2017_3_OR_NEWER
                    if (Tools.current == Tool.Scale || Tools.current == Tool.Transform)
                    #else
                    if (Tools.current == Tool.Scale)
                    #endif
                    {
                        lbGroup.minClearingRadius = lbGroupLocationItem.transform.localScale.x / 2f;
                        lbGroup.maxClearingRadius = lbGroup.minClearingRadius;

                        // Update the LB Editor Windows
                        LBEditorHelper.RepaintEditorWindow(typeof(LandscapeBuilderWindow));

                        // Resize all the locations in the scene
                        LBGroupLocationItem.RefreshLocationSizesInScene(landscape, lbGroup, true);
                    }
                }

                #region Changed Rotation

                // Clamp rotation
                if (!lbGroup.isFixedRotation)
                {
                    lbGroupLocationItem.transform.rotation = Quaternion.identity;
                }
                //else
                //{
                //    Vector3 eulerAngles = lbGroupLocationItem.transform.rotation.eulerAngles;
                //    if (eulerAngles.x != 0f || eulerAngles.z != 0f)
                //    {
                //        //lbGroupLocationItem.transform.rotation = Quaternion.Euler(0f, lbGroupLocationItem.rotationY, 0f);
                //    }
                //}
                #endregion

                #region Changed Radius
#if UNITY_2017_3_OR_NEWER
                if (Tools.current == Tool.Scale || Tools.current == Tool.Transform)
#else
                if (Tools.current == Tool.Scale)
                #endif
                {
                    // Equally scale x-z axis
                    float   currentScale = lbGroup.minClearingRadius * 2f;
                    float   maxScale     = -currentScale;
                    Vector3 localScale   = lbGroupLocationItem.transform.localScale;

                    // Delta = Abs(localScale.) - currentScale
                    float deltaX = (localScale.x < 0f ? -localScale.x : localScale.x);
                    float deltaY = (localScale.y < 0f ? -localScale.y : localScale.y);
                    float deltaZ = (localScale.z < 0f ? -localScale.z : localScale.z);

                    // Get the max scale amount of any of the axis
                    if (deltaX != currentScale && deltaX > maxScale)
                    {
                        maxScale = localScale.x;
                    }
                    if (deltaZ != currentScale && deltaZ > maxScale)
                    {
                        maxScale = localScale.z;
                    }

                    // Did the user change the scale?
                    if (maxScale != -currentScale)
                    {
                        // Clamp scaling to 0.2
                        if (maxScale < 0.2f)
                        {
                            maxScale = 0.2f;
                        }

                        localScale.x = maxScale;

                        // Make x-z axis the same
                        localScale.z = localScale.x;

                        // Don't change y-axis
                        localScale.y = 0.1f;

                        lbGroupLocationItem.transform.localScale = localScale;
                    }
                    else if (deltaY > 0f)
                    {
                        // Local Y axis scaling
                        localScale.y = 0.1f;
                        lbGroupLocationItem.transform.localScale = localScale;
                    }
                }
                #endregion
            }
        }