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> /// Constructor for cloning a layer /// </summary> /// <param name="lbLandscapeMesh"></param> public LBLandscapeMesh(LBLandscapeMesh lbLandscapeMesh) { this.mesh = lbLandscapeMesh.mesh; this.materials = new List <Material>(lbLandscapeMesh.materials); this.offset = lbLandscapeMesh.offset; this.maxMeshes = lbLandscapeMesh.maxMeshes; this.minProximity = lbLandscapeMesh.minProximity; this.randomiseYRotation = lbLandscapeMesh.randomiseYRotation; this.fixedYRotation = lbLandscapeMesh.fixedYRotation; this.XRotation = lbLandscapeMesh.XRotation; this.ZRotation = lbLandscapeMesh.ZRotation; this.isTerrainAligned = lbLandscapeMesh.isTerrainAligned; this.minScale = lbLandscapeMesh.minScale; this.maxScale = lbLandscapeMesh.maxScale; this.minHeight = lbLandscapeMesh.minHeight; this.maxHeight = lbLandscapeMesh.maxHeight; this.minInclination = lbLandscapeMesh.minInclination; this.maxInclination = lbLandscapeMesh.maxInclination; this.meshPlacingMode = lbLandscapeMesh.meshPlacingMode; this.map = lbLandscapeMesh.map; this.mapColour = lbLandscapeMesh.mapColour; this.mapTolerance = lbLandscapeMesh.mapTolerance; this.mapToleranceBlendCurve = new AnimationCurve(lbLandscapeMesh.mapToleranceBlendCurve.keys); this.mapIsPath = lbLandscapeMesh.mapIsPath; this.useNoise = lbLandscapeMesh.useNoise; this.noiseTileSize = lbLandscapeMesh.noiseTileSize; this.noiseOffset = lbLandscapeMesh.noiseOffset; this.meshPlacementCutoff = lbLandscapeMesh.meshPlacementCutoff; this.isClustered = lbLandscapeMesh.isClustered; this.clusterDistance = lbLandscapeMesh.clusterDistance; this.clusterDensity = lbLandscapeMesh.clusterDensity; this.clusterResolution = lbLandscapeMesh.clusterResolution; this.removeGrass = lbLandscapeMesh.removeGrass; this.minGrassProximity = lbLandscapeMesh.minGrassProximity; this.showMesh = lbLandscapeMesh.showMesh; this.isDisabled = lbLandscapeMesh.isDisabled; this.usePrefab = lbLandscapeMesh.usePrefab; this.prefab = lbLandscapeMesh.prefab; this.isCombineMesh = lbLandscapeMesh.isCombineMesh; this.isCreateCollider = lbLandscapeMesh.isCreateCollider; this.isRemoveEmptyGameObjects = lbLandscapeMesh.isRemoveEmptyGameObjects; this.minTreeProximity = lbLandscapeMesh.minTreeProximity; this.isTerrainFlattened = lbLandscapeMesh.isTerrainFlattened; this.flattenDistance = lbLandscapeMesh.flattenDistance; this.flattenBlendRate = lbLandscapeMesh.flattenBlendRate; this.flattenHeightOffset = lbLandscapeMesh.flattenHeightOffset; if (lbLandscapeMesh.filterList != null) { this.filterList = LBFilter.CopyList(lbLandscapeMesh.filterList); } else { this.filterList = new List <LBFilter>(); } this.isKeepPrefabConnection = lbLandscapeMesh.isKeepPrefabConnection; if (lbLandscapeMesh.prefabName == null) { this.prefabName = string.Empty; } else { this.prefabName = lbLandscapeMesh.prefabName; } }
/// <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); } } }