public static void SceneGUI(BuildrEditMode editMode, BuildrData data, bool shouldSnap, float handleSize) { if (GUI.changed) { EditorUtility.SetDirty(editMode); EditorUtility.SetDirty(data); editMode.UpdateRender(); } }
public static void InspectorGUI(BuildrEditMode _editMode, BuildrData _data) { editMode = _editMode; data = _data; constraints = data.generatorConstraints; EditModes newmode = (EditModes)EditorGUILayout.EnumPopup(mode); if (newmode != mode) { mode = newmode; switch (mode) { case EditModes.general: editMode.stage = BuildrEditMode.stages.building; break; case EditModes.floorplan: editMode.stage = BuildrEditMode.stages.floorplan; editMode.SetMode(BuildrEditMode.modes.floorplan); break; } } switch (mode) { case EditModes.general: GeneralOptionsInspector(); break; case EditModes.floorplan: EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Constrain Building Generation to Floorplan", GUILayout.Width(280)); constraints.constrainPlanByPlan = EditorGUILayout.Toggle(constraints.constrainPlanByPlan); EditorGUILayout.EndHorizontal(); EditorGUI.BeginDisabledGroup(!constraints.constrainPlanByPlan); BuildrEditModeFloorplan.InspectorGUI(editMode, _data.plan); EditorGUI.EndDisabledGroup(); if (data.plan != null) { constraints.plan = data.plan.Duplicate(); } break; } if (GUI.changed) { EditorUtility.SetDirty(_editMode); EditorUtility.SetDirty(_data); _editMode.UpdateRender(); } }
void OnEnable() { if (target != null) { _editMode = (BuildrEditMode)target; _data = _editMode.data; } bool editing = (_data != null) ? _data.editing : true; if (!editing) { BuildrGenerateModeEditor.OnEnable(); } }
public static void SceneGUI(BuildrEditMode editMode, BuildrData data, bool shouldSnap, float handleSize) { if(editMode.fullMesh==null) return; Rect HUDRect = new Rect(0,0,300,300); Handles.BeginGUI(); GUILayout.BeginArea(HUDRect); EditorGUILayout.LabelField("Buildr"); EditorGUILayout.LabelField("Vertices: "+editMode.fullMesh.vertexCount); EditorGUILayout.LabelField("Triangles "+editMode.fullMesh.triangleCount/3); GUILayout.EndArea(); Handles.EndGUI(); bool isLegal = !(data.plan.illegalPoints.Length > 0); if (isLegal) isLegal = editMode.transform.localScale == Vector3.one; if(isLegal) return; int numberOfFacades = data.facades.Count; int numberOfRoofs = data.roofs.Count; int numberOfTextures = data.textures.Count; if (numberOfFacades == 0 || numberOfRoofs == 0 || numberOfTextures == 0) return; Vector3 position = editMode.transform.position; BuildrPlan area = data.plan; int numberOfVolumes = area.numberOfVolumes; int facadeCounter = 0; for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = data.plan.volumes[s]; int volumeSize = volume.Count; Vector3 floorCentre = Vector3.zero; Handles.color = Color.red; for (int p = 0; p < volumeSize; p++) { int point = volume.points[p]; Vector3 pointPos = area.points[point].vector3; floorCentre += pointPos; List<Vector3> verts = new List<Vector3>(); int indexB = (p < volumeSize - 1) ? p + 1 : 0; Vector3 volumeHeight = Vector3.up * (volume.numberOfFloors * data.floorHeight); verts.Add(pointPos + position); verts.Add(area.points[volume.points[indexB]].vector3 + position); verts.Add(verts[1] + volumeHeight); verts.Add(verts[0] + volumeHeight); Handles.DrawSolidRectangleWithOutline(verts.ToArray(), new Color(1,0,0,0.2f), Color.red); Handles.DrawLine(verts[2], verts[3]); facadeCounter++; } } }
public static void SceneGUI(BuildrEditMode _editMode, BuildrData _data, bool shouldSnap, float handleSize) { Vector3 camDirection = Camera.current.transform.forward; Vector3 camPosition = Camera.current.transform.position; Vector3 position = _editMode.transform.position; data = _data; BuildrPlan plan = data.plan; BuildrVolume selectedVolume = plan.volumes[selectedVolumeIndex]; int selectedVolumeSize = selectedVolume.Count; Handles.color = Color.white; int facadeCounter = 0; GUIStyle whiteLabelStyle = new GUIStyle(); whiteLabelStyle.normal.textColor = Color.white; whiteLabelStyle.alignment = TextAnchor.MiddleCenter; whiteLabelStyle.fixedWidth = 75.0f; int numberOfVolumes = plan.numberOfVolumes; for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = data.plan.volumes[s]; int volumeSize = volume.Count; Vector3 floorCentre = Vector3.zero; for (int p = 0; p < volumeSize; p++) { int point = volume.points[p]; Vector3 pointPos = plan.points[point].vector3; floorCentre += pointPos; } floorCentre /= volumeSize; if (s == selectedVolumeIndex) { whiteLabelStyle.normal.textColor = BuildrColours.RED; whiteLabelStyle.fontStyle = FontStyle.Bold; } else { whiteLabelStyle.normal.textColor = Color.white; whiteLabelStyle.fontStyle = FontStyle.Normal; } //Volume height/floor number slider Vector3 volumeHeightDir = Vector3.up * (volume.numberOfFloors * data.floorHeight); Vector3 volumePosition = floorCentre + position + volumeHeightDir; Handles.color = Color.white; if (Vector3.Dot(camDirection, volumePosition - camPosition) > 0)//only display label when facade is facing camera { Handles.Label(volumePosition + (Vector3.up * (handleSize * 0.1f)), "volume " + s, whiteLabelStyle); } } whiteLabelStyle.normal.textColor = Color.white; whiteLabelStyle.fontStyle = FontStyle.Normal; for (int p = 0; p < selectedVolumeSize; p++) { int point = selectedVolume.points[p]; Vector3 pointPos = plan.points[point].vector3; List <Vector3> verts = new List <Vector3>(); int indexB = (p < selectedVolumeSize - 1) ? p + 1 : 0; Vector3 floorHeightVector = Vector3.up * (selectedFloor * data.floorHeight); Vector3 ceilingHeightVector = Vector3.up * ((selectedFloor + 1) * data.floorHeight); Vector3 p0 = pointPos + position; Vector3 p1 = plan.points[selectedVolume.points[indexB]].vector3 + position; verts.Add(pointPos + position); verts.Add(plan.points[selectedVolume.points[indexB]].vector3 + position); verts.Add(verts[1] + floorHeightVector); verts.Add(verts[0] + floorHeightVector); Handles.color = BuildrColours.RED; Handles.DrawLine(p0 + floorHeightVector, p1 + floorHeightVector); Handles.DrawLine(p0 + ceilingHeightVector, p1 + ceilingHeightVector); Handles.DrawLine(p0 + floorHeightVector, p0 + ceilingHeightVector); if (_editMode.showFacadeMarkers) { Handles.color = Color.white; Vector3 facadeDirection = Vector3.Cross((verts[0] - verts[1]), Vector3.up); Vector3 centerPos = (verts[0] + verts[1]) * 0.5f; bool camVisible = Vector3.Dot(camDirection, centerPos - camPosition) > 0; bool facadeVisible = Vector3.Dot(camDirection, facadeDirection) < 0; if (camVisible && facadeVisible)//only display label when facade is facing camera and is in camera view { Vector3 labelPos = centerPos + facadeDirection.normalized; Handles.Label(labelPos, "facade " + facadeCounter, whiteLabelStyle); Handles.DrawLine(centerPos, labelPos); } } facadeCounter++; } }
//private static BuildrData data; public static void InspectorGUI(BuildrEditMode editMode, BuildrData _data) { //ensure that the model exists in the scene if (editMode.fullMesh == null) { editMode.UpdateRender(); } Undo.RecordObject(_data, "Building Modified"); //texture library string array BuildrTexture[] textures = _data.textures.ToArray(); int numberOfTextures = textures.Length; string[] textureNames = new string[numberOfTextures]; for (int t = 0; t < numberOfTextures; t++) { textureNames[t] = textures[t].name; } //Render a full version version EditorGUILayout.LabelField("Building Generation Types"); EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUI.BeginDisabledGroup(editMode.renderMode == BuildrEditMode.renderModes.full); if (GUILayout.Button("Full Detail", GUILayout.Height(28))) { editMode.UpdateRender(BuildrEditMode.renderModes.full); } EditorGUI.EndDisabledGroup(); //Render a low detail version EditorGUI.BeginDisabledGroup(editMode.renderMode == BuildrEditMode.renderModes.lowDetail); if (GUILayout.Button("Low Detail", GUILayout.Height(28))) { editMode.UpdateRender(BuildrEditMode.renderModes.lowDetail); } EditorGUI.EndDisabledGroup(); //Render a box version EditorGUI.BeginDisabledGroup(editMode.renderMode == BuildrEditMode.renderModes.box); if (GUILayout.Button("Box Outline", GUILayout.Height(28))) { editMode.UpdateRender(BuildrEditMode.renderModes.box); } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); //Toggle showing the wireframe when we have selected the model. EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUILayout.LabelField("Show Wireframe"); editMode.showWireframe = EditorGUILayout.Toggle(editMode.showWireframe, GUILayout.Width(15)); EditorGUILayout.EndHorizontal(); //Tangent calculation EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUI.BeginDisabledGroup(editMode.fullMesh.hasTangents); if (GUILayout.Button("Build Tangents", GUILayout.Height(38))) { if (editMode.fullMesh != null) { editMode.fullMesh.SolveTangents(); } if (editMode.detailMesh != null) { editMode.detailMesh.SolveTangents(); } GUI.changed = false; } EditorGUI.EndDisabledGroup(); if (!editMode.fullMesh.hasTangents) { EditorGUILayout.HelpBox("The model doesn't have tangents", MessageType.Warning); } EditorGUILayout.EndHorizontal(); //Lightmap rendering EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUI.BeginDisabledGroup(editMode.fullMesh.lightmapUvsCalculated); if (GUILayout.Button("Build Lightmap UVs", GUILayout.Height(38))) { // Undo.RegisterSceneUndo("Build Lightmap UVs"); if (editMode.fullMesh != null) { for (int i = 0; i < editMode.fullMesh.meshCount; i++) { Unwrapping.GenerateSecondaryUVSet(editMode.fullMesh[i].mesh); } } editMode.fullMesh.lightmapUvsCalculated = true; if (editMode.detailMesh != null) { for (int i = 0; i < editMode.detailMesh.meshCount; i++) { Unwrapping.GenerateSecondaryUVSet(editMode.detailMesh[i].mesh); } editMode.detailMesh.lightmapUvsCalculated = true; } int numberOfInteriors = editMode.interiorMeshes.Count; for (int i = 0; i < numberOfInteriors; i++) { DynamicMeshGenericMultiMaterialMesh interiorMesh = editMode.interiorMeshes[i]; for (int j = 0; j < interiorMesh.meshCount; j++) { Unwrapping.GenerateSecondaryUVSet(interiorMesh[j].mesh); } interiorMesh.lightmapUvsCalculated = true; } GUI.changed = false; } EditorGUI.EndDisabledGroup(); if (!editMode.fullMesh.lightmapUvsCalculated) { EditorGUILayout.HelpBox("The model doesn't have lightmap UVs", MessageType.Warning); } EditorGUILayout.EndHorizontal(); //Mesh Optimisation EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUI.BeginDisabledGroup(editMode.fullMesh.optimised); if (GUILayout.Button("Optimise Mesh For Runtime", GUILayout.Height(38))) { // Undo.RegisterSceneUndo("Optimise Mesh"); if (editMode.fullMesh != null) { for (int i = 0; i < editMode.fullMesh.meshCount; i++) { MeshUtility.Optimize(editMode.fullMesh[i].mesh); } editMode.fullMesh.optimised = true; } if (editMode.detailMesh != null) { for (int i = 0; i < editMode.detailMesh.meshCount; i++) { MeshUtility.Optimize(editMode.detailMesh[i].mesh); } editMode.detailMesh.optimised = true; } GUI.changed = false; } EditorGUI.EndDisabledGroup(); if (!editMode.fullMesh.optimised) { EditorGUILayout.HelpBox("The model is currently fully optimised for runtime", MessageType.Warning); } EditorGUILayout.EndHorizontal(); //Underside render toggle EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUILayout.LabelField("Render Underside of Building"); bool drawUnderside = EditorGUILayout.Toggle(_data.drawUnderside, GUILayout.Width(15)); if (drawUnderside != _data.drawUnderside) { _data.drawUnderside = drawUnderside; } EditorGUILayout.EndHorizontal(); //Define the height of foundations if you need them EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUILayout.LabelField("Foundation Height", GUILayout.Width(120)); _data.foundationHeight = EditorGUILayout.Slider(_data.foundationHeight, 0, 25); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Foundation Texture", GUILayout.Width(120)); _data.foundationTexture = EditorGUILayout.Popup(_data.foundationTexture, textureNames, GUILayout.Width(260)); EditorGUILayout.EndHorizontal(); //Collider mesh EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUILayout.LabelField("Generate Collider"); _data.generateCollider = (BuildrData.ColliderGenerationModes)EditorGUILayout.EnumPopup(_data.generateCollider); EditorGUILayout.EndHorizontal(); //One draw call mesh -TODO // EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); // EditorGUILayout.LabelField("One Draw Call"); // _data.oneDrawCall = EditorGUILayout.Toggle(_data.oneDrawCall); // EditorGUILayout.EndHorizontal(); for (int i = 0; i < editMode.fullMesh.meshCount; i++) { EditorUtility.SetSelectedWireframeHidden(editMode.meshHolders[i].GetComponent <Renderer>(), !editMode.showWireframe); } }
//private static BuildrData data; public static void InspectorGUI(BuildrEditMode editMode, BuildrData _data) { //ensure that the model exists in the scene if (editMode.fullMesh == null) editMode.UpdateRender(); Undo.RecordObject(_data, "Building Modified"); //texture library string array BuildrTexture[] textures = _data.textures.ToArray(); int numberOfTextures = textures.Length; string[] textureNames = new string[numberOfTextures]; for (int t = 0; t < numberOfTextures; t++) textureNames[t] = textures[t].name; //Render a full version version EditorGUILayout.LabelField("Building Generation Types"); EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUI.BeginDisabledGroup(editMode.renderMode == BuildrEditMode.renderModes.full); if (GUILayout.Button("Full Detail", GUILayout.Height(28))) { editMode.UpdateRender(BuildrEditMode.renderModes.full); } EditorGUI.EndDisabledGroup(); //Render a low detail version EditorGUI.BeginDisabledGroup(editMode.renderMode == BuildrEditMode.renderModes.lowDetail); if (GUILayout.Button("Low Detail", GUILayout.Height(28))) { editMode.UpdateRender(BuildrEditMode.renderModes.lowDetail); } EditorGUI.EndDisabledGroup(); //Render a box version EditorGUI.BeginDisabledGroup(editMode.renderMode == BuildrEditMode.renderModes.box); if (GUILayout.Button("Box Outline", GUILayout.Height(28))) { editMode.UpdateRender(BuildrEditMode.renderModes.box); } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); //Toggle showing the wireframe when we have selected the model. EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUILayout.LabelField("Show Wireframe"); editMode.showWireframe = EditorGUILayout.Toggle(editMode.showWireframe, GUILayout.Width(15)); EditorGUILayout.EndHorizontal(); //Tangent calculation EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUI.BeginDisabledGroup(editMode.fullMesh.hasTangents); if (GUILayout.Button("Build Tangents", GUILayout.Height(38))) { if (editMode.fullMesh != null) editMode.fullMesh.SolveTangents(); if(editMode.detailMesh != null) editMode.detailMesh.SolveTangents(); GUI.changed = false; } EditorGUI.EndDisabledGroup(); if (!editMode.fullMesh.hasTangents) EditorGUILayout.HelpBox("The model doesn't have tangents", MessageType.Warning); EditorGUILayout.EndHorizontal(); //Lightmap rendering EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUI.BeginDisabledGroup(editMode.fullMesh.lightmapUvsCalculated); if (GUILayout.Button("Build Lightmap UVs", GUILayout.Height(38))) { // Undo.RegisterSceneUndo("Build Lightmap UVs"); if(editMode.fullMesh != null) { for (int i = 0; i < editMode.fullMesh.meshCount; i++) Unwrapping.GenerateSecondaryUVSet(editMode.fullMesh[i].mesh);} editMode.fullMesh.lightmapUvsCalculated = true; if(editMode.detailMesh != null) { for (int i = 0; i < editMode.detailMesh.meshCount; i++) Unwrapping.GenerateSecondaryUVSet(editMode.detailMesh[i].mesh); editMode.detailMesh.lightmapUvsCalculated = true; } int numberOfInteriors = editMode.interiorMeshes.Count; for(int i = 0; i < numberOfInteriors; i++) { DynamicMeshGenericMultiMaterialMesh interiorMesh = editMode.interiorMeshes[i]; for (int j = 0; j < interiorMesh.meshCount; j++) Unwrapping.GenerateSecondaryUVSet(interiorMesh[j].mesh); interiorMesh.lightmapUvsCalculated = true; } GUI.changed = false; } EditorGUI.EndDisabledGroup(); if (!editMode.fullMesh.lightmapUvsCalculated) EditorGUILayout.HelpBox("The model doesn't have lightmap UVs", MessageType.Warning); EditorGUILayout.EndHorizontal(); //Mesh Optimisation EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUI.BeginDisabledGroup(editMode.fullMesh.optimised); if (GUILayout.Button("Optimise Mesh For Runtime", GUILayout.Height(38))) { // Undo.RegisterSceneUndo("Optimise Mesh"); if (editMode.fullMesh != null) { for (int i = 0; i < editMode.fullMesh.meshCount; i++) MeshUtility.Optimize(editMode.fullMesh[i].mesh); editMode.fullMesh.optimised = true; } if (editMode.detailMesh != null) { for(int i = 0; i < editMode.detailMesh.meshCount; i++) MeshUtility.Optimize(editMode.detailMesh[i].mesh); editMode.detailMesh.optimised = true; } GUI.changed = false; } EditorGUI.EndDisabledGroup(); if (!editMode.fullMesh.optimised) EditorGUILayout.HelpBox("The model is currently fully optimised for runtime", MessageType.Warning); EditorGUILayout.EndHorizontal(); //Underside render toggle EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUILayout.LabelField("Render Underside of Building"); bool drawUnderside = EditorGUILayout.Toggle(_data.drawUnderside, GUILayout.Width(15)); if(drawUnderside != _data.drawUnderside) { _data.drawUnderside = drawUnderside; } EditorGUILayout.EndHorizontal(); //Define the height of foundations if you need them EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUILayout.LabelField("Foundation Height", GUILayout.Width(120)); _data.foundationHeight = EditorGUILayout.Slider(_data.foundationHeight, 0, 25); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Foundation Texture", GUILayout.Width(120)); _data.foundationTexture = EditorGUILayout.Popup(_data.foundationTexture, textureNames, GUILayout.Width(260)); EditorGUILayout.EndHorizontal(); //Collider mesh EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUILayout.LabelField("Generate Collider"); _data.generateCollider = (BuildrData.ColliderGenerationModes)EditorGUILayout.EnumPopup(_data.generateCollider); EditorGUILayout.EndHorizontal(); //One draw call mesh -TODO // EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); // EditorGUILayout.LabelField("One Draw Call"); // _data.oneDrawCall = EditorGUILayout.Toggle(_data.oneDrawCall); // EditorGUILayout.EndHorizontal(); for (int i = 0; i < editMode.fullMesh.meshCount; i++) EditorUtility.SetSelectedWireframeHidden(editMode.meshHolders[i].GetComponent<Renderer>(), !editMode.showWireframe); }
public static void InspectorGUI(BuildrEditMode editMode, BuildrData _data) { data = _data; Undo.RecordObject(data, "Interior Modified"); BuildrTexture[] textures = data.textures.ToArray(); int numberOfTextures = textures.Length; string[] textureNames = new string[numberOfTextures]; for (int t = 0; t < numberOfTextures; t++) textureNames[t] = textures[t].name; EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUILayout.LabelField("Render Interior of Building"); bool renderInterior = EditorGUILayout.Toggle(_data.renderInteriors, GUILayout.Width(15)); if (renderInterior != _data.renderInteriors) { _data.renderInteriors = renderInterior; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUILayout.LabelField("Cull All Building Bays"); bool cullBays = EditorGUILayout.Toggle(_data.cullBays, GUILayout.Width(15)); if (cullBays != _data.cullBays) { _data.cullBays = cullBays; } EditorGUILayout.EndHorizontal(); //Floor Height EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Floor height", GUILayout.Width(200)); float newFloorHeight = EditorGUILayout.FloatField(data.floorHeight, GUILayout.Width(50)); if (newFloorHeight != data.floorHeight) { data.floorHeight = newFloorHeight; } EditorGUILayout.LabelField("metres", GUILayout.Width(50)); EditorGUILayout.EndHorizontal(); EditorGUI.BeginDisabledGroup(!renderInterior); //Ceiling Height EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Interior Ceiling Height", GUILayout.Width(200)); float newCeilingHeight = EditorGUILayout.Slider(data.interiorCeilingHeight, 0, 1); if (newCeilingHeight != data.interiorCeilingHeight) { data.interiorCeilingHeight = newCeilingHeight; } EditorGUILayout.EndHorizontal(); BuildrPlan plan = data.plan; int numberOfVolumes = plan.numberOfVolumes; int[] volumeSeletionsList = new int[numberOfVolumes]; string[] volumeSeletionsStringList = new string[numberOfVolumes]; for (int s = 0; s < numberOfVolumes; s++) { volumeSeletionsStringList[s] = ("volume " + s); volumeSeletionsList[s] = (s); } selectedVolumeIndex = EditorGUILayout.IntPopup("Selected Volume", selectedVolumeIndex, volumeSeletionsStringList, volumeSeletionsList, GUILayout.Width(400)); BuildrVolume volume = plan.volumes[selectedVolumeIndex]; //Stairs EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Generate Stairs", GUILayout.Width(110)); volume.generateStairs = EditorGUILayout.Toggle(volume.generateStairs); EditorGUILayout.EndHorizontal(); if(plan.cores.Count == 0) EditorGUILayout.HelpBox("There are no building cores defined. Go to floorplan to define one so you can generate a stairwell", MessageType.Error); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Stair Width", GUILayout.Width(110)); volume.staircaseWidth = EditorGUILayout.Slider(volume.staircaseWidth, 0.5f, 5.0f); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Minimum Step Riser Value", GUILayout.Width(150)); volume.stepHeight = EditorGUILayout.Slider(volume.stepHeight, 0.05f, 0.5f); EditorGUILayout.EndHorizontal(); EditorGUI.BeginDisabledGroup(!volume.generateStairs); EditorGUILayout.BeginVertical("box"); EditorGUILayout.LabelField("Stairwell Textures"); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Wall Texture", GUILayout.Width(120)); volume.stairwellWallTexture = EditorGUILayout.Popup(volume.stairwellWallTexture, textureNames); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Floor Texture", GUILayout.Width(120)); volume.stairwellFloorTexture = EditorGUILayout.Popup(volume.stairwellFloorTexture, textureNames); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Ceiling Texture", GUILayout.Width(120)); volume.stairwellCeilingTexture = EditorGUILayout.Popup(volume.stairwellCeilingTexture, textureNames); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Step Texture", GUILayout.Width(120)); volume.stairwellStepTexture = EditorGUILayout.Popup(volume.stairwellStepTexture, textureNames); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); EditorGUI.EndDisabledGroup(); //Basement floors EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Basement Floors", GUILayout.Width(110)); EditorGUILayout.LabelField(volume.numberOfBasementFloors.ToString("F0"), GUILayout.Width(40)); EditorGUI.BeginDisabledGroup(volume.numberOfBasementFloors < 1); if (GUILayout.Button("-")) volume.numberOfBasementFloors--; EditorGUI.EndDisabledGroup(); if (GUILayout.Button("+")) volume.numberOfBasementFloors++; EditorGUILayout.EndHorizontal(); int numberOfFloors = volume.numberOfFloors; int numberOfBasementFloors = volume.numberOfBasementFloors; int totalNumberOfFloors = numberOfBasementFloors + numberOfFloors; int[] floorSeletionsList = new int[totalNumberOfFloors]; string[] floorSeletionsStringList = new string[totalNumberOfFloors]; for (int f = -numberOfBasementFloors; f < numberOfFloors; f++) { int index = f + numberOfBasementFloors; if(f>0) floorSeletionsStringList[index] = "floor " + f; else if(f<0) floorSeletionsStringList[index] = "basement " + -f; else floorSeletionsStringList[index] = "ground floor "; floorSeletionsList[index] = (f); } selectedFloor = EditorGUILayout.IntPopup("Selected Floor", selectedFloor, floorSeletionsStringList, floorSeletionsList, GUILayout.Width(400)); EditorGUILayout.LabelField("Interior Textures"); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Floor Texture", GUILayout.Width(120)); volume.FloorTexture(selectedFloor, EditorGUILayout.Popup(volume.FloorTexture(selectedFloor), textureNames)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Wall Texture", GUILayout.Width(120)); volume.WallTexture(selectedFloor, EditorGUILayout.Popup(volume.WallTexture(selectedFloor), textureNames)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Ceiling Texture", GUILayout.Width(120)); volume.CeilingTexture(selectedFloor, EditorGUILayout.Popup(volume.CeilingTexture(selectedFloor), textureNames)); EditorGUILayout.EndHorizontal(); if(GUILayout.Button("Use Values for All Floors")) { int useFloorTextureIndex = volume.FloorTexture(selectedFloor); int useWallTextureIndex = volume.WallTexture(selectedFloor); int useCeilingTextureIndex = volume.CeilingTexture(selectedFloor); for(int f = 0; f < numberOfFloors; f++) { volume.FloorTexture(f, useFloorTextureIndex); volume.WallTexture(f, useWallTextureIndex); volume.CeilingTexture(f, useCeilingTextureIndex); } } if (GUILayout.Button("Use Values for Entire Building")) { int useFloorTextureIndex = volume.FloorTexture(selectedFloor); int useWallTextureIndex = volume.WallTexture(selectedFloor); int useCeilingTextureIndex = volume.CeilingTexture(selectedFloor); for (int v = 0; v < numberOfVolumes; v++) { BuildrVolume thisvolume = plan.volumes[v]; int numberOfFloorsToModifiy = thisvolume.numberOfFloors; for (int f = 0; f < numberOfFloorsToModifiy; f++) { thisvolume.FloorTexture(f, useFloorTextureIndex); thisvolume.WallTexture(f, useWallTextureIndex); thisvolume.CeilingTexture(f, useCeilingTextureIndex); } } } EditorGUI.EndDisabledGroup(); }
public static void InspectorGUI(BuildrEditMode editMode, BuildrData _data) { int helpWidth = 20; data = _data; Undo.RecordObject(data, "Facade Modified"); BuildrFacadeDesign[] facades = data.facades.ToArray(); int numberOfFacades = facades.Length; selectedFacade = Mathf.Clamp(selectedFacade, 0, numberOfFacades - 1); if (numberOfFacades == 0) { EditorGUILayout.HelpBox("There are no facade designs to show", MessageType.Info); return; } bool hasUnusedFacades = false; int unusedIndex = 0; //Check all facades have een used and warn if there are unused ones for(int i = 0; i < numberOfFacades; i++) { bool facadeUnused = true; foreach(BuildrVolume volume in data.plan.volumes) { if(volume.ContainsFacade(i)) { facadeUnused = false; break; } } if(facadeUnused) { hasUnusedFacades = true; unusedIndex = i; break; } } if (hasUnusedFacades) EditorGUILayout.HelpBox("There are facade designs that are not applied to your building and are unused.\nGo to the Building section to apply them to a facade.\nCheck facade design \""+facades[unusedIndex].name+"\"", MessageType.Warning); //Facade Selector EditorGUILayout.BeginVertical("box"); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Facade Design:", GUILayout.Width(145)); string[] facadeNames = new string[numberOfFacades]; for (int f = 0; f < numberOfFacades; f++) facadeNames[f] = facades[f].name; selectedFacade = EditorGUILayout.Popup(selectedFacade, facadeNames); BuildrFacadeDesign bFacade = facades[selectedFacade]; EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Add", GUILayout.Width(60))) { data.facades.Add(new BuildrFacadeDesign("new facade " + numberOfFacades)); facades = data.facades.ToArray(); numberOfFacades++; selectedFacade = numberOfFacades - 1; } if (GUILayout.Button("Duplicate", GUILayout.Width(90))) { data.facades.Add(bFacade.Duplicate()); facades = data.facades.ToArray(); numberOfFacades++; selectedFacade = numberOfFacades - 1; } if (GUILayout.Button("Delete", GUILayout.Width(70))) { if (EditorUtility.DisplayDialog("Deleting Facade Design Entry", "Are you sure you want to delete this facade?", "Delete", "Cancel")) { data.RemoveFacadeDesign(bFacade); selectedFacade = 0; GUI.changed = true; return; } } if (GUILayout.Button("Import", GUILayout.Width(71))) { string xmlPath = EditorUtility.OpenFilePanel("Select the XML file...", "Assets/BuildR/Exported/", "xml"); if (xmlPath == "") return; BuildrXMLImporter.ImportFacades(xmlPath, _data); facades = _data.facades.ToArray(); selectedFacade = 0; GUI.changed = true; } if (GUILayout.Button("Export", GUILayout.Width(71))) { string xmlPath = EditorUtility.SaveFilePanel("Export as...", "Assets/BuildR/Exported/", _data.name + "_facadeLibrary", "xml"); if (xmlPath == "") return; BuildrXMLExporter.ExportFacades(xmlPath, _data); GUI.changed = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.EndVertical(); bFacade = facades[selectedFacade];//reassign bFacade.name = EditorGUILayout.TextField("Facade Name: ", bFacade.name); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Facade Design Type:", GUILayout.Width(145)); bFacade.type = (BuildrFacadeDesign.types)EditorGUILayout.EnumPopup(bFacade.type); if (GUILayout.Button("?", GUILayout.Width(helpWidth))) { string helpTitle = "Help - Design Type"; string helpBody = "This allows you to select the type of design you're using.\n" + "Simple - the facade openings will be uniform\n" + "Patterned - the facade openings will follow a pattern of defined dimensions and textures\n"; EditorUtility.DisplayDialog(helpTitle, helpBody, "close"); } EditorGUILayout.EndHorizontal(); int numberOfTextures = data.textures.Count; string[] textureNames = new string[numberOfTextures]; for (int t = 0; t < numberOfTextures; t++) textureNames[t] = data.textures[t].name; bFacade.hasWindows = EditorGUILayout.Toggle("Facade Has Bays", bFacade.hasWindows); if (bFacade.hasWindows) { if (bFacade.type == BuildrFacadeDesign.types.simple) { BuildrBay bbay = bFacade.simpleBay; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Render Bay", GUILayout.Width(146)); bool renderBayBack = EditorGUILayout.Toggle(bbay.renderBack); if (renderBayBack != bbay.renderBack) { bbay.renderBack = renderBayBack; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Bay Model", GUILayout.Width(146)); bbay.bayModel = (GameObject)EditorGUILayout.ObjectField(bbay.bayModel, typeof(GameObject), false); if (GUILayout.Button("Clear", GUILayout.Width(70))) bbay.bayModel = null; EditorGUILayout.EndHorizontal(); float bbayopeningWidth = Mathf.Max(EditorGUILayout.FloatField("Opening Width", bbay.openingWidth), 0); if (bbayopeningWidth != bbay.openingWidth) { bbay.openingWidth = bbayopeningWidth; } float bbayopeningHeight = Mathf.Max(EditorGUILayout.FloatField("Opening Height", bbay.openingHeight), 0); if (bbayopeningHeight > data.floorHeight) bbayopeningHeight = data.floorHeight; if (bbayopeningHeight != bbay.openingHeight) { bbay.openingHeight = bbayopeningHeight; } float bbayminimumBayWidth = Mathf.Max(EditorGUILayout.FloatField("Min. Spacing", bbay.minimumBayWidth), 0); if (bbayminimumBayWidth != bbay.minimumBayWidth) { bbay.minimumBayWidth = bbayminimumBayWidth; } float bbayopeningWidthRatio = EditorGUILayout.Slider("Horizontal Space Ratio", bbay.openingWidthRatio, 0, 1); if(bbayopeningWidthRatio != bbay.openingWidthRatio) { bbay.openingWidthRatio = bbayopeningWidthRatio; } float bbayopeningHeightRatio = EditorGUILayout.Slider("Vertical Space Ratio", bbay.openingHeightRatio, 0, 1); if (bbayopeningHeightRatio != bbay.openingHeightRatio) { bbay.openingHeightRatio = bbayopeningHeightRatio; } float bbayopeningDepth = EditorGUILayout.Slider("Opening Depth", bbay.openingDepth, -depth, depth); if (bbayopeningDepth != bbay.openingDepth) { bbay.openingDepth = bbayopeningDepth; } float bbaycolumnDepth = EditorGUILayout.Slider("Column Depth", bbay.columnDepth, -depth, depth); if (bbaycolumnDepth != bbay.columnDepth) { bbay.columnDepth = bbaycolumnDepth; } float bbayrowDepth = EditorGUILayout.Slider("Row Depth", bbay.rowDepth, -depth, depth); if (bbayrowDepth != bbay.rowDepth) { bbay.rowDepth = bbayrowDepth; } float bbaycrossDepth = EditorGUILayout.Slider("Cross Depth", bbay.crossDepth, -depth, depth); if (bbaycrossDepth != bbay.crossDepth) { bbay.crossDepth = bbaycrossDepth; } int numberOfTextureSlots = bbay.numberOfTextures; string[] titles = new string[numberOfTextureSlots]; for (int bft = 0; bft < numberOfTextureSlots; bft++) { titles[bft] = ((BuildrBay.TextureNames)(bft)).ToString(); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Wall Surface:", GUILayout.Width(75)); editTextureOnFacade = EditorGUILayout.Popup(editTextureOnFacade, titles); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Wall Texture:", GUILayout.Width(75)); int newFacadeTextureID = EditorGUILayout.Popup(bbay.textureValues[editTextureOnFacade], textureNames); if (newFacadeTextureID != bbay.textureValues[editTextureOnFacade]) { bbay.textureValues[editTextureOnFacade] = newFacadeTextureID; } EditorGUILayout.EndHorizontal(); BuildrTexture bTexture = data.textures[bbay.textureValues[editTextureOnFacade]]; Texture2D texture = bTexture.texture; EditorGUILayout.BeginHorizontal(); if (texture != null) GUILayout.Label(texture, GUILayout.Width(100), GUILayout.Height(100)); else EditorGUILayout.HelpBox("No texture assigned for '" + textureNames[bbay.textureValues[editTextureOnFacade]] + "', assign one in the Textures menu above", MessageType.Warning); bbay.flipValues[editTextureOnFacade] = EditorGUILayout.Toggle("Flip 90\u00B0", bbay.flipValues[editTextureOnFacade]); EditorGUILayout.EndHorizontal(); } else { //Patterned design GUI int numberOfBays = bFacade.bayPattern.Count; int numberOfBayDesigns = data.bays.Count; EditorGUILayout.BeginHorizontal(); GUILayout.BeginHorizontal("box"); if (GUILayout.Button("Add New Bay Design")) { BuildrBay newBay = new BuildrBay("new bay design " + (numberOfBayDesigns + 1)); data.bays.Add(newBay); bFacade.bayPattern.Add(numberOfBayDesigns); numberOfBays++; selectedBayPatternIndex = numberOfBays - 1; numberOfBayDesigns++; GUI.changed = true; } EditorGUILayout.EndHorizontal(); if (numberOfBays == 0 || data.bays.Count == 0) { EditorGUILayout.HelpBox("There are no bay designs to show", MessageType.Info); // EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); return; } BuildrBay[] bays = new BuildrBay[numberOfBays]; for (int i = 0; i < numberOfBays; i++) { bays[i] = data.bays[bFacade.bayPattern[i]]; } selectedBayPatternIndex = Mathf.Clamp(selectedBayPatternIndex, 0, numberOfBays - 1); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.BeginHorizontal("box"); string[] bayDesignNames = new string[data.bays.Count]; for (int i = 0; i < numberOfBayDesigns; i++) { bayDesignNames[i] = data.bays[i].name; } selectedBayDesign = EditorGUILayout.Popup(selectedBayDesign, bayDesignNames); if (GUILayout.Button("Add Selected")) { bFacade.bayPattern.Add(selectedBayDesign); GUI.changed = true; } if (GUILayout.Button("Duplicate Selected")) { BuildrBay newBay = data.bays[selectedBayDesign].Duplicate(); data.bays.Add(newBay); bFacade.bayPattern.Add(numberOfBayDesigns); numberOfBays++; selectedBayPatternIndex = numberOfBays - 1; numberOfBayDesigns++; GUI.changed = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal(); GUILayout.BeginVertical("box"); EditorGUILayout.LabelField("Bay Design Order:"); var scrollbarHStyle = new GUIStyle(GUI.skin.horizontalScrollbar); var scrollbarBackStyle = new GUIStyle(); var scrollbarVStyle = new GUIStyle(GUI.skin.verticalScrollbar); scrollbarVStyle.fixedHeight = scrollbarVStyle.fixedWidth = 0; bayDesignPatternScrollView = EditorGUILayout.BeginScrollView(bayDesignPatternScrollView, false, false, scrollbarHStyle, scrollbarVStyle, scrollbarBackStyle, GUILayout.Height(40)); List<string> bayNames = new List<string>(); foreach (int bayIndex in bFacade.bayPattern) { bayNames.Add(data.bays[bayIndex].name); } selectedBayPatternIndex = GUILayout.Toolbar(selectedBayPatternIndex, bayNames.ToArray()); EditorGUILayout.EndScrollView(); BuildrBay bBay = data.bays[bFacade.bayPattern[selectedBayPatternIndex]]; EditorGUILayout.BeginHorizontal(); EditorGUI.BeginDisabledGroup(selectedBayPatternIndex == 0); if (GUILayout.Button("<<", GUILayout.Width(40))) { int bayDesignIndex = bFacade.bayPattern[selectedBayPatternIndex]; bFacade.bayPattern.RemoveAt(selectedBayPatternIndex); bFacade.bayPattern.Insert(selectedBayPatternIndex - 1, bayDesignIndex); selectedBayPatternIndex--; GUI.changed = true; } EditorGUI.EndDisabledGroup(); if (GUILayout.Button("Remove")) { bFacade.bayPattern.RemoveAt(selectedBayPatternIndex); GUI.changed = true; } if (GUILayout.Button("Delete")) { if (EditorUtility.DisplayDialog("Deleting Bay Design Entry", "Are you sure you want to delete this bay?", "Delete", "Cancel")) { int deletedBayDesignIndex = bFacade.bayPattern[selectedBayPatternIndex]; Debug.Log("Delete Bay Design " + deletedBayDesignIndex); Debug.Log("Delete Bay Design " + data.bays[deletedBayDesignIndex].name); data.bays.RemoveAt(deletedBayDesignIndex); int numberOfFacadeDesigns = data.facades.Count; for (int i = 0; i < numberOfFacadeDesigns; i++) { BuildrFacadeDesign checkFacade = data.facades[i]; int bayPatternSize = checkFacade.bayPattern.Count; for (int j = 0; j < bayPatternSize; j++) { if (checkFacade.bayPattern[j] == deletedBayDesignIndex) { checkFacade.bayPattern.RemoveAt(j); j--; bayPatternSize--; } else if (checkFacade.bayPattern[j] > deletedBayDesignIndex) checkFacade.bayPattern[j]--; } } GUI.changed = true; } } EditorGUI.BeginDisabledGroup(selectedBayPatternIndex == numberOfBays - 1); if (GUILayout.Button(">>", GUILayout.Width(40))) { int bayDesignIndex = bFacade.bayPattern[selectedBayPatternIndex]; bFacade.bayPattern.Insert(selectedBayPatternIndex + 2, bayDesignIndex); bFacade.bayPattern.RemoveAt(selectedBayPatternIndex); selectedBayPatternIndex++; GUI.changed = true; } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); GUILayout.Space(10); EditorGUILayout.BeginVertical("box"); bBay.name = EditorGUILayout.TextField("Name: ", bBay.name); bool bBayisOpening = EditorGUILayout.Toggle("Has Opening", bBay.isOpening); if(bBayisOpening != bBay.isOpening) { bBay.isOpening = bBayisOpening; } bool bBayRenderBack = EditorGUILayout.Toggle("Render Back", bBay.renderBack); if (bBayRenderBack != bBay.renderBack) { bBay.renderBack = bBayRenderBack; } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Bay Model", GUILayout.Width(146)); bBay.bayModel = (GameObject)EditorGUILayout.ObjectField(bBay.bayModel, typeof(GameObject), false); if (GUILayout.Button("Clear", GUILayout.Width(70))) bBay.bayModel = null; EditorGUILayout.EndHorizontal(); float bBayopeningWidth = Mathf.Max(EditorGUILayout.FloatField("Opening Width", bBay.openingWidth), 0); if (bBayopeningWidth != bBay.openingWidth) { bBay.openingWidth = bBayopeningWidth; } float bBayopeningHeight = Mathf.Clamp(EditorGUILayout.FloatField("Opening Height", bBay.openingHeight), 0, data.floorHeight); if (bBayopeningHeight != bBay.openingHeight) { bBay.openingHeight = bBayopeningHeight; } float bBayminimumBayWidth = Mathf.Max(EditorGUILayout.FloatField("Bay Spacing Width", bBay.minimumBayWidth), 0); if (bBayminimumBayWidth != bBay.minimumBayWidth) { bBay.minimumBayWidth = bBayminimumBayWidth; } float bBayopeningWidthRatio = EditorGUILayout.Slider("Horizontal Space Ratio", bBay.openingWidthRatio, 0, 1); if (bBayopeningWidthRatio != bBay.openingWidthRatio) { bBay.openingWidthRatio = bBayopeningWidthRatio; } float bBayopeningHeightRatio = EditorGUILayout.Slider("Vertical Space Ratio", bBay.openingHeightRatio, 0, 1); if (bBayopeningHeightRatio != bBay.openingHeightRatio) { bBay.openingHeightRatio = bBayopeningHeightRatio; } float bBayopeningDepth = EditorGUILayout.Slider("Opening Depth", bBay.openingDepth, -depth, depth); if (bBayopeningDepth != bBay.openingDepth) { bBay.openingDepth = bBayopeningDepth; } float bBaycolumnDepth = EditorGUILayout.Slider("Column depth", bBay.columnDepth, -depth, depth); if (bBaycolumnDepth != bBay.columnDepth) { bBay.columnDepth = bBaycolumnDepth; } float bBayrowDepth = EditorGUILayout.Slider("Row depth", bBay.rowDepth, -depth, depth); if (bBayrowDepth != bBay.rowDepth) { bBay.rowDepth = bBayrowDepth; } float bBaycrossDepth = EditorGUILayout.Slider("Cross depth", bBay.crossDepth, -depth, depth); if (bBaycrossDepth != bBay.crossDepth) { bBay.crossDepth = bBaycrossDepth; } //BAY TEXTURES int numberOfTextureSlots = bBay.numberOfTextures; string[] titles = new string[numberOfTextureSlots]; for (int bft = 0; bft < numberOfTextureSlots; bft++) { titles[bft] = ((BuildrBay.TextureNames)(bft)).ToString(); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Surface:", GUILayout.Width(75)); editTextureOnFacade = EditorGUILayout.Popup(editTextureOnFacade, titles); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Texture:", GUILayout.Width(75)); bBay.textureValues[editTextureOnFacade] = EditorGUILayout.Popup(bBay.textureValues[editTextureOnFacade], textureNames); EditorGUILayout.EndHorizontal(); BuildrTexture bTexture = data.textures[bBay.textureValues[editTextureOnFacade]]; Texture2D texture = bTexture.texture; EditorGUILayout.BeginHorizontal(); if (texture != null) GUILayout.Label(texture, GUILayout.Width(100), GUILayout.Height(100)); else EditorGUILayout.HelpBox("No texture assigned for '" + textureNames[bBay.textureValues[editTextureOnFacade]] + "', assign one in the Textures menu above", MessageType.Warning); bFacade.flipValues[editTextureOnFacade] = EditorGUILayout.Toggle("Flip 90\u00B0", bFacade.flipValues[editTextureOnFacade]); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); } } else { editTextureOnFacade = 7; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Surface:", GUILayout.Width(75)); EditorGUILayout.LabelField("Wall"); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Texture:", GUILayout.Width(75)); int newFacadeTexture = EditorGUILayout.Popup(bFacade.simpleBay.textureValues[editTextureOnFacade], textureNames); if (newFacadeTexture != bFacade.simpleBay.textureValues[editTextureOnFacade]) { bFacade.simpleBay.textureValues[editTextureOnFacade] = newFacadeTexture; } EditorGUILayout.EndHorizontal(); BuildrTexture bTexture = data.textures[bFacade.simpleBay.textureValues[editTextureOnFacade]]; Texture2D texture = bTexture.texture; EditorGUILayout.BeginHorizontal(); if (texture != null) GUILayout.Label(texture, GUILayout.Width(100), GUILayout.Height(100)); else EditorGUILayout.HelpBox("No texture assigned for '" + textureNames[bFacade.simpleBay.textureValues[editTextureOnFacade]] + "', assign one in the Textures menu above", MessageType.Warning); bFacade.simpleBay.flipValues[editTextureOnFacade] = EditorGUILayout.Toggle("Flip 90\u00B0", bFacade.simpleBay.flipValues[editTextureOnFacade]); EditorGUILayout.EndHorizontal(); } }
public static void InspectorGUI(BuildrEditMode editMode, BuildrData _data) { data = _data; Undo.RecordObject(data, "Building Modified"); BuildrPlan plan = data.plan; int numberOfFacadeFaces = 0; int numberOfVolumes = plan.numberOfVolumes; int numberOfFacadeDesigns = data.facades.Count; if (numberOfVolumes == 0) { EditorGUILayout.HelpBox("There are no defined volumes, go to Floorplan and define one", MessageType.Error); return; } int numberOfFacades = data.facades.Count; int numberOfRoofs = data.roofs.Count; int numberOfTextures = data.textures.Count; bool legalBuilding = true; if (numberOfFacades == 0) { EditorGUILayout.HelpBox("There are no facade designs to render building, go to Facades to define a default one", MessageType.Error); legalBuilding = false; } if (numberOfRoofs == 0) { EditorGUILayout.HelpBox("There are no roof designs to render building, go to Facades to define a default one", MessageType.Error); legalBuilding = false; } if (numberOfTextures == 0) { EditorGUILayout.HelpBox("There are no textures to render building, go to Textures to define a default one", MessageType.Error); legalBuilding = false; } if (!legalBuilding) return; //Building Name EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Name", GUILayout.Width(200)); data.name = EditorGUILayout.TextField(data.name, GUILayout.Width(200)); EditorGUILayout.EndHorizontal(); //Floor Height EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Floor height", GUILayout.Width(200)); data.floorHeight = EditorGUILayout.FloatField(data.floorHeight, GUILayout.Width(50)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Number of Floors", GUILayout.Width(200)); int[] volumeSeletionsList = new int[numberOfVolumes]; string[] volumeSeletionsStringList = new string[numberOfVolumes]; for (int s = 0; s < numberOfVolumes; s++) { volumeSeletionsStringList[s] = ("volume " + s); volumeSeletionsList[s] = (s); } selectedFloorNumberVolume = EditorGUILayout.IntPopup(selectedFloorNumberVolume, volumeSeletionsStringList, volumeSeletionsList, GUILayout.Width(100)); int numberOfFloors = EditorGUILayout.IntField(data.plan.volumes[selectedFloorNumberVolume].numberOfFloors); if (GUILayout.Button("^")) numberOfFloors++; if (GUILayout.Button("v")) numberOfFloors--; data.plan.volumes[selectedFloorNumberVolume].numberOfFloors = Mathf.Max(numberOfFloors, 1); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Show Facade Markers", GUILayout.Width(200)); editMode.showFacadeMarkers = EditorGUILayout.Toggle(editMode.showFacadeMarkers, GUILayout.Width(200)); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); GUIStyle titlesyle = new GUIStyle(GUI.skin.label); titlesyle.fixedHeight = 60; titlesyle.fixedWidth = 400; titlesyle.alignment = TextAnchor.UpperCenter; titlesyle.fontStyle = FontStyle.Bold; titlesyle.normal.textColor = Color.white; EditorGUILayout.LabelField("Facade Design", titlesyle); Texture2D facadeTexture = new Texture2D(1, 1); facadeTexture.SetPixel(0, 0, BuildrColours.MAGENTA); facadeTexture.Apply(); Rect sqrPos = new Rect(0, 0, 0, 0); if (Event.current.type == EventType.Repaint) sqrPos = GUILayoutUtility.GetLastRect(); GUI.DrawTexture(sqrPos, facadeTexture); EditorGUI.LabelField(sqrPos, "Facade Design", titlesyle); //create/display the facade selector List<int> facadeSeletionsList = new List<int>(); List<int> facadeRenderList = new List<int>(); List<string> facadeSeletionsStringList = new List<string>(); for (int s = 0; s < numberOfVolumes; s++) { int numberOfPoints = plan.volumes[s].Count; numberOfFacadeFaces += numberOfPoints; for (int p = 0; p < numberOfPoints; p++) { int index = facadeSeletionsList.Count; facadeSeletionsStringList.Add("facade " + index); facadeSeletionsList.Add(index); facadeRenderList.Add(p); } } int[] facadeSelections = facadeSeletionsList.ToArray(); string[] facadeSelectionString = facadeSeletionsStringList.ToArray(); selectedFacade = EditorGUILayout.IntPopup("Selected Facade", selectedFacade, facadeSelectionString, facadeSelections, GUILayout.Width(400)); //grab the selected facade int facadeCount = 0; int selectedVolumePoint = 0; for (int s = 0; s < numberOfVolumes; s++) { int numberOfPoints = plan.volumes[s].Count; for (int p = 0; p < numberOfPoints; p++) { if (selectedFacade == facadeCount) { selectedVolume = s; selectedVolumePoint = p; selectedPoint = plan.volumes[s].points[p]; } facadeCount++; } } BuildrVolume volume = plan.volumes[selectedVolume]; BuildrVolumeStylesUnit[] styles = volume.styles.GetContents(); bool renderFacade = volume.renderFacade[selectedVolumePoint]; volume.renderFacade[selectedVolumePoint] = EditorGUILayout.Toggle("Render Facade", renderFacade); //ensure the selected style isn't out of bounds int numberOfStyles = styles.Length; if (selectedStyle >= numberOfStyles) selectedStyle = 0; //compose a list of style ids from the volume style library List<int> entryNum = new List<int>(); for (int s = 0; s < numberOfStyles; s++) { if (selectedPoint == styles[s].facadeID) entryNum.Add(s); } int numberOfFacadeStyles = entryNum.Count; if (GUILayout.Button("Add style to facade", GUILayout.Width(400))) volume.styles.AddStyle(0, selectedPoint, 1); GUILayout.BeginHorizontal("box"); GUILayout.BeginHorizontal("box"); EditorGUILayout.LabelField("Style", GUILayout.Width(160)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal("box"); GUILayout.Label("Floors", GUILayout.Width(78)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal("box"); GUILayout.Label("Position", GUILayout.Width(54)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal("box"); GUILayout.Label(" ", GUILayout.Width(55)); GUILayout.EndHorizontal(); GUILayout.EndHorizontal(); for (int s = 0; s < numberOfFacadeStyles; s++) { int index = entryNum[s]; BuildrVolumeStylesUnit styleUnit = styles[index]; GUILayout.BeginHorizontal("box"); GUILayout.BeginHorizontal("box"); string[] facadeNames = new string[numberOfFacadeDesigns]; for (int f = 0; f < numberOfFacadeDesigns; f++) facadeNames[f] = data.facades[f].name; int selectedFacadeDesign = EditorGUILayout.Popup(styleUnit.styleID, facadeNames, GUILayout.Width(160)); if (selectedFacadeDesign != styleUnit.styleID) { volume.styles.ModifyStyle(index, selectedFacadeDesign); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal("box"); int currentFloors = styleUnit.floors; currentFloors = EditorGUILayout.IntField(currentFloors, GUILayout.Width(20)); if (GUILayout.Button("+", GUILayout.Width(25))) currentFloors++; EditorGUI.BeginDisabledGroup(currentFloors < 2); if (GUILayout.Button("-", GUILayout.Width(25))) currentFloors--; EditorGUI.EndDisabledGroup(); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal("box"); EditorGUI.BeginDisabledGroup((s < 1)); { if (GUILayout.Button("^", GUILayout.Width(25))) { volume.styles.MoveEntry(entryNum[s], entryNum[s - 1] + 1); GUI.changed = true; } } EditorGUI.EndDisabledGroup(); EditorGUI.BeginDisabledGroup((s > numberOfFacadeStyles - 2)); { if (GUILayout.Button("v", GUILayout.Width(25))) { volume.styles.MoveEntry(entryNum[s], entryNum[s + 1] + 1); GUI.changed = true; } } EditorGUI.EndDisabledGroup(); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal("box"); if (GUILayout.Button("remove", GUILayout.Width(55))) { volume.styles.RemoveStyle(index); } GUILayout.EndHorizontal(); GUILayout.EndHorizontal(); if (currentFloors != styleUnit.floors) { volume.styles.ModifyFloors(index, currentFloors); GUI.changed = true; } } EditorGUILayout.Space(); titlesyle = new GUIStyle(GUI.skin.label); titlesyle.fixedHeight = 60; titlesyle.fixedWidth = 400; titlesyle.alignment = TextAnchor.UpperCenter; titlesyle.fontStyle = FontStyle.Bold; titlesyle.normal.textColor = Color.black; EditorGUILayout.LabelField("Roof Design", titlesyle); facadeTexture = new Texture2D(1, 1); facadeTexture.SetPixel(0, 0, BuildrColours.CYAN); facadeTexture.Apply(); sqrPos = new Rect(0, 0, 0, 0); if (Event.current.type == EventType.Repaint) sqrPos = GUILayoutUtility.GetLastRect(); GUI.DrawTexture(sqrPos, facadeTexture); EditorGUI.LabelField(sqrPos, "Roof Design", titlesyle); //create/display the roof selector volumeSeletionsList = new int[numberOfVolumes]; volumeSeletionsStringList = new string[numberOfVolumes]; for (int s = 0; s < numberOfVolumes; s++) { volumeSeletionsStringList[s] = ("volume " + s); volumeSeletionsList[s] = (s); } selectedRoofVolume = EditorGUILayout.IntPopup("Selected Volume", selectedRoofVolume, volumeSeletionsStringList, volumeSeletionsList, GUILayout.Width(400)); string[] roofNames = new string[numberOfRoofs]; int[] roofList = new int[numberOfRoofs]; for (int r = 0; r < numberOfRoofs; r++) { roofList[r] = r; roofNames[r] = data.roofs[r].name; } volume = data.plan.volumes[selectedRoofVolume]; volume.roofDesignID = EditorGUILayout.IntPopup("Selected Roof Design", volume.roofDesignID, roofNames, roofList, GUILayout.Width(400)); }
public static void SceneGUI(BuildrEditMode editMode, BuildrData data, bool shouldSnap, float handleSize) { if (data.details.Count == 0) { return; } Undo.RecordObject(data, "Detail Modified"); int numberOfFacades = data.facades.Count; int numberOfRoofs = data.roofs.Count; int numberOfTextures = data.textures.Count; if (numberOfFacades == 0 || numberOfRoofs == 0 || numberOfTextures == 0) { return; } Vector3 position = editMode.transform.position; BuildrPlan plan = data.plan; int numberOfVolumes = plan.numberOfVolumes; BuildrDetail bDetail = data.details[selectedDetail]; float volumeHeight = 0; Vector3 baseLeft = Vector3.zero; Vector3 baseRight = Vector3.zero; int faceIndex = bDetail.face; int facadeCounter = 0; for (int v = 0; v < numberOfVolumes; v++) { BuildrVolume volume = data.plan.volumes[v]; int volumeSize = volume.Count; Vector3 floorCentre = Vector3.zero; Handles.color = Color.white; for (int p = 0; p < volumeSize; p++) { int point = volume.points[p]; int indexB = volume.points[(p + 1) % volumeSize]; Vector3 fb0 = plan.points[point].vector3; Vector3 fb1 = plan.points[indexB].vector3; if (bDetail.face == facadeCounter && bDetail.type == BuildrDetail.Types.Facade) { baseLeft = fb0; baseRight = fb1; } floorCentre += baseLeft; List <Vector3> verts = new List <Vector3>(); volumeHeight = (volume.numberOfFloors * data.floorHeight); Vector3 volumeHeightVector = Vector3.up * volumeHeight; verts.Add(fb0 + position); verts.Add(fb1 + position); verts.Add(verts[1] + volumeHeightVector); verts.Add(verts[0] + volumeHeightVector); if (bDetail.face == facadeCounter && bDetail.type == BuildrDetail.Types.Facade) { //display something to highlight this facade Handles.DrawSolidRectangleWithOutline(verts.ToArray(), Color.clear, BuildrColours.MAGENTA); } Handles.color = BuildrColours.CYAN; if (v == bDetail.face && bDetail.type == BuildrDetail.Types.Roof) { Handles.DrawLine(verts[2], verts[3]); } if (editMode.showFacadeMarkers) { Handles.color = Color.white; Vector3 camDirection = Camera.current.transform.forward; Vector3 facadeDirection = Vector3.Cross((verts[0] - verts[1]), Vector3.up); GUIStyle facadeLabelStyle = new GUIStyle(); facadeLabelStyle.normal.textColor = Color.white; facadeLabelStyle.alignment = TextAnchor.MiddleCenter; facadeLabelStyle.fixedWidth = 75.0f; if (Vector3.Dot(camDirection, facadeDirection) < 0)//only display label when facade is facing camera { Vector3 centerPos = (verts[0] + verts[1]) * 0.5f; Vector3 labelPos = centerPos + facadeDirection.normalized; Handles.Label(labelPos, "facade " + facadeCounter, facadeLabelStyle); Handles.DrawLine(centerPos, labelPos); } } facadeCounter++; } } Vector3 handlePosition = bDetail.worldPosition + position;// new Vector3(basePos.x, volumeHeight * bDetail.faceUv.y, basePos.z); Vector3 baseDir = (baseRight - baseLeft).normalized; Vector3 baseCross = Vector3.Cross(Vector3.up, baseDir); Quaternion currentRot = Quaternion.Euler(bDetail.userRotation); Quaternion faceRotation = (bDetail.type == BuildrDetail.Types.Facade) ? Quaternion.LookRotation(baseCross) : Quaternion.identity; switch (Tools.current) { case Tool.Move: Vector3 dirX, dirY, dirZ; if (bDetail.type == BuildrDetail.Types.Facade) { dirX = baseDir; dirY = baseCross; dirZ = Vector3.up; } else { dirX = Vector3.right; dirY = Vector3.up; dirZ = Vector3.forward; } Vector3 newSliderPos; Handles.color = BuildrColours.RED; newSliderPos = Handles.Slider(handlePosition, dirX, handleSize * 0.666f, Handles.ArrowCap, 0.0f); Handles.color = BuildrColours.BLUE; newSliderPos = Handles.Slider(newSliderPos, dirZ, handleSize * 0.666f, Handles.ArrowCap, 0.0f); Handles.color = BuildrColours.GREEN; newSliderPos = Handles.Slider(newSliderPos, dirY, handleSize * 0.666f, Handles.ArrowCap, 0.0f); Vector3 sliderDiff = newSliderPos - handlePosition; if (sliderDiff != Vector3.zero) { float newXUV = 0, newYUV = 0, newHeight = bDetail.faceHeight; if (bDetail.type == BuildrDetail.Types.Facade) { float facadeWidth = Vector3.Distance(baseLeft, baseRight); float sliderDiffX = Mathf.Sqrt(sliderDiff.x * sliderDiff.x + sliderDiff.z * sliderDiff.z) * Mathf.Sign(Vector3.Dot(baseDir, sliderDiff)); newXUV = sliderDiffX / facadeWidth + bDetail.faceUv.x; newYUV = sliderDiff.y / volumeHeight + bDetail.faceUv.y; } else { BuildrVolume volume = plan.volumes[faceIndex]; int numberOfVolumePoints = volume.points.Count; Vector3 minPoint = plan.points[volume.points[0]].vector3; Vector3 maxPoint = plan.points[volume.points[0]].vector3; for (int p = 1; p < numberOfVolumePoints; p++) { Vector3 fp0 = plan.points[volume.points[p]].vector3; if (fp0.x < minPoint.x) { minPoint.x = fp0.x; } if (fp0.z < minPoint.z) { minPoint.z = fp0.z; } if (fp0.x > maxPoint.x) { maxPoint.x = fp0.x; } if (fp0.z > maxPoint.z) { maxPoint.z = fp0.z; } } float roofWidth = maxPoint.x - minPoint.x; float roofDepth = maxPoint.z - minPoint.z; newXUV = sliderDiff.x / roofWidth + bDetail.faceUv.x; newYUV = sliderDiff.z / roofDepth + bDetail.faceUv.y; newHeight += sliderDiff.y; } bDetail.faceUv = new Vector2(newXUV, newYUV); bDetail.faceHeight = newHeight; } break; case Tool.Rotate: currentRot = Handles.RotationHandle(currentRot, handlePosition); bDetail.userRotation = currentRot.eulerAngles; break; case Tool.Scale: bDetail.scale = Handles.ScaleHandle(bDetail.scale, handlePosition, currentRot * faceRotation, handleSize * 0.666f); break; } //draw mesh bounds if (bDetail.mesh != null) { Bounds meshBounds = bDetail.mesh.bounds; Quaternion rotation = bDetail.worldRotation; Vector3 p0 = rotation * (new Vector3(meshBounds.min.x, meshBounds.min.y, meshBounds.min.z)) + bDetail.worldPosition; Vector3 p1 = rotation * (new Vector3(meshBounds.max.x, meshBounds.min.y, meshBounds.min.z)) + bDetail.worldPosition; Vector3 p2 = rotation * (new Vector3(meshBounds.min.x, meshBounds.min.y, meshBounds.max.z)) + bDetail.worldPosition; Vector3 p3 = rotation * (new Vector3(meshBounds.max.x, meshBounds.min.y, meshBounds.max.z)) + bDetail.worldPosition; Vector3 p4 = rotation * (new Vector3(meshBounds.min.x, meshBounds.max.y, meshBounds.min.z)) + bDetail.worldPosition; Vector3 p5 = rotation * (new Vector3(meshBounds.max.x, meshBounds.max.y, meshBounds.min.z)) + bDetail.worldPosition; Vector3 p6 = rotation * (new Vector3(meshBounds.min.x, meshBounds.max.y, meshBounds.max.z)) + bDetail.worldPosition; Vector3 p7 = rotation * (new Vector3(meshBounds.max.x, meshBounds.max.y, meshBounds.max.z)) + bDetail.worldPosition; Handles.color = BuildrColours.BLUE; Handles.DrawLine(p0, p1); Handles.DrawLine(p0, p2); Handles.DrawLine(p1, p3); Handles.DrawLine(p2, p3); Handles.DrawLine(p0, p4); Handles.DrawLine(p1, p5); Handles.DrawLine(p2, p6); Handles.DrawLine(p3, p7); Handles.DrawLine(p4, p5); Handles.DrawLine(p4, p6); Handles.DrawLine(p5, p7); Handles.DrawLine(p6, p7); if (clickPlace) { Vector3 planeBase = Vector3.zero; Vector3 planeNormal = Vector3.up; Vector3 planeSize = Vector3.zero; if (bDetail.type == BuildrDetail.Types.Facade) { //find facade int facadeCount = 0; bool facadeFound = false; for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = plan.volumes[s]; int numberOfVolumePoints = volume.points.Count; for (int p = 0; p < numberOfVolumePoints; p++) { if (facadeCount == faceIndex) { int indexA = p; int indexB = (p + 1) % numberOfVolumePoints; Vector3 fp0 = plan.points[volume.points[indexA]].vector3; Vector3 fp1 = plan.points[volume.points[indexB]].vector3; planeBase = fp0; planeNormal = Vector3.Cross(Vector3.up, fp1 - fp0).normalized; planeSize.x = Vector3.Distance(fp0, fp1); planeSize.y = volume.numberOfFloors * data.floorHeight; facadeFound = true; break; } facadeCount++; } if (facadeFound) { break; } } } else { BuildrVolume volume = plan.volumes[faceIndex]; int numberOfVolumePoints = volume.points.Count; Vector3 minPoint = plan.points[volume.points[0]].vector3; Vector3 maxPoint = plan.points[volume.points[0]].vector3; for (int p = 1; p < numberOfVolumePoints; p++) { Vector3 fp0 = plan.points[volume.points[p]].vector3; if (fp0.x < minPoint.x) { minPoint.x = fp0.x; } if (fp0.z < minPoint.z) { minPoint.z = fp0.z; } if (fp0.x > maxPoint.x) { maxPoint.x = fp0.x; } if (fp0.z > maxPoint.z) { maxPoint.z = fp0.z; } } planeSize.x = maxPoint.x - minPoint.x; planeSize.z = maxPoint.z - minPoint.z; planeBase = minPoint; planeBase.y = (data.floorHeight * volume.numberOfFloors); } float distance; Plane buildingPlane = new Plane(planeNormal, planeBase); Ray ray = Camera.current.ScreenPointToRay(new Vector3(Event.current.mousePosition.x, Screen.height - Event.current.mousePosition.y - 30, 0)); if (buildingPlane.Raycast(ray, out distance)) { Vector3 mousePlanePoint = ray.GetPoint(distance); Quaternion mouseLookDirection = Quaternion.LookRotation(buildingPlane.normal); if (Handles.Button(mousePlanePoint, mouseLookDirection, handleSize * 0.1f, handleSize * 0.1f, Handles.CircleCap)) { float xUv, yUv; if (bDetail.type == BuildrDetail.Types.Facade) { Vector3 facadeBaseMousePoint = new Vector3(mousePlanePoint.x, 0, mousePlanePoint.z); xUv = Vector3.Distance(planeBase, facadeBaseMousePoint) / planeSize.x; yUv = (mousePlanePoint.y - planeBase.y) / planeSize.y; } else { xUv = (mousePlanePoint.x - planeBase.x) / planeSize.x; yUv = (mousePlanePoint.z - planeBase.z) / planeSize.z; } bDetail.faceUv = new Vector2(xUv, yUv); clickPlace = false; GUI.changed = true; } } } } if (GUI.changed) { EditorUtility.SetDirty(editMode); EditorUtility.SetDirty(data); editMode.UpdateRender(); } }
public static void InspectorGUI(BuildrEditMode editMode, BuildrData data) { BuildrDetail[] details = data.details.ToArray(); int numberOfDetails = details.Length; selectedDetail = Mathf.Clamp(selectedDetail, 0, numberOfDetails - 1); if (numberOfDetails == 0) { EditorGUILayout.HelpBox("There are no details to show", MessageType.Info); if (GUILayout.Button("Add New")) { data.details.Add(new BuildrDetail("new detail " + numberOfDetails)); numberOfDetails++; selectedDetail = numberOfDetails - 1; } return; } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Detail", GUILayout.Width(75)); string[] detailNames = new string[numberOfDetails]; for (int t = 0; t < numberOfDetails; t++) { detailNames[t] = details[t].name; } selectedDetail = EditorGUILayout.Popup(selectedDetail, detailNames); EditorGUILayout.EndHorizontal(); BuildrDetail bDetail = details[selectedDetail]; EditorGUILayout.BeginHorizontal(); EditorGUILayout.Space(); if (GUILayout.Button("Add New", GUILayout.Width(81))) { data.details.Add(new BuildrDetail("new detail " + numberOfDetails)); numberOfDetails++; selectedDetail = numberOfDetails - 1; } if (GUILayout.Button("Duplicate", GUILayout.Width(90))) { data.details.Add(bDetail.Duplicate()); numberOfDetails++; selectedDetail = numberOfDetails - 1; } if (GUILayout.Button("Delete", GUILayout.Width(71))) { if (EditorUtility.DisplayDialog("Deleting Building Detail Entry", "Are you sure you want to delete this detail?", "Delete", "Cancel")) { data.details.Remove(bDetail); selectedDetail = 0; GUI.changed = true; return; } } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); details = data.details.ToArray(); detailNames = new string[numberOfDetails]; for (int t = 0; t < numberOfDetails; t++) { detailNames[t] = details[t].name; } bDetail = details[selectedDetail];//reassign EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginVertical(); bDetail.name = EditorGUILayout.TextField("Name", bDetail.name); bDetail.mesh = (Mesh)EditorGUILayout.ObjectField("Mesh", bDetail.mesh, typeof(Mesh), false); EditorGUIUtility.LookLikeControls(); bDetail.material.mainTexture = (Texture)EditorGUILayout.ObjectField("Texture", bDetail.material.mainTexture, typeof(Texture), false, GUILayout.Height(140)); if (bDetail.material.mainTexture != null) { string texturePath = AssetDatabase.GetAssetPath(bDetail.material.mainTexture); TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(texturePath); if (!textureImporter.isReadable) { EditorGUILayout.HelpBox("The texture you have selected is not readable." + "\nPlease select the readable checkbox under advanced texture settings." + "\nOr move this texture to the BuildR texture folder and reimport.", MessageType.Error); } } BuildrPlan plan = data.plan; int numberOfVolumes = plan.numberOfVolumes; int numberOfFaces = 0; List <int> faceSeletionsList = new List <int>(); List <string> faceSeletionsStringList = new List <string>(); if (bDetail.type == BuildrDetail.Types.Facade) { for (int s = 0; s < numberOfVolumes; s++) { int numberOfPoints = plan.volumes[s].Count; numberOfFaces += numberOfPoints; for (int p = 0; p < numberOfPoints; p++) { int index = faceSeletionsList.Count; faceSeletionsStringList.Add("facade " + index); faceSeletionsList.Add(index); } } } else { bDetail.face = Mathf.Clamp(0, numberOfVolumes - 1, bDetail.face); for (int s = 0; s < numberOfVolumes; s++) { int index = faceSeletionsList.Count; faceSeletionsStringList.Add("roof " + index); faceSeletionsList.Add(index); } } if (!clickPlace) { if (GUILayout.Button("Place Detail with Mouse")) { clickPlace = true; } } else { if (GUILayout.Button("Cancel Place Detail")) { clickPlace = false; } } BuildrDetail.Types bDetailtype = (BuildrDetail.Types)EditorGUILayout.EnumPopup("Face Type", bDetail.type); if (bDetailtype != bDetail.type) { bDetail.type = bDetailtype; } int[] faceSelections = faceSeletionsList.ToArray(); string[] faceSelectionString = faceSeletionsStringList.ToArray(); int bDetailface = EditorGUILayout.IntPopup("Selected Face", bDetail.face, faceSelectionString, faceSelections); if (bDetailface != bDetail.face) { bDetail.face = bDetailface; } Vector2 bDetailfaceUv = EditorGUILayout.Vector2Field("Face UV", bDetail.faceUv); if (bDetailfaceUv != bDetail.faceUv) { bDetail.faceUv = bDetailfaceUv; } float bDetailfaceHeight = EditorGUILayout.FloatField("Face Height", bDetail.faceHeight); if (bDetailfaceHeight != bDetail.faceHeight) { bDetail.faceHeight = bDetailfaceHeight; } Vector3 bDetailuserRotation = EditorGUILayout.Vector3Field("Rotation", bDetail.userRotation); if (bDetailuserRotation != bDetail.userRotation) { bDetail.userRotation = bDetailuserRotation; } Vector3 bDetailscale = EditorGUILayout.Vector3Field("Object Scale", bDetail.scale); if (bDetailscale != bDetail.scale) { bDetail.scale = bDetailscale; } EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(GUILayout.Width(120)); if (bDetail.mesh != null) { Texture2D previewMeshImage = AssetPreview.GetAssetPreview(bDetail.mesh); GUILayout.Label(previewMeshImage); } else { Texture2D previewMeshImage = new Texture2D(118, 118); GUILayout.Label(previewMeshImage); GUILayout.Label("No Mesh Selected"); } if (bDetail.material.mainTexture != null) { Texture previewMeshImage = bDetail.material.mainTexture; GUILayout.Label(previewMeshImage, GUILayout.Width(128), GUILayout.Height(128)); } else { Texture2D previewMeshImage = new Texture2D(118, 118); GUILayout.Label(previewMeshImage); GUILayout.Label("No Texture Selected"); } EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); }
public static void InspectorGUI(BuildrEditMode editMode, BuildrData _data) { data = _data; Undo.RecordObject(data, "Roof Modified"); BuildrRoofDesign[] roofs = data.roofs.ToArray(); int numberOfRoofs = roofs.Length; selectedRoof = Mathf.Clamp(selectedRoof, 0, numberOfRoofs - 1); if (GUILayout.Button("Add new roof design")) { data.roofs.Add(new BuildrRoofDesign("new roof " + numberOfRoofs)); roofs = data.roofs.ToArray(); numberOfRoofs++; selectedRoof = numberOfRoofs - 1; } if (numberOfRoofs == 0) { EditorGUILayout.HelpBox("There are no roof designs to show", MessageType.Info); return; } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Design: ", GUILayout.Width(75)); string[] roofNames = new string[numberOfRoofs]; for (int f = 0; f < numberOfRoofs; f++) { roofNames[f] = roofs[f].name; } selectedRoof = EditorGUILayout.Popup(selectedRoof, roofNames); BuildrRoofDesign bRoof = roofs[selectedRoof]; EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Delete", GUILayout.Width(75))) { if (EditorUtility.DisplayDialog("Deleting Roof Design Entry", "Are you sure you want to delete this roof?", "Delete", "Cancel")) { data.RemoveRoofDesign(bRoof); selectedRoof = 0; GUI.changed = true; return; } } if (GUILayout.Button("Import", GUILayout.Width(71))) { string xmlPath = EditorUtility.OpenFilePanel("Select the XML file...", "Assets/BuildR/Exported/", "xml"); if (xmlPath == "") { return; } BuildrXMLImporter.ImportRoofs(xmlPath, _data); GUI.changed = true; } if (GUILayout.Button("Export", GUILayout.Width(71))) { string xmlPath = EditorUtility.SaveFilePanel("Export as...", "Assets/BuildR/Exported/", _data.name + "_roofLibrary", "xml"); if (xmlPath == "") { return; } BuildrXMLExporter.ExportRoofs(xmlPath, _data); GUI.changed = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Name: ", GUILayout.Width(75)); bRoof.name = EditorGUILayout.TextField(bRoof.name); EditorGUILayout.EndHorizontal(); //ROOF STYLE EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Style: ", GUILayout.Width(75)); BuildrRoofDesign.styles bRoofstyle = (BuildrRoofDesign.styles)EditorGUILayout.EnumPopup(bRoof.style); if (bRoofstyle != bRoof.style) { bRoof.style = bRoofstyle; } EditorGUILayout.EndHorizontal(); if (bRoof.style != BuildrRoofDesign.styles.flat && bRoof.style != BuildrRoofDesign.styles.mansard && bRoof.style != BuildrRoofDesign.styles.steepled && bRoof.style != BuildrRoofDesign.styles.hipped) { EditorGUILayout.HelpBox("Please note that this design can only be used on sections with 4 points." + "\nComplex sections can only use the Flat, Mansard and Steeple designs.", MessageType.Warning); } if (bRoof.style != BuildrRoofDesign.styles.flat) { bRoof.height = Mathf.Max(EditorGUILayout.FloatField("Height", bRoof.height), 0); } if (bRoof.style == BuildrRoofDesign.styles.mansard) { bRoof.floorDepth = Mathf.Max(EditorGUILayout.FloatField("Base Depth", bRoof.floorDepth), 0); bRoof.depth = Mathf.Max(EditorGUILayout.FloatField("Top Depth", bRoof.depth), 0); } if (bRoof.style == BuildrRoofDesign.styles.barrel) { bRoof.barrelSegments = Mathf.Max(EditorGUILayout.IntField("Barrel Segments", bRoof.barrelSegments), 3); } if (bRoof.style == BuildrRoofDesign.styles.barrel || bRoof.style == BuildrRoofDesign.styles.gabled || bRoof.style == BuildrRoofDesign.styles.hipped) { //two directions of the ridge bRoof.direction = Mathf.Clamp(bRoof.direction, 0, 1); string[] options = new string[2] { "short", "long" }; bRoof.direction = EditorGUILayout.Popup(bRoof.direction, options); } if (bRoof.style == BuildrRoofDesign.styles.leanto || bRoof.style == BuildrRoofDesign.styles.sawtooth) { //four directions of the ridge bRoof.direction = Mathf.Clamp(bRoof.direction, 0, 3); string[] options = new string[4] { "left", "up", "right", "down" }; bRoof.direction = EditorGUILayout.Popup(bRoof.direction, options); } if (bRoof.style == BuildrRoofDesign.styles.sawtooth) { bRoof.sawtoothTeeth = Mathf.Max(EditorGUILayout.IntField("Number of 'teeth'", bRoof.sawtoothTeeth), 2); } //PARAPET bool bRoofparapet = EditorGUILayout.Toggle("Has Parapet", bRoof.parapet); if (bRoofparapet != bRoof.parapet) { bRoof.parapet = bRoofparapet; } if (bRoof.parapet) { float bRoofparapetHeight = Mathf.Max(EditorGUILayout.FloatField("Parapet Width", bRoof.parapetHeight), 0); if (bRoofparapetHeight != bRoof.parapetHeight) { bRoof.parapetHeight = bRoofparapetHeight; } float bRoofparapetFrontDepth = Mathf.Max(EditorGUILayout.FloatField("Parapet Front Depth", bRoof.parapetFrontDepth), 0); if (bRoofparapetFrontDepth != bRoof.parapetFrontDepth) { bRoof.parapetFrontDepth = bRoofparapetFrontDepth; } float bRoofparapetBackDepth = Mathf.Max(EditorGUILayout.FloatField("Parapet Back Depth", bRoof.parapetBackDepth), 0); if (bRoofparapetBackDepth != bRoof.parapetBackDepth) { bRoof.parapetBackDepth = bRoofparapetBackDepth; } if (bRoof.parapetStyle == BuildrRoofDesign.parapetStyles.fancy)//NOT IMPLMENTED...YET... { EditorGUILayout.HelpBox("This allows you to specify a model mesh that will be used to create a parapet." + "\nIt should not repeat as Buildr will attempt to repeat the style to fit the length of the facade.", MessageType.Info); bRoof.parapetDesign = (Mesh)EditorGUILayout.ObjectField("Parapet Mesh", bRoof.parapetDesign, typeof(Mesh), false); bRoof.parapetDesignWidth = Mathf.Max(EditorGUILayout.FloatField("Parapet Design Width", bRoof.parapetDesignWidth), 0); } } //DORMERS if (bRoof.style == BuildrRoofDesign.styles.mansard) { bool bRoofhasDormers = EditorGUILayout.Toggle("Has Dormers", bRoof.hasDormers); if (bRoofhasDormers != bRoof.hasDormers) { bRoof.hasDormers = bRoofhasDormers; } if (bRoof.hasDormers) { float bRoofdormerWidth = Mathf.Max(EditorGUILayout.FloatField("Dormer Width", bRoof.dormerWidth), 0); if (bRoofdormerWidth != bRoof.dormerWidth) { bRoof.dormerWidth = bRoofdormerWidth; } float bRoofdormerHeight = Mathf.Clamp(EditorGUILayout.FloatField("Dormer Height", bRoof.dormerHeight), 0, bRoof.height); if (bRoofdormerHeight != bRoof.dormerHeight) { bRoof.dormerHeight = bRoofdormerHeight; } float bRoofdormerRoofHeight = Mathf.Clamp(EditorGUILayout.FloatField("Dormer Roof Height", bRoof.dormerRoofHeight), 0, bRoof.dormerHeight); if (bRoofdormerRoofHeight != bRoof.dormerRoofHeight) { bRoof.dormerRoofHeight = bRoofdormerRoofHeight; } float bRoofminimumDormerSpacing = Mathf.Max(EditorGUILayout.FloatField("Dormer Minimum Spacing", bRoof.minimumDormerSpacing), 0); if (bRoofminimumDormerSpacing != bRoof.minimumDormerSpacing) { bRoof.minimumDormerSpacing = bRoofminimumDormerSpacing; } float bRoofdormerHeightRatio = EditorGUILayout.Slider("Dormer Height Ratio", bRoof.dormerHeightRatio, 0, 1); if (bRoofdormerHeightRatio != bRoof.dormerHeightRatio) { bRoof.dormerHeightRatio = bRoofdormerHeightRatio; } } } //TEXTURES int numberOfTextures = data.textures.Count; string[] textureNames = new string[numberOfTextures]; for (int t = 0; t < numberOfTextures; t++) { textureNames[t] = data.textures[t].name; } int numberOfTextureSlots = bRoof.numberOfTextures; string[] titles = new string[numberOfTextureSlots]; for (int brt = 0; brt < numberOfTextureSlots; brt++) { titles[brt] = ((BuildrRoofDesign.textureNames)(brt)).ToString(); } editTextureOnRoof = EditorGUILayout.Popup("Texture Surface:", editTextureOnRoof, titles); int selectedRoofTexture = EditorGUILayout.Popup("Selected Texture:", bRoof.textureValues[editTextureOnRoof], textureNames); if (selectedRoofTexture != bRoof.textureValues[editTextureOnRoof]) { bRoof.textureValues[editTextureOnRoof] = selectedRoofTexture; } BuildrTexture bTexture = data.textures[bRoof.textureValues[editTextureOnRoof]]; Texture2D texture = bTexture.texture; EditorGUILayout.BeginHorizontal(); if (texture != null) { GUILayout.Label(texture, GUILayout.Width(100), GUILayout.Height(100)); } else { EditorGUILayout.HelpBox("No texture assigned for '" + textureNames[bRoof.textureValues[editTextureOnRoof]] + "', assign one in the Textures menu above", MessageType.Warning); } bRoof.flipValues[editTextureOnRoof] = EditorGUILayout.Toggle("Flip 90\u00B0", bRoof.flipValues[editTextureOnRoof]); EditorGUILayout.EndHorizontal(); }
public static void InspectorGUI(BuildrEditMode editMode, BuildrPlan plan) { EditorGUILayout.Space(); Undo.RecordObject(plan, "Floorplan Modified"); editMode.showDimensionLines = EditorGUILayout.Toggle("Show Wall Dimensions", editMode.showDimensionLines); if (editMode.mode != BuildrEditMode.modes.floorplan) { EditorGUILayout.LabelField("Current Mode: " + editMode.mode.ToString()); if (GUILayout.Button("Cancel")) { editMode.SetMode(BuildrEditMode.modes.floorplan); UpdateGUI(); } } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Snap to Grid", GUILayout.Width(100)); bool editModesnapFloorplanToGrid = EditorGUILayout.Toggle(editMode.snapFloorplanToGrid); if(editModesnapFloorplanToGrid != editMode.snapFloorplanToGrid) { //Snapping modified editMode.snapFloorplanToGrid = editModesnapFloorplanToGrid; if(editModesnapFloorplanToGrid) { int numberOfPoints = plan.points.Count; for (int i = 0; i < numberOfPoints; i++) { Vector2z point = plan.points[i]; Vector3 snappedPoint = point.vector3; snappedPoint.x -= snappedPoint.x % editMode.floorplanGridSize; snappedPoint.z -= snappedPoint.z % editMode.floorplanGridSize; point.vector3 = snappedPoint; } } } EditorGUI.BeginDisabledGroup(!editMode.snapFloorplanToGrid); EditorGUILayout.LabelField("Grid Size", GUILayout.Width(100)); editMode.floorplanGridSize = EditorGUILayout.FloatField(editMode.floorplanGridSize); EditorGUILayout.LabelField("metres", GUILayout.Width(60)); EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); if(GUILayout.Button("Recenter Floorplan to Origin")) { Vector3 currentCenter = Vector3.zero; int numberOfPoints = plan.points.Count; for (int i = 0; i < numberOfPoints; i++) currentCenter += plan.points[i].vector3; currentCenter *= (1.0f / numberOfPoints); for (int i = 0; i < numberOfPoints; i++) plan.points[i].vector3 += -currentCenter; int numberOfCores = plan.cores.Count; for(int i = 0; i < numberOfCores; i++) { Rect core = plan.cores[i]; plan.cores[i] = new Rect(core.xMin - currentCenter.x, core.yMin - currentCenter.z, core.width, core.height); } } if (GUILayout.Button("Recenter Origin to Floorplan")) { Vector3 currentCenter = Vector3.zero; int numberOfPoints = plan.points.Count; for (int i = 0; i < numberOfPoints; i++) currentCenter += plan.points[i].vector3; currentCenter *= (1.0f / numberOfPoints); for (int i = 0; i < numberOfPoints; i++) plan.points[i].vector3 += -currentCenter; int numberOfCores = plan.cores.Count; for (int i = 0; i < numberOfCores; i++) { Rect core = plan.cores[i]; plan.cores[i] = new Rect(core.xMin - currentCenter.x, core.yMin - currentCenter.z, core.width, core.height); } editMode.transform.position += currentCenter; } EditorGUILayout.LabelField("New Volume Plans"); if (GUILayout.Button("Add New Volume Square")) { editMode.SetMode(BuildrEditMode.modes.addNewVolume); UpdateGUI(); } if (GUILayout.Button("Add New Volume By Drawing Rectangle")) { editMode.SetMode(BuildrEditMode.modes.addNewVolumeByDraw); UpdateGUI(); } if (GUILayout.Button("Add New Volume By Drawing Points")) { editMode.SetMode(BuildrEditMode.modes.addNewVolumeByPoints); UpdateGUI(); } if (GUILayout.Button("Add New Volume By Extending Wall")) { editMode.SetMode(BuildrEditMode.modes.addVolumeByWall); UpdateGUI(); } if (GUILayout.Button("Merge Volumes")) { editMode.SetMode(BuildrEditMode.modes.mergeVolumes); UpdateGUI(); } if (GUILayout.Button("Split Volumes")) { editMode.SetMode(BuildrEditMode.modes.splitVolume); UpdateGUI(); } if (GUILayout.Button("Remove Volume")) { editMode.SetMode(BuildrEditMode.modes.removeVolume); UpdateGUI(); } EditorGUILayout.LabelField("Volume Plan Modification"); if (GUILayout.Button("Split Wall")) { editMode.SetMode(BuildrEditMode.modes.splitwall); UpdateGUI(); } if (GUILayout.Button("Add Point To Volume")) { editMode.SetMode(BuildrEditMode.modes.addPointToVolume); UpdateGUI(); } if (GUILayout.Button("Remove Wall Point")) { editMode.SetMode(BuildrEditMode.modes.removewall); UpdateGUI(); } if (GUILayout.Button("Extrude Wall")) { editMode.SetMode(BuildrEditMode.modes.extrudewallselect); UpdateGUI(); } EditorGUILayout.LabelField("Core Modification"); if (GUILayout.Button("Add Building Core")) { editMode.SetMode(BuildrEditMode.modes.addNewCore); UpdateGUI(); } if (GUILayout.Button("Remove Building Core")) { editMode.SetMode(BuildrEditMode.modes.removeCore); UpdateGUI(); } }
public static void SceneGUI(BuildrEditMode editMode, BuildrPlan plan, bool shouldSnap, float handleSize) { Vector3 position = editMode.transform.position; Plane buildingPlane = new Plane(Vector3.up, position); float distance; Vector3 mousePlanePoint = Vector3.zero; Camera sceneCamera = Camera.current; Ray ray = sceneCamera.ScreenPointToRay(new Vector3(Event.current.mousePosition.x, Screen.height - Event.current.mousePosition.y - 30, 0)); if (buildingPlane.Raycast(ray, out distance)) { mousePlanePoint = ray.GetPoint(distance); } Quaternion mouseLookDirection = Quaternion.LookRotation(-ray.direction); //Draw the floorplan outline int numberOfVolumes = plan.numberOfVolumes; for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volumeLinks = plan.volumes[s]; int volumeSize = volumeLinks.Count; for (int l = 0; l < volumeSize; l++) { Handles.color = Color.white; Vector3[] wallPositions = plan.GetWallVectors(s, l); Handles.DrawLine(wallPositions[0] + position, wallPositions[1] + position); } } //draw outlines of building cores int numberOfCores = plan.cores.Count; for(int c = 0; c < numberOfCores; c++) { Rect coreOutline = plan.cores[c]; Vector3 coreCenter = new Vector3(coreOutline.center.x,0,coreOutline.center.y); Handles.Label(coreCenter + position, "Core " + (c + 1)); Vector3 coreBL = new Vector3(coreOutline.xMin,0, coreOutline.yMin) + position; Vector3 coreBR = new Vector3(coreOutline.xMax,0, coreOutline.yMin) + position; Vector3 coreTL = new Vector3(coreOutline.xMin,0, coreOutline.yMax) + position; Vector3 coreTR = new Vector3(coreOutline.xMax,0, coreOutline.yMax) + position; Handles.DrawLine(coreBL,coreBR); Handles.DrawLine(coreBR,coreTR); Handles.DrawLine(coreTR,coreTL); Handles.DrawLine(coreTL,coreBL); } //Draw red lines over illegal point/lines int numberOfIllegalPoints = plan.numberOfIllegalPoints; if (numberOfIllegalPoints > 0) { Handles.color = Color.red; Vector2z[] illegalPoints = plan.illegalPoints; for (int i = 0; i < numberOfIllegalPoints - 1; i += 2) { Vector3 a, b; a = illegalPoints[i].vector3 + position; b = illegalPoints[i + 1].vector3 + position; Handles.DrawLine(a, b); } } SceneView.focusedWindow.wantsMouseMove = false; Vector3 vertA; Vector3 vertB; int selectedPoint; switch (editMode.mode) { case BuildrEditMode.modes.floorplan: Vector3 sliderPos = Vector3.zero; int numberOfPoints = plan.points.Count; int numberOfSelectedPoints = editMode.selectedPoints.Count; //Per point scene gui for (int i = 0; i < numberOfPoints; i++) { Vector2z point = plan.points[i]; Vector3 pointPos = point.vector3 + position; float pointHandleSize = HandleUtility.GetHandleSize(pointPos); bool selected = editMode.selectedPoints.Contains(i); if (selected) { Handles.color = Color.green; //Handles.Label(pointPos, "point "+i); sliderPos += point.vector3; if (Handles.Button(pointPos, Quaternion.identity, pointHandleSize * 0.1f, pointHandleSize * 0.1f, Handles.DotCap)) { editMode.selectedPoints.Remove(i); } } else { Handles.color = Color.white; if (Handles.Button(pointPos, Quaternion.identity, pointHandleSize * 0.05f, pointHandleSize * 0.05f, Handles.DotCap)) { if (!shouldSnap) editMode.selectedPoints.Clear(); editMode.selectedPoints.Add(i); } } float pointDot = Vector3.Dot(sceneCamera.transform.forward, pointPos - sceneCamera.transform.position); if(pointDot > 0.0f) { Handles.color = Color.white; GUIStyle pointLabelStyle = new GUIStyle(); pointLabelStyle.normal.textColor = Color.white; pointLabelStyle.fontStyle = FontStyle.Bold; pointLabelStyle.alignment = TextAnchor.MiddleCenter; pointLabelStyle.fixedWidth = 50.0f; Handles.Label(pointPos + Vector3.up * 2, "point " + i, pointLabelStyle); } } //draw plan dimensions if (editMode.showDimensionLines) { Handles.color = Color.white; for (int v = 0; v < numberOfVolumes; v++) { BuildrVolume volume = plan.volumes[v]; int volumeSize = volume.Count; for (int l = 0; l < volumeSize; l++) { if (plan.GetConnectingVolumeIndex(v, volume.points[l], volume.points[(l + 1) % volumeSize]) != -1) continue; vertA = plan.points[volume.points[l]].vector3 + position; vertB = plan.points[volume.points[(l + 1) % volumeSize]].vector3 + position; float wallWidth = Vector3.Distance(vertA, vertB); Vector3 facadeDirection = Vector3.Cross((vertA - vertB), Vector3.up).normalized; Vector3 labelPos = (vertA + vertB) * 0.5f + facadeDirection; GUIStyle widthStyle = new GUIStyle(); widthStyle.normal.textColor = Color.white; widthStyle.alignment = TextAnchor.MiddleCenter; widthStyle.fixedWidth = 50.0f; Handles.Label(labelPos, wallWidth.ToString("F2") + "m", widthStyle); if (wallWidth > 3)//draw guidelines { float gapSpace = (HandleUtility.GetHandleSize(labelPos) * 0.5f) / wallWidth; Vector3 lineStopA = Vector3.Lerp(vertA, vertB, (0.5f - gapSpace)) + facadeDirection; Vector3 lineStopB = Vector3.Lerp(vertA, vertB, (0.5f + gapSpace)) + facadeDirection; Handles.DrawLine(vertA + facadeDirection, lineStopA); Handles.DrawLine(vertA + facadeDirection, vertA); Handles.DrawLine(vertB + facadeDirection, lineStopB); Handles.DrawLine(vertB + facadeDirection, vertB); } } } } //selected point scene gui if (numberOfSelectedPoints > 0) { // Undo.SetSnapshotTarget(plan, "Floorplan Node Moved"); sliderPos /= numberOfSelectedPoints; Vector3 dirX = (sliderPos.x < 0) ? Vector3.right : Vector3.left; Vector3 dirZ = (sliderPos.z < 0) ? Vector3.forward : Vector3.back; sliderPos += position; Vector3 newSliderPos; Handles.color = Color.red; newSliderPos = Handles.Slider(sliderPos, dirX, HandleUtility.GetHandleSize(sliderPos) * 0.666f, Handles.ArrowCap, 0.0f); Handles.color = Color.blue; newSliderPos = Handles.Slider(newSliderPos, dirZ, HandleUtility.GetHandleSize(newSliderPos) * 0.666f, Handles.ArrowCap, 0.0f); Vector3 sliderDiff = newSliderPos - sliderPos; for (int i = 0; i < numberOfPoints; i++) { if (editMode.selectedPoints.Contains(i)) { if(sliderDiff != Vector3.zero) { Vector2z point = plan.points[i]; point.vector3 += sliderDiff; if(editMode.snapFloorplanToGrid) { Vector3 snappedPoint = point.vector3; snappedPoint.x -= snappedPoint.x % editMode.floorplanGridSize; snappedPoint.z -= snappedPoint.z % editMode.floorplanGridSize; point.vector3 = snappedPoint; } } } } } //core gui for(int c = 0; c < numberOfCores; c++) { // Undo.SetSnapshotTarget(plan, "Core Node Moved"); Rect coreOutline = plan.cores[c]; Vector3 coreLeft = new Vector3(coreOutline.xMin, 0, (coreOutline.yMin + coreOutline.yMax)/2); Vector3 coreRight = new Vector3(coreOutline.xMax, 0, (coreOutline.yMin + coreOutline.yMax)/2); Vector3 coreBottom = new Vector3((coreOutline.xMin + coreOutline.xMax) / 2, 0, coreOutline.yMin); Vector3 coreTop = new Vector3((coreOutline.xMin + coreOutline.xMax) / 2, 0, coreOutline.yMax); Vector3 newCoreLeft = Handles.Slider(coreLeft + position, Vector3.left, HandleUtility.GetHandleSize(coreLeft) * 0.666f, Handles.ArrowCap, 0.0f); Vector3 newCoreRight = Handles.Slider(coreRight + position, Vector3.right, HandleUtility.GetHandleSize(coreLeft) * 0.666f, Handles.ArrowCap, 0.0f); Vector3 newCoreBottom = Handles.Slider(coreBottom + position, Vector3.back, HandleUtility.GetHandleSize(coreLeft) * 0.666f, Handles.ArrowCap, 0.0f); Vector3 newCoreTop = Handles.Slider(coreTop + position, Vector3.forward, HandleUtility.GetHandleSize(coreLeft) * 0.666f, Handles.ArrowCap, 0.0f); newCoreLeft -= position; newCoreRight -= position; newCoreBottom -= position; newCoreTop -= position; if (coreLeft != newCoreLeft) coreOutline.xMin = Mathf.Min(newCoreLeft.x, coreOutline.xMax - 1.0f); if (coreRight != newCoreRight) coreOutline.xMax = Mathf.Max(newCoreRight.x, coreOutline.xMin + 1.0f); if (coreBottom != newCoreBottom) coreOutline.yMin = Mathf.Min(newCoreBottom.z, coreOutline.yMax - 1.0f); if (coreTop != newCoreTop) coreOutline.yMax = Mathf.Max(newCoreTop.z, coreOutline.yMin + 1.0f); plan.cores[c] = coreOutline; } break; case BuildrEditMode.modes.addNewVolume: Vector3 basePoint = mousePlanePoint; Vector3 width = Vector3.right * 10; Vector3 height = Vector3.forward * 10; Vector3[] verts = new Vector3[4] { basePoint - width - height, basePoint + width - height, basePoint + width + height, basePoint + height - width }; Handles.DrawSolidRectangleWithOutline(verts, new Color(0.2f, 0.4f, 0.9f, 0.5f), new Color(0.1f, 0.2f, 1.0f, 0.85f)); Handles.Label(mousePlanePoint, "Click to place a new volume"); if (Handles.Button(basePoint, Quaternion.identity, 0, 10, Handles.CircleCap)) { // Undo.RegisterUndo(plan.GetUndoObjects(), "Add new volume"); plan.AddVolume(verts, -position); editMode.SetMode(BuildrEditMode.modes.floorplan); EditorUtility.SetDirty(plan); } break; case BuildrEditMode.modes.addNewVolumeByDraw: if (editMode.startVolumeDraw == Vector3.zero) { Handles.Label(mousePlanePoint, "Click to select the start point of this volume"); if (Handles.Button(mousePlanePoint, Quaternion.identity, handleSize * 0.1f, handleSize * 0.1f, Handles.CircleCap)) { editMode.startVolumeDraw = mousePlanePoint; } } else { Vector3 baseDrawPoint = editMode.startVolumeDraw; Vector3 finishDrawPoint = mousePlanePoint; Vector3[] drawVerts = new Vector3[4]; drawVerts[0] = new Vector3(baseDrawPoint.x, 0, baseDrawPoint.z); drawVerts[1] = new Vector3(finishDrawPoint.x, 0, baseDrawPoint.z); drawVerts[2] = new Vector3(finishDrawPoint.x, 0, finishDrawPoint.z); drawVerts[3] = new Vector3(baseDrawPoint.x, 0, finishDrawPoint.z); Handles.DrawSolidRectangleWithOutline(drawVerts, new Color(0.2f, 0.4f, 0.9f, 0.5f), new Color(0.1f, 0.2f, 1.0f, 0.85f)); Handles.Label(mousePlanePoint, "Click to finish and add a new volume"); if (Handles.Button(mousePlanePoint, Quaternion.identity, 0, 10, Handles.CircleCap)) { // Undo.RegisterUndo(plan.GetUndoObjects(), "Add new volume"); plan.AddVolume(drawVerts, -position); editMode.SetMode(BuildrEditMode.modes.floorplan); EditorUtility.SetDirty(plan); } } break; case BuildrEditMode.modes.addNewVolumeByPoints: int numberOfDrawnPoints = editMode.volumeDrawPoints.Count; bool allowNewPoint = true; for (int p = 0; p < numberOfDrawnPoints; p++) { Vector3 point = editMode.volumeDrawPoints[p]; if (p == 0 && Vector3.Distance(point, mousePlanePoint) < 3 && numberOfDrawnPoints >= 3) { allowNewPoint = false;//hovering over the first point - don't add a new point - ready to complete the volume plan Handles.color = Color.green; } Vector3 lookDirection = -(point - Camera.current.transform.position); int p2 = (p + 1) % numberOfDrawnPoints; if (p < numberOfDrawnPoints - 1 || !allowNewPoint)//don't draw last line Handles.DrawLine(point, editMode.volumeDrawPoints[p2]); float pointhandleSize = HandleUtility.GetHandleSize(point); if (Handles.Button(point, Quaternion.LookRotation(lookDirection), pointhandleSize * 0.1f, pointhandleSize * 0.1f, Handles.DotCap)) { if (p == 0 && numberOfDrawnPoints >= 3) { plan.AddVolume(editMode.volumeDrawPoints.ToArray(), -position); editMode.SetMode(BuildrEditMode.modes.floorplan); EditorUtility.SetDirty(plan); GUI.changed = true; return; } } } if (allowNewPoint) { bool isLegal = true; if (numberOfDrawnPoints >= 1) { Vector2z newPoint = new Vector2z(mousePlanePoint); Vector2z lastPoint = new Vector2z(editMode.volumeDrawPoints[numberOfDrawnPoints - 1]); for (int op = 0; op < numberOfDrawnPoints - 1; op++)//don't do the final line { int op2 = (op + 1) % numberOfDrawnPoints; if (BuildrUtils.FastLineIntersection(newPoint, lastPoint, new Vector2z(editMode.volumeDrawPoints[op]), new Vector2z(editMode.volumeDrawPoints[op2]))) isLegal = false; } for (int v = 0; v < numberOfVolumes; v++) { BuildrVolume volume = plan.volumes[v]; int volumeSize = volume.Count; for (int l = 0; l < volumeSize; l++) { int vp1 = l; int vp2 = (l + 1) % volumeSize; Vector2z v2zPos = new Vector2z(position); Vector2z p1 = newPoint - v2zPos; Vector2z p2 = lastPoint - v2zPos; Vector2z p3 = plan.points[volume.points[vp1]]; Vector2z p4 = plan.points[volume.points[vp2]]; if (BuildrUtils.FastLineIntersection(p1, p2, p3, p4)) isLegal = false; } } Handles.Label(mousePlanePoint, "Click to add another point to the volume wall"); if (!isLegal) Handles.color = Color.red; Handles.DrawLine(lastPoint.vector3, newPoint.vector3); } else { Handles.Label(mousePlanePoint, "Click to add the first point in this volume wall"); } Handles.color = Color.white; if (Handles.Button(mousePlanePoint, mouseLookDirection, 0, 10, Handles.CircleCap)) { if (isLegal) { // Undo.RegisterUndo(plan.GetUndoObjects(), "Add new wall line for new volume"); editMode.volumeDrawPoints.Add(mousePlanePoint); EditorUtility.SetDirty(plan); } else { EditorUtility.DisplayDialog("Error", "Wall lines cannot intersect other wall lines", "ok, sorry"); } } } else { Handles.Label(mousePlanePoint, "Click to complete the volume wall plan"); } break; case BuildrEditMode.modes.removeVolume: for (int v = 0; v < numberOfVolumes; v++) { BuildrVolume volume = plan.volumes[v]; int volumeSize = volume.Count; Vector3 centerPoint = Vector3.zero; for (int l = 0; l < volumeSize; l++) { centerPoint += plan.points[volume.points[l]].vector3; } centerPoint /= volumeSize; centerPoint += position; Handles.color = Color.red; float centerPointHandleSize = HandleUtility.GetHandleSize(centerPoint); if (Handles.Button(centerPoint, Quaternion.identity, centerPointHandleSize * 0.1f, centerPointHandleSize * 0.1f, Handles.DotCap)) { // Undo.RegisterUndo(plan.GetUndoObjects(), "Remove volume"); // Undo.RegisterSceneUndo("Remove Volume"); plan.RemoveVolume(volume); numberOfVolumes--; v--; editMode.SetMode(BuildrEditMode.modes.floorplan); EditorUtility.SetDirty(plan); } } break; case BuildrEditMode.modes.mergeVolumes: List<int> usedPointsA = new List<int>(); List<int> usedPointsB = new List<int>(); for (int v = 0; v < numberOfVolumes; v++) { BuildrVolume volume = plan.volumes[v]; int volumeSize = volume.Count; for (int p = 0; p < volumeSize; p++) { int a = volume.points[p]; int b = volume.points[(p + 1) % volumeSize]; bool alreadyDrawn = false; foreach (int pa in usedPointsA) { if (pa == a || pa == b) { int pb = usedPointsB[usedPointsA.IndexOf(pa)]; if (pb == a || pb == b) { alreadyDrawn = true; break; } } } if (!alreadyDrawn) { usedPointsA.Add(a); usedPointsA.Add(b); usedPointsB.Add(b); usedPointsB.Add(a); int otherV = plan.GetConnectingVolumeIndex(v, a, b); if (otherV == -1) continue;//it's not connected to another volume vertA = plan.points[a].vector3 + position; vertB = plan.points[b].vector3 + position; Vector3 diff = vertA - vertB; Vector3 facadeDirection = Vector3.Cross(diff, Vector3.up).normalized; Vector3 midPoint = Vector3.Lerp(vertA, vertB, 0.5f); float mergeHandleSize = HandleUtility.GetHandleSize(midPoint) * 0.1f; Vector3 outPointA = midPoint + (facadeDirection * mergeHandleSize * 6); Vector3 outPointB = midPoint - (facadeDirection * mergeHandleSize * 6); Handles.ArrowCap(0, outPointA, Quaternion.LookRotation(-facadeDirection), mergeHandleSize * 4); Handles.ArrowCap(0, outPointB, Quaternion.LookRotation(facadeDirection), mergeHandleSize * 4); GUIStyle pointLabelStyle = new GUIStyle(); pointLabelStyle.normal.textColor = Color.white; pointLabelStyle.fontStyle = FontStyle.Bold; pointLabelStyle.alignment = TextAnchor.MiddleCenter; pointLabelStyle.fixedWidth = 50.0f; Handles.Label(midPoint + Vector3.up * mergeHandleSize * 3, "Merge", pointLabelStyle); if (Handles.Button(midPoint, Quaternion.identity, mergeHandleSize, mergeHandleSize, Handles.DotCap)) { // Undo.RegisterSceneUndo("Merge Volume"); int otherVolume = plan.GetConnectingVolumeIndex(v, a, b); plan.MergeVolumes(v, otherVolume); numberOfVolumes--; editMode.SetMode(BuildrEditMode.modes.floorplan); EditorUtility.SetDirty(plan); } } } } break; //SUB VOLUME FUNCTIONS case BuildrEditMode.modes.splitwall: SceneView.focusedWindow.wantsMouseMove = true; float pointDistance = 999; int wallIndex = -1; int volumeIndex = -1; Vector3 closestPoint = Vector3.zero; Vector3 usePoint = Vector3.zero; vertA = Vector3.zero; vertB = Vector3.zero; for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volumeLinks = plan.volumes[s]; int volumeSize = volumeLinks.Count; for (int l = 0; l < volumeSize; l++) { Vector3[] wallVectors = plan.GetWallVectors(s, l); closestPoint = BuildrUtils.ClosestPointOnLine(wallVectors[0] + position, wallVectors[1] + position, mousePlanePoint); float thisDist = Vector3.Distance(closestPoint, mousePlanePoint); if (thisDist < pointDistance) { wallIndex = l; volumeIndex = s; vertA = wallVectors[0]; vertB = wallVectors[1]; usePoint = closestPoint; pointDistance = thisDist; editMode.selectedPoints.Clear(); } Handles.color = Color.white; float wallHandleSize = HandleUtility.GetHandleSize(wallVectors[0] + position); Handles.DotCap(0, wallVectors[0] + position, Quaternion.identity, wallHandleSize * 0.05f); } } if (wallIndex != -1 && pointDistance < 5 && volumeIndex != -1) { float pointHandleSize = HandleUtility.GetHandleSize(usePoint); if (Handles.Button(usePoint, Quaternion.identity, pointHandleSize * 0.1f, pointHandleSize * 0.1f, Handles.DotCap)) { // Undo.RegisterUndo(plan.GetUndoObjects(), "Split Wall"); int newPointID = plan.AddWallPoint(usePoint - position, wallIndex, volumeIndex); editMode.selectedPoints.Clear(); editMode.selectedPoints.Add(newPointID); editMode.SetMode(BuildrEditMode.modes.floorplan); EditorUtility.SetDirty(plan); } Handles.color = Color.white; GUIStyle widthStyle = new GUIStyle(); widthStyle.normal.textColor = Color.white; widthStyle.alignment = TextAnchor.MiddleCenter; widthStyle.fixedWidth = 50.0f; Vector3 facadeDirection = Vector3.Cross((vertA - vertB), Vector3.up).normalized; float wallWidthA = Vector3.Distance(vertA, usePoint); Vector3 labelPosA = (vertA + usePoint) * 0.5f + facadeDirection; Handles.Label(labelPosA, wallWidthA.ToString("F2") + "m", widthStyle); if (wallWidthA > 3)//draw guidelines { float gapSpace = (pointHandleSize * 0.5f) / wallWidthA; Vector3 lineStopA = Vector3.Lerp(vertA, usePoint, (0.5f - gapSpace)) + facadeDirection; Vector3 lineStopB = Vector3.Lerp(vertA, usePoint, (0.5f + gapSpace)) + facadeDirection; Handles.DrawLine(vertA + facadeDirection, lineStopA); Handles.DrawLine(vertA + facadeDirection, vertA); Handles.DrawLine(usePoint + facadeDirection, lineStopB); Handles.DrawLine(usePoint + facadeDirection, usePoint); } float wallWidthB = Vector3.Distance(usePoint, vertB); Vector3 labelPosB = (usePoint + vertB) * 0.5f + facadeDirection; Handles.Label(labelPosB, wallWidthB.ToString("F2") + "m", widthStyle); if (wallWidthB > 3)//draw guidelines { float gapSpace = (pointHandleSize * 0.5f) / wallWidthB; Vector3 lineStopA = Vector3.Lerp(vertB, usePoint, (0.5f - gapSpace)) + facadeDirection; Vector3 lineStopB = Vector3.Lerp(vertB, usePoint, (0.5f + gapSpace)) + facadeDirection; Handles.DrawLine(vertB + facadeDirection, lineStopA); Handles.DrawLine(vertB + facadeDirection, vertB); Handles.DrawLine(usePoint + facadeDirection, lineStopB); Handles.DrawLine(usePoint + facadeDirection, usePoint); } } Handles.color = Color.white; break; case BuildrEditMode.modes.removewall: int index = 0; foreach (Vector2z point in plan.points) { Handles.color = Color.white; Vector3 pointPos = point.vector3 + position; float pointHandleSize = HandleUtility.GetHandleSize(pointPos); if (Handles.Button(pointPos, Quaternion.identity, pointHandleSize * 0.1f, pointHandleSize * 0.1f, Handles.DotCap)) { // Undo.RegisterSceneUndo("Delete Wall Point"); plan.RemovePoint(index); editMode.SetMode(BuildrEditMode.modes.floorplan); break; } index++; } break; case BuildrEditMode.modes.extrudewallselect: Handles.color = Color.blue; for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = plan.volumes[s]; int volumeSize = volume.Count; for (int l = 0; l < volumeSize; l++) { int a = volume.points[l]; int b = (l < volume.points.Count - 1) ? volume.points[l + 1] : volume.points[0]; if (plan.GetConnectingVolumeIndex(s, a, b) == -1)//if the volume wall has not been connected to two volumes yet... { Vector3[] pIndexes = plan.GetWallVectors(s, l); Vector3 pA = pIndexes[0]; Vector3 pB = pIndexes[1]; Vector3 pC = (pA + pB) / 2 + position; float pointHandleSize = HandleUtility.GetHandleSize(pC); if (Handles.Button(pC, Quaternion.identity, pointHandleSize * 0.1f, pointHandleSize * 0.1f, Handles.DotCap)) { // Undo.RegisterSceneUndo("Extrude wall"); int wallIndexA = l; int newPointAIndex = plan.AddWallPoint(pA, wallIndexA, s); int wallIndexB = l + 1; int newPointBIndex = plan.AddWallPoint(pB, wallIndexB, s); editMode.SetMode(BuildrEditMode.modes.floorplan); editMode.selectedPoints.Clear(); editMode.selectedPoints.Add(newPointAIndex); editMode.selectedPoints.Add(newPointBIndex); break; } } } } Handles.color = Color.white; break; case BuildrEditMode.modes.addVolumeByPoint: Handles.color = Color.blue; for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = plan.volumes[s]; int volumeSize = volume.Count; for (int l = 0; l < volumeSize; l++) { int a = volume.points[l]; int b = (l < volume.points.Count - 1) ? volume.points[l + 1] : volume.points[0]; if (plan.GetConnectingVolumeIndex(s, a, b) == -1)//if the volume wall has not been connected to two volumes yet... { Vector3[] pointVectors = plan.GetWallVectors(s, l); Vector3 pA = pointVectors[0]; Vector3 pB = pointVectors[1]; Vector3 pC = (pA + pB) / 2 + position; float pointHandleSize = HandleUtility.GetHandleSize(pC); if (Handles.Button(pC, Quaternion.identity, pointHandleSize * 0.1f, pointHandleSize * 0.1f, Handles.DotCap)) { Vector2z[] newPoints = new Vector2z[1]; float pointDist = Vector3.Distance(pA, pB); Vector3 newPointPos = Vector3.Cross(pA - pB, Vector3.up).normalized * pointDist; newPoints[0] = new Vector2z(pC + newPointPos); int indexa, indexb; indexa = volume.points[l]; if (l < volumeSize - 1) indexb = volume.points[l + 1]; else indexb = volume.points[0]; plan.AddVolume(indexa, indexb, newPoints); editMode.SetMode(BuildrEditMode.modes.floorplan); break; } } } } Handles.color = Color.white; break; case BuildrEditMode.modes.addVolumeByWall: Handles.color = Color.blue; for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = plan.volumes[s]; int volumeSize = volume.Count; for (int l = 0; l < volumeSize; l++) { int a = volume.points[l]; int b = (l < volume.points.Count - 1) ? volume.points[l + 1] : volume.points[0]; if (plan.GetConnectingVolumeIndex(s, a, b) == -1) { Vector3[] pIndexes = plan.GetWallVectors(s, l); Vector3 pA = pIndexes[0]; Vector3 pB = pIndexes[1]; Vector3 pC = (pA + pB) / 2 + position; float pointHandleSize = HandleUtility.GetHandleSize(pC); if (Handles.Button(pC, Quaternion.identity, pointHandleSize * 0.1f, pointHandleSize * 0.1f, Handles.DotCap)) { // Undo.RegisterSceneUndo("Add volume by wall"); Vector2z[] newPoints = new Vector2z[2]; float pointDist = Vector3.Distance(pA, pB); Vector3 newPointPos = Vector3.Cross(pA - pB, Vector3.up).normalized * pointDist; newPoints[0] = new Vector2z(pA + newPointPos); newPoints[1] = new Vector2z(pB + newPointPos); int indexa, indexb; indexa = volume.points[l]; if (l < volumeSize - 1) indexb = volume.points[l + 1]; else indexb = volume.points[0]; plan.AddVolume(indexa, indexb, newPoints); editMode.SetMode(BuildrEditMode.modes.floorplan); break; } } } } Handles.color = Color.white; break; case BuildrEditMode.modes.addPointToVolume: numberOfPoints = plan.numberOfPoints; if (editMode.selectedPoint == -1) { for (int p = 0; p < numberOfPoints; p++) { Vector2z point = plan.points[p]; Handles.color = Color.white; Vector3 pointPos = point.vector3 + position; float pointhandleSize = HandleUtility.GetHandleSize(pointPos); if (Handles.Button(pointPos, Quaternion.identity, pointhandleSize * 0.1f, pointhandleSize * 0.1f, Handles.DotCap)) { // Undo.RegisterSceneUndo("Select Wall Point"); editMode.selectedPoint = p; break; } } } else { selectedPoint = editMode.selectedPoint; Vector2z startPoint = plan.points[selectedPoint]; Vector2z endPoint = new Vector2z(mousePlanePoint - position); bool isLegal = true; for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = plan.volumes[s]; if (!volume.Contains(selectedPoint)) continue; int volumeSize = volume.Count; for (int l = 0; l < volumeSize; l++) { int a = volume.points[l]; int b = volume.points[(l + 1) % volumeSize]; if (a == selectedPoint || b == selectedPoint) continue; if (BuildrUtils.FastLineIntersection(startPoint, endPoint, plan.points[a], plan.points[b])) isLegal = false; } } Handles.color = isLegal ? Color.white : Color.red; Handles.DrawLine(startPoint.vector3 + position, endPoint.vector3 + position); } break; case BuildrEditMode.modes.splitVolume: numberOfPoints = plan.numberOfPoints; selectedPoint = editMode.selectedPoint; if (selectedPoint == -1) { for (int p = 0; p < numberOfPoints; p++) { Vector2z point = plan.points[p]; Handles.color = Color.white; Vector3 pointPos = point.vector3 + position; float pointhandleSize = HandleUtility.GetHandleSize(pointPos); if (Handles.Button(pointPos, Quaternion.identity, pointhandleSize * 0.1f, pointhandleSize * 0.1f, Handles.DotCap)) { // Undo.RegisterSceneUndo("Select Wall Point"); editMode.selectedPoint = p; break; } } } else { for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = plan.volumes[s]; if (!volume.Contains(selectedPoint)) continue; int volumeSize = volume.Count; for (int l = 0; l < volumeSize; l++) { int o = volume.points[l]; int a = selectedPoint; int selectedVolumePoint = volume.IndexOf(selectedPoint); int b = volume.points[(selectedVolumePoint + 1) % volumeSize]; int volb = (selectedVolumePoint - 1) % volumeSize; if (volb == -1) volb = volumeSize - 1; int c = volume.points[volb]; if (o == a || o == b || o == c) continue; Vector3 pointPos = plan.points[o].vector3 + position; bool isLegal = true; for (int j = 0; j < volumeSize; j++) { int ob = volume.points[j]; int oc = volume.points[(j + 1) % volumeSize]; if (ob == selectedPoint || oc == selectedPoint || ob == o || oc == o) continue; if (BuildrUtils.FastLineIntersection(plan.points[selectedPoint], plan.points[o], plan.points[ob], plan.points[oc])) isLegal = false; } Vector2z pA = plan.points[a]; Vector2z pB = plan.points[b]; Vector2z pC = plan.points[c]; Vector2z pO = plan.points[o]; float startAng, endAng, mouseAng, ang; Vector3 cross; Vector2z diff; diff = pC - pA; ang = Vector2.Angle(Vector2.up, diff.vector2); cross = Vector3.Cross(Vector3.forward, diff.vector3); startAng = (cross.y > 0) ? ang : 360 - ang; diff = pB - pA; ang = Vector2.Angle(Vector2.up, diff.vector2); cross = Vector3.Cross(Vector3.forward, diff.vector3); endAng = (cross.y > 0) ? ang : 360 - ang; diff = pO - pA; ang = Vector2.Angle(Vector2.up, diff.vector2); cross = Vector3.Cross(Vector3.forward, diff.vector3); mouseAng = (cross.y > 0) ? ang : 360 - ang; mouseAng = (360 + (mouseAng % 360)) % 360; startAng = (3600000 + startAng) % 360; endAng = (3600000 + endAng) % 360; bool isBetween = false; if (startAng < endAng) isBetween = startAng <= mouseAng && mouseAng <= endAng; else isBetween = startAng <= mouseAng || mouseAng <= endAng; if (isLegal && !isBetween) isLegal = false; if (isLegal) { Handles.color = Color.white; float pointhandleSize = HandleUtility.GetHandleSize(pointPos); if (Handles.Button(pointPos, Quaternion.identity, pointhandleSize * 0.1f, pointhandleSize * 0.1f, Handles.DotCap)) { // Undo.RegisterSceneUndo("Split Volume"); plan.SplitVolume(s, a, o); editMode.selectedPoint = -1; editMode.SetMode(BuildrEditMode.modes.floorplan); return; } Handles.color = new Color(1, 0, 0, 0.25f); Handles.DrawLine(plan.points[selectedPoint].vector3 + position, plan.points[o].vector3 + position); } } } } break; case BuildrEditMode.modes.addNewCore: SceneView.focusedWindow.wantsMouseMove = true; Vector3 coreBasePoint = mousePlanePoint; Vector3 coreWidth = Vector3.right * 2.5f; Vector3 coreHeight = Vector3.forward * 2.5f; Vector3[] coreVerts = new Vector3[4] { coreBasePoint - coreWidth - coreHeight, coreBasePoint + coreWidth - coreHeight, coreBasePoint + coreWidth + coreHeight, coreBasePoint + coreHeight - coreWidth }; Color newCoreColour = BuildrColours.RED; newCoreColour.a = 0.5f; Handles.DrawSolidRectangleWithOutline(coreVerts, newCoreColour, BuildrColours.YELLOW); Handles.Label(mousePlanePoint, "Click to place a new core"); if (Handles.Button(coreBasePoint, Quaternion.identity, 0, 10, Handles.CircleCap)) { // Undo.RegisterSceneUndo("Add new core"); Vector3 coreBase = coreBasePoint - position; Rect newCoreRect = new Rect(coreBase.x - 2.5f, coreBase.z - 2.5f, 5.0f, 5.0f); plan.cores.Add(newCoreRect); editMode.SetMode(BuildrEditMode.modes.floorplan); EditorUtility.SetDirty(plan); } break; case BuildrEditMode.modes.removeCore: for (int c = 0; c < numberOfCores; c++) { Rect core = plan.cores[c]; Vector3 centerPoint = new Vector3(core.center.x, 0, core.center.y) + position; Handles.color = Color.red; float centerPointHandleSize = HandleUtility.GetHandleSize(centerPoint); if (Handles.Button(centerPoint, Quaternion.identity, centerPointHandleSize * 0.1f, centerPointHandleSize * 0.1f, Handles.DotCap)) { // Undo.RegisterSceneUndo("Remove Core"); plan.cores.RemoveAt(c); numberOfCores--; c--; editMode.SetMode(BuildrEditMode.modes.floorplan); EditorUtility.SetDirty(plan); } } break; } bool clickedOutside = false; if (Event.current.isMouse) { RaycastHit hitInfo; clickedOutside = true; if (Physics.Raycast(ray, out hitInfo)) { if (hitInfo.collider.gameObject == editMode.gameObject) clickedOutside = false; } } if (clickedOutside) editMode.selectedPoints.Clear(); if (GUI.changed) { plan.CheckPlan(); EditorUtility.SetDirty(editMode); EditorUtility.SetDirty(plan); editMode.UpdateRender(); } }
public static void InspectorGUI(BuildrEditMode editMode, BuildrData _data) { data = _data; Undo.RecordObject(data, "Roof Modified"); BuildrRoofDesign[] roofs = data.roofs.ToArray(); int numberOfRoofs = roofs.Length; selectedRoof = Mathf.Clamp(selectedRoof, 0, numberOfRoofs - 1); if (GUILayout.Button("Add new roof design")) { data.roofs.Add(new BuildrRoofDesign("new roof " + numberOfRoofs)); roofs = data.roofs.ToArray(); numberOfRoofs++; selectedRoof = numberOfRoofs - 1; } if (numberOfRoofs == 0) { EditorGUILayout.HelpBox("There are no roof designs to show", MessageType.Info); return; } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Design: ", GUILayout.Width(75)); string[] roofNames = new string[numberOfRoofs]; for (int f = 0; f < numberOfRoofs; f++) roofNames[f] = roofs[f].name; selectedRoof = EditorGUILayout.Popup(selectedRoof, roofNames); BuildrRoofDesign bRoof = roofs[selectedRoof]; EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Delete", GUILayout.Width(75))) { if (EditorUtility.DisplayDialog("Deleting Roof Design Entry", "Are you sure you want to delete this roof?", "Delete", "Cancel")) { data.RemoveRoofDesign(bRoof); selectedRoof = 0; GUI.changed = true; return; } } if (GUILayout.Button("Import", GUILayout.Width(71))) { string xmlPath = EditorUtility.OpenFilePanel("Select the XML file...", "Assets/BuildR/Exported/", "xml"); if (xmlPath == "") return; BuildrXMLImporter.ImportRoofs(xmlPath, _data); GUI.changed = true; } if (GUILayout.Button("Export", GUILayout.Width(71))) { string xmlPath = EditorUtility.SaveFilePanel("Export as...", "Assets/BuildR/Exported/", _data.name + "_roofLibrary", "xml"); if (xmlPath == "") return; BuildrXMLExporter.ExportRoofs(xmlPath, _data); GUI.changed = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Name: ", GUILayout.Width(75)); bRoof.name = EditorGUILayout.TextField(bRoof.name); EditorGUILayout.EndHorizontal(); //ROOF STYLE EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Style: ", GUILayout.Width(75)); BuildrRoofDesign.styles bRoofstyle = (BuildrRoofDesign.styles)EditorGUILayout.EnumPopup(bRoof.style); if(bRoofstyle != bRoof.style) { bRoof.style = bRoofstyle; } EditorGUILayout.EndHorizontal(); if (bRoof.style != BuildrRoofDesign.styles.flat && bRoof.style != BuildrRoofDesign.styles.mansard && bRoof.style != BuildrRoofDesign.styles.steepled && bRoof.style != BuildrRoofDesign.styles.hipped) { EditorGUILayout.HelpBox("Please note that this design can only be used on sections with 4 points." + "\nComplex sections can only use the Flat, Mansard and Steeple designs.", MessageType.Warning); } if (bRoof.style != BuildrRoofDesign.styles.flat) bRoof.height = Mathf.Max(EditorGUILayout.FloatField("Height", bRoof.height), 0); if (bRoof.style == BuildrRoofDesign.styles.mansard) { bRoof.floorDepth = Mathf.Max(EditorGUILayout.FloatField("Base Depth", bRoof.floorDepth), 0); bRoof.depth = Mathf.Max(EditorGUILayout.FloatField("Top Depth", bRoof.depth), 0); } if (bRoof.style == BuildrRoofDesign.styles.barrel) bRoof.barrelSegments = Mathf.Max(EditorGUILayout.IntField("Barrel Segments", bRoof.barrelSegments), 3); if (bRoof.style == BuildrRoofDesign.styles.barrel || bRoof.style == BuildrRoofDesign.styles.gabled || bRoof.style == BuildrRoofDesign.styles.hipped) { //two directions of the ridge bRoof.direction = Mathf.Clamp(bRoof.direction, 0, 1); string[] options = new string[2] { "short", "long" }; bRoof.direction = EditorGUILayout.Popup(bRoof.direction, options); } if (bRoof.style == BuildrRoofDesign.styles.leanto || bRoof.style == BuildrRoofDesign.styles.sawtooth) { //four directions of the ridge bRoof.direction = Mathf.Clamp(bRoof.direction, 0, 3); string[] options = new string[4] { "left", "up", "right", "down" }; bRoof.direction = EditorGUILayout.Popup(bRoof.direction, options); } if (bRoof.style == BuildrRoofDesign.styles.sawtooth) bRoof.sawtoothTeeth = Mathf.Max(EditorGUILayout.IntField("Number of 'teeth'", bRoof.sawtoothTeeth), 2); //PARAPET bool bRoofparapet = EditorGUILayout.Toggle("Has Parapet", bRoof.parapet); if(bRoofparapet != bRoof.parapet) { bRoof.parapet = bRoofparapet; } if (bRoof.parapet) { float bRoofparapetHeight = Mathf.Max(EditorGUILayout.FloatField("Parapet Width", bRoof.parapetHeight), 0); if(bRoofparapetHeight != bRoof.parapetHeight) { bRoof.parapetHeight = bRoofparapetHeight; } float bRoofparapetFrontDepth = Mathf.Max(EditorGUILayout.FloatField("Parapet Front Depth", bRoof.parapetFrontDepth), 0); if (bRoofparapetFrontDepth != bRoof.parapetFrontDepth) { bRoof.parapetFrontDepth = bRoofparapetFrontDepth; } float bRoofparapetBackDepth = Mathf.Max(EditorGUILayout.FloatField("Parapet Back Depth", bRoof.parapetBackDepth), 0); if (bRoofparapetBackDepth != bRoof.parapetBackDepth) { bRoof.parapetBackDepth = bRoofparapetBackDepth; } if (bRoof.parapetStyle == BuildrRoofDesign.parapetStyles.fancy)//NOT IMPLMENTED...YET... { EditorGUILayout.HelpBox("This allows you to specify a model mesh that will be used to create a parapet." + "\nIt should not repeat as Buildr will attempt to repeat the style to fit the length of the facade.", MessageType.Info); bRoof.parapetDesign = (Mesh)EditorGUILayout.ObjectField("Parapet Mesh", bRoof.parapetDesign, typeof(Mesh), false); bRoof.parapetDesignWidth = Mathf.Max(EditorGUILayout.FloatField("Parapet Design Width", bRoof.parapetDesignWidth), 0); } } //DORMERS if (bRoof.style == BuildrRoofDesign.styles.mansard) { bool bRoofhasDormers = EditorGUILayout.Toggle("Has Dormers", bRoof.hasDormers); if(bRoofhasDormers != bRoof.hasDormers) { bRoof.hasDormers = bRoofhasDormers; } if (bRoof.hasDormers) { float bRoofdormerWidth = Mathf.Max(EditorGUILayout.FloatField("Dormer Width", bRoof.dormerWidth), 0); if (bRoofdormerWidth != bRoof.dormerWidth) { bRoof.dormerWidth = bRoofdormerWidth; } float bRoofdormerHeight = Mathf.Clamp(EditorGUILayout.FloatField("Dormer Height", bRoof.dormerHeight), 0, bRoof.height); if (bRoofdormerHeight != bRoof.dormerHeight) { bRoof.dormerHeight = bRoofdormerHeight; } float bRoofdormerRoofHeight = Mathf.Clamp(EditorGUILayout.FloatField("Dormer Roof Height", bRoof.dormerRoofHeight), 0, bRoof.dormerHeight); if (bRoofdormerRoofHeight != bRoof.dormerRoofHeight) { bRoof.dormerRoofHeight = bRoofdormerRoofHeight; } float bRoofminimumDormerSpacing = Mathf.Max(EditorGUILayout.FloatField("Dormer Minimum Spacing", bRoof.minimumDormerSpacing), 0); if (bRoofminimumDormerSpacing != bRoof.minimumDormerSpacing) { bRoof.minimumDormerSpacing = bRoofminimumDormerSpacing; } float bRoofdormerHeightRatio = EditorGUILayout.Slider("Dormer Height Ratio", bRoof.dormerHeightRatio, 0, 1); if (bRoofdormerHeightRatio != bRoof.dormerHeightRatio) { bRoof.dormerHeightRatio = bRoofdormerHeightRatio; } } } //TEXTURES int numberOfTextures = data.textures.Count; string[] textureNames = new string[numberOfTextures]; for (int t = 0; t < numberOfTextures; t++) textureNames[t] = data.textures[t].name; int numberOfTextureSlots = bRoof.numberOfTextures; string[] titles = new string[numberOfTextureSlots]; for (int brt = 0; brt < numberOfTextureSlots; brt++) { titles[brt] = ((BuildrRoofDesign.textureNames)(brt)).ToString(); } editTextureOnRoof = EditorGUILayout.Popup("Texture Surface:", editTextureOnRoof, titles); int selectedRoofTexture = EditorGUILayout.Popup("Selected Texture:", bRoof.textureValues[editTextureOnRoof], textureNames); if(selectedRoofTexture != bRoof.textureValues[editTextureOnRoof]) { bRoof.textureValues[editTextureOnRoof] = selectedRoofTexture; } BuildrTexture bTexture = data.textures[bRoof.textureValues[editTextureOnRoof]]; Texture2D texture = bTexture.texture; EditorGUILayout.BeginHorizontal(); if (texture != null) GUILayout.Label(texture, GUILayout.Width(100), GUILayout.Height(100)); else EditorGUILayout.HelpBox("No texture assigned for '" + textureNames[bRoof.textureValues[editTextureOnRoof]] + "', assign one in the Textures menu above", MessageType.Warning); bRoof.flipValues[editTextureOnRoof] = EditorGUILayout.Toggle("Flip 90\u00B0", bRoof.flipValues[editTextureOnRoof]); EditorGUILayout.EndHorizontal(); }
public static void InspectorGUI(BuildrEditMode editMode, BuildrData _data) { data = _data; Undo.RecordObject(data, "Building Modified"); BuildrPlan plan = data.plan; int numberOfFacadeFaces = 0; int numberOfVolumes = plan.numberOfVolumes; int numberOfFacadeDesigns = data.facades.Count; if (numberOfVolumes == 0) { EditorGUILayout.HelpBox("There are no defined volumes, go to Floorplan and define one", MessageType.Error); return; } int numberOfFacades = data.facades.Count; int numberOfRoofs = data.roofs.Count; int numberOfTextures = data.textures.Count; bool legalBuilding = true; if (numberOfFacades == 0) { EditorGUILayout.HelpBox("There are no facade designs to render building, go to Facades to define a default one", MessageType.Error); legalBuilding = false; } if (numberOfRoofs == 0) { EditorGUILayout.HelpBox("There are no roof designs to render building, go to Facades to define a default one", MessageType.Error); legalBuilding = false; } if (numberOfTextures == 0) { EditorGUILayout.HelpBox("There are no textures to render building, go to Textures to define a default one", MessageType.Error); legalBuilding = false; } if (!legalBuilding) { return; } //Building Name EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Name", GUILayout.Width(200)); data.name = EditorGUILayout.TextField(data.name, GUILayout.Width(200)); EditorGUILayout.EndHorizontal(); //Floor Height EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Floor height", GUILayout.Width(200)); data.floorHeight = EditorGUILayout.FloatField(data.floorHeight, GUILayout.Width(50)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Number of Floors", GUILayout.Width(200)); int[] volumeSeletionsList = new int[numberOfVolumes]; string[] volumeSeletionsStringList = new string[numberOfVolumes]; for (int s = 0; s < numberOfVolumes; s++) { volumeSeletionsStringList[s] = ("volume " + s); volumeSeletionsList[s] = (s); } selectedFloorNumberVolume = EditorGUILayout.IntPopup(selectedFloorNumberVolume, volumeSeletionsStringList, volumeSeletionsList, GUILayout.Width(100)); int numberOfFloors = EditorGUILayout.IntField(data.plan.volumes[selectedFloorNumberVolume].numberOfFloors); if (GUILayout.Button("^")) { numberOfFloors++; } if (GUILayout.Button("v")) { numberOfFloors--; } data.plan.volumes[selectedFloorNumberVolume].numberOfFloors = Mathf.Max(numberOfFloors, 1); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Show Facade Markers", GUILayout.Width(200)); editMode.showFacadeMarkers = EditorGUILayout.Toggle(editMode.showFacadeMarkers, GUILayout.Width(200)); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); GUIStyle titlesyle = new GUIStyle(GUI.skin.label); titlesyle.fixedHeight = 60; titlesyle.fixedWidth = 400; titlesyle.alignment = TextAnchor.UpperCenter; titlesyle.fontStyle = FontStyle.Bold; titlesyle.normal.textColor = Color.white; EditorGUILayout.LabelField("Facade Design", titlesyle); Texture2D facadeTexture = new Texture2D(1, 1); facadeTexture.SetPixel(0, 0, BuildrColours.MAGENTA); facadeTexture.Apply(); Rect sqrPos = new Rect(0, 0, 0, 0); if (Event.current.type == EventType.Repaint) { sqrPos = GUILayoutUtility.GetLastRect(); } GUI.DrawTexture(sqrPos, facadeTexture); EditorGUI.LabelField(sqrPos, "Facade Design", titlesyle); //create/display the facade selector List <int> facadeSeletionsList = new List <int>(); List <int> facadeRenderList = new List <int>(); List <string> facadeSeletionsStringList = new List <string>(); for (int s = 0; s < numberOfVolumes; s++) { int numberOfPoints = plan.volumes[s].Count; numberOfFacadeFaces += numberOfPoints; for (int p = 0; p < numberOfPoints; p++) { int index = facadeSeletionsList.Count; facadeSeletionsStringList.Add("facade " + index); facadeSeletionsList.Add(index); facadeRenderList.Add(p); } } int[] facadeSelections = facadeSeletionsList.ToArray(); string[] facadeSelectionString = facadeSeletionsStringList.ToArray(); selectedFacade = EditorGUILayout.IntPopup("Selected Facade", selectedFacade, facadeSelectionString, facadeSelections, GUILayout.Width(400)); //grab the selected facade int facadeCount = 0; int selectedVolumePoint = 0; for (int s = 0; s < numberOfVolumes; s++) { int numberOfPoints = plan.volumes[s].Count; for (int p = 0; p < numberOfPoints; p++) { if (selectedFacade == facadeCount) { selectedVolume = s; selectedVolumePoint = p; selectedPoint = plan.volumes[s].points[p]; } facadeCount++; } } BuildrVolume volume = plan.volumes[selectedVolume]; BuildrVolumeStylesUnit[] styles = volume.styles.GetContents(); bool renderFacade = volume.renderFacade[selectedVolumePoint]; volume.renderFacade[selectedVolumePoint] = EditorGUILayout.Toggle("Render Facade", renderFacade); //ensure the selected style isn't out of bounds int numberOfStyles = styles.Length; if (selectedStyle >= numberOfStyles) { selectedStyle = 0; } //compose a list of style ids from the volume style library List <int> entryNum = new List <int>(); for (int s = 0; s < numberOfStyles; s++) { if (selectedPoint == styles[s].facadeID) { entryNum.Add(s); } } int numberOfFacadeStyles = entryNum.Count; if (GUILayout.Button("Add style to facade", GUILayout.Width(400))) { volume.styles.AddStyle(0, selectedPoint, 1); } GUILayout.BeginHorizontal("box"); GUILayout.BeginHorizontal("box"); EditorGUILayout.LabelField("Style", GUILayout.Width(160)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal("box"); GUILayout.Label("Floors", GUILayout.Width(78)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal("box"); GUILayout.Label("Position", GUILayout.Width(54)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal("box"); GUILayout.Label(" ", GUILayout.Width(55)); GUILayout.EndHorizontal(); GUILayout.EndHorizontal(); for (int s = 0; s < numberOfFacadeStyles; s++) { int index = entryNum[s]; BuildrVolumeStylesUnit styleUnit = styles[index]; GUILayout.BeginHorizontal("box"); GUILayout.BeginHorizontal("box"); string[] facadeNames = new string[numberOfFacadeDesigns]; for (int f = 0; f < numberOfFacadeDesigns; f++) { facadeNames[f] = data.facades[f].name; } int selectedFacadeDesign = EditorGUILayout.Popup(styleUnit.styleID, facadeNames, GUILayout.Width(160)); if (selectedFacadeDesign != styleUnit.styleID) { volume.styles.ModifyStyle(index, selectedFacadeDesign); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal("box"); int currentFloors = styleUnit.floors; currentFloors = EditorGUILayout.IntField(currentFloors, GUILayout.Width(20)); if (GUILayout.Button("+", GUILayout.Width(25))) { currentFloors++; } EditorGUI.BeginDisabledGroup(currentFloors < 2); if (GUILayout.Button("-", GUILayout.Width(25))) { currentFloors--; } EditorGUI.EndDisabledGroup(); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal("box"); EditorGUI.BeginDisabledGroup((s < 1)); { if (GUILayout.Button("^", GUILayout.Width(25))) { volume.styles.MoveEntry(entryNum[s], entryNum[s - 1] + 1); GUI.changed = true; } } EditorGUI.EndDisabledGroup(); EditorGUI.BeginDisabledGroup((s > numberOfFacadeStyles - 2)); { if (GUILayout.Button("v", GUILayout.Width(25))) { volume.styles.MoveEntry(entryNum[s], entryNum[s + 1] + 1); GUI.changed = true; } } EditorGUI.EndDisabledGroup(); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal("box"); if (GUILayout.Button("remove", GUILayout.Width(55))) { volume.styles.RemoveStyle(index); } GUILayout.EndHorizontal(); GUILayout.EndHorizontal(); if (currentFloors != styleUnit.floors) { volume.styles.ModifyFloors(index, currentFloors); GUI.changed = true; } } EditorGUILayout.Space(); titlesyle = new GUIStyle(GUI.skin.label); titlesyle.fixedHeight = 60; titlesyle.fixedWidth = 400; titlesyle.alignment = TextAnchor.UpperCenter; titlesyle.fontStyle = FontStyle.Bold; titlesyle.normal.textColor = Color.black; EditorGUILayout.LabelField("Roof Design", titlesyle); facadeTexture = new Texture2D(1, 1); facadeTexture.SetPixel(0, 0, BuildrColours.CYAN); facadeTexture.Apply(); sqrPos = new Rect(0, 0, 0, 0); if (Event.current.type == EventType.Repaint) { sqrPos = GUILayoutUtility.GetLastRect(); } GUI.DrawTexture(sqrPos, facadeTexture); EditorGUI.LabelField(sqrPos, "Roof Design", titlesyle); //create/display the roof selector volumeSeletionsList = new int[numberOfVolumes]; volumeSeletionsStringList = new string[numberOfVolumes]; for (int s = 0; s < numberOfVolumes; s++) { volumeSeletionsStringList[s] = ("volume " + s); volumeSeletionsList[s] = (s); } selectedRoofVolume = EditorGUILayout.IntPopup("Selected Volume", selectedRoofVolume, volumeSeletionsStringList, volumeSeletionsList, GUILayout.Width(400)); string[] roofNames = new string[numberOfRoofs]; int[] roofList = new int[numberOfRoofs]; for (int r = 0; r < numberOfRoofs; r++) { roofList[r] = r; roofNames[r] = data.roofs[r].name; } volume = data.plan.volumes[selectedRoofVolume]; volume.roofDesignID = EditorGUILayout.IntPopup("Selected Roof Design", volume.roofDesignID, roofNames, roofList, GUILayout.Width(400)); }
public static void InspectorGUI(BuildrEditMode editMode, BuildrData data) { if (data.plan == null || data.plan.numberOfVolumes == 0) { EditorGUILayout.HelpBox("There are no defined volumes, go to Floorplan and define one", MessageType.Error); return; } const int guiWidth = 400; const int textWidth = 348; const int toggleWidth = 25; const int helpWidth = 20; CURRENT_TRANSFORM = editMode.transform; EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Filename", GUILayout.Width(225)); data.exportFilename = EditorGUILayout.TextField(data.exportFilename, GUILayout.Width(175)); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Filetype", GUILayout.Width(350)); data.filetype = (BuildrData.filetypes)EditorGUILayout.EnumPopup(data.filetype, GUILayout.Width(50)); switch (data.filetype) { case BuildrData.filetypes.obj: FILE_EXTENTION = ".obj"; break; case BuildrData.filetypes.fbx: FILE_EXTENTION = ".fbx"; break; } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Export Full Mesh", GUILayout.Width(textWidth)); data.fullmesh = EditorGUILayout.Toggle(data.fullmesh, GUILayout.Width(toggleWidth)); if (GUILayout.Button("?", GUILayout.Width(helpWidth))) { string helpTitle = "Help - Export Full Mesh"; string helpBody = "Select this checkbox if you want your export the full detail model."; EditorUtility.DisplayDialog(helpTitle, helpBody, "close"); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Place Exported Model Into Scene", GUILayout.Width(textWidth)); data.placeIntoScene = EditorGUILayout.Toggle(data.placeIntoScene, GUILayout.Width(toggleWidth)); if (GUILayout.Button("?", GUILayout.Width(helpWidth))) { string helpTitle = "Help - Place Exported Model Into Scene"; string helpBody = "Select this checkbox if you want your exported models to be copied into your scene." + "\nThese will be positioned correctly and will include colliders and LOD models if you opt to export them also."; EditorUtility.DisplayDialog(helpTitle, helpBody, "close"); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Copy Textures into Export Folder", GUILayout.Width(textWidth)); data.copyTexturesIntoExportFolder = EditorGUILayout.Toggle(data.copyTexturesIntoExportFolder, GUILayout.Width(toggleWidth)); if (GUILayout.Button("?", GUILayout.Width(helpWidth))) { string helpTitle = "Help - Copy Textures into Export Folder"; string helpBody = "Check this box if you want to copy the textures you are using into the export folder." + "\nThis is useful if you plan to use the exported model elsewhere. Having the model and the textures in one folder will allow you to move this model with ease."; EditorUtility.DisplayDialog(helpTitle, helpBody, "close"); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Export Collider"); data.generateCollider = (BuildrData.ColliderGenerationModes)EditorGUILayout.EnumPopup(data.generateCollider, GUILayout.Width(80)); if (GUILayout.Button("?", GUILayout.Width(helpWidth))) { string helpTitle = "Help - Export Collider Mesh"; string helpBody = "Check this box if you wish to generate a collider mesh for your model." + "\nThis will generate a mesh to be used with colliders."; EditorUtility.DisplayDialog(helpTitle, helpBody, "close"); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Export as Prefab", GUILayout.Width(textWidth)); data.createPrefabOnExport = EditorGUILayout.Toggle(data.createPrefabOnExport, GUILayout.Width(toggleWidth)); if (GUILayout.Button("?", GUILayout.Width(helpWidth))) { string helpTitle = "Help - Export as Prefab"; string helpBody = "Select this if you wish to create a prefab of your model." + "\nThis is recommended if you're exporting a collider so they will get packaged together."; EditorUtility.DisplayDialog(helpTitle, helpBody, "close"); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Export a Low Detail Version", GUILayout.Width(textWidth)); data.exportLowLOD = EditorGUILayout.Toggle(data.exportLowLOD, GUILayout.Width(toggleWidth)); if (GUILayout.Button("?", GUILayout.Width(helpWidth))) { string helpTitle = "Help - Export a Low Detail Version"; string helpBody = "Check this box to export a simplified model of your building." + "\nIdeal to use as a low level of detail version of your model." + "\nGeometry will be significantly reduced." + "\nFacades will flat and exported as a single atlased texture" + "\nThe model will use 1 draw call and will have around 10% of the triangles and verticies"; EditorUtility.DisplayDialog(helpTitle, helpBody, "close"); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Export with tangents", GUILayout.Width(textWidth)); data.includeTangents = EditorGUILayout.Toggle(data.includeTangents, GUILayout.Width(toggleWidth)); if (GUILayout.Button("?", GUILayout.Width(helpWidth))) { string helpTitle = "Help - with tangents"; string helpBody = "Export the models with calculated tangents." + "\nSome shaders require tangents to be calculated on the model." + "\nUnity will do this automatically on all imported meshes so it's not neccessary here." + "/nBut you might want them if you're taking them to another program."; EditorUtility.DisplayDialog(helpTitle, helpBody, "close"); } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); bool unreadableTextures = false; bool nullTextures = false; string unreadableTextureList = ""; foreach (BuildrTexture bTexture in data.textures)//check texture readablility { if (bTexture.type == BuildrTexture.Types.Substance) { continue;//substances are preset in BuildrTexture class } if (bTexture.texture != null) { string texturePath = AssetDatabase.GetAssetPath(bTexture.texture); TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(texturePath); if (!textureImporter.isReadable) { unreadableTextures = true; if (unreadableTextureList.Length > 0) { unreadableTextureList += ", "; } unreadableTextureList += "'" + bTexture.name + "'"; } } else { nullTextures = true; } } if (unreadableTextures) { EditorGUILayout.HelpBox("Unreadable Texture Error." + "\nThe following textures you are useing are not readable." + "\n" + unreadableTextureList + "." + "\nPlease select the readable checkbox under advanced texture settings." + "\nOr move this texture to the BuildR texture folder and reimport.", MessageType.Error); } if (nullTextures) { EditorGUILayout.HelpBox("Null Texture Error" + "\nSome of the textures have not been set" + "\nEnsure you are not using null textures to proceed.", MessageType.Error); } bool usingSubstances = false; foreach (BuildrTexture bTexture in data.textures) { if (bTexture.type == BuildrTexture.Types.Substance) { usingSubstances = true; break; } } if (usingSubstances) { EditorGUILayout.HelpBox("Model uses Substance textures." + "\nExporting model to " + data.filetype + " will lose references to this texture and it will be rendered white.", MessageType.Warning); } EditorGUI.BeginDisabledGroup(unreadableTextures || nullTextures); if (GUILayout.Button("Export", GUILayout.Width(guiWidth), GUILayout.Height(40))) { ExportModel(data); } if (GUILayout.Button("Export Data to XML", GUILayout.Width(guiWidth))) { BuildrXMLExporter.Export(ROOT_FOLDER + data.exportFilename + "/", data.exportFilename, data); AssetDatabase.Refresh(); } EditorGUI.EndDisabledGroup(); CURRENT_TRANSFORM = null; }
public static void SceneGUI(BuildrEditMode editMode, BuildrData _data, bool shouldSnap, float handleSize) { data = _data; Vector3 camDirection = Camera.current.transform.forward; Vector3 camPosition = Camera.current.transform.position; int numberOfFacades = data.facades.Count; int numberOfRoofs = data.roofs.Count; int numberOfTextures = data.textures.Count; if (numberOfFacades == 0 || numberOfRoofs == 0 || numberOfTextures == 0) return; Vector3 position = editMode.transform.position; float floorHeight = data.floorHeight; BuildrPlan area = data.plan; int numberOfVolumes = area.numberOfVolumes; int facadeCounter = 0; for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = data.plan.volumes[s]; int volumeSize = volume.Count; Vector3 floorCentre = Vector3.zero; Handles.color = Color.white; for (int p = 0; p < volumeSize; p++) { int point = volume.points[p]; Vector3 pointPos = area.points[point].vector3; floorCentre += pointPos; List<Vector3> verts = new List<Vector3>(); int indexB = (p < volumeSize - 1) ? p + 1 : 0; Vector3 volumeHeight = Vector3.up * (volume.numberOfFloors * data.floorHeight); verts.Add(pointPos + position); verts.Add(area.points[volume.points[indexB]].vector3 + position); verts.Add(verts[1] + volumeHeight); verts.Add(verts[0] + volumeHeight); if (s == selectedVolume && point == selectedPoint) //display something to highlight this facade Handles.DrawSolidRectangleWithOutline(verts.ToArray(), Color.clear, BuildrColours.MAGENTA); Handles.color = BuildrColours.CYAN; if (s == selectedRoofVolume) Handles.DrawLine(verts[2], verts[3]); if (editMode.showFacadeMarkers) { Handles.color = Color.white; Vector3 facadeDirection = Vector3.Cross((verts[0] - verts[1]), Vector3.up); GUIStyle facadeLabelStyle = new GUIStyle(); facadeLabelStyle.normal.textColor = Color.white; facadeLabelStyle.alignment = TextAnchor.MiddleCenter; facadeLabelStyle.fixedWidth = 75.0f; Vector3 centerPos = (verts[0] + verts[1]) * 0.5f; bool camVisible = Vector3.Dot(camDirection, centerPos - camPosition) > 0; bool facadeVisible = Vector3.Dot(camDirection, facadeDirection) < 0; if (camVisible && facadeVisible)//only display label when facade is facing camera and is in camera view { Vector3 labelPos = centerPos + facadeDirection.normalized; Handles.Label(labelPos, "facade " + facadeCounter, facadeLabelStyle); Handles.DrawLine(centerPos, labelPos); } } facadeCounter++; } floorCentre /= volumeSize; //Volume height/floor number slider Vector3 volumeHeightDir = Vector3.up * (volume.numberOfFloors * data.floorHeight); Vector3 volumePosition = floorCentre + position + volumeHeightDir; if (Vector3.Dot(camDirection, volumePosition - camPosition) > 0)//only display label when facade is facing camera { Handles.Label(volumePosition + (Vector3.up * (handleSize * 0.1f)), "volume " + s); Handles.Label(volumePosition, "number of floors " + volume.numberOfFloors); } Handles.color = Color.green; volume.height = Handles.Slider(volumePosition, Vector3.up).y - position.y; if (volume.height < data.floorHeight) volume.height = data.floorHeight; volume.numberOfFloors = Mathf.RoundToInt(volume.height / floorHeight); } }
public static void InspectorGUI(BuildrEditMode _editMode, BuildrData _data) { data = _data; BuildrTexture[] textures = data.textures.ToArray(); int numberOfTextures = textures.Length; selectedTexture = Mathf.Clamp(selectedTexture, 0, numberOfTextures - 1); int currentSelectedTexture = selectedTexture;//keep tack of what we had selected to reset fields if changed Undo.RecordObject(data, "Texture Modified"); if (numberOfTextures == 0) { EditorGUILayout.HelpBox("There are no textures to show", MessageType.Info); if (GUILayout.Button("Add New")) { data.textures.Add(new BuildrTexture("new texture " + numberOfTextures)); numberOfTextures++; selectedTexture = numberOfTextures - 1; } return; } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Texture", GUILayout.Width(75)); string[] textureNames = new string[numberOfTextures]; for (int t = 0; t < numberOfTextures; t++) { textureNames[t] = textures[t].name; } selectedTexture = EditorGUILayout.Popup(selectedTexture, textureNames); EditorGUILayout.EndHorizontal(); BuildrTexture bTexture = textures[selectedTexture]; EditorGUILayout.BeginHorizontal(); EditorGUILayout.Space(); if (GUILayout.Button("Add New", GUILayout.Width(81))) { data.textures.Add(new BuildrTexture("new texture " + numberOfTextures)); numberOfTextures++; selectedTexture = numberOfTextures - 1; } if (GUILayout.Button("Duplicate", GUILayout.Width(90))) { data.textures.Add(bTexture.Duplicate()); numberOfTextures++; selectedTexture = numberOfTextures - 1; } if (GUILayout.Button("Delete", GUILayout.Width(71))) { if (EditorUtility.DisplayDialog("Deleting Texture Entry", "Are you sure you want to delete this texture?", "Delete", "Cancel")) { data.RemoveTexture(bTexture); selectedTexture = 0; GUI.changed = true; return; } } if (GUILayout.Button("Import", GUILayout.Width(71))) { string xmlPath = EditorUtility.OpenFilePanel("Select the XML file...", "Assets/BuildR/Exported/", "xml"); if (xmlPath == "") { return; } BuildrXMLImporter.ImportTextures(xmlPath, _data); textures = data.textures.ToArray(); selectedTexture = 0; GUI.changed = true; } if (GUILayout.Button("Export", GUILayout.Width(71))) { string xmlPath = EditorUtility.SaveFilePanel("Export as...", "Assets/BuildR/Exported/", _data.name + "_textureLibrary", "xml"); if (xmlPath == "") { return; } BuildrXMLExporter.ExportTextures(xmlPath, _data); GUI.changed = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); textures = data.textures.ToArray(); textureNames = new string[numberOfTextures]; for (int t = 0; t < numberOfTextures; t++) { textureNames[t] = textures[t].name; } bTexture = textures[selectedTexture];//reassign string textureName = bTexture.name; GUIStyle redText = new GUIStyle(GUI.skin.textField); if (textureName.Contains(" ")) { redText.focused.textColor = Color.red; textureName = EditorGUILayout.TextField("Name", textureName, redText); } else { redText.focused.textColor = defaultCol; textureName = EditorGUILayout.TextField("Name", textureName, redText); } bTexture.name = textureName; bool conflictingName = false; for (int i = 0; i < textureNames.Length; i++) { if (selectedTexture != i) { if (textureNames[i] == bTexture.name) { conflictingName = true; } } } if (conflictingName) { EditorGUILayout.HelpBox("You have named this texture the same as another.", MessageType.Warning); } if (currentSelectedTexture != selectedTexture) { GUIUtility.hotControl = 0; GUIUtility.keyboardControl = 0; } bTexture.type = (BuildrTexture.Types)EditorGUILayout.EnumPopup("Type", bTexture.type); switch (bTexture.type) { case BuildrTexture.Types.Basic: if (bTexture.texture != null) { string texturePath = AssetDatabase.GetAssetPath(bTexture.texture); TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(texturePath); if (!textureImporter.isReadable) { EditorGUILayout.HelpBox("The texture you have selected is not readable." + "\nPlease select the readable checkbox under advanced texture settings." + "\nOr move this texture to the BuildR texture folder and reimport.", MessageType.Error); } } //Shader Time Shader[] tempshaders = (Shader[])Resources.FindObjectsOfTypeAll(typeof(Shader)); List <string> shaderNames = new List <string>(ShaderProperties.NAMES); foreach (Shader shader in tempshaders) { if (!string.IsNullOrEmpty(shader.name) && !shader.name.StartsWith("__") && !shader.name.Contains("hidden")) { shaderNames.Add(shader.name); } } int selectedShaderIndex = shaderNames.IndexOf(bTexture.material.shader.name); int newSelectedShaderIndex = EditorGUILayout.Popup("Shader", selectedShaderIndex, shaderNames.ToArray()); if (selectedShaderIndex != newSelectedShaderIndex) { bTexture.material.shader = Shader.Find(shaderNames[newSelectedShaderIndex]); } Shader selectedShader = bTexture.material.shader; int propertyCount = ShaderUtil.GetPropertyCount(selectedShader); for (int s = 0; s < propertyCount; s++) { ShaderUtil.ShaderPropertyType propertyTpe = ShaderUtil.GetPropertyType(selectedShader, s); string shaderPropertyName = ShaderUtil.GetPropertyName(selectedShader, s); switch (propertyTpe) { case ShaderUtil.ShaderPropertyType.TexEnv: Texture shaderTexture = bTexture.material.GetTexture(shaderPropertyName); Texture newShaderTexture = (Texture)EditorGUILayout.ObjectField(shaderPropertyName, shaderTexture, typeof(Texture), false); if (shaderTexture != newShaderTexture) { bTexture.material.SetTexture(shaderPropertyName, newShaderTexture); } break; case ShaderUtil.ShaderPropertyType.Color: Color shaderColor = bTexture.material.GetColor(shaderPropertyName); Color newShaderColor = EditorGUILayout.ColorField(shaderPropertyName, shaderColor); if (shaderColor != newShaderColor) { bTexture.material.SetColor(shaderPropertyName, newShaderColor); } break; case ShaderUtil.ShaderPropertyType.Float: float shaderFloat = bTexture.material.GetFloat(shaderPropertyName); float newShaderFloat = EditorGUILayout.FloatField(shaderPropertyName, shaderFloat); if (shaderFloat != newShaderFloat) { bTexture.material.SetFloat(shaderPropertyName, newShaderFloat); } break; case ShaderUtil.ShaderPropertyType.Range: float shaderRange = bTexture.material.GetFloat(shaderPropertyName); float rangeMin = ShaderUtil.GetRangeLimits(selectedShader, s, 1); float rangeMax = ShaderUtil.GetRangeLimits(selectedShader, s, 2); float newShaderRange = EditorGUILayout.Slider(shaderPropertyName, shaderRange, rangeMin, rangeMax); if (shaderRange != newShaderRange) { bTexture.material.SetFloat(shaderPropertyName, newShaderRange); } break; case ShaderUtil.ShaderPropertyType.Vector: Vector3 shaderVector = bTexture.material.GetVector(shaderPropertyName); Vector3 newShaderVector = EditorGUILayout.Vector3Field(shaderPropertyName, shaderVector); if (shaderVector != newShaderVector) { bTexture.material.SetVector(shaderPropertyName, newShaderVector); } break; } } bool tiled = EditorGUILayout.Toggle("Is Tiled", bTexture.tiled); if (tiled != bTexture.tiled) { bTexture.tiled = tiled; } if (bTexture.tiled) { bool patterned = EditorGUILayout.Toggle("Has Pattern", bTexture.patterned); if (patterned != bTexture.patterned) { bTexture.patterned = patterned; } } else { bTexture.patterned = false; } if (bTexture.texture == null) { return; } Vector2 textureUnitSize = bTexture.textureUnitSize; if (bTexture.tiled) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("texture width", GUILayout.Width(75)); //, GUILayout.Width(42)); textureUnitSize.x = EditorGUILayout.FloatField(bTexture.textureUnitSize.x, GUILayout.Width(25)); EditorGUILayout.LabelField("metres", GUILayout.Width(40)); //, GUILayout.Width(42)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("texture height", GUILayout.Width(75));//, GUILayout.Width(42)); textureUnitSize.y = EditorGUILayout.FloatField(bTexture.textureUnitSize.y, GUILayout.Width(25)); EditorGUILayout.LabelField("metres", GUILayout.Width(40)); EditorGUILayout.EndHorizontal(); if (bTexture.textureUnitSize != textureUnitSize) { bTexture.textureUnitSize = textureUnitSize; } } Vector2 tileUnitSize = bTexture.tileUnitUV; if (bTexture.patterned) { float minWidth = 2 / bTexture.texture.width; float minHeight = 2 / bTexture.texture.height; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("unit width", GUILayout.Width(75)); float tileUnitSizex = EditorGUILayout.Slider(tileUnitSize.x, minWidth, 1.0f); if (tileUnitSizex != tileUnitSize.x) { tileUnitSize.x = tileUnitSizex; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("unit height", GUILayout.Width(75)); float tileUnitSizey = EditorGUILayout.Slider(tileUnitSize.y, minHeight, 1.0f); if (tileUnitSizey != tileUnitSize.y) { tileUnitSize.y = tileUnitSizey; } EditorGUILayout.EndHorizontal(); bTexture.tileUnitUV = tileUnitSize; EditorGUILayout.Space(); } const int previewTextureUnitSize = 120; const int previewTileUnitSize = 59; const int previewTileUnitPadding = 2; const int previewPadding = 25; EditorGUILayout.BeginHorizontal(); if (bTexture.tiled) { EditorGUILayout.LabelField("1 Metre Squared", GUILayout.Width(previewTextureUnitSize)); } GUILayout.Space(previewPadding); if (bTexture.patterned) { EditorGUILayout.LabelField("Texture Pattern Units", GUILayout.Width(previewTileUnitSize * 2)); } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); if (Event.current.type == EventType.Repaint) { texturePreviewPostion = GUILayoutUtility.GetLastRect(); } if (bTexture.tiled) { Rect previewRect = new Rect(texturePreviewPostion.x, texturePreviewPostion.y, previewTextureUnitSize, previewTextureUnitSize); Rect sourceRect = new Rect(0, 0, (1.0f / textureUnitSize.x), (1.0f / textureUnitSize.y)); Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0); } if (bTexture.patterned) { Rect previewRect = new Rect(previewTextureUnitSize + previewPadding, 0, previewTileUnitSize, previewTileUnitSize); Rect sourceRect = new Rect(0, tileUnitSize.y, tileUnitSize.x, tileUnitSize.y); previewRect.x += texturePreviewPostion.x; previewRect.y += texturePreviewPostion.y; Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0); sourceRect.x += tileUnitSize.x; previewRect.x += previewTileUnitSize + previewTileUnitPadding; Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0); sourceRect.x += -tileUnitSize.x; sourceRect.y += -tileUnitSize.y; previewRect.x += -(previewTileUnitSize + previewTileUnitPadding); previewRect.y += previewTileUnitSize + previewTileUnitPadding; Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0); sourceRect.x += tileUnitSize.x; previewRect.x += previewTileUnitSize + previewTileUnitPadding; Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0); } if (!bTexture.tiled) { EditorGUILayout.LabelField("Tile texture"); EditorGUILayout.BeginHorizontal(); int currentXTiles = bTexture.tiledX; GUILayout.Label("tile x", GUILayout.Width(38)); currentXTiles = EditorGUILayout.IntField(currentXTiles, GUILayout.Width(20)); if (GUILayout.Button("+", GUILayout.Width(25))) { currentXTiles++; } EditorGUI.BeginDisabledGroup(currentXTiles < 2); if (GUILayout.Button("-", GUILayout.Width(25))) { currentXTiles--; } EditorGUI.EndDisabledGroup(); bTexture.tiledX = currentXTiles; int currentYTiles = bTexture.tiledY; GUILayout.Label("tile y", GUILayout.Width(38)); currentYTiles = EditorGUILayout.IntField(currentYTiles, GUILayout.Width(20)); if (GUILayout.Button("+", GUILayout.Width(25))) { currentYTiles++; } EditorGUI.BeginDisabledGroup(currentYTiles < 2); if (GUILayout.Button("-", GUILayout.Width(25))) { currentYTiles--; } EditorGUI.EndDisabledGroup(); bTexture.tiledY = currentYTiles; EditorGUILayout.EndHorizontal(); GUILayout.Space(10); EditorGUILayout.Space(); if (Event.current.type == EventType.Repaint) { texturePreviewPostion = GUILayoutUtility.GetLastRect(); } Rect previewRect = new Rect(texturePreviewPostion.x, texturePreviewPostion.y, previewTextureUnitSize, previewTextureUnitSize); Rect sourceRect = new Rect(0, 0, currentXTiles, currentYTiles); Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0); } GUILayout.Space(previewTextureUnitSize); break; case BuildrTexture.Types.Substance: bTexture.proceduralMaterial = (ProceduralMaterial)EditorGUILayout.ObjectField("Procedural Material", bTexture.proceduralMaterial, typeof(ProceduralMaterial), false); if (bTexture.proceduralMaterial != null) { ProceduralMaterial pMat = bTexture.proceduralMaterial; GUILayout.Label(pMat.GetGeneratedTexture(pMat.mainTexture.name), GUILayout.Width(400)); } else { EditorGUILayout.HelpBox("There is no substance material set.", MessageType.Error); } break; case BuildrTexture.Types.User: bTexture.userMaterial = (Material)EditorGUILayout.ObjectField("User Material", bTexture.userMaterial, typeof(Material), false); if (bTexture.userMaterial != null) { Material mat = bTexture.userMaterial; GUILayout.Label(mat.mainTexture, GUILayout.Width(400)); } else { EditorGUILayout.HelpBox("There is no substance material set.", MessageType.Error); } break; } }
public static void SceneGUI(BuildrEditMode editMode, BuildrData data, bool shouldSnap, float handleSize) { switch (mode) { case EditModes.general: //No scene actions break; case EditModes.floorplan: BuildrEditModeFloorplan.SceneGUI(editMode, data.plan, false, handleSize); break; } if (constraints.constrainPlanByArea) { Rect area = constraints.area; Vector3 position = editMode.transform.position; Vector3 areaLeft = new Vector3(area.xMin, 0, (area.yMin + area.yMax) / 2); Vector3 areaRight = new Vector3(area.xMax, 0, (area.yMin + area.yMax) / 2); Vector3 areaBottom = new Vector3((area.xMin + area.xMax) / 2, 0, area.yMin); Vector3 areaTop = new Vector3((area.xMin + area.xMax) / 2, 0, area.yMax); Vector3 newAreaLeft = Handles.Slider(areaLeft + position, Vector3.left, HandleUtility.GetHandleSize(areaLeft) * 0.666f, Handles.ArrowCap, 0.0f); Vector3 newAreaRight = Handles.Slider(areaRight + position, Vector3.right, HandleUtility.GetHandleSize(areaLeft) * 0.666f, Handles.ArrowCap, 0.0f); Vector3 newAreaBottom = Handles.Slider(areaBottom + position, Vector3.back, HandleUtility.GetHandleSize(areaLeft) * 0.666f, Handles.ArrowCap, 0.0f); Vector3 newAreaTop = Handles.Slider(areaTop + position, Vector3.forward, HandleUtility.GetHandleSize(areaLeft) * 0.666f, Handles.ArrowCap, 0.0f); newAreaLeft -= position; newAreaRight -= position; newAreaBottom -= position; newAreaTop -= position; if (areaLeft != newAreaLeft) { area.xMin = Mathf.Min(newAreaLeft.x, area.xMax - 1.0f); } if (areaRight != newAreaRight) { area.xMax = Mathf.Max(newAreaRight.x, area.xMin + 1.0f); } if (areaBottom != newAreaBottom) { area.yMin = Mathf.Min(newAreaBottom.z, area.yMax - 1.0f); } if (areaTop != newAreaTop) { area.yMax = Mathf.Max(newAreaTop.z, area.yMin + 1.0f); } constraints.area = area; Vector3 coreBL = new Vector3(area.xMin, 0, area.yMin) + position; Vector3 coreBR = new Vector3(area.xMax, 0, area.yMin) + position; Vector3 coreTL = new Vector3(area.xMin, 0, area.yMax) + position; Vector3 coreTR = new Vector3(area.xMax, 0, area.yMax) + position; Handles.DrawLine(coreBL, coreBR); Handles.DrawLine(coreBR, coreTR); Handles.DrawLine(coreTR, coreTL); Handles.DrawLine(coreTL, coreBL); } }
public static void SceneGUI(BuildrEditMode editMode, BuildrData _data, bool shouldSnap, float handleSize) { data = _data; Vector3 camDirection = Camera.current.transform.forward; Vector3 camPosition = Camera.current.transform.position; int numberOfFacades = data.facades.Count; int numberOfRoofs = data.roofs.Count; int numberOfTextures = data.textures.Count; if (numberOfFacades == 0 || numberOfRoofs == 0 || numberOfTextures == 0) { return; } Vector3 position = editMode.transform.position; float floorHeight = data.floorHeight; BuildrPlan area = data.plan; int numberOfVolumes = area.numberOfVolumes; int facadeCounter = 0; for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = data.plan.volumes[s]; int volumeSize = volume.Count; Vector3 floorCentre = Vector3.zero; Handles.color = Color.white; for (int p = 0; p < volumeSize; p++) { int point = volume.points[p]; Vector3 pointPos = area.points[point].vector3; floorCentre += pointPos; List <Vector3> verts = new List <Vector3>(); int indexB = (p < volumeSize - 1) ? p + 1 : 0; Vector3 volumeHeight = Vector3.up * (volume.numberOfFloors * data.floorHeight); verts.Add(pointPos + position); verts.Add(area.points[volume.points[indexB]].vector3 + position); verts.Add(verts[1] + volumeHeight); verts.Add(verts[0] + volumeHeight); if (s == selectedVolume && point == selectedPoint) { //display something to highlight this facade Handles.DrawSolidRectangleWithOutline(verts.ToArray(), Color.clear, BuildrColours.MAGENTA); } Handles.color = BuildrColours.CYAN; if (s == selectedRoofVolume) { Handles.DrawLine(verts[2], verts[3]); } if (editMode.showFacadeMarkers) { Handles.color = Color.white; Vector3 facadeDirection = Vector3.Cross((verts[0] - verts[1]), Vector3.up); GUIStyle facadeLabelStyle = new GUIStyle(); facadeLabelStyle.normal.textColor = Color.white; facadeLabelStyle.alignment = TextAnchor.MiddleCenter; facadeLabelStyle.fixedWidth = 75.0f; Vector3 centerPos = (verts[0] + verts[1]) * 0.5f; bool camVisible = Vector3.Dot(camDirection, centerPos - camPosition) > 0; bool facadeVisible = Vector3.Dot(camDirection, facadeDirection) < 0; if (camVisible && facadeVisible)//only display label when facade is facing camera and is in camera view { Vector3 labelPos = centerPos + facadeDirection.normalized; Handles.Label(labelPos, "facade " + facadeCounter, facadeLabelStyle); Handles.DrawLine(centerPos, labelPos); } } facadeCounter++; } floorCentre /= volumeSize; //Volume height/floor number slider Vector3 volumeHeightDir = Vector3.up * (volume.numberOfFloors * data.floorHeight); Vector3 volumePosition = floorCentre + position + volumeHeightDir; if (Vector3.Dot(camDirection, volumePosition - camPosition) > 0)//only display label when facade is facing camera { Handles.Label(volumePosition + (Vector3.up * (handleSize * 0.1f)), "volume " + s); Handles.Label(volumePosition, "number of floors " + volume.numberOfFloors); } Handles.color = Color.green; volume.height = Handles.Slider(volumePosition, Vector3.up).y - position.y; if (volume.height < data.floorHeight) { volume.height = data.floorHeight; } volume.numberOfFloors = Mathf.RoundToInt(volume.height / floorHeight); } }
public static void SceneGUI(BuildrEditMode editMode, BuildrData data, bool shouldSnap, float handleSize) { }
public static void SceneGUI(BuildrEditMode _editMode, BuildrData _data, bool shouldSnap, float handleSize) { Vector3 camDirection = Camera.current.transform.forward; Vector3 camPosition = Camera.current.transform.position; Vector3 position = _editMode.transform.position; data = _data; BuildrPlan plan = data.plan; BuildrVolume selectedVolume = plan.volumes[selectedVolumeIndex]; int selectedVolumeSize = selectedVolume.Count; Handles.color = Color.white; int facadeCounter = 0; GUIStyle whiteLabelStyle = new GUIStyle(); whiteLabelStyle.normal.textColor = Color.white; whiteLabelStyle.alignment = TextAnchor.MiddleCenter; whiteLabelStyle.fixedWidth = 75.0f; int numberOfVolumes = plan.numberOfVolumes; for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = data.plan.volumes[s]; int volumeSize = volume.Count; Vector3 floorCentre = Vector3.zero; for (int p = 0; p < volumeSize; p++) { int point = volume.points[p]; Vector3 pointPos = plan.points[point].vector3; floorCentre += pointPos; } floorCentre /= volumeSize; if(s==selectedVolumeIndex) { whiteLabelStyle.normal.textColor = BuildrColours.RED; whiteLabelStyle.fontStyle = FontStyle.Bold; } else { whiteLabelStyle.normal.textColor = Color.white; whiteLabelStyle.fontStyle = FontStyle.Normal; } //Volume height/floor number slider Vector3 volumeHeightDir = Vector3.up * (volume.numberOfFloors * data.floorHeight); Vector3 volumePosition = floorCentre + position + volumeHeightDir; Handles.color = Color.white; if (Vector3.Dot(camDirection, volumePosition - camPosition) > 0)//only display label when facade is facing camera { Handles.Label(volumePosition + (Vector3.up * (handleSize * 0.1f)), "volume " + s, whiteLabelStyle); } } whiteLabelStyle.normal.textColor = Color.white; whiteLabelStyle.fontStyle = FontStyle.Normal; for (int p = 0; p < selectedVolumeSize; p++) { int point = selectedVolume.points[p]; Vector3 pointPos = plan.points[point].vector3; List<Vector3> verts = new List<Vector3>(); int indexB = (p < selectedVolumeSize - 1) ? p + 1 : 0; Vector3 floorHeightVector = Vector3.up * (selectedFloor * data.floorHeight); Vector3 ceilingHeightVector = Vector3.up * ((selectedFloor+1) * data.floorHeight); Vector3 p0 = pointPos + position; Vector3 p1 = plan.points[selectedVolume.points[indexB]].vector3 + position; verts.Add(pointPos + position); verts.Add(plan.points[selectedVolume.points[indexB]].vector3 + position); verts.Add(verts[1] + floorHeightVector); verts.Add(verts[0] + floorHeightVector); Handles.color = BuildrColours.RED; Handles.DrawLine(p0 + floorHeightVector, p1 + floorHeightVector); Handles.DrawLine(p0 + ceilingHeightVector, p1 + ceilingHeightVector); Handles.DrawLine(p0 + floorHeightVector, p0 + ceilingHeightVector); if (_editMode.showFacadeMarkers) { Handles.color = Color.white; Vector3 facadeDirection = Vector3.Cross((verts[0] - verts[1]), Vector3.up); Vector3 centerPos = (verts[0] + verts[1]) * 0.5f; bool camVisible = Vector3.Dot(camDirection, centerPos - camPosition) > 0; bool facadeVisible = Vector3.Dot(camDirection, facadeDirection) < 0; if (camVisible && facadeVisible)//only display label when facade is facing camera and is in camera view { Vector3 labelPos = centerPos + facadeDirection.normalized; Handles.Label(labelPos, "facade " + facadeCounter, whiteLabelStyle); Handles.DrawLine(centerPos, labelPos); } } facadeCounter++; } }
public static void InspectorGUI(BuildrEditMode editMode, BuildrData _data) { int helpWidth = 20; data = _data; Undo.RecordObject(data, "Facade Modified"); BuildrFacadeDesign[] facades = data.facades.ToArray(); int numberOfFacades = facades.Length; selectedFacade = Mathf.Clamp(selectedFacade, 0, numberOfFacades - 1); if (numberOfFacades == 0) { EditorGUILayout.HelpBox("There are no facade designs to show", MessageType.Info); return; } bool hasUnusedFacades = false; int unusedIndex = 0; //Check all facades have een used and warn if there are unused ones for (int i = 0; i < numberOfFacades; i++) { bool facadeUnused = true; foreach (BuildrVolume volume in data.plan.volumes) { if (volume.ContainsFacade(i)) { facadeUnused = false; break; } } if (facadeUnused) { hasUnusedFacades = true; unusedIndex = i; break; } } if (hasUnusedFacades) { EditorGUILayout.HelpBox("There are facade designs that are not applied to your building and are unused.\nGo to the Building section to apply them to a facade.\nCheck facade design \"" + facades[unusedIndex].name + "\"", MessageType.Warning); } //Facade Selector EditorGUILayout.BeginVertical("box"); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Facade Design:", GUILayout.Width(145)); string[] facadeNames = new string[numberOfFacades]; for (int f = 0; f < numberOfFacades; f++) { facadeNames[f] = facades[f].name; } selectedFacade = EditorGUILayout.Popup(selectedFacade, facadeNames); BuildrFacadeDesign bFacade = facades[selectedFacade]; EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Add", GUILayout.Width(60))) { data.facades.Add(new BuildrFacadeDesign("new facade " + numberOfFacades)); facades = data.facades.ToArray(); numberOfFacades++; selectedFacade = numberOfFacades - 1; } if (GUILayout.Button("Duplicate", GUILayout.Width(90))) { data.facades.Add(bFacade.Duplicate()); facades = data.facades.ToArray(); numberOfFacades++; selectedFacade = numberOfFacades - 1; } if (GUILayout.Button("Delete", GUILayout.Width(70))) { if (EditorUtility.DisplayDialog("Deleting Facade Design Entry", "Are you sure you want to delete this facade?", "Delete", "Cancel")) { data.RemoveFacadeDesign(bFacade); selectedFacade = 0; GUI.changed = true; return; } } if (GUILayout.Button("Import", GUILayout.Width(71))) { string xmlPath = EditorUtility.OpenFilePanel("Select the XML file...", "Assets/BuildR/Exported/", "xml"); if (xmlPath == "") { return; } BuildrXMLImporter.ImportFacades(xmlPath, _data); facades = _data.facades.ToArray(); selectedFacade = 0; GUI.changed = true; } if (GUILayout.Button("Export", GUILayout.Width(71))) { string xmlPath = EditorUtility.SaveFilePanel("Export as...", "Assets/BuildR/Exported/", _data.name + "_facadeLibrary", "xml"); if (xmlPath == "") { return; } BuildrXMLExporter.ExportFacades(xmlPath, _data); GUI.changed = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.EndVertical(); bFacade = facades[selectedFacade];//reassign bFacade.name = EditorGUILayout.TextField("Facade Name: ", bFacade.name); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Facade Design Type:", GUILayout.Width(145)); bFacade.type = (BuildrFacadeDesign.types)EditorGUILayout.EnumPopup(bFacade.type); if (GUILayout.Button("?", GUILayout.Width(helpWidth))) { string helpTitle = "Help - Design Type"; string helpBody = "This allows you to select the type of design you're using.\n" + "Simple - the facade openings will be uniform\n" + "Patterned - the facade openings will follow a pattern of defined dimensions and textures\n"; EditorUtility.DisplayDialog(helpTitle, helpBody, "close"); } EditorGUILayout.EndHorizontal(); int numberOfTextures = data.textures.Count; string[] textureNames = new string[numberOfTextures]; for (int t = 0; t < numberOfTextures; t++) { textureNames[t] = data.textures[t].name; } bFacade.hasWindows = EditorGUILayout.Toggle("Facade Has Bays", bFacade.hasWindows); if (bFacade.hasWindows) { if (bFacade.type == BuildrFacadeDesign.types.simple) { BuildrBay bbay = bFacade.simpleBay; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Render Bay", GUILayout.Width(146)); bool renderBayBack = EditorGUILayout.Toggle(bbay.renderBack); if (renderBayBack != bbay.renderBack) { bbay.renderBack = renderBayBack; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Bay Model", GUILayout.Width(146)); bbay.bayModel = (GameObject)EditorGUILayout.ObjectField(bbay.bayModel, typeof(GameObject), false); if (GUILayout.Button("Clear", GUILayout.Width(70))) { bbay.bayModel = null; } EditorGUILayout.EndHorizontal(); float bbayopeningWidth = Mathf.Max(EditorGUILayout.FloatField("Opening Width", bbay.openingWidth), 0); if (bbayopeningWidth != bbay.openingWidth) { bbay.openingWidth = bbayopeningWidth; } float bbayopeningHeight = Mathf.Max(EditorGUILayout.FloatField("Opening Height", bbay.openingHeight), 0); if (bbayopeningHeight > data.floorHeight) { bbayopeningHeight = data.floorHeight; } if (bbayopeningHeight != bbay.openingHeight) { bbay.openingHeight = bbayopeningHeight; } float bbayminimumBayWidth = Mathf.Max(EditorGUILayout.FloatField("Min. Spacing", bbay.minimumBayWidth), 0); if (bbayminimumBayWidth != bbay.minimumBayWidth) { bbay.minimumBayWidth = bbayminimumBayWidth; } float bbayopeningWidthRatio = EditorGUILayout.Slider("Horizontal Space Ratio", bbay.openingWidthRatio, 0, 1); if (bbayopeningWidthRatio != bbay.openingWidthRatio) { bbay.openingWidthRatio = bbayopeningWidthRatio; } float bbayopeningHeightRatio = EditorGUILayout.Slider("Vertical Space Ratio", bbay.openingHeightRatio, 0, 1); if (bbayopeningHeightRatio != bbay.openingHeightRatio) { bbay.openingHeightRatio = bbayopeningHeightRatio; } float bbayopeningDepth = EditorGUILayout.Slider("Opening Depth", bbay.openingDepth, -depth, depth); if (bbayopeningDepth != bbay.openingDepth) { bbay.openingDepth = bbayopeningDepth; } float bbaycolumnDepth = EditorGUILayout.Slider("Column Depth", bbay.columnDepth, -depth, depth); if (bbaycolumnDepth != bbay.columnDepth) { bbay.columnDepth = bbaycolumnDepth; } float bbayrowDepth = EditorGUILayout.Slider("Row Depth", bbay.rowDepth, -depth, depth); if (bbayrowDepth != bbay.rowDepth) { bbay.rowDepth = bbayrowDepth; } float bbaycrossDepth = EditorGUILayout.Slider("Cross Depth", bbay.crossDepth, -depth, depth); if (bbaycrossDepth != bbay.crossDepth) { bbay.crossDepth = bbaycrossDepth; } int numberOfTextureSlots = bbay.numberOfTextures; string[] titles = new string[numberOfTextureSlots]; for (int bft = 0; bft < numberOfTextureSlots; bft++) { titles[bft] = ((BuildrBay.TextureNames)(bft)).ToString(); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Wall Surface:", GUILayout.Width(75)); editTextureOnFacade = EditorGUILayout.Popup(editTextureOnFacade, titles); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Wall Texture:", GUILayout.Width(75)); int newFacadeTextureID = EditorGUILayout.Popup(bbay.textureValues[editTextureOnFacade], textureNames); if (newFacadeTextureID != bbay.textureValues[editTextureOnFacade]) { bbay.textureValues[editTextureOnFacade] = newFacadeTextureID; } EditorGUILayout.EndHorizontal(); BuildrTexture bTexture = data.textures[bbay.textureValues[editTextureOnFacade]]; Texture2D texture = bTexture.texture; EditorGUILayout.BeginHorizontal(); if (texture != null) { GUILayout.Label(texture, GUILayout.Width(100), GUILayout.Height(100)); } else { EditorGUILayout.HelpBox("No texture assigned for '" + textureNames[bbay.textureValues[editTextureOnFacade]] + "', assign one in the Textures menu above", MessageType.Warning); } bbay.flipValues[editTextureOnFacade] = EditorGUILayout.Toggle("Flip 90\u00B0", bbay.flipValues[editTextureOnFacade]); EditorGUILayout.EndHorizontal(); } else { //Patterned design GUI int numberOfBays = bFacade.bayPattern.Count; int numberOfBayDesigns = data.bays.Count; EditorGUILayout.BeginHorizontal(); GUILayout.BeginHorizontal("box"); if (GUILayout.Button("Add New Bay Design")) { BuildrBay newBay = new BuildrBay("new bay design " + (numberOfBayDesigns + 1)); data.bays.Add(newBay); bFacade.bayPattern.Add(numberOfBayDesigns); numberOfBays++; selectedBayPatternIndex = numberOfBays - 1; numberOfBayDesigns++; GUI.changed = true; } EditorGUILayout.EndHorizontal(); if (numberOfBays == 0 || data.bays.Count == 0) { EditorGUILayout.HelpBox("There are no bay designs to show", MessageType.Info); // EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); return; } BuildrBay[] bays = new BuildrBay[numberOfBays]; for (int i = 0; i < numberOfBays; i++) { bays[i] = data.bays[bFacade.bayPattern[i]]; } selectedBayPatternIndex = Mathf.Clamp(selectedBayPatternIndex, 0, numberOfBays - 1); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.BeginHorizontal("box"); string[] bayDesignNames = new string[data.bays.Count]; for (int i = 0; i < numberOfBayDesigns; i++) { bayDesignNames[i] = data.bays[i].name; } selectedBayDesign = EditorGUILayout.Popup(selectedBayDesign, bayDesignNames); if (GUILayout.Button("Add Selected")) { bFacade.bayPattern.Add(selectedBayDesign); GUI.changed = true; } if (GUILayout.Button("Duplicate Selected")) { BuildrBay newBay = data.bays[selectedBayDesign].Duplicate(); data.bays.Add(newBay); bFacade.bayPattern.Add(numberOfBayDesigns); numberOfBays++; selectedBayPatternIndex = numberOfBays - 1; numberOfBayDesigns++; GUI.changed = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal(); GUILayout.BeginVertical("box"); EditorGUILayout.LabelField("Bay Design Order:"); var scrollbarHStyle = new GUIStyle(GUI.skin.horizontalScrollbar); var scrollbarBackStyle = new GUIStyle(); var scrollbarVStyle = new GUIStyle(GUI.skin.verticalScrollbar); scrollbarVStyle.fixedHeight = scrollbarVStyle.fixedWidth = 0; bayDesignPatternScrollView = EditorGUILayout.BeginScrollView(bayDesignPatternScrollView, false, false, scrollbarHStyle, scrollbarVStyle, scrollbarBackStyle, GUILayout.Height(40)); List <string> bayNames = new List <string>(); foreach (int bayIndex in bFacade.bayPattern) { bayNames.Add(data.bays[bayIndex].name); } selectedBayPatternIndex = GUILayout.Toolbar(selectedBayPatternIndex, bayNames.ToArray()); EditorGUILayout.EndScrollView(); BuildrBay bBay = data.bays[bFacade.bayPattern[selectedBayPatternIndex]]; EditorGUILayout.BeginHorizontal(); EditorGUI.BeginDisabledGroup(selectedBayPatternIndex == 0); if (GUILayout.Button("<<", GUILayout.Width(40))) { int bayDesignIndex = bFacade.bayPattern[selectedBayPatternIndex]; bFacade.bayPattern.RemoveAt(selectedBayPatternIndex); bFacade.bayPattern.Insert(selectedBayPatternIndex - 1, bayDesignIndex); selectedBayPatternIndex--; GUI.changed = true; } EditorGUI.EndDisabledGroup(); if (GUILayout.Button("Remove")) { bFacade.bayPattern.RemoveAt(selectedBayPatternIndex); GUI.changed = true; } if (GUILayout.Button("Delete")) { if (EditorUtility.DisplayDialog("Deleting Bay Design Entry", "Are you sure you want to delete this bay?", "Delete", "Cancel")) { int deletedBayDesignIndex = bFacade.bayPattern[selectedBayPatternIndex]; Debug.Log("Delete Bay Design " + deletedBayDesignIndex); Debug.Log("Delete Bay Design " + data.bays[deletedBayDesignIndex].name); data.bays.RemoveAt(deletedBayDesignIndex); int numberOfFacadeDesigns = data.facades.Count; for (int i = 0; i < numberOfFacadeDesigns; i++) { BuildrFacadeDesign checkFacade = data.facades[i]; int bayPatternSize = checkFacade.bayPattern.Count; for (int j = 0; j < bayPatternSize; j++) { if (checkFacade.bayPattern[j] == deletedBayDesignIndex) { checkFacade.bayPattern.RemoveAt(j); j--; bayPatternSize--; } else if (checkFacade.bayPattern[j] > deletedBayDesignIndex) { checkFacade.bayPattern[j]--; } } } GUI.changed = true; } } EditorGUI.BeginDisabledGroup(selectedBayPatternIndex == numberOfBays - 1); if (GUILayout.Button(">>", GUILayout.Width(40))) { int bayDesignIndex = bFacade.bayPattern[selectedBayPatternIndex]; bFacade.bayPattern.Insert(selectedBayPatternIndex + 2, bayDesignIndex); bFacade.bayPattern.RemoveAt(selectedBayPatternIndex); selectedBayPatternIndex++; GUI.changed = true; } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); GUILayout.Space(10); EditorGUILayout.BeginVertical("box"); bBay.name = EditorGUILayout.TextField("Name: ", bBay.name); bool bBayisOpening = EditorGUILayout.Toggle("Has Opening", bBay.isOpening); if (bBayisOpening != bBay.isOpening) { bBay.isOpening = bBayisOpening; } bool bBayRenderBack = EditorGUILayout.Toggle("Render Back", bBay.renderBack); if (bBayRenderBack != bBay.renderBack) { bBay.renderBack = bBayRenderBack; } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Bay Model", GUILayout.Width(146)); bBay.bayModel = (GameObject)EditorGUILayout.ObjectField(bBay.bayModel, typeof(GameObject), false); if (GUILayout.Button("Clear", GUILayout.Width(70))) { bBay.bayModel = null; } EditorGUILayout.EndHorizontal(); float bBayopeningWidth = Mathf.Max(EditorGUILayout.FloatField("Opening Width", bBay.openingWidth), 0); if (bBayopeningWidth != bBay.openingWidth) { bBay.openingWidth = bBayopeningWidth; } float bBayopeningHeight = Mathf.Clamp(EditorGUILayout.FloatField("Opening Height", bBay.openingHeight), 0, data.floorHeight); if (bBayopeningHeight != bBay.openingHeight) { bBay.openingHeight = bBayopeningHeight; } float bBayminimumBayWidth = Mathf.Max(EditorGUILayout.FloatField("Bay Spacing Width", bBay.minimumBayWidth), 0); if (bBayminimumBayWidth != bBay.minimumBayWidth) { bBay.minimumBayWidth = bBayminimumBayWidth; } float bBayopeningWidthRatio = EditorGUILayout.Slider("Horizontal Space Ratio", bBay.openingWidthRatio, 0, 1); if (bBayopeningWidthRatio != bBay.openingWidthRatio) { bBay.openingWidthRatio = bBayopeningWidthRatio; } float bBayopeningHeightRatio = EditorGUILayout.Slider("Vertical Space Ratio", bBay.openingHeightRatio, 0, 1); if (bBayopeningHeightRatio != bBay.openingHeightRatio) { bBay.openingHeightRatio = bBayopeningHeightRatio; } float bBayopeningDepth = EditorGUILayout.Slider("Opening Depth", bBay.openingDepth, -depth, depth); if (bBayopeningDepth != bBay.openingDepth) { bBay.openingDepth = bBayopeningDepth; } float bBaycolumnDepth = EditorGUILayout.Slider("Column depth", bBay.columnDepth, -depth, depth); if (bBaycolumnDepth != bBay.columnDepth) { bBay.columnDepth = bBaycolumnDepth; } float bBayrowDepth = EditorGUILayout.Slider("Row depth", bBay.rowDepth, -depth, depth); if (bBayrowDepth != bBay.rowDepth) { bBay.rowDepth = bBayrowDepth; } float bBaycrossDepth = EditorGUILayout.Slider("Cross depth", bBay.crossDepth, -depth, depth); if (bBaycrossDepth != bBay.crossDepth) { bBay.crossDepth = bBaycrossDepth; } //BAY TEXTURES int numberOfTextureSlots = bBay.numberOfTextures; string[] titles = new string[numberOfTextureSlots]; for (int bft = 0; bft < numberOfTextureSlots; bft++) { titles[bft] = ((BuildrBay.TextureNames)(bft)).ToString(); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Surface:", GUILayout.Width(75)); editTextureOnFacade = EditorGUILayout.Popup(editTextureOnFacade, titles); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Texture:", GUILayout.Width(75)); bBay.textureValues[editTextureOnFacade] = EditorGUILayout.Popup(bBay.textureValues[editTextureOnFacade], textureNames); EditorGUILayout.EndHorizontal(); BuildrTexture bTexture = data.textures[bBay.textureValues[editTextureOnFacade]]; Texture2D texture = bTexture.texture; EditorGUILayout.BeginHorizontal(); if (texture != null) { GUILayout.Label(texture, GUILayout.Width(100), GUILayout.Height(100)); } else { EditorGUILayout.HelpBox("No texture assigned for '" + textureNames[bBay.textureValues[editTextureOnFacade]] + "', assign one in the Textures menu above", MessageType.Warning); } bFacade.flipValues[editTextureOnFacade] = EditorGUILayout.Toggle("Flip 90\u00B0", bFacade.flipValues[editTextureOnFacade]); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); } } else { editTextureOnFacade = 7; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Surface:", GUILayout.Width(75)); EditorGUILayout.LabelField("Wall"); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Texture:", GUILayout.Width(75)); int newFacadeTexture = EditorGUILayout.Popup(bFacade.simpleBay.textureValues[editTextureOnFacade], textureNames); if (newFacadeTexture != bFacade.simpleBay.textureValues[editTextureOnFacade]) { bFacade.simpleBay.textureValues[editTextureOnFacade] = newFacadeTexture; } EditorGUILayout.EndHorizontal(); BuildrTexture bTexture = data.textures[bFacade.simpleBay.textureValues[editTextureOnFacade]]; Texture2D texture = bTexture.texture; EditorGUILayout.BeginHorizontal(); if (texture != null) { GUILayout.Label(texture, GUILayout.Width(100), GUILayout.Height(100)); } else { EditorGUILayout.HelpBox("No texture assigned for '" + textureNames[bFacade.simpleBay.textureValues[editTextureOnFacade]] + "', assign one in the Textures menu above", MessageType.Warning); } bFacade.simpleBay.flipValues[editTextureOnFacade] = EditorGUILayout.Toggle("Flip 90\u00B0", bFacade.simpleBay.flipValues[editTextureOnFacade]); EditorGUILayout.EndHorizontal(); } }
public static void InspectorGUI(BuildrEditMode _editMode, BuildrData _data) { data = _data; BuildrTexture[] textures = data.textures.ToArray(); int numberOfTextures = textures.Length; selectedTexture = Mathf.Clamp(selectedTexture, 0, numberOfTextures - 1); int currentSelectedTexture = selectedTexture;//keep tack of what we had selected to reset fields if changed Undo.RecordObject(data, "Texture Modified"); if(numberOfTextures == 0) { EditorGUILayout.HelpBox("There are no textures to show", MessageType.Info); if(GUILayout.Button("Add New")) { data.textures.Add(new BuildrTexture("new texture " + numberOfTextures)); numberOfTextures++; selectedTexture = numberOfTextures - 1; } return; } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Texture", GUILayout.Width(75)); string[] textureNames = new string[numberOfTextures]; for(int t = 0; t < numberOfTextures; t++) textureNames[t] = textures[t].name; selectedTexture = EditorGUILayout.Popup(selectedTexture, textureNames); EditorGUILayout.EndHorizontal(); BuildrTexture bTexture = textures[selectedTexture]; EditorGUILayout.BeginHorizontal(); EditorGUILayout.Space(); if(GUILayout.Button("Add New", GUILayout.Width(81))) { data.textures.Add(new BuildrTexture("new texture " + numberOfTextures)); numberOfTextures++; selectedTexture = numberOfTextures - 1; } if(GUILayout.Button("Duplicate", GUILayout.Width(90))) { data.textures.Add(bTexture.Duplicate()); numberOfTextures++; selectedTexture = numberOfTextures - 1; } if(GUILayout.Button("Delete", GUILayout.Width(71))) { if(EditorUtility.DisplayDialog("Deleting Texture Entry", "Are you sure you want to delete this texture?", "Delete", "Cancel")) { data.RemoveTexture(bTexture); selectedTexture = 0; GUI.changed = true; return; } } if (GUILayout.Button("Import", GUILayout.Width(71))) { string xmlPath = EditorUtility.OpenFilePanel("Select the XML file...", "Assets/BuildR/Exported/", "xml"); if (xmlPath == "") return; BuildrXMLImporter.ImportTextures(xmlPath, _data); textures = data.textures.ToArray(); selectedTexture = 0; GUI.changed = true; } if (GUILayout.Button("Export", GUILayout.Width(71))) { string xmlPath = EditorUtility.SaveFilePanel("Export as...", "Assets/BuildR/Exported/", _data.name + "_textureLibrary", "xml"); if (xmlPath == "") return; BuildrXMLExporter.ExportTextures(xmlPath, _data); GUI.changed = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); textures = data.textures.ToArray(); textureNames = new string[numberOfTextures]; for(int t = 0; t < numberOfTextures; t++) textureNames[t] = textures[t].name; bTexture = textures[selectedTexture];//reassign string textureName = bTexture.name; GUIStyle redText = new GUIStyle(GUI.skin.textField); if(textureName.Contains(" ")) { redText.focused.textColor = Color.red; textureName = EditorGUILayout.TextField("Name", textureName, redText); } else { redText.focused.textColor = defaultCol; textureName = EditorGUILayout.TextField("Name", textureName, redText); } bTexture.name = textureName; bool conflictingName = false; for(int i = 0; i < textureNames.Length; i++) { if(selectedTexture != i) { if(textureNames[i] == bTexture.name) conflictingName = true; } } if(conflictingName) EditorGUILayout.HelpBox("You have named this texture the same as another.", MessageType.Warning); if(currentSelectedTexture != selectedTexture) { GUIUtility.hotControl = 0; GUIUtility.keyboardControl = 0; } bTexture.type = (BuildrTexture.Types)EditorGUILayout.EnumPopup("Type", bTexture.type); switch(bTexture.type) { case BuildrTexture.Types.Basic: if(bTexture.texture != null) { string texturePath = AssetDatabase.GetAssetPath(bTexture.texture); TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(texturePath); if(!textureImporter.isReadable) { EditorGUILayout.HelpBox("The texture you have selected is not readable." + "\nPlease select the readable checkbox under advanced texture settings." + "\nOr move this texture to the BuildR texture folder and reimport.", MessageType.Error); } } //Shader Time Shader[] tempshaders = (Shader[])Resources.FindObjectsOfTypeAll(typeof(Shader)); List<string> shaderNames = new List<string>(ShaderProperties.NAMES); foreach(Shader shader in tempshaders) { if(!string.IsNullOrEmpty(shader.name) && !shader.name.StartsWith("__") && !shader.name.Contains("hidden")) shaderNames.Add(shader.name); } int selectedShaderIndex = shaderNames.IndexOf(bTexture.material.shader.name); int newSelectedShaderIndex = EditorGUILayout.Popup("Shader", selectedShaderIndex, shaderNames.ToArray()); if(selectedShaderIndex != newSelectedShaderIndex) { bTexture.material.shader = Shader.Find(shaderNames[newSelectedShaderIndex]); } Shader selectedShader = bTexture.material.shader; int propertyCount = ShaderUtil.GetPropertyCount(selectedShader); for(int s = 0; s < propertyCount; s++) { ShaderUtil.ShaderPropertyType propertyTpe = ShaderUtil.GetPropertyType(selectedShader, s); string shaderPropertyName = ShaderUtil.GetPropertyName(selectedShader, s); switch(propertyTpe) { case ShaderUtil.ShaderPropertyType.TexEnv: Texture shaderTexture = bTexture.material.GetTexture(shaderPropertyName); Texture newShaderTexture = (Texture)EditorGUILayout.ObjectField(shaderPropertyName, shaderTexture, typeof(Texture), false); if(shaderTexture != newShaderTexture) { bTexture.material.SetTexture(shaderPropertyName, newShaderTexture); } break; case ShaderUtil.ShaderPropertyType.Color: Color shaderColor = bTexture.material.GetColor(shaderPropertyName); Color newShaderColor = EditorGUILayout.ColorField(shaderPropertyName, shaderColor); if(shaderColor != newShaderColor) { bTexture.material.SetColor(shaderPropertyName, newShaderColor); } break; case ShaderUtil.ShaderPropertyType.Float: float shaderFloat = bTexture.material.GetFloat(shaderPropertyName); float newShaderFloat = EditorGUILayout.FloatField(shaderPropertyName, shaderFloat); if(shaderFloat != newShaderFloat) { bTexture.material.SetFloat(shaderPropertyName, newShaderFloat); } break; case ShaderUtil.ShaderPropertyType.Range: float shaderRange = bTexture.material.GetFloat(shaderPropertyName); float rangeMin = ShaderUtil.GetRangeLimits(selectedShader, s, 1); float rangeMax = ShaderUtil.GetRangeLimits(selectedShader, s, 2); float newShaderRange = EditorGUILayout.Slider(shaderPropertyName, shaderRange, rangeMin, rangeMax); if(shaderRange != newShaderRange) { bTexture.material.SetFloat(shaderPropertyName, newShaderRange); } break; case ShaderUtil.ShaderPropertyType.Vector: Vector3 shaderVector = bTexture.material.GetVector(shaderPropertyName); Vector3 newShaderVector = EditorGUILayout.Vector3Field(shaderPropertyName, shaderVector); if(shaderVector != newShaderVector) { bTexture.material.SetVector(shaderPropertyName, newShaderVector); } break; } } bool tiled = EditorGUILayout.Toggle("Is Tiled", bTexture.tiled); if(tiled != bTexture.tiled) { bTexture.tiled = tiled; } if(bTexture.tiled) { bool patterned = EditorGUILayout.Toggle("Has Pattern", bTexture.patterned); if(patterned != bTexture.patterned) { bTexture.patterned = patterned; } } else bTexture.patterned = false; if(bTexture.texture == null) return; Vector2 textureUnitSize = bTexture.textureUnitSize; if(bTexture.tiled) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("texture width", GUILayout.Width(75));//, GUILayout.Width(42)); textureUnitSize.x = EditorGUILayout.FloatField(bTexture.textureUnitSize.x, GUILayout.Width(25)); EditorGUILayout.LabelField("metres", GUILayout.Width(40));//, GUILayout.Width(42)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("texture height", GUILayout.Width(75));//, GUILayout.Width(42)); textureUnitSize.y = EditorGUILayout.FloatField(bTexture.textureUnitSize.y, GUILayout.Width(25)); EditorGUILayout.LabelField("metres", GUILayout.Width(40)); EditorGUILayout.EndHorizontal(); if(bTexture.textureUnitSize != textureUnitSize) { bTexture.textureUnitSize = textureUnitSize; } } Vector2 tileUnitSize = bTexture.tileUnitUV; if(bTexture.patterned) { float minWidth = 2 / bTexture.texture.width; float minHeight = 2 / bTexture.texture.height; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("unit width", GUILayout.Width(75)); float tileUnitSizex = EditorGUILayout.Slider(tileUnitSize.x, minWidth, 1.0f); if(tileUnitSizex != tileUnitSize.x) { tileUnitSize.x = tileUnitSizex; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("unit height", GUILayout.Width(75)); float tileUnitSizey = EditorGUILayout.Slider(tileUnitSize.y, minHeight, 1.0f); if(tileUnitSizey != tileUnitSize.y) { tileUnitSize.y = tileUnitSizey; } EditorGUILayout.EndHorizontal(); bTexture.tileUnitUV = tileUnitSize; EditorGUILayout.Space(); } const int previewTextureUnitSize = 120; const int previewTileUnitSize = 59; const int previewTileUnitPadding = 2; const int previewPadding = 25; EditorGUILayout.BeginHorizontal(); if(bTexture.tiled) { EditorGUILayout.LabelField("1 Metre Squared", GUILayout.Width(previewTextureUnitSize)); } GUILayout.Space(previewPadding); if(bTexture.patterned) { EditorGUILayout.LabelField("Texture Pattern Units", GUILayout.Width(previewTileUnitSize * 2)); } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); if(Event.current.type == EventType.Repaint) texturePreviewPostion = GUILayoutUtility.GetLastRect(); if(bTexture.tiled) { Rect previewRect = new Rect(texturePreviewPostion.x, texturePreviewPostion.y, previewTextureUnitSize, previewTextureUnitSize); Rect sourceRect = new Rect(0, 0, (1.0f / textureUnitSize.x), (1.0f / textureUnitSize.y)); Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0); } if(bTexture.patterned) { Rect previewRect = new Rect(previewTextureUnitSize + previewPadding, 0, previewTileUnitSize, previewTileUnitSize); Rect sourceRect = new Rect(0, tileUnitSize.y, tileUnitSize.x, tileUnitSize.y); previewRect.x += texturePreviewPostion.x; previewRect.y += texturePreviewPostion.y; Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0); sourceRect.x += tileUnitSize.x; previewRect.x += previewTileUnitSize + previewTileUnitPadding; Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0); sourceRect.x += -tileUnitSize.x; sourceRect.y += -tileUnitSize.y; previewRect.x += -(previewTileUnitSize + previewTileUnitPadding); previewRect.y += previewTileUnitSize + previewTileUnitPadding; Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0); sourceRect.x += tileUnitSize.x; previewRect.x += previewTileUnitSize + previewTileUnitPadding; Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0); } if(!bTexture.tiled) { EditorGUILayout.LabelField("Tile texture"); EditorGUILayout.BeginHorizontal(); int currentXTiles = bTexture.tiledX; GUILayout.Label("tile x", GUILayout.Width(38)); currentXTiles = EditorGUILayout.IntField(currentXTiles, GUILayout.Width(20)); if(GUILayout.Button("+", GUILayout.Width(25))) { currentXTiles++; } EditorGUI.BeginDisabledGroup(currentXTiles < 2); if(GUILayout.Button("-", GUILayout.Width(25))) { currentXTiles--; } EditorGUI.EndDisabledGroup(); bTexture.tiledX = currentXTiles; int currentYTiles = bTexture.tiledY; GUILayout.Label("tile y", GUILayout.Width(38)); currentYTiles = EditorGUILayout.IntField(currentYTiles, GUILayout.Width(20)); if(GUILayout.Button("+", GUILayout.Width(25))) { currentYTiles++; } EditorGUI.BeginDisabledGroup(currentYTiles < 2); if(GUILayout.Button("-", GUILayout.Width(25))) { currentYTiles--; } EditorGUI.EndDisabledGroup(); bTexture.tiledY = currentYTiles; EditorGUILayout.EndHorizontal(); GUILayout.Space(10); EditorGUILayout.Space(); if(Event.current.type == EventType.Repaint) texturePreviewPostion = GUILayoutUtility.GetLastRect(); Rect previewRect = new Rect(texturePreviewPostion.x, texturePreviewPostion.y, previewTextureUnitSize, previewTextureUnitSize); Rect sourceRect = new Rect(0, 0, currentXTiles, currentYTiles); Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0); } GUILayout.Space(previewTextureUnitSize); break; case BuildrTexture.Types.Substance: bTexture.proceduralMaterial = (ProceduralMaterial)EditorGUILayout.ObjectField("Procedural Material", bTexture.proceduralMaterial, typeof(ProceduralMaterial), false); if(bTexture.proceduralMaterial != null) { ProceduralMaterial pMat = bTexture.proceduralMaterial; GUILayout.Label(pMat.GetGeneratedTexture(pMat.mainTexture.name), GUILayout.Width(400)); } else { EditorGUILayout.HelpBox("There is no substance material set.", MessageType.Error); } break; case BuildrTexture.Types.User: bTexture.userMaterial = (Material)EditorGUILayout.ObjectField("User Material", bTexture.userMaterial, typeof(Material), false); if (bTexture.userMaterial != null) { Material mat = bTexture.userMaterial; GUILayout.Label(mat.mainTexture, GUILayout.Width(400)); } else EditorGUILayout.HelpBox("There is no substance material set.", MessageType.Error); break; } }
public static void InspectorGUI(BuildrEditMode editMode, BuildrData data) { if (data.plan==null || data.plan.numberOfVolumes == 0) { EditorGUILayout.HelpBox("There are no defined volumes, go to Floorplan and define one", MessageType.Error); return; } const int guiWidth = 400; const int textWidth = 348; const int toggleWidth = 25; const int helpWidth = 20; CURRENT_TRANSFORM = editMode.transform; EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Filename", GUILayout.Width(225)); data.exportFilename = EditorGUILayout.TextField(data.exportFilename, GUILayout.Width(175)); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Filetype", GUILayout.Width(350)); data.filetype = (BuildrData.filetypes)EditorGUILayout.EnumPopup(data.filetype, GUILayout.Width(50)); switch (data.filetype) { case BuildrData.filetypes.obj: FILE_EXTENTION = ".obj"; break; case BuildrData.filetypes.fbx: FILE_EXTENTION = ".fbx"; break; } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Export Full Mesh", GUILayout.Width(textWidth)); data.fullmesh = EditorGUILayout.Toggle(data.fullmesh, GUILayout.Width(toggleWidth)); if (GUILayout.Button("?", GUILayout.Width(helpWidth))) { string helpTitle = "Help - Export Full Mesh"; string helpBody = "Select this checkbox if you want your export the full detail model."; EditorUtility.DisplayDialog(helpTitle, helpBody, "close"); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Place Exported Model Into Scene", GUILayout.Width(textWidth)); data.placeIntoScene = EditorGUILayout.Toggle(data.placeIntoScene, GUILayout.Width(toggleWidth)); if (GUILayout.Button("?", GUILayout.Width(helpWidth))) { string helpTitle = "Help - Place Exported Model Into Scene"; string helpBody = "Select this checkbox if you want your exported models to be copied into your scene." + "\nThese will be positioned correctly and will include colliders and LOD models if you opt to export them also."; EditorUtility.DisplayDialog(helpTitle, helpBody, "close"); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Copy Textures into Export Folder", GUILayout.Width(textWidth)); data.copyTexturesIntoExportFolder = EditorGUILayout.Toggle(data.copyTexturesIntoExportFolder, GUILayout.Width(toggleWidth)); if (GUILayout.Button("?", GUILayout.Width(helpWidth))) { string helpTitle = "Help - Copy Textures into Export Folder"; string helpBody = "Check this box if you want to copy the textures you are using into the export folder." + "\nThis is useful if you plan to use the exported model elsewhere. Having the model and the textures in one folder will allow you to move this model with ease."; EditorUtility.DisplayDialog(helpTitle, helpBody, "close"); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Export Collider"); data.generateCollider = (BuildrData.ColliderGenerationModes)EditorGUILayout.EnumPopup(data.generateCollider, GUILayout.Width(80)); if (GUILayout.Button("?", GUILayout.Width(helpWidth))) { string helpTitle = "Help - Export Collider Mesh"; string helpBody = "Check this box if you wish to generate a collider mesh for your model." + "\nThis will generate a mesh to be used with colliders."; EditorUtility.DisplayDialog(helpTitle, helpBody, "close"); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Export as Prefab", GUILayout.Width(textWidth)); data.createPrefabOnExport = EditorGUILayout.Toggle(data.createPrefabOnExport, GUILayout.Width(toggleWidth)); if (GUILayout.Button("?", GUILayout.Width(helpWidth))) { string helpTitle = "Help - Export as Prefab"; string helpBody = "Select this if you wish to create a prefab of your model." + "\nThis is recommended if you're exporting a collider so they will get packaged together."; EditorUtility.DisplayDialog(helpTitle, helpBody, "close"); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Export a Low Detail Version", GUILayout.Width(textWidth)); data.exportLowLOD = EditorGUILayout.Toggle(data.exportLowLOD, GUILayout.Width(toggleWidth)); if (GUILayout.Button("?", GUILayout.Width(helpWidth))) { string helpTitle = "Help - Export a Low Detail Version"; string helpBody = "Check this box to export a simplified model of your building." + "\nIdeal to use as a low level of detail version of your model." + "\nGeometry will be significantly reduced." + "\nFacades will flat and exported as a single atlased texture" + "\nThe model will use 1 draw call and will have around 10% of the triangles and verticies"; EditorUtility.DisplayDialog(helpTitle, helpBody, "close"); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Export with tangents", GUILayout.Width(textWidth)); data.includeTangents = EditorGUILayout.Toggle(data.includeTangents, GUILayout.Width(toggleWidth)); if (GUILayout.Button("?", GUILayout.Width(helpWidth))) { string helpTitle = "Help - with tangents"; string helpBody = "Export the models with calculated tangents." + "\nSome shaders require tangents to be calculated on the model." + "\nUnity will do this automatically on all imported meshes so it's not neccessary here." + "/nBut you might want them if you're taking them to another program."; EditorUtility.DisplayDialog(helpTitle, helpBody, "close"); } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); bool unreadableTextures = false; bool nullTextures = false; string unreadableTextureList = ""; foreach (BuildrTexture bTexture in data.textures)//check texture readablility { if(bTexture.type == BuildrTexture.Types.Substance) continue;//substances are preset in BuildrTexture class if (bTexture.texture != null) { string texturePath = AssetDatabase.GetAssetPath(bTexture.texture); TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(texturePath); if (!textureImporter.isReadable) { unreadableTextures = true; if (unreadableTextureList.Length > 0) unreadableTextureList += ", "; unreadableTextureList += "'" + bTexture.name + "'"; } } else { nullTextures = true; } } if (unreadableTextures) { EditorGUILayout.HelpBox("Unreadable Texture Error." + "\nThe following textures you are useing are not readable." + "\n" + unreadableTextureList + "." + "\nPlease select the readable checkbox under advanced texture settings." + "\nOr move this texture to the BuildR texture folder and reimport.", MessageType.Error); } if (nullTextures) { EditorGUILayout.HelpBox("Null Texture Error" + "\nSome of the textures have not been set" + "\nEnsure you are not using null textures to proceed.", MessageType.Error); } bool usingSubstances = false; foreach(BuildrTexture bTexture in data.textures) { if(bTexture.type == BuildrTexture.Types.Substance) { usingSubstances = true; break; } } if (usingSubstances) { EditorGUILayout.HelpBox("Model uses Substance textures." + "\nExporting model to " + data.filetype + " will lose references to this texture and it will be rendered white.", MessageType.Warning); } EditorGUI.BeginDisabledGroup(unreadableTextures || nullTextures); if (GUILayout.Button("Export", GUILayout.Width(guiWidth), GUILayout.Height(40))) { ExportModel(data); } if (GUILayout.Button("Export Data to XML", GUILayout.Width(guiWidth))) { BuildrXMLExporter.Export(ROOT_FOLDER + data.exportFilename + "/", data.exportFilename, data); AssetDatabase.Refresh(); } EditorGUI.EndDisabledGroup(); CURRENT_TRANSFORM = null; }
public static void SceneGUI(BuildrEditMode editMode, BuildrData data, bool shouldSnap, float handleSize) { if (data.details.Count == 0) return; Undo.RecordObject(data, "Detail Modified"); int numberOfFacades = data.facades.Count; int numberOfRoofs = data.roofs.Count; int numberOfTextures = data.textures.Count; if (numberOfFacades == 0 || numberOfRoofs == 0 || numberOfTextures == 0) return; Vector3 position = editMode.transform.position; BuildrPlan plan = data.plan; int numberOfVolumes = plan.numberOfVolumes; BuildrDetail bDetail = data.details[selectedDetail]; float volumeHeight = 0; Vector3 baseLeft = Vector3.zero; Vector3 baseRight = Vector3.zero; int faceIndex = bDetail.face; int facadeCounter = 0; for (int v = 0; v < numberOfVolumes; v++) { BuildrVolume volume = data.plan.volumes[v]; int volumeSize = volume.Count; Vector3 floorCentre = Vector3.zero; Handles.color = Color.white; for (int p = 0; p < volumeSize; p++) { int point = volume.points[p]; int indexB = volume.points[(p + 1) % volumeSize]; Vector3 fb0 = plan.points[point].vector3; Vector3 fb1 = plan.points[indexB].vector3; if (bDetail.face == facadeCounter && bDetail.type == BuildrDetail.Types.Facade) { baseLeft = fb0; baseRight = fb1; } floorCentre += baseLeft; List<Vector3> verts = new List<Vector3>(); volumeHeight = (volume.numberOfFloors * data.floorHeight); Vector3 volumeHeightVector = Vector3.up * volumeHeight; verts.Add(fb0 + position); verts.Add(fb1 + position); verts.Add(verts[1] + volumeHeightVector); verts.Add(verts[0] + volumeHeightVector); if (bDetail.face == facadeCounter && bDetail.type == BuildrDetail.Types.Facade) //display something to highlight this facade Handles.DrawSolidRectangleWithOutline(verts.ToArray(), Color.clear, BuildrColours.MAGENTA); Handles.color = BuildrColours.CYAN; if (v == bDetail.face && bDetail.type == BuildrDetail.Types.Roof) Handles.DrawLine(verts[2], verts[3]); if (editMode.showFacadeMarkers) { Handles.color = Color.white; Vector3 camDirection = Camera.current.transform.forward; Vector3 facadeDirection = Vector3.Cross((verts[0] - verts[1]), Vector3.up); GUIStyle facadeLabelStyle = new GUIStyle(); facadeLabelStyle.normal.textColor = Color.white; facadeLabelStyle.alignment = TextAnchor.MiddleCenter; facadeLabelStyle.fixedWidth = 75.0f; if (Vector3.Dot(camDirection, facadeDirection) < 0)//only display label when facade is facing camera { Vector3 centerPos = (verts[0] + verts[1]) * 0.5f; Vector3 labelPos = centerPos + facadeDirection.normalized; Handles.Label(labelPos, "facade " + facadeCounter, facadeLabelStyle); Handles.DrawLine(centerPos, labelPos); } } facadeCounter++; } } Vector3 handlePosition = bDetail.worldPosition + position;// new Vector3(basePos.x, volumeHeight * bDetail.faceUv.y, basePos.z); Vector3 baseDir = (baseRight - baseLeft).normalized; Vector3 baseCross = Vector3.Cross(Vector3.up, baseDir); Quaternion currentRot = Quaternion.Euler(bDetail.userRotation); Quaternion faceRotation = (bDetail.type == BuildrDetail.Types.Facade) ? Quaternion.LookRotation(baseCross) : Quaternion.identity; switch (Tools.current) { case Tool.Move: Vector3 dirX, dirY, dirZ; if (bDetail.type == BuildrDetail.Types.Facade) { dirX = baseDir; dirY = baseCross; dirZ = Vector3.up; } else { dirX = Vector3.right; dirY = Vector3.up; dirZ = Vector3.forward; } Vector3 newSliderPos; Handles.color = BuildrColours.RED; newSliderPos = Handles.Slider(handlePosition, dirX, handleSize * 0.666f, Handles.ArrowCap, 0.0f); Handles.color = BuildrColours.BLUE; newSliderPos = Handles.Slider(newSliderPos, dirZ, handleSize * 0.666f, Handles.ArrowCap, 0.0f); Handles.color = BuildrColours.GREEN; newSliderPos = Handles.Slider(newSliderPos, dirY, handleSize * 0.666f, Handles.ArrowCap, 0.0f); Vector3 sliderDiff = newSliderPos - handlePosition; if (sliderDiff != Vector3.zero) { float newXUV = 0, newYUV = 0, newHeight = bDetail.faceHeight; if (bDetail.type == BuildrDetail.Types.Facade) { float facadeWidth = Vector3.Distance(baseLeft, baseRight); float sliderDiffX = Mathf.Sqrt(sliderDiff.x * sliderDiff.x + sliderDiff.z * sliderDiff.z) * Mathf.Sign(Vector3.Dot(baseDir, sliderDiff)); newXUV = sliderDiffX / facadeWidth + bDetail.faceUv.x; newYUV = sliderDiff.y / volumeHeight + bDetail.faceUv.y; } else { BuildrVolume volume = plan.volumes[faceIndex]; int numberOfVolumePoints = volume.points.Count; Vector3 minPoint = plan.points[volume.points[0]].vector3; Vector3 maxPoint = plan.points[volume.points[0]].vector3; for (int p = 1; p < numberOfVolumePoints; p++) { Vector3 fp0 = plan.points[volume.points[p]].vector3; if (fp0.x < minPoint.x) minPoint.x = fp0.x; if (fp0.z < minPoint.z) minPoint.z = fp0.z; if (fp0.x > maxPoint.x) maxPoint.x = fp0.x; if (fp0.z > maxPoint.z) maxPoint.z = fp0.z; } float roofWidth = maxPoint.x - minPoint.x; float roofDepth = maxPoint.z - minPoint.z; newXUV = sliderDiff.x / roofWidth + bDetail.faceUv.x; newYUV = sliderDiff.z / roofDepth + bDetail.faceUv.y; newHeight += sliderDiff.y; } bDetail.faceUv = new Vector2(newXUV, newYUV); bDetail.faceHeight = newHeight; } break; case Tool.Rotate: currentRot = Handles.RotationHandle(currentRot, handlePosition); bDetail.userRotation = currentRot.eulerAngles; break; case Tool.Scale: bDetail.scale = Handles.ScaleHandle(bDetail.scale, handlePosition, currentRot * faceRotation, handleSize * 0.666f); break; } //draw mesh bounds if (bDetail.mesh != null) { Bounds meshBounds = bDetail.mesh.bounds; Quaternion rotation = bDetail.worldRotation; Vector3 p0 = rotation * (new Vector3(meshBounds.min.x, meshBounds.min.y, meshBounds.min.z)) + bDetail.worldPosition; Vector3 p1 = rotation * (new Vector3(meshBounds.max.x, meshBounds.min.y, meshBounds.min.z)) + bDetail.worldPosition; Vector3 p2 = rotation * (new Vector3(meshBounds.min.x, meshBounds.min.y, meshBounds.max.z)) + bDetail.worldPosition; Vector3 p3 = rotation * (new Vector3(meshBounds.max.x, meshBounds.min.y, meshBounds.max.z)) + bDetail.worldPosition; Vector3 p4 = rotation * (new Vector3(meshBounds.min.x, meshBounds.max.y, meshBounds.min.z)) + bDetail.worldPosition; Vector3 p5 = rotation * (new Vector3(meshBounds.max.x, meshBounds.max.y, meshBounds.min.z)) + bDetail.worldPosition; Vector3 p6 = rotation * (new Vector3(meshBounds.min.x, meshBounds.max.y, meshBounds.max.z)) + bDetail.worldPosition; Vector3 p7 = rotation * (new Vector3(meshBounds.max.x, meshBounds.max.y, meshBounds.max.z)) + bDetail.worldPosition; Handles.color = BuildrColours.BLUE; Handles.DrawLine(p0, p1); Handles.DrawLine(p0, p2); Handles.DrawLine(p1, p3); Handles.DrawLine(p2, p3); Handles.DrawLine(p0, p4); Handles.DrawLine(p1, p5); Handles.DrawLine(p2, p6); Handles.DrawLine(p3, p7); Handles.DrawLine(p4, p5); Handles.DrawLine(p4, p6); Handles.DrawLine(p5, p7); Handles.DrawLine(p6, p7); if (clickPlace) { Vector3 planeBase = Vector3.zero; Vector3 planeNormal = Vector3.up; Vector3 planeSize = Vector3.zero; if (bDetail.type == BuildrDetail.Types.Facade) { //find facade int facadeCount = 0; bool facadeFound = false; for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = plan.volumes[s]; int numberOfVolumePoints = volume.points.Count; for (int p = 0; p < numberOfVolumePoints; p++) { if (facadeCount == faceIndex) { int indexA = p; int indexB = (p + 1) % numberOfVolumePoints; Vector3 fp0 = plan.points[volume.points[indexA]].vector3; Vector3 fp1 = plan.points[volume.points[indexB]].vector3; planeBase = fp0; planeNormal = Vector3.Cross(Vector3.up, fp1 - fp0).normalized; planeSize.x = Vector3.Distance(fp0, fp1); planeSize.y = volume.numberOfFloors * data.floorHeight; facadeFound = true; break; } facadeCount++; } if (facadeFound) break; } } else { BuildrVolume volume = plan.volumes[faceIndex]; int numberOfVolumePoints = volume.points.Count; Vector3 minPoint = plan.points[volume.points[0]].vector3; Vector3 maxPoint = plan.points[volume.points[0]].vector3; for (int p = 1; p < numberOfVolumePoints; p++) { Vector3 fp0 = plan.points[volume.points[p]].vector3; if (fp0.x < minPoint.x) minPoint.x = fp0.x; if (fp0.z < minPoint.z) minPoint.z = fp0.z; if (fp0.x > maxPoint.x) maxPoint.x = fp0.x; if (fp0.z > maxPoint.z) maxPoint.z = fp0.z; } planeSize.x = maxPoint.x - minPoint.x; planeSize.z = maxPoint.z - minPoint.z; planeBase = minPoint; planeBase.y = (data.floorHeight * volume.numberOfFloors); } float distance; Plane buildingPlane = new Plane(planeNormal, planeBase); Ray ray = Camera.current.ScreenPointToRay(new Vector3(Event.current.mousePosition.x, Screen.height - Event.current.mousePosition.y - 30, 0)); if (buildingPlane.Raycast(ray, out distance)) { Vector3 mousePlanePoint = ray.GetPoint(distance); Quaternion mouseLookDirection = Quaternion.LookRotation(buildingPlane.normal); if (Handles.Button(mousePlanePoint, mouseLookDirection, handleSize * 0.1f, handleSize * 0.1f, Handles.CircleCap)) { float xUv, yUv; if (bDetail.type == BuildrDetail.Types.Facade) { Vector3 facadeBaseMousePoint = new Vector3(mousePlanePoint.x, 0, mousePlanePoint.z); xUv = Vector3.Distance(planeBase, facadeBaseMousePoint) / planeSize.x; yUv = (mousePlanePoint.y - planeBase.y) / planeSize.y; } else { xUv = (mousePlanePoint.x - planeBase.x) / planeSize.x; yUv = (mousePlanePoint.z - planeBase.z) / planeSize.z; } bDetail.faceUv = new Vector2(xUv, yUv); clickPlace = false; GUI.changed = true; } } } } if (GUI.changed) { EditorUtility.SetDirty(editMode); EditorUtility.SetDirty(data); editMode.UpdateRender(); } }
public static void InspectorGUI(BuildrEditMode editMode, BuildrData data) { BuildrDetail[] details = data.details.ToArray(); int numberOfDetails = details.Length; selectedDetail = Mathf.Clamp(selectedDetail, 0, numberOfDetails - 1); if (numberOfDetails == 0) { EditorGUILayout.HelpBox("There are no details to show", MessageType.Info); if (GUILayout.Button("Add New")) { data.details.Add(new BuildrDetail("new detail " + numberOfDetails)); numberOfDetails++; selectedDetail = numberOfDetails - 1; } return; } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Detail", GUILayout.Width(75)); string[] detailNames = new string[numberOfDetails]; for (int t = 0; t < numberOfDetails; t++) detailNames[t] = details[t].name; selectedDetail = EditorGUILayout.Popup(selectedDetail, detailNames); EditorGUILayout.EndHorizontal(); BuildrDetail bDetail = details[selectedDetail]; EditorGUILayout.BeginHorizontal(); EditorGUILayout.Space(); if (GUILayout.Button("Add New", GUILayout.Width(81))) { data.details.Add(new BuildrDetail("new detail " + numberOfDetails)); numberOfDetails++; selectedDetail = numberOfDetails - 1; } if (GUILayout.Button("Duplicate", GUILayout.Width(90))) { data.details.Add(bDetail.Duplicate()); numberOfDetails++; selectedDetail = numberOfDetails - 1; } if (GUILayout.Button("Delete", GUILayout.Width(71))) { if (EditorUtility.DisplayDialog("Deleting Building Detail Entry", "Are you sure you want to delete this detail?", "Delete", "Cancel")) { data.details.Remove(bDetail); selectedDetail = 0; GUI.changed = true; return; } } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); details = data.details.ToArray(); detailNames = new string[numberOfDetails]; for (int t = 0; t < numberOfDetails; t++) detailNames[t] = details[t].name; bDetail = details[selectedDetail];//reassign EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginVertical(); bDetail.name = EditorGUILayout.TextField("Name", bDetail.name); bDetail.mesh = (Mesh)EditorGUILayout.ObjectField("Mesh", bDetail.mesh, typeof(Mesh), false); EditorGUIUtility.LookLikeControls(); bDetail.material.mainTexture = (Texture)EditorGUILayout.ObjectField("Texture", bDetail.material.mainTexture, typeof(Texture), false, GUILayout.Height(140)); if (bDetail.material.mainTexture != null) { string texturePath = AssetDatabase.GetAssetPath(bDetail.material.mainTexture); TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(texturePath); if (!textureImporter.isReadable) { EditorGUILayout.HelpBox("The texture you have selected is not readable." + "\nPlease select the readable checkbox under advanced texture settings." + "\nOr move this texture to the BuildR texture folder and reimport.", MessageType.Error); } } BuildrPlan plan = data.plan; int numberOfVolumes = plan.numberOfVolumes; int numberOfFaces = 0; List<int> faceSeletionsList = new List<int>(); List<string> faceSeletionsStringList = new List<string>(); if (bDetail.type == BuildrDetail.Types.Facade) { for (int s = 0; s < numberOfVolumes; s++) { int numberOfPoints = plan.volumes[s].Count; numberOfFaces += numberOfPoints; for (int p = 0; p < numberOfPoints; p++) { int index = faceSeletionsList.Count; faceSeletionsStringList.Add("facade " + index); faceSeletionsList.Add(index); } } } else { bDetail.face = Mathf.Clamp(0, numberOfVolumes - 1, bDetail.face); for (int s = 0; s < numberOfVolumes; s++) { int index = faceSeletionsList.Count; faceSeletionsStringList.Add("roof " + index); faceSeletionsList.Add(index); } } if (!clickPlace) { if (GUILayout.Button("Place Detail with Mouse")) { clickPlace = true; } } else { if (GUILayout.Button("Cancel Place Detail")) { clickPlace = false; } } BuildrDetail.Types bDetailtype = (BuildrDetail.Types)EditorGUILayout.EnumPopup("Face Type", bDetail.type); if(bDetailtype != bDetail.type) { bDetail.type = bDetailtype; } int[] faceSelections = faceSeletionsList.ToArray(); string[] faceSelectionString = faceSeletionsStringList.ToArray(); int bDetailface = EditorGUILayout.IntPopup("Selected Face", bDetail.face, faceSelectionString, faceSelections); if(bDetailface != bDetail.face) { bDetail.face = bDetailface; } Vector2 bDetailfaceUv = EditorGUILayout.Vector2Field("Face UV", bDetail.faceUv); if(bDetailfaceUv != bDetail.faceUv) { bDetail.faceUv = bDetailfaceUv; } float bDetailfaceHeight = EditorGUILayout.FloatField("Face Height", bDetail.faceHeight); if(bDetailfaceHeight != bDetail.faceHeight) { bDetail.faceHeight = bDetailfaceHeight; } Vector3 bDetailuserRotation = EditorGUILayout.Vector3Field("Rotation", bDetail.userRotation); if(bDetailuserRotation != bDetail.userRotation) { bDetail.userRotation = bDetailuserRotation; } Vector3 bDetailscale = EditorGUILayout.Vector3Field("Object Scale", bDetail.scale); if(bDetailscale != bDetail.scale) { bDetail.scale = bDetailscale; } EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(GUILayout.Width(120)); if (bDetail.mesh != null) { Texture2D previewMeshImage = AssetPreview.GetAssetPreview(bDetail.mesh); GUILayout.Label(previewMeshImage); } else { Texture2D previewMeshImage = new Texture2D(118, 118); GUILayout.Label(previewMeshImage); GUILayout.Label("No Mesh Selected"); } if (bDetail.material.mainTexture != null) { Texture previewMeshImage = bDetail.material.mainTexture; GUILayout.Label(previewMeshImage, GUILayout.Width(128), GUILayout.Height(128)); } else { Texture2D previewMeshImage = new Texture2D(118, 118); GUILayout.Label(previewMeshImage); GUILayout.Label("No Texture Selected"); } EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); }
public static void SceneGUI(BuildrEditMode editMode, BuildrData data, bool shouldSnap, float handleSize) { if (editMode.fullMesh == null) { return; } Rect HUDRect = new Rect(0, 0, 300, 300); Handles.BeginGUI(); GUILayout.BeginArea(HUDRect); EditorGUILayout.LabelField("Buildr"); EditorGUILayout.LabelField("Vertices: " + editMode.fullMesh.vertexCount); EditorGUILayout.LabelField("Triangles " + editMode.fullMesh.triangleCount / 3); GUILayout.EndArea(); Handles.EndGUI(); bool isLegal = !(data.plan.illegalPoints.Length > 0); if (isLegal) { isLegal = editMode.transform.localScale == Vector3.one; } if (isLegal) { return; } int numberOfFacades = data.facades.Count; int numberOfRoofs = data.roofs.Count; int numberOfTextures = data.textures.Count; if (numberOfFacades == 0 || numberOfRoofs == 0 || numberOfTextures == 0) { return; } Vector3 position = editMode.transform.position; BuildrPlan area = data.plan; int numberOfVolumes = area.numberOfVolumes; int facadeCounter = 0; for (int s = 0; s < numberOfVolumes; s++) { BuildrVolume volume = data.plan.volumes[s]; int volumeSize = volume.Count; Vector3 floorCentre = Vector3.zero; Handles.color = Color.red; for (int p = 0; p < volumeSize; p++) { int point = volume.points[p]; Vector3 pointPos = area.points[point].vector3; floorCentre += pointPos; List <Vector3> verts = new List <Vector3>(); int indexB = (p < volumeSize - 1) ? p + 1 : 0; Vector3 volumeHeight = Vector3.up * (volume.numberOfFloors * data.floorHeight); verts.Add(pointPos + position); verts.Add(area.points[volume.points[indexB]].vector3 + position); verts.Add(verts[1] + volumeHeight); verts.Add(verts[0] + volumeHeight); Handles.DrawSolidRectangleWithOutline(verts.ToArray(), new Color(1, 0, 0, 0.2f), Color.red); Handles.DrawLine(verts[2], verts[3]); facadeCounter++; } } }
public static void InspectorGUI(BuildrEditMode editMode, BuildrData _data) { data = _data; Undo.RecordObject(data, "Interior Modified"); BuildrTexture[] textures = data.textures.ToArray(); int numberOfTextures = textures.Length; string[] textureNames = new string[numberOfTextures]; for (int t = 0; t < numberOfTextures; t++) { textureNames[t] = textures[t].name; } EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUILayout.LabelField("Render Interior of Building"); bool renderInterior = EditorGUILayout.Toggle(_data.renderInteriors, GUILayout.Width(15)); if (renderInterior != _data.renderInteriors) { _data.renderInteriors = renderInterior; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUILayout.LabelField("Cull All Building Bays"); bool cullBays = EditorGUILayout.Toggle(_data.cullBays, GUILayout.Width(15)); if (cullBays != _data.cullBays) { _data.cullBays = cullBays; } EditorGUILayout.EndHorizontal(); //Floor Height EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Floor height", GUILayout.Width(200)); float newFloorHeight = EditorGUILayout.FloatField(data.floorHeight, GUILayout.Width(50)); if (newFloorHeight != data.floorHeight) { data.floorHeight = newFloorHeight; } EditorGUILayout.LabelField("metres", GUILayout.Width(50)); EditorGUILayout.EndHorizontal(); EditorGUI.BeginDisabledGroup(!renderInterior); //Ceiling Height EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Interior Ceiling Height", GUILayout.Width(200)); float newCeilingHeight = EditorGUILayout.Slider(data.interiorCeilingHeight, 0, 1); if (newCeilingHeight != data.interiorCeilingHeight) { data.interiorCeilingHeight = newCeilingHeight; } EditorGUILayout.EndHorizontal(); BuildrPlan plan = data.plan; int numberOfVolumes = plan.numberOfVolumes; int[] volumeSeletionsList = new int[numberOfVolumes]; string[] volumeSeletionsStringList = new string[numberOfVolumes]; for (int s = 0; s < numberOfVolumes; s++) { volumeSeletionsStringList[s] = ("volume " + s); volumeSeletionsList[s] = (s); } selectedVolumeIndex = EditorGUILayout.IntPopup("Selected Volume", selectedVolumeIndex, volumeSeletionsStringList, volumeSeletionsList, GUILayout.Width(400)); BuildrVolume volume = plan.volumes[selectedVolumeIndex]; //Stairs EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Generate Stairs", GUILayout.Width(110)); volume.generateStairs = EditorGUILayout.Toggle(volume.generateStairs); EditorGUILayout.EndHorizontal(); if (plan.cores.Count == 0) { EditorGUILayout.HelpBox("There are no building cores defined. Go to floorplan to define one so you can generate a stairwell", MessageType.Error); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Stair Width", GUILayout.Width(110)); volume.staircaseWidth = EditorGUILayout.Slider(volume.staircaseWidth, 0.5f, 5.0f); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Minimum Step Riser Value", GUILayout.Width(150)); volume.stepHeight = EditorGUILayout.Slider(volume.stepHeight, 0.05f, 0.5f); EditorGUILayout.EndHorizontal(); EditorGUI.BeginDisabledGroup(!volume.generateStairs); EditorGUILayout.BeginVertical("box"); EditorGUILayout.LabelField("Stairwell Textures"); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Wall Texture", GUILayout.Width(120)); volume.stairwellWallTexture = EditorGUILayout.Popup(volume.stairwellWallTexture, textureNames); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Floor Texture", GUILayout.Width(120)); volume.stairwellFloorTexture = EditorGUILayout.Popup(volume.stairwellFloorTexture, textureNames); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Ceiling Texture", GUILayout.Width(120)); volume.stairwellCeilingTexture = EditorGUILayout.Popup(volume.stairwellCeilingTexture, textureNames); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Step Texture", GUILayout.Width(120)); volume.stairwellStepTexture = EditorGUILayout.Popup(volume.stairwellStepTexture, textureNames); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); EditorGUI.EndDisabledGroup(); //Basement floors EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Basement Floors", GUILayout.Width(110)); EditorGUILayout.LabelField(volume.numberOfBasementFloors.ToString("F0"), GUILayout.Width(40)); EditorGUI.BeginDisabledGroup(volume.numberOfBasementFloors < 1); if (GUILayout.Button("-")) { volume.numberOfBasementFloors--; } EditorGUI.EndDisabledGroup(); if (GUILayout.Button("+")) { volume.numberOfBasementFloors++; } EditorGUILayout.EndHorizontal(); int numberOfFloors = volume.numberOfFloors; int numberOfBasementFloors = volume.numberOfBasementFloors; int totalNumberOfFloors = numberOfBasementFloors + numberOfFloors; int[] floorSeletionsList = new int[totalNumberOfFloors]; string[] floorSeletionsStringList = new string[totalNumberOfFloors]; for (int f = -numberOfBasementFloors; f < numberOfFloors; f++) { int index = f + numberOfBasementFloors; if (f > 0) { floorSeletionsStringList[index] = "floor " + f; } else if (f < 0) { floorSeletionsStringList[index] = "basement " + -f; } else { floorSeletionsStringList[index] = "ground floor "; } floorSeletionsList[index] = (f); } selectedFloor = EditorGUILayout.IntPopup("Selected Floor", selectedFloor, floorSeletionsStringList, floorSeletionsList, GUILayout.Width(400)); EditorGUILayout.LabelField("Interior Textures"); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Floor Texture", GUILayout.Width(120)); volume.FloorTexture(selectedFloor, EditorGUILayout.Popup(volume.FloorTexture(selectedFloor), textureNames)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Wall Texture", GUILayout.Width(120)); volume.WallTexture(selectedFloor, EditorGUILayout.Popup(volume.WallTexture(selectedFloor), textureNames)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Ceiling Texture", GUILayout.Width(120)); volume.CeilingTexture(selectedFloor, EditorGUILayout.Popup(volume.CeilingTexture(selectedFloor), textureNames)); EditorGUILayout.EndHorizontal(); if (GUILayout.Button("Use Values for All Floors")) { int useFloorTextureIndex = volume.FloorTexture(selectedFloor); int useWallTextureIndex = volume.WallTexture(selectedFloor); int useCeilingTextureIndex = volume.CeilingTexture(selectedFloor); for (int f = 0; f < numberOfFloors; f++) { volume.FloorTexture(f, useFloorTextureIndex); volume.WallTexture(f, useWallTextureIndex); volume.CeilingTexture(f, useCeilingTextureIndex); } } if (GUILayout.Button("Use Values for Entire Building")) { int useFloorTextureIndex = volume.FloorTexture(selectedFloor); int useWallTextureIndex = volume.WallTexture(selectedFloor); int useCeilingTextureIndex = volume.CeilingTexture(selectedFloor); for (int v = 0; v < numberOfVolumes; v++) { BuildrVolume thisvolume = plan.volumes[v]; int numberOfFloorsToModifiy = thisvolume.numberOfFloors; for (int f = 0; f < numberOfFloorsToModifiy; f++) { thisvolume.FloorTexture(f, useFloorTextureIndex); thisvolume.WallTexture(f, useWallTextureIndex); thisvolume.CeilingTexture(f, useCeilingTextureIndex); } } } EditorGUI.EndDisabledGroup(); }