private void DrawViewModeInfo() { float uiWidth = _editorUIRect.width * _infoPanelSettingsWidth; char upArrow = '\u25B2'; char downArrow = '\u25BC'; float arrayWidth = 25; GUIStyle editNodesBoxStyle = new GUIStyle(GUI.skin.textArea); GUIStyle entryStyle = new GUIStyle(GUI.skin.box); using (var hs = new EditorGUILayout.HorizontalScope()) { using (var vs = new EditorGUILayout.VerticalScope(EditorStyles.helpBox, GUILayout.MaxWidth(uiWidth))) { EditorGUILayout.LabelField("This tool allows to Paint & Edit POINT attributes of Editable nodes."); EditorGUILayout.LabelField("Painting vertex colors is directly supported if a Paint SOP is made editable."); EditorGUILayout.LabelField("Use node list on the right to re-order editable nodes by order of edit operations."); EditorGUILayout.LabelField("Nodes that take inputs from other editable nodes should come after them in the list."); } using (var vs = new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) { // Draw each editable node (attribute store), along with buttons to re-order the node. using (var hs2 = new EditorGUILayout.HorizontalScope()) { HEU_EditorUI.DrawHeadingLabel("EDIT ORDER"); SerializedProperty cookUpstreamSerializedProperty = HEU_EditorUtility.GetSerializedProperty(_toolsInfoSerializedObject, "_alwaysCookUpstream"); if (cookUpstreamSerializedProperty != null) { EditorGUILayout.PropertyField(cookUpstreamSerializedProperty, new GUIContent("Always Cook Inputs", "For multiple editable nodes, this forces each one to always cook upstream inputs first before applying edits."), GUILayout.Width(168)); } } using (var vs2 = new EditorGUILayout.VerticalScope(editNodesBoxStyle)) { using (var scrollScope = new EditorGUILayout.ScrollViewScope(_editNodeScrollPos)) { _editNodeScrollPos = scrollScope.scrollPosition; int numStores = _attributesStores.Count; for (int i = 0; i < numStores; ++i) { using (var hsi = new EditorGUILayout.HorizontalScope(entryStyle)) { if (GUILayout.Button(upArrow.ToString(), GUILayout.MaxWidth(arrayWidth))) { if (i > 0) { _asset.ReorderAttributeStore(i, i - 1); } } if (GUILayout.Button(downArrow.ToString(), GUILayout.MaxWidth(arrayWidth))) { if (i < numStores - 1) { _asset.ReorderAttributeStore(i, i + 1); } } EditorGUILayout.LabelField(_attributesStores[i].GeoName); } } } } } } }
/// <summary> /// Draw the Generate section. /// </summary> private static bool DrawGenerateSection(HEU_HoudiniAssetRoot assetRoot, SerializedObject assetRootSerializedObject, HEU_HoudiniAsset asset, SerializedObject assetObject) { bool bSkipDrawing = false; float separatorDistance = 5f; float screenWidth = EditorGUIUtility.currentViewWidth; float buttonHeight = 30f; float widthPadding = 55f; float doubleButtonWidth = Mathf.Round(screenWidth - widthPadding + separatorDistance); float singleButtonWidth = Mathf.Round((screenWidth - widthPadding) * 0.5f); GUIStyle buttonStyle = new GUIStyle(GUI.skin.button); buttonStyle.fontStyle = FontStyle.Bold; buttonStyle.fontSize = 11; buttonStyle.alignment = TextAnchor.MiddleLeft; buttonStyle.fixedHeight = buttonHeight; buttonStyle.padding.left = 6; buttonStyle.padding.right = 6; buttonStyle.margin.left = 0; buttonStyle.margin.right = 0; GUIStyle centredButtonStyle = new GUIStyle(buttonStyle); centredButtonStyle.alignment = TextAnchor.MiddleCenter; GUIStyle buttonSetStyle = new GUIStyle(GUI.skin.box); RectOffset br = buttonSetStyle.margin; br.left = 4; br.right = 4; buttonSetStyle.margin = br; GUIStyle boxStyle = new GUIStyle(GUI.skin.GetStyle("ColorPickerBackground")); br = boxStyle.margin; br.left = 4; br.right = 4; boxStyle.margin = br; boxStyle.padding = br; GUIStyle promptButtonStyle = new GUIStyle(GUI.skin.button); promptButtonStyle.fontSize = 11; promptButtonStyle.alignment = TextAnchor.MiddleCenter; promptButtonStyle.fixedHeight = 30; promptButtonStyle.margin.left = 34; promptButtonStyle.margin.right = 34; _recookhdaContent.text = " Recook Asset"; HEU_HoudiniAsset.AssetBuildAction pendingBuildAction = HEU_HoudiniAsset.AssetBuildAction.NONE; SerializedProperty pendingBuildProperty = HEU_EditorUtility.GetSerializedProperty(assetObject, "_requestBuildAction"); if (pendingBuildProperty != null) { pendingBuildAction = (HEU_HoudiniAsset.AssetBuildAction)pendingBuildProperty.enumValueIndex; } // Track changes for the build and bake targets EditorGUI.BeginChangeCheck(); HEU_HoudiniAsset.AssetCookStatus cookStatus = GetCookStatusFromSerializedAsset(assetObject); if (cookStatus == HEU_HoudiniAsset.AssetCookStatus.SELECT_SUBASSET) { // Prompt user to select subasset GUIStyle promptStyle = new GUIStyle(GUI.skin.label); promptStyle.fontStyle = FontStyle.Bold; promptStyle.normal.textColor = HEU_EditorUI.IsEditorDarkSkin() ? Color.green : Color.blue; EditorGUILayout.LabelField("SELECT AN ASSET TO INSTANTIATE:", promptStyle); EditorGUILayout.Separator(); int selectedIndex = -1; string[] subassetNames = asset.SubassetNames; for (int i = 0; i < subassetNames.Length; ++i) { if (GUILayout.Button(subassetNames[i], promptButtonStyle)) { selectedIndex = i; break; } EditorGUILayout.Separator(); } if (selectedIndex >= 0) { SerializedProperty selectedIndexProperty = HEU_EditorUtility.GetSerializedProperty(assetObject, "_selectedSubassetIndex"); if (selectedIndexProperty != null) { selectedIndexProperty.intValue = selectedIndex; } } bSkipDrawing = true; } else { HEU_EditorUI.BeginSection(); { if (cookStatus == HEU_HoudiniAsset.AssetCookStatus.COOKING || cookStatus == HEU_HoudiniAsset.AssetCookStatus.POSTCOOK) { _recookhdaContent.text = " Cooking Asset"; } else if (cookStatus == HEU_HoudiniAsset.AssetCookStatus.LOADING || cookStatus == HEU_HoudiniAsset.AssetCookStatus.POSTLOAD) { _reloadhdaContent.text = " Loading Asset"; } SerializedProperty showGenerateProperty = assetObject.FindProperty("_showGenerateSection"); showGenerateProperty.boolValue = HEU_EditorUI.DrawFoldOut(showGenerateProperty.boolValue, "GENERATE"); if (showGenerateProperty.boolValue) { bool bHasPendingAction = (pendingBuildAction != HEU_HoudiniAsset.AssetBuildAction.NONE) || (cookStatus != HEU_HoudiniAsset.AssetCookStatus.NONE); HEU_EditorUI.DrawSeparator(); EditorGUI.BeginDisabledGroup(bHasPendingAction); using (var hs = new EditorGUILayout.HorizontalScope(boxStyle)) { if (GUILayout.Button(_reloadhdaContent, buttonStyle, GUILayout.Width(singleButtonWidth))) { pendingBuildAction = HEU_HoudiniAsset.AssetBuildAction.RELOAD; bSkipDrawing = true; } GUILayout.Space(separatorDistance); if (!bSkipDrawing && GUILayout.Button(_recookhdaContent, buttonStyle, GUILayout.Width(singleButtonWidth))) { pendingBuildAction = HEU_HoudiniAsset.AssetBuildAction.COOK; bSkipDrawing = true; } } using (var hs = new EditorGUILayout.HorizontalScope(boxStyle)) { if (GUILayout.Button(_removeheContent, buttonStyle, GUILayout.Width(singleButtonWidth))) { pendingBuildAction = HEU_HoudiniAsset.AssetBuildAction.STRIP_HEDATA; bSkipDrawing = true; } GUILayout.Space(separatorDistance); if (GUILayout.Button(_duplicateContent, buttonStyle, GUILayout.Width(singleButtonWidth))) { pendingBuildAction = HEU_HoudiniAsset.AssetBuildAction.DUPLICATE; bSkipDrawing = true; } } EditorGUI.EndDisabledGroup(); HEU_EditorUI.DrawSeparator(); } } HEU_EditorUI.EndSection(); HEU_EditorUI.DrawSeparator(); HEU_EditorUI.BeginSection(); { SerializedProperty showBakeProperty = assetObject.FindProperty("_showBakeSection"); showBakeProperty.boolValue = HEU_EditorUI.DrawFoldOut(showBakeProperty.boolValue, "BAKE"); if (showBakeProperty.boolValue) { if (!bSkipDrawing) { // Bake -> New Instance, New Prefab, Existing instance or prefab using (var vs = new EditorGUILayout.HorizontalScope(boxStyle)) { if (GUILayout.Button(_bakegameobjectContent, buttonStyle, GUILayout.Width(singleButtonWidth))) { asset.BakeToNewStandalone(); } GUILayout.Space(separatorDistance); if (GUILayout.Button(_bakeprefabContent, buttonStyle, GUILayout.Width(singleButtonWidth))) { asset.BakeToNewPrefab(); } } HEU_EditorUI.DrawSeparator(); using (var hs2 = new EditorGUILayout.VerticalScope(boxStyle)) { if (GUILayout.Button(_bakeandreplaceContent, centredButtonStyle, GUILayout.Width(doubleButtonWidth))) { if (assetRoot._bakeTargets == null || assetRoot._bakeTargets.Count == 0) { // No bake target means user probably forgot to set one. So complain! HEU_EditorUtility.DisplayDialog("No Bake Targets", "Bake Update requires atleast one valid GameObject.\n\nDrag a GameObject or Prefab onto the Drag and drop GameObjects / Prefabs field!", "OK"); } else { int numTargets = assetRoot._bakeTargets.Count; for (int i = 0; i < numTargets; ++i) { GameObject bakeGO = assetRoot._bakeTargets[i]; if (bakeGO != null) { if (HEU_EditorUtility.IsPrefabOriginal(bakeGO)) { // Prefab original means its true prefab, and not an instance of it // TODO: allow user to cancel asset.BakeToExistingPrefab(bakeGO); } else { // This is for all standalone (including prefab instances) asset.BakeToExistingStandalone(bakeGO); } } else { Debug.LogWarning("Unable to bake to null target at index " + i); } } } } using (var hs = new EditorGUILayout.VerticalScope(buttonSetStyle)) { SerializedProperty bakeTargetsProp = assetRootSerializedObject.FindProperty("_bakeTargets"); if (bakeTargetsProp != null) { EditorGUILayout.PropertyField(bakeTargetsProp, _dragAndDropField, true, GUILayout.Width(doubleButtonWidth - 9f)); } } } } } } HEU_EditorUI.EndSection(); HEU_EditorUI.DrawSeparator(); if (pendingBuildAction != HEU_HoudiniAsset.AssetBuildAction.NONE) { // Sanity check to make sure the asset is part of the AssetUpater HEU_AssetUpdater.AddAssetForUpdate(asset); // Apply pending build action based on user UI interaction above pendingBuildProperty.enumValueIndex = (int)pendingBuildAction; if (pendingBuildAction == HEU_HoudiniAsset.AssetBuildAction.COOK) { // Forcing recook without checking for changes allows users to do a semi-reset on the output, // without needing to reload (loose changes) or change parameter then undo. SerializedProperty checkParameterChange = HEU_EditorUtility.GetSerializedProperty(assetObject, "_checkParameterChangeForCook"); if (checkParameterChange != null) { checkParameterChange.boolValue = false; } } } } if (EditorGUI.EndChangeCheck()) { assetRootSerializedObject.ApplyModifiedProperties(); assetObject.ApplyModifiedProperties(); } return bSkipDrawing; }
public bool DrawHandles(HEU_HoudiniAsset asset) { List<HEU_Handle> handles = CacheHandles(); HEU_HandleManipMode manipMode = GetCurrentGlobalManipMode(); GUIStyle textStyle = new GUIStyle(EditorStyles.textField); textStyle.contentOffset = new Vector2(1.4f, 1.4f); HEU_Parameters assetParameters = asset.Parameters; SerializedObject serializedParametersObject = new SerializedObject(assetParameters); SerializedProperty parameterListProperty = HEU_EditorUtility.GetSerializedProperty(serializedParametersObject, "_parameterList"); bool bChanged = false; Matrix4x4 defaultMatrix = Handles.matrix; foreach (HEU_Handle handle in handles) { if (handle.HandleType == HEU_Handle.HEU_HandleType.XFORM) { Handles.matrix = asset.transform.localToWorldMatrix; Vector3 handlePosition = handle.HandlePosition; Quaternion handleRotation = handle.HandleRotation; Vector3 handleScale = handle.HandleScale; string handleName = handle.HandleName; if (manipMode == HEU_HandleManipMode.MOVE) { if (!handle.HasTranslateHandle()) { continue; } bool bDisabled = handle.IsTranslateHandleDisabled(); if (bDisabled) { handleName += " (disabled)"; } GUIContent labelContent = new GUIContent(handleName); labelContent.tooltip = handleName; Handles.Label(handlePosition, labelContent, textStyle); if (bDisabled) { bool bLighting = Handles.lighting; Handles.lighting = false; Handles.PositionHandle(handlePosition, handleRotation); Handles.lighting = bLighting; continue; } Vector3 updatedPosition = Handles.PositionHandle(handlePosition, handleRotation); if (updatedPosition != handlePosition) { if (!handle.GetUpdatedPosition(asset, ref updatedPosition)) { continue; } HEU_HandleParamBinding translateBinding = handle.GetTranslateBinding(); if (translateBinding != null) { HEU_ParameterData paramData = assetParameters.GetParameterWithParmID(translateBinding._parmID); if (paramData != null && paramData._unityIndex < parameterListProperty.arraySize) { SerializedProperty paramDataProperty = parameterListProperty.GetArrayElementAtIndex(paramData._unityIndex); float[] posFloats = new float[3]; posFloats[0] = updatedPosition[0]; posFloats[1] = updatedPosition[1]; posFloats[2] = updatedPosition[2]; bChanged |= UpdateFloatArrayProperty(paramDataProperty, posFloats, translateBinding); } } } } else if (manipMode == HEU_HandleManipMode.ROTATE) { if (!handle.HasRotateHandle()) { continue; } bool bDisabled = handle.IsRotateHandleDisabled(); if (bDisabled) { handleName += " (disabled)"; } GUIContent labelContent = new GUIContent(handleName); labelContent.tooltip = handleName; Handles.Label(handlePosition, labelContent, textStyle); if (bDisabled) { bool bLighting = Handles.lighting; Handles.lighting = false; Handles.RotationHandle(handleRotation, handlePosition); Handles.lighting = bLighting; continue; } Quaternion updatedRotation = Handles.RotationHandle(handleRotation, handlePosition); if (updatedRotation != handleRotation) { if (!handle.GetUpdatedRotation(asset, ref updatedRotation)) { continue; } HEU_HandleParamBinding rotateBinding = handle.GetRotateBinding(); if (rotateBinding != null) { HEU_ParameterData paramData = assetParameters.GetParameterWithParmID(rotateBinding._parmID); if (paramData != null && paramData._unityIndex < parameterListProperty.arraySize) { SerializedProperty paramDataProperty = parameterListProperty.GetArrayElementAtIndex(paramData._unityIndex); float[] rotFloats = new float[3]; rotFloats[0] = updatedRotation[0]; rotFloats[1] = updatedRotation[1]; rotFloats[2] = updatedRotation[2]; bChanged |= UpdateFloatArrayProperty(paramDataProperty, rotFloats, rotateBinding); } } } } else if (manipMode == HEU_HandleManipMode.SCALE) { if (!handle.HasScaleHandle()) { continue; } bool bDisabled = handle.IsScaleHandleDisabled(); if (bDisabled) { handleName += " (disabled)"; } GUIContent labelContent = new GUIContent(handleName); labelContent.tooltip = handleName; Handles.Label(handlePosition, labelContent, textStyle); if (bDisabled) { bool bLighting = Handles.lighting; Handles.lighting = false; Handles.ScaleHandle(handleScale, handlePosition, handleRotation, 1f); Handles.lighting = bLighting; continue; } Vector3 updatedScale = Handles.ScaleHandle(handleScale, handlePosition, handleRotation, 1f); if (updatedScale != handleScale) { HEU_HandleParamBinding scaleBinding = handle.GetScaleBinding(); if (scaleBinding != null) { HEU_ParameterData paramData = assetParameters.GetParameterWithParmID(scaleBinding._parmID); if (paramData != null && paramData._unityIndex < parameterListProperty.arraySize) { SerializedProperty paramDataProperty = parameterListProperty.GetArrayElementAtIndex(paramData._unityIndex); float[] scaleFloats = new float[3]; scaleFloats[0] = updatedScale[0]; scaleFloats[1] = updatedScale[1]; scaleFloats[2] = updatedScale[2]; bChanged |= UpdateFloatArrayProperty(paramDataProperty, scaleFloats, scaleBinding); } } } } } } if (bChanged) { serializedParametersObject.ApplyModifiedProperties(); } Handles.matrix = defaultMatrix; return bChanged; }
public static void ExportAllAssetsGeo() { HEU_EditorUtility.ExportAllAssetsToGeoFiles(); }
public override void OnInspectorGUI() { // Try acquiring asset reference in here again due to Undo. // Eg. After a delete, Undo requires us to re-acquire references. TryAcquiringAsset(); if (_houdiniAsset == null) { DrawNoHDAInfo(); return; } // Always hook into asset UI callback. This could have got reset on code refresh. _houdiniAsset._refreshUIDelegate = RefreshUI; serializedObject.Update(); _houdiniAssetSerializedObject.Update(); bool guiEnabled = GUI.enabled; GUIStyle backgroundStyle = new GUIStyle(GUI.skin.GetStyle("box")); RectOffset br = backgroundStyle.margin; br.top = 10; br.bottom = 6; br.left = 4; br.right = 4; backgroundStyle.margin = br; br = backgroundStyle.padding; br.top = 8; br.bottom = 8; br.left = 8; br.right = 8; backgroundStyle.padding = br; using (var hs = new EditorGUILayout.VerticalScope(backgroundStyle)) { HEU_EditorUI.DrawSeparator(); DrawHeaderSection(); DrawLicenseInfo(); bool bSkipDraw = DrawGenerateSection(_houdiniAssetRoot, serializedObject, _houdiniAsset, _houdiniAssetSerializedObject); ; if (!bSkipDraw) { SerializedProperty assetCookStatusProperty = HEU_EditorUtility.GetSerializedProperty(_houdiniAssetSerializedObject, "_cookStatus"); if (assetCookStatusProperty != null) { // Track changes to Houdini Asset gameobject EditorGUI.BeginChangeCheck(); DrawEventsSection(_houdiniAsset, _houdiniAssetSerializedObject); DrawAssetOptions(_houdiniAsset, _houdiniAssetSerializedObject); DrawCurvesSection(_houdiniAsset, _houdiniAssetSerializedObject); DrawInputNodesSection(_houdiniAsset, _houdiniAssetSerializedObject); // If this is a Curve asset, we don't need to draw parameters as its redundant if(_houdiniAsset.AssetType != HEU_HoudiniAsset.HEU_AssetType.TYPE_CURVE) { DrawParameters(_houdiniAsset.Parameters, ref _parameterEditor); } DrawInstanceInputs(_houdiniAsset, _houdiniAssetSerializedObject); // Check if any changes occurred, and if so, trigger a recook if (EditorGUI.EndChangeCheck()) { _houdiniAssetSerializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties(); // Do recook if values have changed if (HEU_PluginSettings.CookingEnabled && _houdiniAsset.AutoCookOnParameterChange && _houdiniAsset.DoesAssetRequireRecook()) { bool bCheckParametersChanged = true; bool bAsync = false; bool bForceCook = false; bool bUploadParameters = true; _houdiniAsset.RequestCook(bCheckParametersChanged, bAsync, bForceCook, bUploadParameters); } } } } } GUI.enabled = guiEnabled; }
public static void RebuildAll() { HEU_EditorUtility.RebuildAll(); }
public static void BakeAndReplaceAll() { HEU_EditorUtility.BakeAndReplaceAllInScene(); }
/// <summary> /// Draw the UI for the given input node /// </summary> /// <param name="inputNode"></param> public static void EditorDrawInputNode(HEU_InputNode inputNode) { int plusButtonWidth = 20; //GUIStyle boldLabelStyle = new GUIStyle(EditorStyles.boldLabel); //boldLabelStyle.alignment = TextAnchor.UpperLeft; GUIContent inputTypeLabel = new GUIContent("Input Type"); GUIContent translateLabel = new GUIContent(" Translate"); GUIContent rotateLabel = new GUIContent(" Rotate"); GUIContent scaleLabel = new GUIContent(" Scale"); PopulateCache(inputNode); EditorGUI.BeginChangeCheck(); EditorGUILayout.BeginVertical(EditorStyles.helpBox); string inputName = inputNode.InputName; if (!string.IsNullOrEmpty(inputName)) { EditorGUILayout.LabelField(inputName); } EditorGUI.indentLevel++; HEU_InputNode.InputObjectType inputObjectType = (HEU_InputNode.InputObjectType)inputNode._uiCache._inputObjectTypeProperty.intValue; HEU_InputNode.InputObjectType userSelectedInputObjectType = (HEU_InputNode.InputObjectType)EditorGUILayout.EnumPopup(inputTypeLabel, inputObjectType); if (userSelectedInputObjectType != inputObjectType) { SerializedProperty pendingInputObjectTypeProperty = HEU_EditorUtility.GetSerializedProperty(inputNode._uiCache._inputNodeSerializedObject, "_pendingInputObjectType"); if (pendingInputObjectTypeProperty != null) { pendingInputObjectTypeProperty.intValue = (int)userSelectedInputObjectType; } } else { if (inputObjectType == HEU_InputNode.InputObjectType.HDA) { // For input asset, filter out other Component types UnityEngine.Object setObject = EditorGUILayout.ObjectField(inputNode._uiCache._inputAssetProperty.objectReferenceValue, typeof(HEU_HoudiniAssetRoot), true); if (setObject != inputNode._uiCache._inputAssetProperty.objectReferenceValue) { GameObject inputGO = setObject != null ? (setObject as HEU_HoudiniAssetRoot).gameObject : null; // Check not setting same asset as self if (inputGO == null || inputGO != inputNode.ParentAsset.RootGameObject) { inputNode._uiCache._inputAssetProperty.objectReferenceValue = inputGO; } } } //else if (inputObjectType == HEU_InputNode.InputObjectType.CURVE) //{ // TODO INPUT CURVE //} else if (inputObjectType == HEU_InputNode.InputObjectType.UNITY_MESH) { EditorGUILayout.PropertyField(inputNode._uiCache._keepWorldTransformProperty); EditorGUILayout.PropertyField(inputNode._uiCache._packBeforeMergeProperty); SerializedProperty inputObjectsProperty = inputNode._uiCache._inputObjectsProperty; if (inputObjectsProperty != null) { int inputCount = inputObjectsProperty.arraySize; bool bSkipElements = false; HEU_EditorUI.DrawSeparator(); using (var hs1 = new EditorGUILayout.HorizontalScope()) { EditorGUILayout.LabelField(string.Format("{0} input objects", inputCount)); if (GUILayout.Button("Add")) { inputObjectsProperty.InsertArrayElementAtIndex(inputCount); FixUpScaleProperty(inputObjectsProperty, inputCount); bSkipElements = true; } if (GUILayout.Button("Clear")) { inputObjectsProperty.ClearArray(); bSkipElements = true; } } if (!bSkipElements) { using (var vs1 = new EditorGUILayout.VerticalScope()) { for (int i = 0; i < inputCount; ++i) { using (var hs2 = new EditorGUILayout.HorizontalScope()) { EditorGUILayout.LabelField("Input " + (i + 1)); //using (var vs3 = new EditorGUILayout.VerticalScope()) { if (GUILayout.Button("+", GUILayout.Width(plusButtonWidth))) { inputObjectsProperty.InsertArrayElementAtIndex(i); FixUpScaleProperty(inputObjectsProperty, i); break; } if (GUILayout.Button("-", GUILayout.Width(plusButtonWidth))) { inputObjectsProperty.DeleteArrayElementAtIndex(i); break; } } } EditorGUI.indentLevel++; using (var vs4 = new EditorGUILayout.VerticalScope()) { HEU_InputNodeUICache.HEU_InputObjectUICache objectCache = inputNode._uiCache._inputObjectCache[i]; EditorGUILayout.PropertyField(objectCache._gameObjectProperty, GUIContent.none); using (new EditorGUI.DisabledScope(!inputNode._uiCache._keepWorldTransformProperty.boolValue)) { objectCache._transformOffsetProperty.boolValue = HEU_EditorUI.DrawToggleLeft(objectCache._transformOffsetProperty.boolValue, "Transform Offset"); if (objectCache._transformOffsetProperty.boolValue) { objectCache._translateProperty.vector3Value = EditorGUILayout.Vector3Field(translateLabel, objectCache._translateProperty.vector3Value); objectCache._rotateProperty.vector3Value = EditorGUILayout.Vector3Field(rotateLabel, objectCache._rotateProperty.vector3Value); objectCache._scaleProperty.vector3Value = EditorGUILayout.Vector3Field(scaleLabel, objectCache._scaleProperty.vector3Value); } } } EditorGUI.indentLevel--; } } } } } } EditorGUI.indentLevel--; EditorGUILayout.EndVertical(); if (EditorGUI.EndChangeCheck()) { inputNode._uiCache._inputNodeSerializedObject.ApplyModifiedProperties(); // When cooking, this will force input data to be uploaded inputNode.RequiresUpload = true; } }
private void DrawTerrainSection(HEU_HoudiniAsset asset, SerializedObject assetObject) { int numVolumes = asset.GetVolumeCacheCount(); if(numVolumes <= 0) { return; } HEU_EditorUI.BeginSection(); { SerializedProperty showTerrainProperty = HEU_EditorUtility.GetSerializedProperty(assetObject, "_showTerrainSection"); if (showTerrainProperty != null) { showTerrainProperty.boolValue = HEU_EditorUI.DrawFoldOut(showTerrainProperty.boolValue, "TERRAIN"); if (showTerrainProperty.boolValue) { // Draw each volume layer List<HEU_VolumeCache> volumeCaches = asset.GetVolumeCaches(); int numCaches = volumeCaches.Count; for (int i = 0; i < numCaches; ++i) { SerializedObject cacheObjectSerialized = new SerializedObject(volumeCaches[i]); bool bChanged = false; SerializedProperty layersProperty = cacheObjectSerialized.FindProperty("_layers"); if (layersProperty == null || layersProperty.arraySize == 0) { continue; } string heading = string.Format("{0}-{1}:", volumeCaches[i].ObjectName, volumeCaches[i].GeoName); if (HEU_EditorUI.DrawFoldOutSerializedProperty(HEU_EditorUtility.GetSerializedProperty(cacheObjectSerialized, "_uiExpanded"), heading, ref bChanged)) { EditorGUI.indentLevel++; int numlayers = layersProperty.arraySize; for (int j = 0; j < numlayers; ++j) { SerializedProperty layerProperty = layersProperty.GetArrayElementAtIndex(j); if (layerProperty == null) { continue; } string layerName = string.Format("Layer: {0}", layerProperty.FindPropertyRelative("_layerName").stringValue); SerializedProperty uiExpandedProperty = layerProperty.FindPropertyRelative("_uiExpanded"); bool bExpanded = uiExpandedProperty != null ? uiExpandedProperty.boolValue : true; bool bNewExpanded = HEU_EditorUI.DrawFoldOut(bExpanded, layerName); if (uiExpandedProperty != null && bExpanded != bNewExpanded) { bChanged = true; uiExpandedProperty.boolValue = bNewExpanded; } if (!bNewExpanded) { continue; } if (HEU_EditorUtility.EditorDrawFloatSliderProperty(layerProperty, "_strength", "Strength", "Amount to multiply the layer values by on import.")) { bChanged = true; } SerializedProperty textureProperty = layerProperty.FindPropertyRelative("_splatTexture"); if (textureProperty != null) { Object textureObject = textureProperty.objectReferenceValue; EditorGUILayout.PropertyField(textureProperty, new GUIContent("Texture", "Texture to use for heightfield layer mask.")); if (textureObject != textureProperty.objectReferenceValue) { bChanged = true; } HEU_EditorUI.DrawSeparator(); } SerializedProperty normalProperty = layerProperty.FindPropertyRelative("_normalTexture"); if (normalProperty != null) { Object normalObject = normalProperty.objectReferenceValue; EditorGUILayout.PropertyField(normalProperty, new GUIContent("NormalMap", "Normal map of the splat applied to the Terrain.")); if (normalObject != normalProperty.objectReferenceValue) { bChanged = true; } HEU_EditorUI.DrawSeparator(); } if (HEU_EditorUtility.EditorDrawFloatSliderProperty(layerProperty, "_metallic", "Metallic", "The metallic value of the splat layer.")) { bChanged = true; } if (HEU_EditorUtility.EditorDrawFloatSliderProperty(layerProperty, "_smoothness", "Smoothness", "The smoothness value of the splat layer when the main texture has no alpha channel.")) { bChanged = true; } if (HEU_EditorUtility.EditorDrawVector2RelativeProperty(layerProperty, "_tileSize", "Tile Size (W, H)", "Size of the tile used in the texture of the SplatPrototype.")) { bChanged = true; } if (HEU_EditorUtility.EditorDrawVector2RelativeProperty(layerProperty, "_tileOffset", "Tile Offset (X, Y)", "Offset of the tile texture of the SplatPrototype.")) { bChanged = true; } HEU_EditorUI.DrawSeparator(); } EditorGUI.indentLevel--; } if(bChanged) { SerializedProperty dirtyProperty = cacheObjectSerialized.FindProperty("_isDirty"); if (dirtyProperty != null) { dirtyProperty.boolValue = true; } cacheObjectSerialized.ApplyModifiedProperties(); } } } } } HEU_EditorUI.EndSection(); HEU_EditorUI.DrawSeparator(); }
private bool DrawDetailsGeneral() { bool bChanged = false; { string oldPath = HEU_PluginSettings.AssetCachePath; EditorGUILayout.LabelField(new GUIContent("Houdini Asset Cache Path:", "Files generated by this plugin will be stored in this folder path relative to Assets/.")); string newPath = EditorGUILayout.TextField("", oldPath); if (!newPath.Equals(oldPath)) { HEU_PluginSettings.AssetCachePath = newPath; bChanged = true; } } HEU_EditorUI.DrawSeparator(); #if UNITY_EDITOR_WIN // Only enabling this for Windows since Mac/Linux have issues dynamically loading // HAPI libraries. { string oldPath = HEU_PluginSettings.HoudiniInstallPath; string fileExt = ""; EditorGUILayout.LabelField(new GUIContent("Override Houdini Install Path:", "Set a specific Houdini installation to use for this plugin. The plugin's default version of Houdini will be ignored.")); using (new EditorGUILayout.HorizontalScope()) { string newPath = EditorGUILayout.DelayedTextField(oldPath); GUIStyle buttonStyle = HEU_EditorUI.GetNewButtonStyle_MarginPadding(0, 0); if (GUILayout.Button("...", buttonStyle, GUILayout.Width(30), GUILayout.Height(18))) { string panelMsg = "Select Houdini Install Path"; panelMsg += " (.app)"; string openFilePath = UnityEditor.EditorUtility.OpenFolderPanel(panelMsg, newPath, fileExt); if (!string.IsNullOrEmpty(openFilePath)) { newPath = openFilePath; } } if (!newPath.Equals(oldPath)) { string msgPath = !string.IsNullOrEmpty(newPath) ? newPath : HEU_Platform.GetHoudiniEngineDefaultPath(); string confirmMsg = string.Format( "Change the Houdini install path?\n" + " New path: {0}\n\n" + "You will need to restart Unity to use this path!", msgPath); bool result = HEU_EditorUtility.DisplayDialog("Houdini Install Path Changed", confirmMsg, "Confirm", "Cancel"); if (result) { HEU_PluginSettings.HoudiniInstallPath = newPath; bChanged = true; } } } #if UNITY_EDITOR_OSX GUIStyle labelStyle = new GUIStyle(GUI.skin.label); labelStyle.wordWrap = true; EditorGUILayout.LabelField(" On macOS, you'll need to select the path to the .app folder.\n E.g. /Applications/Houdini/Houdini16.5.616/Houdini Core 16.5.616.app", labelStyle); #endif } HEU_EditorUI.DrawSeparator(); #endif { string oldPath = HEU_PluginSettings.HoudiniDebugLaunchPath; string fileExt = ""; EditorGUILayout.LabelField(new GUIContent("Houdini Debug Executable:", "Set Houdini executable to launch when opening debug scenes.")); using (new EditorGUILayout.HorizontalScope()) { string newPath = EditorGUILayout.DelayedTextField(oldPath); GUIStyle buttonStyle = HEU_EditorUI.GetNewButtonStyle_MarginPadding(0, 0); if (GUILayout.Button("...", buttonStyle, GUILayout.Width(30), GUILayout.Height(18))) { string panelMsg = "Select Houdini Executable"; #if UNITY_EDITOR_OSX panelMsg += " (.app)"; #endif string openFilePath = UnityEditor.EditorUtility.OpenFilePanel(panelMsg, newPath, fileExt); if (!string.IsNullOrEmpty(openFilePath)) { newPath = openFilePath; } } if (!newPath.Equals(oldPath)) { HEU_PluginSettings.HoudiniDebugLaunchPath = newPath; bChanged = true; } } #if UNITY_EDITOR_OSX GUIStyle labelStyle = new GUIStyle(GUI.skin.label); labelStyle.wordWrap = true; EditorGUILayout.LabelField(" On macOS, you'll need to select the path to the .app folder.\n E.g. /Applications/Houdini/Houdini18.0.100/Houdini Core 18.0.100.app", labelStyle); #endif } HEU_EditorUI.DrawSeparator(); { bool oldValue = HEU_PluginSettings.UseFullPathNamesForOutput; bool newValue = HEU_EditorUI.DrawToggleLeft(oldValue, "Use Full Path Names For Output"); if (!newValue.Equals(oldValue)) { HEU_PluginSettings.UseFullPathNamesForOutput = newValue; bChanged = true; } } HEU_EditorUI.DrawSeparator(); { bool oldValue = HEU_PluginSettings.SetCurrentThreadToInvariantCulture; bool newValue = HEU_EditorUI.DrawToggleLeft(oldValue, "Set Current Thread To Invariant Culture", "Enabling this sets to use InvariantCutulre which fixes locale-specific parsing issues such as using comma instead of dot for decimals."); if (!newValue.Equals(oldValue)) { HEU_PluginSettings.SetCurrentThreadToInvariantCulture = newValue; bChanged = true; } } return bChanged; }
public void OnGUI() { bool guiEnabled = GUI.enabled; _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition); using (var vs = new EditorGUILayout.VerticalScope(GUI.skin.box)) { DrawSection(this, "GENERAL", this.DrawDetailsGeneral, ref _showGeneral); DrawSection(this, "ENVIRONMENT", this.DrawDetailsEnvironment, ref _showEnvironment); DrawSection(this, "COOKING", this.DrawDetailsCooking, ref _showCooking); DrawSection(this, "GEOMETRY", this.DrawDetailsGeometry, ref _showGeometry); DrawSection(this, "MATERIALS", this.DrawDetailsMaterials, ref _showMaterials); DrawSection(this, "SESSION", this.DrawSessionSettings, ref _showSession); DrawSection(this, "TOOLS", this.DrawToolSettings, ref _showTools); DrawSection(this, "ADVANCED", this.DrawAdvancedSettings, ref _showAdvanced); float buttonHeight = 25; float buttonWidth = 200; GUIStyle yellowButtonStyle = new GUIStyle(GUI.skin.button); yellowButtonStyle.normal.textColor = HEU_EditorUI.GetUISafeTextColorYellow(); yellowButtonStyle.fontStyle = FontStyle.Bold; yellowButtonStyle.fontSize = 12; yellowButtonStyle.fixedHeight = buttonHeight; yellowButtonStyle.fixedWidth = buttonWidth; using (var hs = new EditorGUILayout.HorizontalScope()) { GUILayout.FlexibleSpace(); if (GUILayout.Button(HEU_EditorStrings.RELOAD_SETTINGS, yellowButtonStyle)) { if (HEU_EditorUtility.DisplayDialog(HEU_EditorStrings.REVERT_SETTINGS + "?", "Are you sure you want to reload plugin settings from heu_settings.ini file?", "Yes", "No")) { HEU_PluginStorage.LoadFromSavedFile(); ResetStateAndRepaint(); } } GUILayout.Space(10); if (GUILayout.Button(HEU_EditorStrings.REVERT_SETTINGS, yellowButtonStyle)) { if (HEU_EditorUtility.DisplayDialog(HEU_EditorStrings.REVERT_SETTINGS + "?", "Are you sure you want to revert all " + HEU_Defines.HEU_PRODUCT_NAME + " plugin settings?", "Yes", "No")) { HEU_PluginStorage.ClearPluginData(); ResetStateAndRepaint(); } } GUILayout.FlexibleSpace(); } } EditorGUILayout.EndScrollView(); GUI.enabled = guiEnabled; }
private void DrawPaintModeScene() { if(_selectedAttributesStore == null || _selectedAttributeData == null) { // Nothing to do if no attribute selected return; } if(!_selectedAttributesStore.HasMeshForPainting()) { // Painting requires a mesh so nothing to do return; } if (!_mouseWithinSceneView) { return; } float brushRadius = GetBrushRadius(); // TODO: use Handles.DrawingScope Color originalHandleColor = Handles.color; Color newHandleColor = originalHandleColor; SerializedProperty handleColorProperty = HEU_EditorUtility.GetSerializedProperty(_toolsInfoSerializedObject, "_brushHandleColor"); if(handleColorProperty != null) { newHandleColor = handleColorProperty.colorValue; } HEU_ToolsInfo.PaintMergeMode paintMergeMode = HEU_ToolsInfo.PaintMergeMode.REPLACE; SerializedProperty paintMergeProperty = HEU_EditorUtility.GetSerializedProperty(_toolsInfoSerializedObject, "_paintMergeMode"); if (paintMergeProperty != null) { paintMergeMode = (HEU_ToolsInfo.PaintMergeMode)paintMergeProperty.intValue; } SerializedProperty isPaintingProperty = HEU_EditorUtility.GetSerializedProperty(_toolsInfoSerializedObject, "_isPainting"); // Enable the mesh collider so that we can raycast to paint using brush MeshCollider collider = _selectedAttributesStore.GetPaintMeshCollider(); if (collider != null) { Ray ray = _currentCamera.ScreenPointToRay(_mousePosition); ray.origin = _currentCamera.transform.position; RaycastHit hit; if (collider.Raycast(ray, out hit, _intersectionRayLength)) { if (_currentEvent.type == EventType.ScrollWheel && _currentEvent.shift) { // Brush resize brushRadius -= _currentEvent.delta.y * _mouseWheelBrushSizeMultiplier; brushRadius = UpdateBrushSize(brushRadius); _GUIChanged = true; _currentEvent.Use(); } else if (_currentEvent.type == EventType.MouseDrag && _currentEvent.shift) { // Brush resize brushRadius += _currentEvent.delta.x * _mouseWheelBrushSizeMultiplier; brushRadius = UpdateBrushSize(brushRadius); _GUIChanged = true; _currentEvent.Use(); } else if (_currentEvent.button == 0 && !_currentEvent.shift && !_currentEvent.alt && !_currentEvent.control && !_mouseOverInfoPanel) { // Painting if (_currentEvent.type == EventType.MouseDown && !isPaintingProperty.boolValue) { PaintingStarted(isPaintingProperty); } if (isPaintingProperty.boolValue) { if(_currentEvent.type == EventType.MouseDown || _currentEvent.type == EventType.MouseDrag) { HandlePaintEvent(hit, brushRadius, paintMergeMode); _currentEvent.Use(); } } } if (!_mouseOverInfoPanel) { Handles.color = newHandleColor; Vector3 endPt = hit.point + (Vector3.Normalize(hit.normal) * brushRadius); Handles.DrawAAPolyLine(2f, new Vector3[] { hit.point, endPt }); HEU_EditorUI.DrawCircleCap(_controlID, hit.point, Quaternion.FromToRotation(Vector3.forward, hit.normal), brushRadius); } } } switch (_currentEvent.type) { case EventType.MouseDown: { // Don't use event here as it will ignore mouse camera controls break; } case EventType.MouseUp: { if (_currentEvent.button == 0) { if(!_currentEvent.shift && !_currentEvent.alt && !_currentEvent.control) { if (isPaintingProperty != null && isPaintingProperty.boolValue) { _currentEvent.Use(); } PaintingFinished(isPaintingProperty); } } break; } case EventType.MouseMove: { // Use the mouse move event will force a repaint allowing for much more responsive UI _currentEvent.Use(); break; } case EventType.Layout: { // This disables deselection on asset while in Edit mode HandleUtility.AddDefaultControl(_controlID); break; } case EventType.Repaint: { break; } } Handles.color = originalHandleColor; }
private void DrawPaintAttributeValues() { // Display the values as editable fields if (_selectedAttributeData == null) { return; } if(!_selectedAttributesStore.HasMeshForPainting()) { HEU_EditorUI.DrawWarningLabel(_noMeshForPainting); return; } SerializedProperty selectedToolsValuesProperty = null; if (_selectedAttributeData._attributeType == HEU_AttributeData.AttributeType.INT) { selectedToolsValuesProperty = HEU_EditorUtility.GetSerializedProperty(_toolsInfoSerializedObject, "_paintIntValue"); if (selectedToolsValuesProperty != null) { ResizeSerializedPropertyArray(selectedToolsValuesProperty, _selectedAttributeData._attributeInfo.tupleSize); HEU_EditorUtility.EditorDrawArrayProperty(selectedToolsValuesProperty, HEU_EditorUtility.EditorDrawIntProperty, _paintValuesLabel); } } else if (_selectedAttributeData._attributeType == HEU_AttributeData.AttributeType.FLOAT) { selectedToolsValuesProperty = HEU_EditorUtility.GetSerializedProperty(_toolsInfoSerializedObject, "_paintFloatValue"); if (selectedToolsValuesProperty != null) { ResizeSerializedPropertyArray(selectedToolsValuesProperty, _selectedAttributeData._attributeInfo.tupleSize); HEU_EditorUtility.EditorDrawArrayProperty(selectedToolsValuesProperty, HEU_EditorUtility.EditorDrawFloatProperty, _paintValuesLabel); } // Display paint color selector if this is a color attribute if (_selectedAttributeData.IsColorAttribute()) { Color color = Color.white; if (selectedToolsValuesProperty.arraySize >= 3) { color.r = selectedToolsValuesProperty.GetArrayElementAtIndex(0).floatValue; color.g = selectedToolsValuesProperty.GetArrayElementAtIndex(1).floatValue; color.b = selectedToolsValuesProperty.GetArrayElementAtIndex(2).floatValue; if (selectedToolsValuesProperty.arraySize >= 4) { color.a = selectedToolsValuesProperty.GetArrayElementAtIndex(3).floatValue; } } Color newColor = EditorGUILayout.ColorField(_paintColorLabel, color); if (color != newColor) { if (selectedToolsValuesProperty.arraySize >= 3) { selectedToolsValuesProperty.GetArrayElementAtIndex(0).floatValue = newColor.r; selectedToolsValuesProperty.GetArrayElementAtIndex(1).floatValue = newColor.g; selectedToolsValuesProperty.GetArrayElementAtIndex(2).floatValue = newColor.b; if (selectedToolsValuesProperty.arraySize >= 4) { selectedToolsValuesProperty.GetArrayElementAtIndex(3).floatValue = newColor.a; } } } } } else if (_selectedAttributeData._attributeType == HEU_AttributeData.AttributeType.STRING) { selectedToolsValuesProperty = HEU_EditorUtility.GetSerializedProperty(_toolsInfoSerializedObject, "_paintStringValue"); if (selectedToolsValuesProperty != null) { ResizeSerializedPropertyArray(selectedToolsValuesProperty, _selectedAttributeData._attributeInfo.tupleSize); HEU_EditorUtility.EditorDrawArrayProperty(selectedToolsValuesProperty, HEU_EditorUtility.EditorDrawTextProperty, _paintValuesLabel); } } if (!_selectedAttributeData.IsColorAttribute()) { HEU_EditorUtility.EditorDrawSerializedProperty(_toolsInfoSerializedObject, "_affectedAreaPaintColor", _affectedAreaColorLabel, "Color to show painted area."); } }
private void DrawAttributeSelection() { // Try to re-use the last selected node string lastSelectedNodeName = null; SerializedProperty lastSelectedNodeNameProperty = HEU_EditorUtility.GetSerializedProperty(_toolsInfoSerializedObject, "_lastAttributeNodeName"); if (lastSelectedNodeNameProperty != null) { lastSelectedNodeName = lastSelectedNodeNameProperty.stringValue; } HEU_AttributesStore foundAttributeStore = null; // Get the names of the all editable nodes having an attribute store for this asset // While doing that, we'll find the last selected attribute store int lastSelectedIndex = 0; List<string> nodeNames = new List<string>(); foreach (HEU_AttributesStore attributeStore in _attributesStores) { string geoName = attributeStore.GeoName; if (!nodeNames.Contains(geoName)) { nodeNames.Add(geoName); // Either re-select last selected node, or select the first one found if (string.IsNullOrEmpty(lastSelectedNodeName) || lastSelectedNodeName.Equals(geoName)) { lastSelectedNodeName = geoName; lastSelectedIndex = nodeNames.Count - 1; foundAttributeStore = attributeStore; } } } // Try to re-use the last selected attribute string lastSelectedAttributeName = null; SerializedProperty lastSelectedAttributeProperty = HEU_EditorUtility.GetSerializedProperty(_toolsInfoSerializedObject, "_lastAttributeName"); if (lastSelectedAttributeProperty != null) { lastSelectedAttributeName = lastSelectedAttributeProperty.stringValue; } // Display a dropdown list of editable nodes with attribute stores int currentSelectedIndex = EditorGUILayout.Popup(_editableNodeLabel, lastSelectedIndex, nodeNames.ToArray()); if (currentSelectedIndex != lastSelectedIndex) { // User changed node selection, so update it lastSelectedNodeName = nodeNames[currentSelectedIndex]; foundAttributeStore = null; foreach (HEU_AttributesStore attributeStore in _attributesStores) { string geoName = attributeStore.GeoName; if (geoName.Equals(lastSelectedNodeName)) { foundAttributeStore = attributeStore; break; } } SetSelectedAttributeStore(foundAttributeStore); // Reset selected attribute to first attribute SetSelectedAttributeData(_selectedAttributesStore.GetAttributeData(0)); lastSelectedAttributeName = _selectedAttributeData._name; lastSelectedAttributeProperty.stringValue = lastSelectedAttributeName; lastSelectedNodeNameProperty.stringValue = lastSelectedNodeName; _GUIChanged = true; } else { // Since selected node hasn't changed, re-use the last selected attribute SetSelectedAttributeStore(foundAttributeStore); SetSelectedAttributeData(_selectedAttributesStore.GetAttributeData(lastSelectedAttributeName)); } // Get attribute names for selected node List<string> attributeNames = _selectedAttributesStore.GetAttributeNames(); // Find the last selected attribute index int lastAttributeIndex = -1; if (!string.IsNullOrEmpty(lastSelectedAttributeName)) { for(int i = 0; i < attributeNames.Count; ++i) { if (lastSelectedAttributeName.Equals(attributeNames[i])) { lastAttributeIndex = i; break; } } } // Use first attribute as default if none selected last time if(lastAttributeIndex == -1) { lastAttributeIndex = 0; HEU_AttributeData data = _selectedAttributesStore.GetAttributeData(0); if (data != null) { lastSelectedAttributeProperty.stringValue = data._name; } } // Display attributes as dropdown if (attributeNames.Count > 0) { int currentAttributeIndex = EditorGUILayout.Popup(_attributeLabel, lastAttributeIndex, attributeNames.ToArray()); if (currentAttributeIndex != lastAttributeIndex) { // User changed attribute selection, so update it SetSelectedAttributeData(_selectedAttributesStore.GetAttributeData(attributeNames[currentAttributeIndex])); lastSelectedAttributeProperty.stringValue = _selectedAttributeData._name; } } }
public static void CookAll() { HEU_EditorUtility.CookAll(); }
public void OnGUI() { if (!_initializedUI) { // Creating of UI elements must happen in OnGUI InitializeUIElements(); } bool bChanged = false; Color originalBGColor = GUI.backgroundColor; bool bRequiresLoad = !HEU_ShelfTools.AreShelvesLoaded(); if (!bRequiresLoad) { // Sanity check that textures are still valid. When scene changes, these get invalidated. if (_guiContents != null && _guiContents.Length > 0) { bRequiresLoad = (_guiContents[0].image == null); } } if (bRequiresLoad) { LoadShelves(); } int numTools = 0; using (new EditorGUILayout.VerticalScope()) { using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) { if (HEU_ShelfTools.AreShelvesLoaded()) { int currentShelfIndex = HEU_ShelfTools.GetCurrentShelfIndex(); HEU_Shelf shelf = null; using (new EditorGUILayout.HorizontalScope()) { GUILayout.FlexibleSpace(); if (GUILayout.Button(_addButton, _buttonStyle, GUILayout.MaxWidth(_buttonWidth), GUILayout.MaxHeight(_buttonHeight))) { string newShelfPath = UnityEditor.EditorUtility.OpenFolderPanel("Add Shelf Folder", "", ""); if (!string.IsNullOrEmpty(newShelfPath) && HEU_Platform.DoesDirectoryExist(newShelfPath)) { AddNewShelfWindow(newShelfPath); bChanged = true; } } } using (new EditorGUILayout.HorizontalScope()) { GUILayout.Label("Active Shelf"); int newShelfIndex = EditorGUILayout.Popup(currentShelfIndex, _shelfNames, _popupStyle); if (currentShelfIndex != newShelfIndex) { // Change shelf currentShelfIndex = newShelfIndex; HEU_ShelfTools.SetCurrentShelf(currentShelfIndex); SelectShelf(currentShelfIndex); } shelf = HEU_ShelfTools.GetShelf(currentShelfIndex); numTools = shelf._tools.Count; using (new EditorGUI.DisabledGroupScope(shelf._defaultShelf)) { if (GUILayout.Button(_removeButton, _buttonStyle, GUILayout.MaxWidth(_buttonWidth))) { HEU_ShelfTools.RemoveShelf(currentShelfIndex); HEU_ShelfTools.SaveShelf(); HEU_ShelfTools.SetReloadShelves(); bChanged = true; } } } HEU_EditorUI.DrawSeparator(); if (!bChanged) { using (EditorGUILayout.ScrollViewScope scroll = new EditorGUILayout.ScrollViewScope(_toolButtonScrollPos)) { if (numTools > 0) { int numXElements = numTools < _toolGridXElements ? numTools : _toolGridXElements; _selectedToolIndex = GUILayout.SelectionGrid(_selectedToolIndex, _guiContents, numXElements, _toolGridStyle); } else { EditorGUILayout.LabelField("No tools found!"); } _toolButtonScrollPos = scroll.scrollPosition; } } } } bool bValidSelection = (_selectedToolIndex >= 0 && _selectedToolIndex < numTools); using (new EditorGUI.DisabledGroupScope(!bValidSelection)) { if (!bValidSelection) { _applyButton.text = "Select a Tool!"; } else { GameObject[] selectedObjects = HEU_EditorUtility.GetSelectedObjects(); if (selectedObjects.Length == 0) { _applyButton.text = "Create Tool (no input selected)!"; } else { _applyButton.text = "Create Tool (selected objects as inputs)!"; } } if (GUILayout.Button(_applyButton, _buttonStyle, GUILayout.MaxHeight(_buttonHeight))) { ProcessUserSelection(_selectedToolIndex); } } } }
public static void RebuildSelected() { HEU_EditorUtility.RebuildSelected(); }
public static void ExecuteToolOperatorSingle(string toolName, string toolPath, GameObject[] inputObjects) { // Single operator means single asset input. If multiple inputs are provided, create tool for each input. List<GameObject> outputObjectsToSelect = new List<GameObject>(); int numInputs = inputObjects.Length; for (int i = 0; i < numInputs; ++i) { if (!IsValidInput(inputObjects[i])) { continue; } GameObject inputObject = inputObjects[i]; GameObject go = HEU_HAPIUtility.InstantiateHDA(toolPath, Vector3.zero, HEU_SessionManager.GetOrCreateDefaultSession(), false); if (go != null) { HEU_HoudiniAssetRoot assetRoot = go.GetComponent<HEU_HoudiniAssetRoot>(); if (assetRoot != null) { HEU_HoudiniAsset asset = assetRoot._houdiniAsset; HEU_SessionBase session = asset.GetAssetSession(true); List<HEU_InputNode> inputNodes = asset.GetInputNodes(); if (inputNodes == null || inputNodes.Count == 0) { Debug.LogErrorFormat("Unable to assign input geometry due to no asset inputs on selected tool."); } else { HEU_InputNode inputNode = inputNodes[0]; inputNode.ResetInputNode(session); inputNode.ChangeInputType(session, HEU_InputNode.InputObjectType.UNITY_MESH); HEU_InputObjectInfo inputInfo = inputNode.AddInputEntryAtEnd(inputObject); inputInfo._useTransformOffset = false; inputNode.KeepWorldTransform = true; inputNode.PackGeometryBeforeMerging = false; inputNode.RequiresUpload = true; asset.RequestCook(true, true, true, true); outputObjectsToSelect.Add(assetRoot.gameObject); } } } else { Debug.LogWarningFormat("Failed to instantiate tool: {0}", toolName); } } if (outputObjectsToSelect.Count > 0) { HEU_EditorUtility.SelectObjects(outputObjectsToSelect.ToArray()); } }
public static void BakeAndReplaceSelected() { HEU_EditorUtility.BakeAndReplaceSelectedInScene(); }
public static void ExecuteToolOperatorMultiple(string toolName, string toolPath, GameObject[] inputObjects) { GameObject outputObjectToSelect = null; GameObject go = HEU_HAPIUtility.InstantiateHDA(toolPath, Vector3.zero, HEU_SessionManager.GetOrCreateDefaultSession(), false); if (go == null) { Debug.LogWarningFormat("Failed to instantiate tool: {0}", toolName); return; } HEU_HoudiniAssetRoot assetRoot = go.GetComponent<HEU_HoudiniAssetRoot>(); if (assetRoot != null) { HEU_HoudiniAsset asset = assetRoot._houdiniAsset; HEU_SessionBase session = asset.GetAssetSession(true); int numInputs = inputObjects.Length; List<HEU_InputNode> inputNodes = asset.GetInputNodes(); if (inputNodes == null || inputNodes.Count == 0) { Debug.LogErrorFormat("Unable to assign input geometry due to no asset inputs on selected tool."); } else { // User could have selected any number of inputs objects, and asset could have any number of inputs. // So use minimum of either to set input object into asset input. int minInputCount = Mathf.Min(inputNodes.Count, numInputs); for (int i = 0; i < minInputCount; ++i) { if (!IsValidInput(inputObjects[i])) { continue; } GameObject inputObject = inputObjects[i]; HEU_InputNode inputNode = inputNodes[i]; inputNode.ResetInputNode(session); inputNode.ChangeInputType(session, HEU_InputNode.InputObjectType.UNITY_MESH); HEU_InputObjectInfo inputInfo = inputNode.AddInputEntryAtEnd(inputObject); inputInfo._useTransformOffset = false; inputNode.KeepWorldTransform = true; inputNode.PackGeometryBeforeMerging = false; inputNode.RequiresUpload = true; } asset.RequestCook(true, true, true, true); outputObjectToSelect = assetRoot.gameObject; } } if (outputObjectToSelect != null) { HEU_EditorUtility.SelectObject(outputObjectToSelect); } }
public static void ExportSelecedAssetsGeo() { HEU_EditorUtility.ExportSelectedAssetsToGeoFiles(); }
/// <summary> /// Open given session in a new Houdini instance. /// </summary> /// <param name="session">Session to open. If null, will use default session.</param> /// <returns>True if successfully loaded session</returns> public static bool OpenSessionInHoudini(HEU_SessionBase session = null) { if (session == null || !session.IsSessionValid()) { session = GetOrCreateDefaultSession(); if (session == null || !session.IsSessionValid()) { session.SetSessionErrorMsg("No valid session found. Unable to open session in Houdini!", true); return false; } } string HIPName = string.Format("hscene_{0}.hip", System.IO.Path.GetRandomFileName().Replace(".", "")); string HIPPath = Application.temporaryCachePath + HEU_Platform.DirectorySeparatorStr + HIPName; if (!session.SaveHIPFile(HIPPath, false)) { session.SetSessionErrorMsg("Unable to save session to .hip file at: " + HIPPath, true); return false; } Debug.Log("Saved session to " + HIPPath); string HoudiniPath = HEU_PluginSettings.HoudiniDebugLaunchPath; #if UNITY_EDITOR_OSX // On macOS, need to find the actual executable, which is within one of .app folders // that Houdini ships with, depending on the installation type. // HoudiniPath should by default be pointing to the HFS (Houdini install) folder. // Or user should have selected one of the .app folders within. // If not set to .app, then set it based on what app is available if (!HoudiniPath.EndsWith(".app", System.StringComparison.InvariantCulture)) { string[] appNames = { "FX", "Core", "Indie", "Apprentice", "Indie", "Indie Steam Edition" }; string tryPath; foreach(string name in appNames) { tryPath = HEU_Platform.BuildPath(HoudiniPath, string.Format("Houdini {0} {1}.app", name, HEU_HoudiniVersion.HOUDINI_VERSION_STRING)); if (HEU_Platform.DoesPathExist(tryPath)) { HoudiniPath = tryPath; break; } } } if (HoudiniPath.EndsWith(".app", System.StringComparison.InvariantCulture)) { // Get the executable name inside the .app, but the executable // name is based on the license type, so need to query the // license type and map it to executable name: // Houdini Apprenctice 18.0.100 // Houdini Core 18.0.100 // Houdini FX 18.0.100 // Houdini Indie 18.0.100 // Houdini Indie Steam Edition 18.0.100 //HoudiniPath = "/Applications/Houdini/Houdini18.0.100/Houdini Indie 18.0.100.app"; string hexecutable = ""; string pattern = @"(.*)/Houdini (.*) (.*).app$"; Regex reg = new Regex(pattern); Match match = reg.Match(HoudiniPath); if (match.Success && match.Groups.Count > 2) { switch(match.Groups[2].Value) { case "Apprentice": hexecutable = "happrentice"; break; case "Core": hexecutable = "houdinicore"; break; case "FX": hexecutable = "houdini"; break; case "Indie": hexecutable = "hindie"; break; case "Indie Steam Edition": hexecutable = "hindie.steam"; break; default: break; } } HoudiniPath += "/Contents/MacOS/" + hexecutable; } #endif var HoudiniProcess = new System.Diagnostics.Process(); HoudiniProcess.StartInfo.FileName = HoudiniPath; HoudiniProcess.StartInfo.Arguments = string.Format("\"{0}\"", HIPPath); if (!HoudiniProcess.Start()) { session.SetSessionErrorMsg("Unable to start Houdini. Check that the Houdini Debug Exectable path is valid in Plugin Settings.", true); HEU_EditorUtility.RevealInFinder(HIPPath); return false; } return true; }
public static void QueryMeshTopology() { HEU_EditorUtility.QuerySelectedMeshTopology(); }
public static void GetSessionInfo() { HEU_EditorUtility.DisplayDialog("Houdini Engine", HEU_SessionManager.GetSessionInfo(), "OK"); }
/// <summary> /// Draw the Object Instance Inputs section for given asset. /// </summary> /// <param name="asset">The HDA asset</param> /// <param name="assetObject">Serialized HDA asset object</param> private void DrawInstanceInputs(HEU_HoudiniAsset asset, SerializedObject assetObject) { HEU_EditorUI.DrawSeparator(); // Get list of object input fields List<HEU_ObjectInstanceInfo> objInstanceInfos = new List<HEU_ObjectInstanceInfo>(); asset.PopulateObjectInstanceInfos(objInstanceInfos); int numObjInstances = objInstanceInfos.Count; // Display input section if at least have 1 input field if (numObjInstances > 0) { HEU_EditorUI.BeginSection(); SerializedProperty showInstanceInputsProperty = assetObject.FindProperty("_showInstanceInputs"); showInstanceInputsProperty.boolValue = HEU_EditorUI.DrawFoldOut(showInstanceInputsProperty.boolValue, "INSTANCE INPUTS"); if (showInstanceInputsProperty.boolValue) { EditorGUI.BeginChangeCheck(); // Draw each instanced input info for (int i = 0; i < numObjInstances; ++i) { EditorGUILayout.BeginVertical(); string inputName = objInstanceInfos[i]._partTarget.PartName + "_" + i; SerializedObject objInstanceSerialized = new SerializedObject(objInstanceInfos[i]); SerializedProperty instancedInputsProperty = HEU_EditorUtility.GetSerializedProperty(objInstanceSerialized, "_instancedInputs"); if (instancedInputsProperty != null) { int inputCount = instancedInputsProperty.arraySize; EditorGUILayout.PropertyField(instancedInputsProperty, new GUIContent(inputName), true); // When input size increases, Unity creates default values for HEU_InstancedInput which results in // zero value for scale offset. This fixes it up. int newInputCount = instancedInputsProperty.arraySize; if (inputCount < newInputCount) { for (int inputIndex = inputCount; inputIndex < newInputCount; ++inputIndex) { SerializedProperty scaleProperty = instancedInputsProperty.GetArrayElementAtIndex(inputIndex).FindPropertyRelative("_scaleOffset"); scaleProperty.vector3Value = Vector3.one; } } } objInstanceSerialized.ApplyModifiedProperties(); EditorGUILayout.EndVertical(); } if(EditorGUI.EndChangeCheck()) { bool bCheckParametersChanged = false; bool bAsync = true; bool bForceCook = false; bool bUploadParameters = true; asset.RequestCook(bCheckParametersChanged, bAsync, bForceCook, bUploadParameters); } } HEU_EditorUI.EndSection(); } }
public static void ShowInstallationInfo() { HEU_EditorUtility.DisplayDialog(HEU_Defines.HEU_INSTALL_INFO, HEU_HAPIUtility.GetHoudiniEngineInstallationInfo(), "OK"); }
private void DrawCurvesSection(HEU_HoudiniAsset asset, SerializedObject assetObject) { if (asset.GetEditableCurveCount() <= 0) { return; } GUIStyle buttonStyle = new GUIStyle(GUI.skin.button); buttonStyle.fontSize = 11; buttonStyle.alignment = TextAnchor.MiddleCenter; buttonStyle.fixedHeight = 24; buttonStyle.margin.left = 34; HEU_EditorUI.BeginSection(); { SerializedProperty showCurvesProperty = HEU_EditorUtility.GetSerializedProperty(assetObject, "_showCurvesSection"); if (showCurvesProperty != null) { showCurvesProperty.boolValue = HEU_EditorUI.DrawFoldOut(showCurvesProperty.boolValue, "CURVES"); if (showCurvesProperty.boolValue) { SerializedProperty curveEditorProperty = HEU_EditorUtility.GetSerializedProperty(assetObject, "_curveEditorEnabled"); if (curveEditorProperty != null) { EditorGUILayout.PropertyField(curveEditorProperty); } HEU_EditorUI.DrawHeadingLabel("Collision Settings"); EditorGUI.indentLevel++; string projectLabel = "Project Curves To "; List<HEU_Curve> curves = asset.GetCurves(); SerializedProperty curveCollisionProperty = HEU_EditorUtility.GetSerializedProperty(assetObject, "_curveDrawCollision"); if (curveCollisionProperty != null) { EditorGUILayout.PropertyField(curveCollisionProperty, new GUIContent("Collision Type")); if (curveCollisionProperty.enumValueIndex == (int)HEU_Curve.CurveDrawCollision.COLLIDERS) { HEU_EditorUtility.EditorDrawSerializedProperty(assetObject, "_curveDrawColliders", label: "Colliders"); projectLabel += "Colliders"; } else if (curveCollisionProperty.enumValueIndex == (int)HEU_Curve.CurveDrawCollision.LAYERMASK) { HEU_EditorUtility.EditorDrawSerializedProperty(assetObject, "_curveDrawLayerMask", label: "Layer Mask"); projectLabel += "Layer"; } HEU_EditorUI.DrawSeparator(); EditorGUI.indentLevel--; HEU_EditorUI.DrawHeadingLabel("Projection Settings"); EditorGUI.indentLevel++; HEU_EditorUtility.EditorDrawSerializedProperty(assetObject, "_curveProjectDirection", label: "Project Direction", tooltip: "The ray cast direction for projecting the curve points."); HEU_EditorUtility.EditorDrawFloatProperty(assetObject, "_curveProjectMaxDistance", label: "Project Max Distance", tooltip: "The maximum ray cast distance for projecting the curve points."); _projectCurvePointsButton.text = projectLabel; if (GUILayout.Button(_projectCurvePointsButton, buttonStyle, GUILayout.MaxWidth(180))) { SerializedProperty projectDirProperty = HEU_EditorUtility.GetSerializedProperty(assetObject, "_curveProjectDirection"); SerializedProperty maxDistanceProperty = HEU_EditorUtility.GetSerializedProperty(assetObject, "_curveProjectMaxDistance"); Vector3 projectDir = projectDirProperty != null ? projectDirProperty.vector3Value : Vector3.down; float maxDistance = maxDistanceProperty != null ? maxDistanceProperty.floatValue : 0; for (int i = 0; i < curves.Count; ++i) { curves[i].ProjectToColliders(asset, projectDir, maxDistance); } } } EditorGUI.indentLevel--; HEU_EditorUI.DrawSeparator(); for (int i = 0; i < curves.Count; ++i) { if (curves[i].Parameters != null) { DrawParameters(curves[i].Parameters, ref _curveParameterEditor); } } } } } HEU_EditorUI.EndSection(); HEU_EditorUI.DrawSeparator(); }
public static void CookSelected() { HEU_EditorUtility.CookSelected(); }
private void DrawTerrainSection(HEU_HoudiniAsset asset, SerializedObject assetObject) { int numVolumes = asset.GetVolumeCacheCount(); if (numVolumes <= 0) { return; } HEU_EditorUI.BeginSection(); { SerializedProperty showTerrainProperty = HEU_EditorUtility.GetSerializedProperty(assetObject, "_showTerrainSection"); if (showTerrainProperty != null) { showTerrainProperty.boolValue = HEU_EditorUI.DrawFoldOut(showTerrainProperty.boolValue, "TERRAIN"); if (showTerrainProperty.boolValue) { // Draw each volume layer List<HEU_VolumeCache> volumeCaches = asset.GetVolumeCaches(); int numCaches = volumeCaches.Count; for (int i = 0; i < numCaches; ++i) { SerializedObject cacheObjectSerialized = new SerializedObject(volumeCaches[i]); bool bChanged = false; bool bStrengthChanged = false; SerializedProperty layersProperty = cacheObjectSerialized.FindProperty("_layers"); if (layersProperty == null || layersProperty.arraySize == 0) { continue; } string heading = string.Format("{0}-{1}:", volumeCaches[i].ObjectName, volumeCaches[i].GeoName); if (HEU_EditorUI.DrawFoldOutSerializedProperty(HEU_EditorUtility.GetSerializedProperty(cacheObjectSerialized, "_uiExpanded"), heading, ref bChanged)) { EditorGUI.indentLevel++; int numlayers = layersProperty.arraySize; for (int j = 0; j < numlayers; ++j) { SerializedProperty layerProperty = layersProperty.GetArrayElementAtIndex(j); if (layerProperty == null) { continue; } // Skipping "height" layer on UI since its treated as Houdini-specific layer string layerName = layerProperty.FindPropertyRelative("_layerName").stringValue; if (layerName.Equals(HEU_Defines.HAPI_HEIGHTFIELD_LAYERNAME_HEIGHT)) { continue; } layerName = string.Format("Layer: {0}", layerName); SerializedProperty uiExpandedProperty = layerProperty.FindPropertyRelative("_uiExpanded"); bool bExpanded = uiExpandedProperty != null ? uiExpandedProperty.boolValue : true; bool bNewExpanded = HEU_EditorUI.DrawFoldOut(bExpanded, layerName); if (uiExpandedProperty != null && bExpanded != bNewExpanded) { bChanged = true; uiExpandedProperty.boolValue = bNewExpanded; } if (!bNewExpanded) { continue; } if (HEU_EditorUtility.EditorDrawFloatSliderProperty(layerProperty, "_strength", "Strength", "Amount to multiply the layer values by on import.")) { bStrengthChanged = true; } HEU_EditorUI.DrawSeparator(); } EditorGUI.indentLevel--; } if (bStrengthChanged) { SerializedProperty dirtyProperty = cacheObjectSerialized.FindProperty("_isDirty"); if (dirtyProperty != null) { dirtyProperty.boolValue = true; bChanged = true; } } if (bChanged) { cacheObjectSerialized.ApplyModifiedProperties(); } } } } } HEU_EditorUI.EndSection(); HEU_EditorUI.DrawSeparator(); }
private float GetBrushRadius() { SerializedProperty property = HEU_EditorUtility.GetSerializedProperty(_toolsInfoSerializedObject, "_paintBrushSize"); return (property != null) ? property.floatValue : 1f; }