private GameObject GetGameObjectFromType(Object obj, System.Type type) { if (type == typeof(GameObject)) { return(obj as GameObject); } else if (type == typeof(HEU_HoudiniAssetRoot)) { HEU_HoudiniAssetRoot heuRoot = obj as HEU_HoudiniAssetRoot; return(heuRoot.gameObject); } else if (type == typeof(Terrain)) { Terrain terrain = obj as Terrain; return(terrain.gameObject); } else if (type == typeof(HEU_BoundingVolume)) { HEU_BoundingVolume volume = obj as HEU_BoundingVolume; return(volume.gameObject); } else if (type == typeof(Tilemap)) { Tilemap tilemap = obj as Tilemap; return(tilemap.gameObject); } else { HEU_Logger.LogErrorFormat("Unsupported type {0} for Selection Window.", type); return(null); } }
private static void ProcessPendingBuildAction( HEU_HoudiniAsset.AssetBuildAction pendingBuildAction, SerializedProperty pendingBuildProperty, HEU_HoudiniAssetRoot assetRoot, SerializedObject assetRootSerializedObject, HEU_HoudiniAsset asset, SerializedObject assetObject) { 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) { // Recook should only update parameters that haven't changed. Otherwise if not checking and updating parameters, // then buttons will trigger callbacks on Recook which is not desired. SerializedProperty checkParameterChange = HEU_EditorUtility.GetSerializedProperty(assetObject, "_checkParameterChangeForCook"); if (checkParameterChange != null) { checkParameterChange.boolValue = true; } // But we do want to always upload input geometry on user hitting Recook expliclity SerializedProperty forceUploadInputs = HEU_EditorUtility.GetSerializedProperty(assetObject, "_forceUploadInputs"); if (forceUploadInputs != null) { forceUploadInputs.boolValue = true; } } } }
public static void CreatePDGAssetLink() { GameObject selectedGO = Selection.activeGameObject; if (selectedGO != null) { HEU_HoudiniAssetRoot assetRoot = selectedGO.GetComponent<HEU_HoudiniAssetRoot>(); if (assetRoot != null) { if (assetRoot._houdiniAsset != null) { string name = string.Format("{0}_PDGLink", assetRoot._houdiniAsset.AssetName); GameObject go = new GameObject(name); HEU_PDGAssetLink assetLink = go.AddComponent<HEU_PDGAssetLink>(); assetLink.Setup(assetRoot._houdiniAsset); Selection.activeGameObject = go; } else { Debug.LogError("Selected gameobject is not an instantiated HDA. Failed to create PDG Asset Link."); } } else { Debug.LogError("Selected gameobject is not an instantiated HDA. Failed to create PDG Asset Link."); } } else { //Debug.LogError("Nothing selected. Select an instantiated HDA first."); HEU_EditorUtility.DisplayErrorDialog("PDG Asset Link", "No HDA selected. You must select an instantiated HDA first.", "OK"); } }
private void DisconnectInputAssetActor(HEU_SessionBase session) { if (!_inputAssetConnected) { return; } if (_inputNodeType == InputNodeType.PARAMETER) { HEU_ParameterData paramData = _parentAsset.Parameters.GetParameter(_paramName); if(paramData == null) { Debug.LogErrorFormat("Unable to find parameter with name {0}!", _paramName); } else if (!session.SetParamStringValue(_nodeID, "", paramData.ParmID, 0)) { Debug.LogErrorFormat("Unable to clear object path parameter for input node!"); } } else if(session != null && _nodeID != HEU_Defines.HEU_INVALID_NODE_ID) { session.DisconnectNodeInput(_nodeID, _inputIndex, false); } HEU_HoudiniAssetRoot inputAssetRoot = _inputAsset != null ? _inputAsset.GetComponent<HEU_HoudiniAssetRoot>() : null; if (inputAssetRoot != null) { _parentAsset.DisconnectFromUpstream(inputAssetRoot._houdiniAsset); } // Must clear this and not delete as this points to existing asset node. // If _inputObjectType changes to MESH, node with this ID will get deleted. _connectedNodeID = HEU_Defines.HEU_INVALID_NODE_ID; _inputAssetConnected = false; }
/// <summary> /// Update the input connection based on the fact that the owner asset was recreated /// in the given session. Asset input connections will be updated, while mesh input /// connections will be invalidated without cleaning up because the IDs can't be trusted. /// </summary> /// <param name="session"></param> public void UpdateOnAssetRecreation(HEU_SessionBase session) { if (_inputObjectType == InputObjectType.HDA && IsInputAssetConnected()) { // For asset inputs, cook the asset if its not valid in session, and update the ID HEU_HoudiniAssetRoot inputAssetRoot = _connectedInputAsset.GetComponent<HEU_HoudiniAssetRoot>(); if (inputAssetRoot != null && !inputAssetRoot._houdiniAsset.IsAssetValidInHoudini(session)) { inputAssetRoot._houdiniAsset.RequestCook(true, false, true, true); // Update the _connectNodeID to the connected asset's ID since it might have changed during cook if (_connectedNodeID != HEU_Defines.HEU_INVALID_NODE_ID) { HAPI_NodeId otherAssetID = inputAssetRoot._houdiniAsset != null ? inputAssetRoot._houdiniAsset.AssetID : HEU_Defines.HEU_INVALID_NODE_ID; if (otherAssetID != _connectedNodeID) { _connectedNodeID = otherAssetID; } if(_connectedNodeID == HEU_Defines.HEU_INVALID_NODE_ID) { ClearConnectedInputAsset(); } } } } else if(_inputObjectType == InputObjectType.UNITY_MESH) { // For mesh input, invalidate _inputObjectsConnectedAssetIDs and _connectedNodeID as their // nodes most likely don't exist, and the IDs will not be correct since this asset got recreated // Note that _inputObjects don't need to be cleared as they will be used when recreating the connections. _inputObjectsConnectedAssetIDs.Clear(); _connectedNodeID = HEU_Defines.HEU_INVALID_NODE_ID; } }
public static GameObject CreateNewAsset(HEU_HoudiniAsset.HEU_AssetType assetType, string rootName = "HoudiniAsset", Transform parentTransform = null, HEU_SessionBase session = null, bool bBuildAsync = true) { if (session == null) { session = HEU_SessionManager.GetOrCreateDefaultSession(); } if (!session.IsSessionValid()) { Debug.LogWarning("Invalid Houdini Engine session!"); return(null); } // This will be the root GameObject for the HDA. Adding HEU_HoudiniAssetRoot // allows to use a custom Inspector. GameObject rootGO = new GameObject(); HEU_HoudiniAssetRoot assetRoot = rootGO.AddComponent <HEU_HoudiniAssetRoot>(); // Set the game object's name to the asset's name rootGO.name = string.Format("{0}{1}", rootName, rootGO.GetInstanceID()); // Under the root, we'll add the HEU_HoudiniAsset onto another GameObject // This will be marked as EditorOnly to strip out for builds GameObject hdaGEO = new GameObject(HEU_PluginSettings.HDAData_Name); hdaGEO.transform.parent = rootGO.transform; // This holds all Houdini Engine data HEU_HoudiniAsset asset = hdaGEO.AddComponent <HEU_HoudiniAsset>(); // Marking as EditorOnly to be excluded from builds if (HEU_GeneralUtility.DoesUnityTagExist(HEU_PluginSettings.EditorOnly_Tag)) { hdaGEO.tag = HEU_PluginSettings.EditorOnly_Tag; } // Bind the root to the asset assetRoot._houdiniAsset = asset; // Populate asset with what we know asset.SetupAsset(assetType, null, rootGO, session); // Build it in Houdini Engine asset.RequestReload(bBuildAsync); if (parentTransform != null) { rootGO.transform.parent = parentTransform; rootGO.transform.localPosition = Vector3.zero; } else { rootGO.transform.position = Vector3.zero; } return(rootGO); }
internal static bool CreateInputNodeWithMultiAssets(HEU_SessionBase session, HEU_HoudiniAsset parentAsset, ref HAPI_NodeId connectMergeID, ref List<HEU_InputHDAInfo> inputAssetInfos, bool bKeepWorldTransform, HAPI_NodeId mergeParentID = -1) { // Create the merge SOP node that the input nodes are going to connect to. if (!session.CreateNode(mergeParentID, "SOP/merge", null, true, out connectMergeID)) { HEU_Logger.LogErrorFormat("Unable to create merge SOP node for connecting input assets."); return false; } int numInputs = inputAssetInfos.Count; for (int i = 0; i < numInputs; ++i) { inputAssetInfos[i]._connectedInputNodeID = HEU_Defines.HEU_INVALID_NODE_ID; if (inputAssetInfos[i]._pendingGO == null) { continue; } // ID of the asset that will be connected HAPI_NodeId inputAssetID = HEU_Defines.HEU_INVALID_NODE_ID; HEU_HoudiniAssetRoot inputAssetRoot = inputAssetInfos[i]._pendingGO.GetComponent<HEU_HoudiniAssetRoot>(); if (inputAssetRoot != null && inputAssetRoot._houdiniAsset != null) { if (!inputAssetRoot._houdiniAsset.IsAssetValidInHoudini(session)) { // Force a recook if its not valid (in case it hasn't been loaded into the session) inputAssetRoot._houdiniAsset.RequestCook(true, false, true, true); } inputAssetID = inputAssetRoot._houdiniAsset.AssetID; } if (inputAssetID == HEU_Defines.HEU_INVALID_NODE_ID) { continue; } if (!session.ConnectNodeInput(connectMergeID, i, inputAssetID)) { HEU_Logger.LogErrorFormat("Unable to connect input nodes!"); return false; } inputAssetInfos[i]._connectedInputNodeID = inputAssetID; inputAssetInfos[i]._connectedGO = inputAssetInfos[i]._pendingGO; inputAssetInfos[i]._connectedMergeNodeID = connectMergeID; parentAsset.ConnectToUpstream(inputAssetRoot._houdiniAsset); } return true; }
public void ReconnectToUpstreamAsset() { if (_inputObjectType == InputObjectType.HDA && IsInputAssetConnected()) { HEU_HoudiniAssetRoot inputAssetRoot = _connectedInputAsset != null ? _connectedInputAsset.GetComponent<HEU_HoudiniAssetRoot>() : null; if (inputAssetRoot != null && inputAssetRoot._houdiniAsset != null) { _parentAsset.ConnectToUpstream(inputAssetRoot._houdiniAsset); } } }
/// <summary> /// Force cook upstream connected asset if its not valid in given session. /// </summary> /// <param name="session"></param> public void CookUpstreamConnectedAsset(HEU_SessionBase session) { if(_inputObjectType == InputObjectType.HDA && IsInputAssetConnected()) { HEU_HoudiniAssetRoot inputAssetRoot = _connectedInputAsset.GetComponent<HEU_HoudiniAssetRoot>(); if (inputAssetRoot != null && !inputAssetRoot._houdiniAsset.IsAssetValidInHoudini(session)) { inputAssetRoot._houdiniAsset.RequestCook(false, false, true, true); } } }
private void ClearConnectedInputAsset() { if (_connectedInputAsset != null) { HEU_HoudiniAssetRoot inputAssetRoot = _connectedInputAsset != null ? _connectedInputAsset.GetComponent<HEU_HoudiniAssetRoot>() : null; if (inputAssetRoot != null) { _parentAsset.DisconnectFromUpstream(inputAssetRoot._houdiniAsset); } _connectedInputAsset = null; } }
public void ReconnectToUpstreamAsset() { if (_inputObjectType == InputObjectType.HDA && AreAnyInputHDAsConnected()) { foreach (HEU_InputHDAInfo hdaInfo in _inputAssetInfos) { HEU_HoudiniAssetRoot inputAssetRoot = hdaInfo._connectedGO != null ? hdaInfo._connectedGO.GetComponent<HEU_HoudiniAssetRoot>() : null; if (inputAssetRoot != null && inputAssetRoot._houdiniAsset != null) { _parentAsset.ConnectToUpstream(inputAssetRoot._houdiniAsset); } } } }
private bool FindAddToInputHDA(string gameObjectName) { HEU_HoudiniAssetRoot inputAssetRoot = HEU_GeneralUtility.GetHDAByGameObjectNameInScene(gameObjectName); if (inputAssetRoot != null && inputAssetRoot._houdiniAsset != null) { // Adding to list will take care of reconnecting InternalAddInputHDAAtEnd(inputAssetRoot.gameObject); return true; } else { Debug.LogWarningFormat("HDA with gameobject name {0} not found. Unable to set input asset.", gameObjectName); } return false; }
/// <summary> /// Get the HDA in the current Unity scene, if it exists, with the assetID. /// </summary> /// <param name="assetID">Asset with this ID will be searched for</param> /// <returns>The asset in the scene with the ID, or null if not found</returns> public static HEU_HoudiniAssetRoot GetAssetInScene(HAPI_NodeId assetID) { HEU_HoudiniAssetRoot foundAsset = null; HEU_HoudiniAssetRoot[] houdiniAssets = GameObject.FindObjectsOfType <HEU_HoudiniAssetRoot>(); foreach (HEU_HoudiniAssetRoot assetRoot in houdiniAssets) { if (assetRoot._houdiniAsset != null && assetRoot._houdiniAsset.AssetID == assetID) { foundAsset = assetRoot; break; } } return(foundAsset); }
private GameObject GetGameObjectFromType(Object obj, System.Type type) { if (type == typeof(GameObject)) { return(obj as GameObject); } else if (type == typeof(HEU_HoudiniAssetRoot)) { HEU_HoudiniAssetRoot heuRoot = obj as HEU_HoudiniAssetRoot; return(heuRoot.gameObject); } else { Debug.LogErrorFormat("Unsupported type {0} for Selection Window.", type); return(null); } }
private void ConnectInputAssetActor(HEU_SessionBase session) { if(_inputAssetConnected) { return; } HEU_HoudiniAssetRoot inputAssetRoot = _inputAsset != null ? _inputAsset.GetComponent<HEU_HoudiniAssetRoot>() : null; if (inputAssetRoot != null && inputAssetRoot._houdiniAsset.IsAssetValidInHoudini(session)) { _connectedNodeID = inputAssetRoot._houdiniAsset.AssetID; ConnectInputNode(session); _parentAsset.ConnectToUpstream(inputAssetRoot._houdiniAsset); _inputAssetConnected = true; } }
public static void ExecuteToolOperatorSingle(string toolName, string toolPath, GameObject[] inputObjects) { GameObject go = HEU_HAPIUtility.InstantiateHDA(toolPath, Vector3.zero, HEU_SessionManager.GetOrCreateDefaultSession(), true); if (go != null) { HEU_HoudiniAssetRoot assetRoot = go.GetComponent<HEU_HoudiniAssetRoot>(); if (assetRoot != null) { //assetRoot._houdiniAsset // TODO } HEU_EditorUtility.SelectObject(go); } else { Debug.LogWarningFormat("Failed to instantiate tool: {0}", toolName); } }
public void TriggerButton(GraphReference reference) { Flow flow = Flow.New(reference); HEU_HoudiniAssetRoot hdaAssetRoot = flow.GetValue <HEU_HoudiniAssetRoot>(inputHDA); if (hdaAssetRoot != null && hdaAssetRoot.HoudiniAsset != null) { hdaAsset = hdaAssetRoot.HoudiniAsset; } System.Action ContinueFlow = () => { flow.Invoke(trigger); }; Debug.Log("Triggered"); ContinueFlow(); }
/// <summary> /// Load and instantiate an HDA asset in Unity and Houdini, for the asset located at given path. /// </summary> /// <param name="filePath">Full path to the HDA in Unity project</param> /// <param name="initialPosition">Initial location to create the instance in Unity.</param> /// <returns>Returns the newly created gameobject for the asset in the scene, or null if creation failed.</returns> public static GameObject InstantiateHDA(string filePath, Vector3 initialPosition, HEU_SessionBase session, bool bBuildAsync) { if (filePath == null || !HEU_Platform.DoesFileExist(filePath)) { return(null); } // This will be the root GameObject for the HDA. Adding HEU_HoudiniAssetRoot // allows to use a custom Inspector. GameObject rootGO = new GameObject(HEU_Defines.HEU_DEFAULT_ASSET_NAME); HEU_HoudiniAssetRoot assetRoot = rootGO.AddComponent <HEU_HoudiniAssetRoot>(); // Under the root, we'll add the HEU_HoudiniAsset onto another GameObject // This will be marked as EditorOnly to strip out for builds GameObject hdaGEO = new GameObject(HEU_PluginSettings.HDAData_Name); hdaGEO.transform.parent = rootGO.transform; // This holds all Houdini Engine data HEU_HoudiniAsset asset = hdaGEO.AddComponent <HEU_HoudiniAsset>(); // Marking as EditorOnly to be excluded from builds if (HEU_GeneralUtility.DoesUnityTagExist(HEU_PluginSettings.EditorOnly_Tag)) { hdaGEO.tag = HEU_PluginSettings.EditorOnly_Tag; } // Bind the root to the asset assetRoot._houdiniAsset = asset; // Populate asset with what we know asset.SetupAsset(HEU_HoudiniAsset.HEU_AssetType.TYPE_HDA, filePath, rootGO, session); // Build it in Houdini Engine asset.RequestReload(bBuildAsync); // Apply Unity transform and possibly upload to Houdini Engine rootGO.transform.position = initialPosition; Debug.LogFormat("{0}: Created new HDA asset from {1} of type {2}.", HEU_Defines.HEU_NAME, filePath, asset.AssetType); return(rootGO); }
private void ClearConnectedInputHDAs() { int numInputs = _inputAssetInfos.Count; for (int i = 0; i < numInputs; ++i) { if (_inputAssetInfos[i] == null) { continue; } HEU_HoudiniAssetRoot inputAssetRoot = _inputAssetInfos[i]._connectedGO != null ? _inputAssetInfos[i]._connectedGO.GetComponent<HEU_HoudiniAssetRoot>() : null; if (inputAssetRoot != null) { _parentAsset.DisconnectFromUpstream(inputAssetRoot._houdiniAsset); } _inputAssetInfos[i]._connectedGO = null; _inputAssetInfos[i]._connectedInputNodeID = HEU_Defines.HEU_INVALID_NODE_ID; } }
/// <summary> /// Get list of user selected Houdini assets root components in the scene. /// </summary> /// <returns>List of selected Houdini asset root components (HEU_HoudiniAssetRoot)</returns> public static HEU_HoudiniAssetRoot[] GetSelectedAssetRoots() { List<HEU_HoudiniAssetRoot> rootAssets = new List<HEU_HoudiniAssetRoot>(); #if UNITY_EDITOR Object[] selectedObjects = Selection.objects; foreach (Object obj in selectedObjects) { GameObject go = obj as GameObject; if (go != null) { HEU_HoudiniAssetRoot root = go.GetComponent<HEU_HoudiniAssetRoot>(); if (root != null) { rootAssets.Add(root); } } } #endif return rootAssets.ToArray(); }
private void ConnectInputAssetActor(HEU_SessionBase session) { if(IsInputAssetConnected()) { Debug.LogWarning("Input asset already connected!"); return; } HEU_HoudiniAssetRoot inputAssetRoot = _inputAsset != null ? _inputAsset.GetComponent<HEU_HoudiniAssetRoot>() : null; if (inputAssetRoot != null && inputAssetRoot._houdiniAsset.IsAssetValidInHoudini(session)) { _connectedNodeID = inputAssetRoot._houdiniAsset.AssetID; ConnectInputNode(session); _parentAsset.ConnectToUpstream(inputAssetRoot._houdiniAsset); _connectedInputAsset = _inputAsset; } }
/// <summary> /// Force cook upstream connected asset if its not valid in given session. /// </summary> /// <param name="session"></param> public void CookUpstreamConnectedAsset(HEU_SessionBase session) { if(_inputObjectType == InputObjectType.HDA && IsInputAssetConnected()) { HEU_HoudiniAssetRoot inputAssetRoot = _connectedInputAsset.GetComponent<HEU_HoudiniAssetRoot>(); if (inputAssetRoot != null && !inputAssetRoot._houdiniAsset.IsAssetValidInHoudini(session)) { inputAssetRoot._houdiniAsset.RequestCook(true, false, true, true); // Update the _connectNodeID to the connected asset's ID since it might have changed during cook if(_connectedNodeID != HEU_Defines.HEU_INVALID_NODE_ID) { HAPI_NodeId otherAssetID = inputAssetRoot._houdiniAsset != null ? inputAssetRoot._houdiniAsset.AssetID : HEU_Defines.HEU_INVALID_NODE_ID; if(otherAssetID != _connectedNodeID) { _connectedNodeID = otherAssetID; } } } } }
// LOGIC ----------------------------------------------------------------------------------------------------- private void OnEnable() { _reloadhdaIcon = Resources.Load("heu_reloadhdaIcon") as Texture2D; _recookhdaIcon = Resources.Load("heu_recookhdaIcon") as Texture2D; _bakegameobjectIcon = Resources.Load("heu_bakegameobjectIcon") as Texture2D; _bakeprefabIcon = Resources.Load("heu_bakeprefabIcon") as Texture2D; _bakeandreplaceIcon = Resources.Load("heu_bakeandreplaceIcon") as Texture2D; _removeheIcon = Resources.Load("heu_removeheIcon") as Texture2D; _duplicateAssetIcon = Resources.Load("heu_duplicateassetIcon") as Texture2D; _reloadhdaContent = new GUIContent(" Reload Asset", _reloadhdaIcon, "Reset and reload the asset in Houdini. Parameter values are reset to default, and material overrides are removed."); _recookhdaContent = new GUIContent(" Recook Asset", _recookhdaIcon, "Force recook of the asset in Houdini with the current parameter values and specified input data. Updates asset if changed in Houdini."); _bakegameobjectContent = new GUIContent(" Bake GameObject", _bakegameobjectIcon, "Bakes the output to a new GameObject. Meshes and Materials are copied."); _bakeprefabContent = new GUIContent(" Bake Prefab", _bakeprefabIcon, "Bakes the output to a new Prefab. Meshes and Materials are copied."); _bakeandreplaceContent = new GUIContent(" Bake Update", _bakeandreplaceIcon, "Update existing GameObject(s) and Prefab(s). Generated components, meshes, and materials are updated."); _removeheContent = new GUIContent(" Keep Only Output", _removeheIcon, "Remove HDA_Data and the Houdini Asset Root object, and leave just the output GameObject."); _duplicateContent = new GUIContent(" Duplicate Asset", _duplicateAssetIcon, "Safe duplication of this asset to create an exact copy. The asset is duplicated in Houdini. All data is copied over."); // Get the root gameobject, and the HDA bound to it _houdiniAssetRoot = target as HEU_HoudiniAssetRoot; TryAcquiringAsset(); }
// LOGIC ----------------------------------------------------------------------------------------------------- private void OnEnable() { _reloadhdaIcon = Resources.Load("heu_reloadhdaIcon") as Texture2D; _recookhdaIcon = Resources.Load("heu_recookhdaIcon") as Texture2D; _bakegameobjectIcon = Resources.Load("heu_bakegameobjectIcon") as Texture2D; _bakeprefabIcon = Resources.Load("heu_bakeprefabIcon") as Texture2D; _bakeandreplaceIcon = Resources.Load("heu_bakeandreplaceIcon") as Texture2D; _removeheIcon = Resources.Load("heu_removeheIcon") as Texture2D; _duplicateAssetIcon = Resources.Load("heu_duplicateassetIcon") as Texture2D; _resetParamIcon = Resources.Load("heu_resetparametersIcon") as Texture2D; _reloadhdaContent = new GUIContent(" Rebuild ", _reloadhdaIcon, "Reload the asset in Houdini and cook it. Current parameter values and input objects will be re-applied. Material overrides will be removed."); _recookhdaContent = new GUIContent(" Recook ", _recookhdaIcon, "Force recook of the asset in Houdini with the current parameter values and specified input data. Updates asset if changed in Houdini."); _bakegameobjectContent = new GUIContent(" GameObject", _bakegameobjectIcon, "Bakes the output to a new GameObject. Meshes and Materials are copied."); _bakeprefabContent = new GUIContent(" Prefab", _bakeprefabIcon, "Bakes the output to a new Prefab. Meshes and Materials are copied."); _bakeandreplaceContent = new GUIContent(" Update", _bakeandreplaceIcon, "Update existing GameObject(s) and Prefab(s). Generated components, meshes, and materials are updated."); _removeheContent = new GUIContent(" Keep Only Output", _removeheIcon, "Remove Houdini Engine data (HDA_Data, Houdini Asset Root object), and leave just the generated Unity data (meshes, materials, instances, etc.)."); _duplicateContent = new GUIContent(" Duplicate", _duplicateAssetIcon, "Safe duplication of this asset to create an exact copy. The asset is duplicated in Houdini. All data is copied over."); _resetParamContent = new GUIContent(" Reset All", _resetParamIcon, "Reset all parameters, materials, and inputs to their HDA default values, clear cache, reload HDA, cook, and generate output."); // Get the root gameobject, and the HDA bound to it _houdiniAssetRoot = target as HEU_HoudiniAssetRoot; TryAcquiringAsset(); }
/// <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)) { float tripleButtonWidth = Mathf.Round((screenWidth - widthPadding) * 0.33f); if (GUILayout.Button(_removeheContent, buttonStyle, GUILayout.Width(tripleButtonWidth))) { pendingBuildAction = HEU_HoudiniAsset.AssetBuildAction.STRIP_HEDATA; bSkipDrawing = true; } GUILayout.Space(separatorDistance); if (GUILayout.Button(_duplicateContent, buttonStyle, GUILayout.Width(tripleButtonWidth))) { pendingBuildAction = HEU_HoudiniAsset.AssetBuildAction.DUPLICATE; bSkipDrawing = true; } GUILayout.Space(separatorDistance); if (GUILayout.Button(_resetParamContent, buttonStyle, GUILayout.Width(tripleButtonWidth))) { pendingBuildAction = HEU_HoudiniAsset.AssetBuildAction.RESET_PARAMS; 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.IsPrefabAsset(bakeGO)) { // Prefab asset means its the source prefab, and not an instance of it 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) { // Recook should only update parameters that haven't changed. Otherwise if not checking and updating parameters, // then buttons will trigger callbacks on Recook which is not desired. SerializedProperty checkParameterChange = HEU_EditorUtility.GetSerializedProperty(assetObject, "_checkParameterChangeForCook"); if (checkParameterChange != null) { checkParameterChange.boolValue = true; } } } } if (EditorGUI.EndChangeCheck()) { assetRootSerializedObject.ApplyModifiedProperties(); assetObject.ApplyModifiedProperties(); } return bSkipDrawing; }
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 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()); } }
private static bool DrawBakeSection(HEU_HoudiniAssetRoot assetRoot, SerializedObject assetRootSerializedObject, HEU_HoudiniAsset asset, SerializedObject assetObject, ref HEU_HoudiniAsset.AssetBuildAction pendingBuildAction) { bool bSkipAutoCook = false; HEU_EditorUI.BeginSection(); { SerializedProperty showBakeProperty = assetObject.FindProperty("_showBakeSection"); showBakeProperty.boolValue = HEU_EditorUI.DrawFoldOut(showBakeProperty.boolValue, "BAKE"); if (showBakeProperty.boolValue) { // Bake -> New Instance, New Prefab, Existing instance or prefab using (var hs = new EditorGUILayout.HorizontalScope(_mainBoxStyle)) { if (GUILayout.Button(_bakegameobjectContent, _mainButtonStyle)) { asset.BakeToNewStandalone(); } GUILayout.Space(_mainButtonSeparatorDistance); if (GUILayout.Button(_bakeprefabContent, _mainButtonStyle)) { asset.BakeToNewPrefab(); } } using (var vs = new EditorGUILayout.VerticalScope(_mainBoxStyle)) { if (GUILayout.Button(_removeheContent, _mainButtonStyle)) { pendingBuildAction = HEU_HoudiniAsset.AssetBuildAction.STRIP_HEDATA; bSkipAutoCook = true; } } using (var hs2 = new EditorGUILayout.VerticalScope(_mainBoxStyle)) { if (GUILayout.Button(_bakeandreplaceContent, _mainCentredButtonStyle)) { 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.IsPrefabAsset(bakeGO)) { // Prefab asset means its the source prefab, and not an instance of it 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(_mainButtonSetStyle)) { SerializedProperty bakeTargetsProp = assetRootSerializedObject.FindProperty("_bakeTargets"); if (bakeTargetsProp != null) { EditorGUILayout.PropertyField(bakeTargetsProp, _dragAndDropField, true); } } } } } HEU_EditorUI.EndSection(); HEU_EditorUI.DrawSeparator(); return bSkipAutoCook; }
public void UploadInput(HEU_SessionBase session) { if (_nodeID == HEU_Defines.HEU_INVALID_NODE_ID) { Debug.LogErrorFormat("Input Node ID is invalid. Unable to upload input. Try recooking."); return; } if(_pendingInputObjectType != _inputObjectType) { ChangeInputType(session, _pendingInputObjectType); } if(_inputObjectType == InputObjectType.UNITY_MESH) { if(_inputObjects == null || _inputObjects.Count == 0) { DisconnectAndDestroyInputAssets(session); } else { DisconnectAndDestroyInputAssets(session); bool bResult = HEU_InputUtility.CreateInputNodeWithMultiObjects(session, _nodeID, ref _connectedNodeID, ref _inputObjects, ref _inputObjectsConnectedAssetIDs, _keepWorldTransform); if(!bResult) { DisconnectAndDestroyInputAssets(session); return; } ConnectInputNode(session); if(!UploadObjectMergeTransformType(session)) { Debug.LogErrorFormat("Failed to upload object merge transform type!"); return; } if (!UploadObjectMergePackGeometry(session)) { Debug.LogErrorFormat("Failed to upload object merge pack geometry value!"); return; } } } else if(_inputObjectType == InputObjectType.HDA) { // Connect HDA. Note only 1 connection supported. if (IsInputAssetConnected()) { DisconnectInputAssetActor(session); } if (_inputAsset != null) { HEU_HoudiniAssetRoot inputAssetRoot = _inputAsset.GetComponent<HEU_HoudiniAssetRoot>(); if(inputAssetRoot != null && inputAssetRoot._houdiniAsset != null) { if (!inputAssetRoot._houdiniAsset.IsAssetValidInHoudini(session)) { // Force a recook if its not valid (in case it hasn't been loaded into the session) inputAssetRoot._houdiniAsset.RequestCook(true, false, true, true); } ConnectInputAssetActor(session); } else { Debug.LogWarningFormat("The input GameObject {0} is not a valid HDA asset.", _inputAsset.name); } } } //else if (_inputObjectType == InputObjectType.CURVE) //{ // TODO INPUT NODE - create new Curve SOP (add HEU_Curve here?) //} else { Debug.LogErrorFormat("Unsupported input type {0}. Unable to upload input.", _inputObjectType); } RequiresUpload = false; RequiresCook = true; ClearUICache(); }
public void LoadPreset(HEU_SessionBase session, HEU_InputPreset inputPreset) { ResetInputNode(session); ChangeInputType(session, inputPreset._inputObjectType); if (inputPreset._inputObjectType == HEU_InputNode.InputObjectType.UNITY_MESH) { int numObjects = inputPreset._inputObjectPresets.Count; for (int i = 0; i < numObjects; ++i) { if (!string.IsNullOrEmpty(inputPreset._inputObjectPresets[i]._gameObjectName)) { GameObject inputGO = null; if (inputPreset._inputObjectPresets[i]._isSceneObject) { inputGO = HEU_GeneralUtility.GetGameObjectByNameInScene(inputPreset._inputObjectPresets[i]._gameObjectName); } else { // Use the _gameObjectName as path to find in scene inputGO = HEU_AssetDatabase.LoadAssetAtPath(inputPreset._inputObjectPresets[i]._gameObjectName, typeof(GameObject)) as GameObject; if(inputGO == null) { Debug.LogErrorFormat("Unable to find input at {0}", inputPreset._inputObjectPresets[i]._gameObjectName); } } if (inputGO != null) { HEU_InputObjectInfo inputObject = AddInputObjectAtEnd(inputGO); inputObject._useTransformOffset = inputPreset._inputObjectPresets[i]._useTransformOffset; inputObject._translateOffset = inputPreset._inputObjectPresets[i]._translateOffset; inputObject._rotateOffset = inputPreset._inputObjectPresets[i]._rotateOffset; inputObject._scaleOffset = inputPreset._inputObjectPresets[i]._scaleOffset; } else { Debug.LogWarningFormat("Gameobject with name {0} not found. Unable to set input object.", inputPreset._inputAssetName); } } } } else if (inputPreset._inputObjectType == HEU_InputNode.InputObjectType.HDA) { if (!string.IsNullOrEmpty(inputPreset._inputAssetName)) { GameObject inputAsset = GameObject.Find(inputPreset._inputAssetName); if (inputAsset != null) { HEU_HoudiniAssetRoot inputAssetRoot = inputAsset != null ? inputAsset.GetComponent<HEU_HoudiniAssetRoot>() : null; if (inputAssetRoot != null && inputAssetRoot._houdiniAsset != null) { // Need to reconnect and make sure connected asset is in this session _inputAsset = inputAsset; if (!inputAssetRoot._houdiniAsset.IsAssetValidInHoudini(session)) { inputAssetRoot._houdiniAsset.RequestCook(true, false, true, true); } _connectedNodeID = inputAssetRoot._houdiniAsset.AssetID; _parentAsset.ConnectToUpstream(inputAssetRoot._houdiniAsset); _connectedInputAsset = _inputAsset; } else { Debug.LogErrorFormat("Input HDA with name {0} is not a valid asset (missing components). Unable to set input asset.", inputPreset._inputAssetName); } } else { Debug.LogWarningFormat("Game with name {0} not found. Unable to set input asset.", inputPreset._inputAssetName); } } } KeepWorldTransform = inputPreset._keepWorldTransform; PackGeometryBeforeMerging = inputPreset._packGeometryBeforeMerging; RequiresUpload = true; ClearUICache(); }