/// <summary> /// Create new instance if none found. /// Loads plugin data from file. /// </summary> public static void InstantiateAndLoad() { if (_instance == null) { _instance = new HEU_PluginStorage(); _instance.LoadPluginData(); // Set the current culture based on user plugin setting. By default (fresh install) // this sets to InvariantCulture to fix decimal parsing issues on certain locales (like es-ES). // Note that this sets for the entire project as long as the plugin is in use. // Users can turn this off from Plugin Settings. SetCurrentCulture(HEU_PluginSettings.SetCurrentThreadToInvariantCulture); HEU_SessionManager.LoadAllSessionData(); _instance.LoadAssetEnvironmentPaths(); } }
public static void ReinitializeSession() { // Force to find engine path again if not found. if (!HEU_Platform.IsPathSet) { HEU_Platform.SetHoudiniEnginePath(); } bool bResult = HEU_SessionManager.RestartSession(); if(!bResult) { HEU_EditorUtility.DisplayDialog("Reinitializing Session", HEU_SessionManager.GetLastSessionError(), "OK"); } else { Debug.Log("Houdini Engine Session restarted."); } }
public HEU_SessionBase GetHoudiniSession(bool bCreateIfNotFound) { HEU_SessionBase session = (_sessionID != HEU_SessionData.INVALID_SESSION_ID) ? HEU_SessionManager.GetSessionWithID(_sessionID) : null; if (session == null || !session.IsSessionValid()) { if (bCreateIfNotFound) { session = HEU_SessionManager.GetOrCreateDefaultSession(); if (session != null && session.IsSessionValid()) { _sessionID = session.GetSessionData().SessionID; } } } return session; }
/// <summary> /// Disconnect from SessionSync and close session. /// </summary> void Disconnect(HEU_SessionSyncData syncData) { if (syncData != null) { syncData.SyncStatus = HEU_SessionSyncData.Status.Stopped; // Store the sync info as it gets cleared in the session below _connectionSyncData = syncData; } if (HEU_SessionManager.CloseDefaultSession()) { Log("Connection closed!"); } else { Log("Failed to close session! "); } }
public static void LoadHoudiniAssetWindow() { if (HEU_SessionManager.ValidatePluginSession()) { string[] extensions = { "HDAs", "otl,hda,otllc,hdalc,otlnc,hdanc" }; string hdaPath = EditorUtility.OpenFilePanelWithFilters("Load Houdini Digital Asset", HEU_PluginSettings.LastLoadHDAPath, extensions); if (!string.IsNullOrEmpty(hdaPath)) { // Store HDA path for next time HEU_PluginSettings.LastLoadHDAPath = Path.GetDirectoryName(hdaPath); GameObject go = HEU_HAPIUtility.InstantiateHDA(hdaPath, Vector3.zero, HEU_SessionManager.GetOrCreateDefaultSession(), true); if (go != null) { HEU_EditorUtility.SelectObject(go); } } } }
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 bool GenerateInstancerBuffers(HEU_SessionBase session, HAPI_NodeId nodeID, List<HAPI_PartInfo> instancerParts, out List<HEU_LoadBufferInstancer> instancerBuffers) { instancerBuffers = null; if (instancerParts.Count == 0) { return true; } instancerBuffers = new List<HEU_LoadBufferInstancer>(); foreach (HAPI_PartInfo partInfo in instancerParts) { HAPI_NodeId geoID = nodeID; HAPI_PartId partID = partInfo.id; string partName = HEU_SessionManager.GetString(partInfo.nameSH, session); HEU_LoadBufferInstancer newBuffer = null; if (partInfo.instancedPartCount > 0) { // Part instancer newBuffer = GeneratePartsInstancerBuffer(session, geoID, partID, partName, partInfo); } else if (partInfo.vertexCount == 0 && partInfo.pointCount > 0) { // Point attribute instancer newBuffer = GeneratePointAttributeInstancerBuffer(session, geoID, partID, partName, partInfo); } else { SetLog(HEU_LoadData.LoadStatus.ERROR, string.Format("Invalid instanced part count: {0} for part {1}", partInfo.instancedPartCount, partName)); continue; } if (newBuffer != null) { instancerBuffers.Add(newBuffer); } } return true; }
public static HEU_MaterialData CreateHoudiniMaterialData(HEU_SessionBase session, HAPI_NodeId assetID, HAPI_NodeId materialID, HAPI_NodeId geoID, HAPI_PartId partID, List<HEU_MaterialData> materialCache, string assetCacheFolderPath) { string materialName = ""; if (materialID == HEU_Defines.HEU_INVALID_NODE_ID) { return GetOrCreateDefaultMaterialInCache(session, geoID, partID, false, materialCache, assetCacheFolderPath); } else { materialName = HEU_SessionManager.GetUniqueMaterialShopName(assetID, materialID); } HEU_MaterialData materialData = ScriptableObject.CreateInstance<HEU_MaterialData>(); materialData._materialSource = HEU_MaterialData.Source.HOUDINI; materialData._materialKey = materialID; materialData._material = HEU_MaterialFactory.CreateNewHoudiniStandardMaterial(assetCacheFolderPath, materialName, true); materialData._material.name = materialName; //Debug.LogFormat("New Material ID: {0} - {1}", materialID, materialName); if (materialID != HEU_Defines.HEU_INVALID_NODE_ID) { // Get material info from Houdini to populate the Unity material values HAPI_MaterialInfo materialInfo = new HAPI_MaterialInfo(); if (session.GetMaterialInfo(materialID, ref materialInfo)) { if (materialInfo.exists) { materialData.UpdateMaterialFromHoudini(materialInfo, assetCacheFolderPath); } } } //Debug.LogFormat("Created new material with id={0} and name={1}", materialID, materialName); materialCache.Add(materialData); return materialData; }
/// <summary> /// Returns the Unity script attribute value, if found, on the specified geo's part. /// The attribute must be of string type, and owned by detail. /// </summary> /// <param name="session">Session that the asset resides in</param> /// <param name="geoID">The geo node's ID</param> /// <param name="partID">The part's ID</param> /// <returns>The name of the Unity script, or null if not found</returns> public static string GetUnityScriptAttributeValue(HEU_SessionBase session, HAPI_NodeId geoID, HAPI_PartId partID) { HAPI_AttributeInfo scriptAttributeInfo = new HAPI_AttributeInfo(); int[] scriptAttr = new int[0]; string scriptString = null; HEU_GeneralUtility.GetAttribute(session, geoID, partID, HEU_PluginSettings.UnityScriptAttributeName, ref scriptAttributeInfo, ref scriptAttr, session.GetAttributeStringData); if (scriptAttributeInfo.exists) { if (scriptAttributeInfo.owner != HAPI_AttributeOwner.HAPI_ATTROWNER_DETAIL) { Debug.LogWarningFormat("Houdini Engine for Unity only supports {0} as detail attributes!", HEU_PluginSettings.UnityScriptAttributeName); } else if (scriptAttr.Length > 0) { scriptString = HEU_SessionManager.GetString(scriptAttr[0]); } } return scriptString; }
// GEOMETRY GETTERS ------------------------------------------------------------------------------------------- public static string GetUniqueMaterialShopName(HAPI_NodeId assetID, HAPI_NodeId materialID) { HEU_SessionBase sessionBase = GetOrCreateDefaultSession(); if (sessionBase != null) { HAPI_AssetInfo assetInfo = new HAPI_AssetInfo(); if (!sessionBase.GetAssetInfo(assetID, ref assetInfo)) { return ""; } HAPI_MaterialInfo materialInfo = new HAPI_MaterialInfo(); if (!sessionBase.GetMaterialInfo(materialID, ref materialInfo)) { return ""; } HAPI_NodeInfo assetNodeInfo = new HAPI_NodeInfo(); if (!sessionBase.GetNodeInfo(assetID, ref assetNodeInfo)) { return ""; } HAPI_NodeInfo materialNodeInfo = new HAPI_NodeInfo(); if (!sessionBase.GetNodeInfo(materialInfo.nodeId, ref materialNodeInfo)) { return ""; } string assetNodeName = HEU_SessionManager.GetString(assetNodeInfo.internalNodePathSH, sessionBase); string materialNodeName = HEU_SessionManager.GetString(materialNodeInfo.internalNodePathSH, sessionBase); if (assetNodeName.Length > 0 && materialNodeName.Length > 0) { // Remove assetNodeName from materialNodeName. Extra position is for separator. string materialName = materialNodeName.Substring(assetNodeName.Length + 1); return materialName.Replace("/", "_"); } } return ""; }
/// <summary> /// Assign Unity layer to the GameObject if found on the part as attribute. /// </summary> /// <param name="session"></param> /// <param name="geoID"></param> /// <param name="partID"></param> /// <param name="gameObject"></param> public static void AssignUnityLayer(HEU_SessionBase session, HAPI_NodeId geoID, HAPI_PartId partID, GameObject gameObject) { HAPI_AttributeInfo layerAttrInfo = new HAPI_AttributeInfo(); int[] layerAttr = new int[0]; HEU_GeneralUtility.GetAttribute(session, geoID, partID, HEU_PluginSettings.UnityLayerAttributeName, ref layerAttrInfo, ref layerAttr, session.GetAttributeStringData); if (layerAttrInfo.exists) { string layerStr = HEU_SessionManager.GetString(layerAttr[0]); if (layerStr.Length > 0) { int layer = LayerMask.NameToLayer(layerStr); if (layer < 0) { Debug.LogWarningFormat("Unity layer '{0}' does not exist for current project. Add the layer in order to use it!", layerStr); } else { HEU_GeneralUtility.SetLayer(gameObject, layer, true); } } } }
/// <summary> /// Assign the Unity tag to the GameObject if found on the part as attribute. /// </summary> public static void AssignUnityTag(HEU_SessionBase session, HAPI_NodeId geoID, HAPI_PartId partID, GameObject gameObject) { HAPI_AttributeInfo tagAttrInfo = new HAPI_AttributeInfo(); int[] tagAttr = new int[0]; HEU_GeneralUtility.GetAttribute(session, geoID, partID, HEU_PluginSettings.UnityTagAttributeName, ref tagAttrInfo, ref tagAttr, session.GetAttributeStringData); if (tagAttrInfo.exists) { string tag = HEU_SessionManager.GetString(tagAttr[0]); if (tag.Length > 0) { try { SetTag(gameObject, tag, true); } catch (Exception ex) { Debug.LogWarning("Tag exception: " + ex.ToString()); Debug.LogWarningFormat("Unity tag '{0}' does not exist for current project. Add the tag in order to use it!", tag); } } } }
/// <summary> /// Launch Houdini with SessionSync enabled and automatically connect to it. /// </summary> void StartAndConnectToHoudini(HEU_SessionSyncData syncData) { if (syncData != null && syncData.SyncStatus != HEU_SessionSyncData.Status.Stopped) { return; } if (!OpenHoudini()) { return; } // Now attempt to connect to it by moving into Connecting state HEU_SessionManager.RecreateDefaultSessionData(); if (syncData == null) { HEU_SessionData sessionData = HEU_SessionManager.GetSessionData(); if (sessionData != null) { syncData = sessionData.GetOrCreateSessionSync(); } else { syncData = new HEU_SessionSyncData(); } syncData._validForConnection = true; } syncData.SyncStatus = HEU_SessionSyncData.Status.Connecting; _connectionSyncData = syncData; Log("Connecting..."); syncData._timeStartConnection = Time.realtimeSinceStartup; syncData._timeLastUpdate = Time.realtimeSinceStartup; }
public static int FindTextureParamByNameOrTag(HEU_SessionBase session, HAPI_NodeId nodeID, HAPI_ParmInfo[] parameters, string parameterName, string useTextureParmName) { int outParmId = GetParameterIndexFromNameOrTag(session, nodeID, parameters, parameterName); if (outParmId < 0) { return outParmId; } // Check if the matching "use" parameter exists. int foundUseParmId = GetParameterIndexFromNameOrTag(session, nodeID, parameters, useTextureParmName); if (foundUseParmId >= 0) { // Found a valid "use" parameter. Check if it is disabled. int[] useValue = new int[1]; int intValuesIndex = parameters[foundUseParmId].intValuesIndex; if (session.GetParamIntValues(nodeID, useValue, parameters[foundUseParmId].intValuesIndex, 1)) { if (useValue.Length > 0 && useValue[0] == 0) { // We found the texture, but the use tag is disabled, so don't use it! return -1; } } } // Finally, make sure that the found texture parm is not empty! int[] parmValueHandle = new int[1]; if (session.GetParamStringValues(nodeID, parmValueHandle, parameters[outParmId].stringValuesIndex, 1)) { string parmValue = HEU_SessionManager.GetString(parmValueHandle[0], session); if (string.IsNullOrEmpty(parmValue)) { return -1; } } return outParmId; }
/// <summary> /// Download the latest HAPI_SessionSyncInfo from Houdini Engine /// to update the local state. /// </summary> void DownloadSessionSyncInfo(HEU_SessionBase session, HEU_SessionSyncData syncData) { if (session == null) { session = HEU_SessionManager.GetDefaultSession(); if (session == null || !session.IsSessionValid()) { return; } } HAPI_SessionSyncInfo syncInfo = new HAPI_SessionSyncInfo(); if (session.GetSessionSyncInfo(ref syncInfo)) { if (HEU_HAPIUtility.IsSessionSyncEqual(ref syncInfo, ref syncData._syncInfo)) { Repaint(); } syncData._syncInfo = syncInfo; } }
/// <summary> /// Helper to parse spare parm containing the filter key words. /// </summary> /// <param name="session">Houdini Engine session that the TOP node is in</param> /// <param name="topNodeID">TOP node to get spare parm from</param> /// <param name="nodeInfo">Previously queried TOP node info</param> /// <param name="nodeTags">Tag data to populate</param> private static void ParseHEngineData(HEU_SessionBase session, HAPI_NodeId topNodeID, ref HAPI_NodeInfo nodeInfo, ref TOPNodeTags nodeTags) { // Turn off session logging error when querying string parm that might not be there bool bLogError = session.LogErrorOverride; session.LogErrorOverride = false; int numStrings = nodeInfo.parmStringValueCount; HAPI_StringHandle henginedatash = 0; if (numStrings > 0 && session.GetParamStringValue(topNodeID, "henginedata", 0, out henginedatash)) { string henginedatastr = HEU_SessionManager.GetString(henginedatash, session); //HEU_Logger.Log("HEngine data: " + henginedatastr); if (!string.IsNullOrEmpty(henginedatastr)) { string[] tags = henginedatastr.Split(','); if (tags != null && tags.Length > 0) { foreach (string t in tags) { if (t.Equals("show")) { nodeTags._showHEngineData = true; nodeTags._show = true; } else if (t.Equals("autoload")) { nodeTags._autoloadHEngineData = true; nodeTags._autoload = true; } } } } } // Logging error back on session.LogErrorOverride = bLogError; }
/// <summary> /// Helper to connect to a running instance of Houdini with SessionSync enabled. /// </summary> bool InternalConnect( SessionMode sessionType, string pipeName, string ip, int port, bool autoClose, float timeout, bool logError) { if (sessionType == SessionMode.Pipe) { return(HEU_SessionManager.ConnectSessionSyncUsingThriftPipe( pipeName, autoClose, timeout, logError)); } else { return(HEU_SessionManager.ConnectSessionSyncUsingThriftSocket( ip, port, autoClose, timeout, logError)); } }
/// <summary> /// Returns the single string value from Attribute with given name and owner type, or null if failed. /// </summary> /// <param name="session">Houdini Engine session to query</param> /// <param name="geoID">The geometry ID in Houdini</param> /// <param name="partID">The part ID in Houdini</param> /// <param name="attrName">Name of the attribute to query</param> /// <param name="attrOwner">Owner type of the attribute</param> /// <returns>Valid string if successful, otherwise returns null</returns> public static string GetAttributeStringValueSingle(HEU_SessionBase session, HAPI_NodeId geoID, HAPI_PartId partID, string attrName, HAPI_AttributeOwner attrOwner) { if (string.IsNullOrEmpty(attrName)) { return null; } HAPI_AttributeInfo attrInfo = new HAPI_AttributeInfo(); int[] stringHandle = new int[0]; HEU_GeneralUtility.GetAttribute(session, geoID, partID, attrName, ref attrInfo, ref stringHandle, session.GetAttributeStringData); if (attrInfo.exists) { if (attrInfo.owner != attrOwner) { Debug.LogWarningFormat("Expected {0} attribute owner for attribute {1} but got {2}!", attrOwner, attrName, attrInfo.owner); } else if (stringHandle.Length > 0) { return HEU_SessionManager.GetString(stringHandle[0]); } } return null; }
private void ParseVolumeDatas(HEU_SessionBase session, List<HEU_PartData> volumeParts) { bool bResult; foreach (HEU_PartData part in volumeParts) { HEU_GeoNode geoNode = part.ParentGeoNode; HAPI_VolumeInfo volumeInfo = new HAPI_VolumeInfo(); bResult = session.GetVolumeInfo(geoNode.GeoID, part.PartID, ref volumeInfo); if(!bResult || volumeInfo.tupleSize != 1 || volumeInfo.zLength != 1 || volumeInfo.storage != HAPI_StorageType.HAPI_STORAGETYPE_FLOAT) { continue; } string volumeName = HEU_SessionManager.GetString(volumeInfo.nameSH, session); //Debug.LogFormat("Part name: {0}, GeoName: {1}, Volume Name: {2}, Display: {3}", part.PartName, geoNode.GeoName, volumeName, geoNode.Displayable); if(volumeName.Equals("height")) { if (_heightMapVolumeData == null) { _heightMapVolumeData = new HEU_VolumeData(); _heightMapVolumeData._partData = part; _heightMapVolumeData._volumeInfo = volumeInfo; } } else { HEU_VolumeData volumeData = new HEU_VolumeData(); volumeData._partData = part; volumeData._volumeInfo = volumeInfo; _textureVolumeDatas.Add(volumeData); } } }
void OnGUI() { HEU_SessionBase sessionBase = HEU_SessionManager.GetDefaultSession(); if (sessionBase == null) { return; } SetupUI(); if (_outputLogUIComponent != null) { float setHeight = this.position.size.y - _bottomPadding; _outputLogUIComponent.SetHeight(setHeight); _outputLogUIComponent.OnGUI(HEU_CookLogs.Instance.GetCookLogString()); } if (GUILayout.Button("Delete Log File")) { HEU_CookLogs.Instance.DeleteCookingFile(); } }
/// <summary> /// For this object's _material, we update the shader attributes and /// fetch the textures from Houdini. /// </summary> /// <param name="materialInfo">This material's info from Houdini</param> /// <param name="assetCacheFolderPath">Path to asset's cache folder</param> public bool UpdateMaterialFromHoudini(HAPI_MaterialInfo materialInfo, string assetCacheFolderPath) { if (_material == null) { return false; } HEU_SessionBase session = HEU_SessionManager.GetOrCreateDefaultSession(); HAPI_NodeInfo nodeInfo = new HAPI_NodeInfo(); if (!session.GetNodeInfo(materialInfo.nodeId, ref nodeInfo)) { return false; } // Get all parameters of this material HAPI_ParmInfo[] parmInfos = new HAPI_ParmInfo[nodeInfo.parmCount]; if (!HEU_GeneralUtility.GetArray1Arg(materialInfo.nodeId, session.GetParams, parmInfos, 0, nodeInfo.parmCount)) { return false; } // Assign transparency shader or non-transparent. bool isTransparent = IsTransparentMaterial(session, materialInfo.nodeId, parmInfos); if (isTransparent) { _material.shader = HEU_MaterialFactory.FindPluginShader(HEU_PluginSettings.DefaultTransparentShader); } else { _material.shader = HEU_MaterialFactory.FindPluginShader(HEU_PluginSettings.DefaultStandardShader); } if (HEU_PluginSettings.UseLegacyShaders) { return UseLegacyShaders(materialInfo, assetCacheFolderPath, session, nodeInfo, parmInfos); } // Diffuse texture - render & extract int diffuseMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_TEX1_ATTR, HEU_Defines.MAT_OGL_TEX1_ATTR_ENABLED); if (diffuseMapParmIndex < 0) { diffuseMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_BASECOLOR_ATTR, HEU_Defines.MAT_BASECOLOR_ATTR_ENABLED); } if (diffuseMapParmIndex >= 0 && diffuseMapParmIndex < parmInfos.Length) { string diffuseTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[diffuseMapParmIndex]); _material.mainTexture = HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[diffuseMapParmIndex].id, diffuseTextureFileName, assetCacheFolderPath, false); } Color diffuseColor; if (!HEU_ParameterUtility.GetParameterColor3Value(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_DIFF_ATTR, Color.white, out diffuseColor)) { HEU_ParameterUtility.GetParameterColor3Value(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_DIFF_ATTR, Color.white, out diffuseColor); } float alpha; GetMaterialAlpha(session, materialInfo.nodeId, parmInfos, 1f, out alpha); if (isTransparent) { int opacityMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_OPACITY_MAP_ATTR, HEU_Defines.MAT_OGL_OPACITY_MAP_ATTR_ENABLED); if (opacityMapParmIndex < 0) { opacityMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OPACITY_MAP_ATTR, HEU_Defines.MAT_OPACITY_MAP_ATTR_ENABLED); } if (opacityMapParmIndex >= 0 && opacityMapParmIndex < parmInfos.Length) { string opacityTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[opacityMapParmIndex]); _material.SetTexture(HEU_Defines.UNITY_SHADER_OPACITY_MAP, HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[opacityMapParmIndex].id, opacityTextureFileName, assetCacheFolderPath, false)); } } diffuseColor.a = alpha; _material.SetColor(HEU_Defines.UNITY_SHADER_COLOR, diffuseColor); if (HEU_PluginSettings.UseSpecularShader) { Color specular; Color defaultSpecular = new Color(0.2f, 0.2f, 0.2f, 1); if (!HEU_ParameterUtility.GetParameterColor3Value(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_SPEC_ATTR, defaultSpecular, out specular)) { HEU_ParameterUtility.GetParameterColor3Value(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_SPEC_ATTR, defaultSpecular, out specular); } _material.SetColor(HEU_Defines.UNITY_SHADER_SPEC_COLOR, specular); int specMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_SPEC_MAP_ATTR, HEU_Defines.MAT_OGL_SPEC_MAP_ATTR_ENABLED); if (specMapParmIndex < 0) { specMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_SPEC_MAP_ATTR, HEU_Defines.MAT_SPEC_MAP_ATTR_ENABLED); } if (specMapParmIndex >= 0 && specMapParmIndex < parmInfos.Length) { string specTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[specMapParmIndex]); _material.SetTexture(HEU_Defines.UNITY_SHADER_SPEC_MAP, HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[specMapParmIndex].id, specTextureFileName, assetCacheFolderPath, false)); } } else { float metallic = 0; if (!HEU_ParameterUtility.GetParameterFloatValue(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_METALLIC_ATTR, 0f, out metallic)) { HEU_ParameterUtility.GetParameterFloatValue(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_METALLIC_ATTR, 0f, out metallic); } _material.SetFloat(HEU_Defines.UNITY_SHADER_METALLIC, metallic); int metallicMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_METALLIC_MAP_ATTR, HEU_Defines.MAT_OGL_METALLIC_MAP_ATTR_ENABLED); if (metallicMapParmIndex < 0) { metallicMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_METALLIC_MAP_ATTR, HEU_Defines.MAT_METALLIC_MAP_ATTR_ENABLED); } if (metallicMapParmIndex >= 0 && metallicMapParmIndex < parmInfos.Length) { string metallicTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[metallicMapParmIndex]); _material.SetTexture(HEU_Defines.UNITY_SHADER_METALLIC_MAP, HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[metallicMapParmIndex].id, metallicTextureFileName, assetCacheFolderPath, false)); } } // Normal map - render & extract texture int normalMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_NORMAL_ATTR, HEU_Defines.MAT_NORMAL_ATTR_ENABLED); if (normalMapParmIndex < 0) { normalMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_NORMAL_ATTR, ""); } if (normalMapParmIndex >= 0 && normalMapParmIndex < parmInfos.Length) { string normalTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[normalMapParmIndex]); Texture2D normalMap = HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[normalMapParmIndex].id, normalTextureFileName, assetCacheFolderPath, true); if (normalMap != null) { _material.SetTexture(HEU_Defines.UNITY_SHADER_BUMP_MAP, normalMap); } } // Emission Color emission; Color defaultEmission = new Color(0, 0, 0, 0); if (!HEU_ParameterUtility.GetParameterColor3Value(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_EMISSIVE_ATTR, defaultEmission, out emission)) { HEU_ParameterUtility.GetParameterColor3Value(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_EMISSIVE_ATTR, defaultEmission, out emission); } _material.SetColor(HEU_Defines.UNITY_SHADER_EMISSION_COLOR, emission); int emissionMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_EMISSIVE_MAP_ATTR, HEU_Defines.MAT_OGL_EMISSIVE_MAP_ATTR_ENABLED); if (emissionMapParmIndex < 0) { emissionMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_EMISSIVE_MAP_ATTR, HEU_Defines.MAT_EMISSIVE_MAP_ATTR_ENABLED); } if (emissionMapParmIndex >= 0 && emissionMapParmIndex < parmInfos.Length) { string emissionTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[emissionMapParmIndex]); _material.SetTexture(HEU_Defines.UNITY_SHADER_EMISSION_MAP, HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[emissionMapParmIndex].id, emissionTextureFileName, assetCacheFolderPath, false)); } // Smoothness (need to invert roughness!) float roughness; float defaultRoughness = 0.5f; if (!HEU_ParameterUtility.GetParameterFloatValue(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_ROUGH_ATTR, defaultRoughness, out roughness)) { HEU_ParameterUtility.GetParameterFloatValue(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_ROUGH_ATTR, defaultRoughness, out roughness); } // Clamp shininess to non-zero as results in very hard shadows. Unity's UI does not allow zero either. _material.SetFloat(HEU_Defines.UNITY_SHADER_SMOOTHNESS, Mathf.Max(0.03f, 1.0f - roughness)); int roughMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_ROUGH_MAP_ATTR, HEU_Defines.MAT_OGL_ROUGH_MAP_ATTR_ENABLED); if (roughMapParmIndex < 0) { roughMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_ROUGH_MAP_ATTR, HEU_Defines.MAT_ROUGH_MAP_ATTR_ENABLED); } if (roughMapParmIndex >= 0 && roughMapParmIndex < parmInfos.Length) { string roughTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[roughMapParmIndex]); _material.SetTexture(HEU_Defines.UNITY_SHADER_SMOOTHNESS_MAP, HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[roughMapParmIndex].id, roughTextureFileName, assetCacheFolderPath, false, invertTexture: true)); } // Occlusion (only has ogl map) int occlusionMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_OCCLUSION_MAP_ATTR, HEU_Defines.MAT_OGL_ROUGH_MAP_ATTR_ENABLED); if (occlusionMapParmIndex >= 0 && occlusionMapParmIndex < parmInfos.Length) { string occlusionTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[occlusionMapParmIndex]); _material.SetTexture(HEU_Defines.UNITY_SHADER_OCCLUSION_MAP, HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[occlusionMapParmIndex].id, occlusionTextureFileName, assetCacheFolderPath, false)); } return true; }
/// <summary> /// For this object's _material, we update the shader attributes and /// fetch the textures from Houdini. /// </summary> /// <param name="materialInfo">This material's info from Houdini</param> /// <param name="assetCacheFolderPath">Path to asset's cache folder</param> public void UpdateMaterialFromHoudini(HAPI_MaterialInfo materialInfo, string assetCacheFolderPath) { HEU_SessionBase session = HEU_SessionManager.GetOrCreateDefaultSession(); HAPI_NodeInfo nodeInfo = new HAPI_NodeInfo(); if (!session.GetNodeInfo(materialInfo.nodeId, ref nodeInfo)) { return; } // Get all parameters of this material HAPI_ParmInfo[] parmInfos = new HAPI_ParmInfo[nodeInfo.parmCount]; if (!HEU_GeneralUtility.GetArray1Arg(materialInfo.nodeId, session.GetParams, parmInfos, 0, nodeInfo.parmCount)) { return; } // Assign transparency shader or non-transparent. if (IsTransparentMaterial(session, materialInfo.nodeId, parmInfos)) { _material.shader = HEU_MaterialFactory.FindPluginShader(HEU_PluginSettings.DefaultTransparentShader); } else { _material.shader = HEU_MaterialFactory.FindPluginShader(HEU_PluginSettings.DefaultStandardShader); } // Diffuse texture - render & extract int diffuseMapParmIndex = HEU_ParameterUtility.GetParameterIndexFromNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_TEX1_ATTR); if (diffuseMapParmIndex < 0) { diffuseMapParmIndex = HEU_ParameterUtility.GetParameterIndexFromNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_BASECOLOR_ATTR); if (diffuseMapParmIndex < 0) { diffuseMapParmIndex = HEU_ParameterUtility.GetParameterIndexFromNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_MAP_ATTR); } } if (diffuseMapParmIndex >= 0 && diffuseMapParmIndex < parmInfos.Length) { string diffuseTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[diffuseMapParmIndex]); _material.mainTexture = HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[diffuseMapParmIndex].id, diffuseTextureFileName, assetCacheFolderPath); } // Normal map - render & extract texture int normalMapParmIndex = HEU_ParameterUtility.GetParameterIndexFromNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_NORMAL_ATTR); if (normalMapParmIndex >= 0 && normalMapParmIndex < parmInfos.Length) { string normalTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[normalMapParmIndex]); Texture2D normalMap = HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[normalMapParmIndex].id, normalTextureFileName, assetCacheFolderPath); if (normalMap != null) { _material.SetTexture(HEU_Defines.UNITY_SHADER_BUMP_MAP, normalMap); } } // Assign shader properties // Clamp shininess to non-zero as results in very hard shadows. Unity's UI does not allow zero either. float shininess = HEU_ParameterUtility.GetParameterFloatValue(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_ROUGH_ATTR, 0f); _material.SetFloat(HEU_Defines.UNITY_SHADER_SHININESS, Mathf.Max(0.03f, 1.0f - shininess)); Color diffuseColor = HEU_ParameterUtility.GetParameterColor3Value(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_DIFF_ATTR, Color.white); diffuseColor.a = HEU_ParameterUtility.GetParameterFloatValue(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_ALPHA_ATTR, 1f); _material.SetColor(HEU_Defines.UNITY_SHADER_COLOR, diffuseColor); Color specular = HEU_ParameterUtility.GetParameterColor3Value(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_SPEC_ATTR, Color.black); _material.SetColor(HEU_Defines.UNITY_SHADER_SPECCOLOR, specular); }
/// <summary> /// Unity callback to draw this UI. /// </summary> void OnGUI() { SetupUI(); HEU_SessionSyncData syncData = GetSessionSyncData(); EditorGUI.BeginChangeCheck(); bool bSessionStarted = (syncData != null && syncData.SyncStatus != HEU_SessionSyncData.Status.Stopped); bool bSessionCanStart = !bSessionStarted; if (bSessionCanStart) { // Only able to start a session if no session exists. HEU_SessionBase session = HEU_SessionManager.GetDefaultSession(); if (session != null && session.IsSessionValid()) { bSessionCanStart = false; } } HEU_HoudiniAssetUI.DrawHeaderSection(); // Draw SessionSync status. if (syncData != null) { if (syncData.SyncStatus == HEU_SessionSyncData.Status.Stopped) { if (!bSessionCanStart) { EditorGUILayout.LabelField("Another session already running. Disconnect it to start SessionSync."); } else { EditorGUILayout.LabelField("Status: " + syncData.SyncStatus); } } else { EditorGUILayout.LabelField("Status: " + syncData.SyncStatus); } } else { if (!bSessionCanStart) { EditorGUILayout.LabelField("Another session already running. Disconnect it to start SessionSync."); } else { EditorGUILayout.LabelField("No active session."); } } EditorGUILayout.Separator(); EditorGUI.indentLevel++; // Draw initial connection buttons (Start, Connect) using (new EditorGUILayout.HorizontalScope()) { using (new EditorGUI.DisabledScope(bSessionStarted || !bSessionCanStart)) { if (GUILayout.Button("Start Houdini")) { StartAndConnectToHoudini(syncData); } else if (GUILayout.Button("Connect to Houdini")) { ConnectSessionSync(syncData); } } } using (new EditorGUI.DisabledScope((syncData == null || !bSessionStarted) && bSessionCanStart)) { if (GUILayout.Button("Disconnect")) { Disconnect(syncData); } } EditorGUILayout.Separator(); // Draw Connection Settings EditorGUILayout.LabelField("Connection Settings"); using (new EditorGUI.DisabledScope(bSessionStarted)) { SessionMode newSessionMode = (SessionMode)EditorGUILayout.EnumPopup("Type", _sessionMode); if (_sessionMode != newSessionMode) { _sessionMode = newSessionMode; HEU_PluginSettings.Session_Mode = newSessionMode; } EditorGUI.indentLevel++; if (_sessionMode == SessionMode.Pipe) { string newPipeName = EditorGUILayout.DelayedTextField("Pipe Name", _pipeName); if (_pipeName != newPipeName) { HEU_PluginSettings.Session_PipeName = newPipeName; _pipeName = newPipeName; } } else if (_sessionMode == SessionMode.Socket) { int newPort = EditorGUILayout.DelayedIntField("Port", _port); HEU_PluginSettings.Session_Port = newPort; if (_port != newPort) { HEU_PluginSettings.Session_Port = newPort; _port = newPort; } } EditorGUI.indentLevel--; } EditorGUILayout.Separator(); // The rest requires syncData // Synchronization settings, and new nodes if (syncData != null) { using (new EditorGUI.DisabledScope(syncData.SyncStatus != HEU_SessionSyncData.Status.Connected)) { EditorGUILayout.LabelField("Synchronization Settings"); EditorGUI.indentLevel++; HEU_PluginSettings.SessionSyncAutoCook = HEU_EditorUI.DrawToggleLeft(HEU_PluginSettings.SessionSyncAutoCook, "Sync With Houdini Cook"); bool enableHoudiniTime = HEU_EditorUI.DrawToggleLeft(syncData._syncInfo.cookUsingHoudiniTime, "Cook Using Houdini Time"); if (syncData._syncInfo.cookUsingHoudiniTime != enableHoudiniTime) { syncData._syncInfo.cookUsingHoudiniTime = enableHoudiniTime; UploadSessionSyncInfo(null, syncData); } bool enableSyncViewport = HEU_EditorUI.DrawToggleLeft(syncData._syncInfo.syncViewport, "Sync Viewport"); if (syncData._syncInfo.syncViewport != enableSyncViewport) { syncData._syncInfo.syncViewport = enableSyncViewport; UploadSessionSyncInfo(null, syncData); } EditorGUI.indentLevel--; } EditorGUILayout.Separator(); EditorGUILayout.LabelField("New Node"); using (new EditorGUI.DisabledScope(syncData.SyncStatus != HEU_SessionSyncData.Status.Connected)) { EditorGUI.indentLevel++; syncData._newNodeName = EditorGUILayout.TextField("Name", syncData._newNodeName); syncData._nodeTypeIndex = EditorGUILayout.Popup("Type", syncData._nodeTypeIndex, _nodeTypesLabels); using (new EditorGUI.DisabledGroupScope(string.IsNullOrEmpty(syncData._newNodeName))) { using (new EditorGUILayout.VerticalScope()) { if (GUILayout.Button("Create")) { if (syncData._nodeTypeIndex >= 0 && syncData._nodeTypeIndex < 3) { HEU_NodeSync.CreateNodeSync(null, _nodeTypes[syncData._nodeTypeIndex], syncData._newNodeName); } else if (syncData._nodeTypeIndex == 3) { CreateCurve(syncData._newNodeName); } else if (syncData._nodeTypeIndex == 4) { CreateInput(syncData._newNodeName); } } if (GUILayout.Button("Load NodeSync")) { LoadNodeSyncDialog(syncData._newNodeName); } } } EditorGUI.indentLevel--; } EditorGUILayout.Separator(); // Log using (new EditorGUILayout.VerticalScope(_backgroundStyle)) { using (new EditorGUILayout.HorizontalScope()) { EditorGUILayout.PrefixLabel(_eventMessageContent); if (GUILayout.Button("Clear")) { ClearLog(); } } string logMsg = GetLog(); using (var scrollViewScope = new EditorGUILayout.ScrollViewScope(_eventMessageScrollPos, GUILayout.Height(120))) { _eventMessageScrollPos = scrollViewScope.scrollPosition; GUILayout.Label(logMsg, _eventMessageStyle); } } } EditorGUI.indentLevel--; if (EditorGUI.EndChangeCheck() && syncData != null) { HEU_SessionBase sessionBase = HEU_SessionManager.GetDefaultSession(); if (sessionBase != null) { HEU_SessionManager.SaveAllSessionData(); } } }
private static void EditorQuit() { Debug.Log("Houdini Engine: Editor is closing. Closing all sessions and clearing cache."); HEU_SessionManager.CloseAllSessions(); HEU_PluginStorage.DeleteAllSavedSessionData(); }
/// <summary> /// Process the part at the given index, creating its data (geometry), /// and adding it to the list of parts. /// </summary> /// <param name="session"></param> /// <param name="partID"></param> /// <returns>A valid HEU_PartData if it has been successfully processed.</returns> private void ProcessPart(HEU_SessionBase session, int partID, ref HAPI_PartInfo partInfo, ref HEU_PartData partData) { HEU_HoudiniAsset parentAsset = ParentAsset; bool bResult = true; //Debug.LogFormat("Part: name={0}, id={1}, type={2}, instanced={3}, instance count={4}, instance part count={5}", HEU_SessionManager.GetString(partInfo.nameSH, session), partID, partInfo.type, partInfo.isInstanced, partInfo.instanceCount, partInfo.instancedPartCount); #if HEU_PROFILER_ON float processPartStartTime = Time.realtimeSinceStartup; #endif bool isPartEditable = IsIntermediateOrEditable(); bool isAttribInstancer = false; if (IsGeoInputType()) { // Setup for input node to accept inputs if (_inputNode == null) { string partName = HEU_SessionManager.GetString(partInfo.nameSH, session); _inputNode = HEU_InputNode.CreateSetupInput(GeoID, 0, partName, HEU_InputNode.InputNodeType.NODE, ParentAsset); if (_inputNode != null) { ParentAsset.AddInputNode(_inputNode); } } if (HEU_HAPIUtility.IsSupportedPolygonType(partInfo.type) && partInfo.vertexCount == 0) { // No geometry for input asset if (partData != null) { // Clean up existing part HEU_PartData.DestroyPart(partData); partData = null; } // No need to process further since we don't have geometry return; } } else { // Preliminary check for attribute instancing (mesh type with no verts but has points with instances) if (HEU_HAPIUtility.IsSupportedPolygonType(partInfo.type) && partInfo.vertexCount == 0 && partInfo.pointCount > 0) { HAPI_AttributeInfo instanceAttrInfo = new HAPI_AttributeInfo(); HEU_GeneralUtility.GetAttributeInfo(session, GeoID, partID, HEU_PluginSettings.UnityInstanceAttr, ref instanceAttrInfo); if (instanceAttrInfo.exists && instanceAttrInfo.count > 0) { isAttribInstancer = true; } } } if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_INVALID) { // Clean up invalid parts if (partData != null) { HEU_PartData.DestroyPart(partData); partData = null; } } else if (partInfo.type < HAPI_PartType.HAPI_PARTTYPE_MAX) { // Process the part based on type. Keep or ignore. // We treat parts of type curve as curves, along with geo nodes that are editable and type curves if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_CURVE) { if (partData == null) { partData = ScriptableObject.CreateInstance <HEU_PartData>(); } partData.Initialize(session, partID, GeoID, _containerObjectNode.ObjectID, this, ref partInfo, HEU_PartData.PartOutputType.CURVE, isPartEditable, _containerObjectNode.IsInstancer(), false); SetupGameObjectAndTransform(partData, parentAsset); partData.ProcessCurvePart(session); } else if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_VOLUME) { // We only process "height" volume parts. Other volume parts are ignored for now. #if TERRAIN_SUPPORTED HAPI_VolumeInfo volumeInfo = new HAPI_VolumeInfo(); bResult = session.GetVolumeInfo(GeoID, partID, ref volumeInfo); if (!bResult) { Debug.LogErrorFormat("Unable to get volume info for geo node {0} and part {1} ", GeoID, partID); } else { if (Displayable && !IsIntermediateOrEditable()) { if (partData == null) { partData = ScriptableObject.CreateInstance <HEU_PartData>(); } else { // Clear volume data (case where switching from polygonal mesh to volume output) partData.ClearGeneratedMeshOutput(); } partData.Initialize(session, partID, GeoID, _containerObjectNode.ObjectID, this, ref partInfo, HEU_PartData.PartOutputType.VOLUME, isPartEditable, _containerObjectNode.IsInstancer(), false); SetupGameObjectAndTransform(partData, ParentAsset); } } #else Debug.LogWarningFormat("Terrain (heightfield volume) is not yet supported."); #endif } else if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_INSTANCER || isAttribInstancer) { if (partData == null) { partData = ScriptableObject.CreateInstance <HEU_PartData>(); } else { partData.ClearGeneratedMeshOutput(); partData.ClearGeneratedVolumeOutput(); } partData.Initialize(session, partID, GeoID, _containerObjectNode.ObjectID, this, ref partInfo, HEU_PartData.PartOutputType.INSTANCER, isPartEditable, _containerObjectNode.IsInstancer(), isAttribInstancer); SetupGameObjectAndTransform(partData, parentAsset); } else if (HEU_HAPIUtility.IsSupportedPolygonType(partInfo.type)) { if (partData == null) { partData = ScriptableObject.CreateInstance <HEU_PartData>(); } else { // Clear volume data (case where switching from something other output to mesh) partData.ClearGeneratedVolumeOutput(); } partData.Initialize(session, partID, GeoID, _containerObjectNode.ObjectID, this, ref partInfo, HEU_PartData.PartOutputType.MESH, isPartEditable, _containerObjectNode.IsInstancer(), false); // This check allows to ignore editable non-display nodes by default, but commented out to allow // them for now. Users can also ignore them by turning on IgnoreNonDisplayNodes //if (Displayable || (Editable && ParentAsset.EditableNodesToolsEnabled)) { SetupGameObjectAndTransform(partData, parentAsset); } } else { Debug.LogWarningFormat("Unsupported part type {0}", partInfo.type); } if (partData != null) { // Success! _parts.Add(partData); // Set unique name for the part string partName = HEU_PluginSettings.UseFullPathNamesForOutput ? GeneratePartFullName(partData.PartName) : partData.PartName; partData.SetGameObjectName(partName); // For intermediate or default-type editable nodes, setup the HEU_AttributeStore if (isPartEditable) { partData.SyncAttributesStore(session, _geoInfo.nodeId, ref partInfo); } else { // Remove attributes store if it has it partData.DestroyAttributesStore(); } } } #if HEU_PROFILER_ON Debug.LogFormat("PART PROCESS TIME:: NAME={0}, TIME={1}", HEU_SessionManager.GetString(partInfo.nameSH, session), (Time.realtimeSinceStartup - processPartStartTime)); #endif }
public void UpdateGeo(HEU_SessionBase session) { // Create or recreate parts. bool bObjectInstancer = _containerObjectNode.IsInstancer(); // Save list of old parts. We'll destroy these after creating new parts. // The reason for temporarily keeping these is to transfer data (eg. instance overrides, attribute data) List <HEU_PartData> oldParts = new List <HEU_PartData>(_parts); _parts.Clear(); try { if (!_geoInfo.isDisplayGeo) { if (ParentAsset.IgnoreNonDisplayNodes) { return; } else if (!_geoInfo.isEditable || (_geoInfo.type != HAPI_GeoType.HAPI_GEOTYPE_DEFAULT && _geoInfo.type != HAPI_GeoType.HAPI_GEOTYPE_INTERMEDIATE && _geoInfo.type != HAPI_GeoType.HAPI_GEOTYPE_CURVE)) { return; } } if (IsGeoCurveType()) { ProcessGeoCurve(session); } else { int numParts = _geoInfo.partCount; //Debug.Log("Number of parts: " + numParts); //Debug.LogFormat("GeoNode type {0}, isTemplated: {1}, isDisplayGeo: {2}, isEditable: {3}", _geoInfo.type, _geoInfo.isTemplated, _geoInfo.isDisplayGeo, _geoInfo.isEditable); for (int i = 0; i < numParts; ++i) { HAPI_PartInfo partInfo = new HAPI_PartInfo(); if (!session.GetPartInfo(GeoID, i, ref partInfo)) { Debug.LogErrorFormat("Unable to get PartInfo for geo node {0} and part {1}.", GeoID, i); continue; } // Find the old part for this new part. HEU_PartData part = null; HEU_PartData oldMatchedPart = null; foreach (HEU_PartData oldPart in oldParts) { string partName = HEU_SessionManager.GetString(partInfo.nameSH, session); if (oldPart.PartName.Equals(partName)) { oldMatchedPart = oldPart; } } if (oldMatchedPart != null) { //Debug.Log("Found matched part: " + oldMatchedPart.name); List <HEU_ObjectInstanceInfo> sourceObjectInstanceInfos = null; if (bObjectInstancer) { // ProcessPart will clear out the object instances, so hence why // we keep a copy here, then restore after processing the parts. sourceObjectInstanceInfos = oldMatchedPart.GetObjectInstanceInfos(); } // Clear out old generated data oldMatchedPart.ClearGeneratedData(); part = oldMatchedPart; oldParts.Remove(oldMatchedPart); ProcessPart(session, i, ref partInfo, ref part); if (part != null && bObjectInstancer && sourceObjectInstanceInfos != null) { // Set object instances from old part into new. This keeps the user set object inputs around. part.SetObjectInstanceInfos(sourceObjectInstanceInfos); } } else { ProcessPart(session, i, ref partInfo, ref part); } } } } finally { HEU_PartData.DestroyParts(oldParts); } }
private void PopulateAttributeData(HEU_SessionBase session, HAPI_NodeId geoID, HAPI_PartId partID, HEU_AttributeData attributeData, ref HAPI_AttributeInfo attributeInfo) { attributeData._attributeInfo = attributeInfo; int tupleSize = attributeInfo.tupleSize; int attributeCount = attributeInfo.count; int arraySize = attributeCount * tupleSize; // First reset arrays if the type had changed since last sync if ((attributeInfo.storage == HAPI_StorageType.HAPI_STORAGETYPE_INT && attributeData._attributeType != HEU_AttributeData.AttributeType.INT) || (attributeInfo.storage == HAPI_StorageType.HAPI_STORAGETYPE_FLOAT && attributeData._attributeType != HEU_AttributeData.AttributeType.FLOAT) || (attributeInfo.storage == HAPI_StorageType.HAPI_STORAGETYPE_STRING && attributeData._attributeType != HEU_AttributeData.AttributeType.STRING)) { // Reset arrays if type is different attributeData._floatValues = null; attributeData._stringValues = null; attributeData._intValues = null; attributeData._attributeState = HEU_AttributeData.AttributeState.INVALID; if(attributeInfo.storage == HAPI_StorageType.HAPI_STORAGETYPE_INT) { attributeData._attributeType = HEU_AttributeData.AttributeType.INT; } else if (attributeInfo.storage == HAPI_StorageType.HAPI_STORAGETYPE_FLOAT) { attributeData._attributeType = HEU_AttributeData.AttributeType.FLOAT; } else if (attributeInfo.storage == HAPI_StorageType.HAPI_STORAGETYPE_STRING) { attributeData._attributeType = HEU_AttributeData.AttributeType.STRING; } } // Make sure the internal array is correctly sized for syncing. if (attributeData._attributeType == HEU_AttributeData.AttributeType.INT) { if (attributeData._intValues == null) { attributeData._intValues = new int[arraySize]; attributeData._attributeState = HEU_AttributeData.AttributeState.INVALID; } else if (attributeData._intValues.Length != arraySize) { System.Array.Resize<int>(ref attributeData._intValues, arraySize); attributeData._attributeState = HEU_AttributeData.AttributeState.INVALID; } attributeData._floatValues = null; attributeData._stringValues = null; if (attributeData._attributeState == HEU_AttributeData.AttributeState.INVALID) { int[] data = new int[0]; HEU_GeneralUtility.GetAttribute(session, geoID, partID, attributeData._name, ref attributeInfo, ref data, session.GetAttributeIntData); for (int i = 0; i < attributeCount; ++i) { for (int tuple = 0; tuple < tupleSize; ++tuple) { attributeData._intValues[i * tupleSize + tuple] = data[i * tupleSize + tuple]; } } } } else if (attributeData._attributeType == HEU_AttributeData.AttributeType.FLOAT) { if (attributeData._floatValues == null) { attributeData._floatValues = new float[arraySize]; attributeData._attributeState = HEU_AttributeData.AttributeState.INVALID; } else if (attributeData._floatValues.Length != arraySize) { System.Array.Resize<float>(ref attributeData._floatValues, arraySize); attributeData._attributeState = HEU_AttributeData.AttributeState.INVALID; } attributeData._intValues = null; attributeData._stringValues = null; if (attributeData._attributeState == HEU_AttributeData.AttributeState.INVALID) { float[] data = new float[0]; HEU_GeneralUtility.GetAttribute(session, geoID, partID, attributeData._name, ref attributeInfo, ref data, session.GetAttributeFloatData); for (int i = 0; i < attributeCount; ++i) { for (int tuple = 0; tuple < tupleSize; ++tuple) { attributeData._floatValues[i * tupleSize + tuple] = data[i * tupleSize + tuple]; } } } } else if (attributeData._attributeType == HEU_AttributeData.AttributeType.STRING) { if (attributeData._stringValues == null) { attributeData._stringValues = new string[arraySize]; attributeData._attributeState = HEU_AttributeData.AttributeState.INVALID; } else if (attributeData._stringValues.Length != arraySize) { System.Array.Resize<string>(ref attributeData._stringValues, arraySize); attributeData._attributeState = HEU_AttributeData.AttributeState.INVALID; } attributeData._intValues = null; attributeData._floatValues = null; if (attributeData._attributeState == HEU_AttributeData.AttributeState.INVALID) { HAPI_StringHandle[] data = new HAPI_StringHandle[0]; HEU_GeneralUtility.GetAttribute(session, geoID, partID, attributeData._name, ref attributeInfo, ref data, session.GetAttributeStringData); for (int i = 0; i < attributeCount; ++i) { for (int tuple = 0; tuple < tupleSize; ++tuple) { HAPI_StringHandle stringHandle = data[i * tupleSize + tuple]; attributeData._stringValues[i * tupleSize + tuple] = HEU_SessionManager.GetString(stringHandle, session); } } } } SetAttributeDataSyncd(attributeData); }
public void SyncAllAttributesFrom(HEU_SessionBase session, HEU_HoudiniAsset asset, HAPI_NodeId geoID, ref HAPI_PartInfo partInfo, GameObject outputGameObject) { _geoID = geoID; _partID = partInfo.id; HAPI_GeoInfo geoInfo = new HAPI_GeoInfo(); if(session.GetGeoInfo(_geoID, ref geoInfo)) { _geoName = HEU_SessionManager.GetString(geoInfo.nameSH, session); } if (outputGameObject != null) { _outputTransform = outputGameObject.transform; } // Need the vertex list of indices to map the positions to vertex colors _vertexIndices = new int[partInfo.vertexCount]; if (!HEU_GeneralUtility.GetArray2Arg(geoID, partInfo.id, session.GetVertexList, _vertexIndices, 0, partInfo.vertexCount)) { return; } // Note that this currently only supports point attributes int attributePointCount = partInfo.attributeCounts[(int)HAPI_AttributeOwner.HAPI_ATTROWNER_POINT]; string[] pointAttributeNames = new string[attributePointCount]; if(!session.GetAttributeNames(geoID, partInfo.id, HAPI_AttributeOwner.HAPI_ATTROWNER_POINT, ref pointAttributeNames, attributePointCount)) { Debug.LogErrorFormat("Failed to sync attributes. Unable to retrieve attribute names."); return; } // Create new list of attributes. We'll move existing attributes that are still in use as we find them. List<HEU_AttributeData> newAttributeDatas = new List<HEU_AttributeData>(); foreach (string pointAttributeName in pointAttributeNames) { if(string.IsNullOrEmpty(pointAttributeName)) { continue; } // Get position attribute values separately. Used for painting and editing points in 3D scene. HAPI_AttributeInfo pointAttributeInfo = new HAPI_AttributeInfo(); if(session.GetAttributeInfo(geoID, partInfo.id, pointAttributeName, HAPI_AttributeOwner.HAPI_ATTROWNER_POINT, ref pointAttributeInfo)) { if (pointAttributeName.Equals(HEU_Defines.HAPI_ATTRIB_POSITION)) { if (pointAttributeInfo.storage != HAPI_StorageType.HAPI_STORAGETYPE_FLOAT) { Debug.LogErrorFormat("Expected float type for position attribute, but got {0}", pointAttributeInfo.storage); return; } _positionAttributeValues = new Vector3[pointAttributeInfo.count]; float[] data = new float[0]; HEU_GeneralUtility.GetAttribute(session, geoID, partInfo.id, pointAttributeName, ref pointAttributeInfo, ref data, session.GetAttributeFloatData); for (int i = 0; i < pointAttributeInfo.count; ++i) { _positionAttributeValues[i] = new Vector3(-data[i * pointAttributeInfo.tupleSize + 0], data[i * pointAttributeInfo.tupleSize + 1], data[i * pointAttributeInfo.tupleSize + 2]); } // We don't let position attributes be editted (for now anyway) continue; } HEU_AttributeData attrData = GetAttributeData(pointAttributeName); if (attrData == null) { // Attribute data not found. Create it. attrData = CreateAttribute(pointAttributeName, ref pointAttributeInfo); //Debug.LogFormat("Created attribute data: {0}", pointAttributeName); } // Add to new list. newAttributeDatas.Add(attrData); // Sync the attribute info to data. PopulateAttributeData(session, geoID, partInfo.id, attrData, ref pointAttributeInfo); if(pointAttributeName.Equals(HEU_Defines.HAPI_ATTRIB_COLOR) || pointAttributeInfo.typeInfo == HAPI_AttributeTypeInfo.HAPI_ATTRIBUTE_TYPE_COLOR) { _hasColorAttribute = true; } } else { // Failed to get point attribute info! } } // Overwriting the old list with the new should automatically remove unused attribute datas. _attributeDatas = newAttributeDatas; }
private static void ProcessDragEvent(Event dragEvent, SceneView sceneView) { if (dragEvent != null && (dragEvent.type == EventType.DragUpdated || dragEvent.type == EventType.DragPerform)) { bool dragHDAs = false; List <string> hdaList = new List <string>(); foreach (string file in DragAndDrop.paths) { if (HEU_HAPIUtility.IsHoudiniAssetFile(file)) { dragHDAs = true; DragAndDrop.visualMode = DragAndDropVisualMode.Move; hdaList.Add(file); break; } } if (dragHDAs) { if (dragEvent.type == EventType.DragPerform) { if (HEU_SessionManager.ValidatePluginSession()) { Vector3 dropPos = Vector3.zero; if (sceneView != null) { Camera camera = sceneView.camera; Vector3 mousePos = HEU_EditorUI.GetMousePosition(ref dragEvent, camera); Ray ray = camera.ScreenPointToRay(mousePos); ray.origin = camera.transform.position; Plane plane = new Plane(); plane.SetNormalAndPosition(Vector3.up, Vector3.zero); float enter = 0f; plane.Raycast(ray, out enter); enter = Mathf.Clamp(enter, camera.nearClipPlane, camera.farClipPlane); dropPos = ray.origin + ray.direction * enter; } List <GameObject> createdGOs = new List <GameObject>(); foreach (string file in hdaList) { GameObject go = HEU_HAPIUtility.InstantiateHDA(file, dropPos, HEU_SessionManager.GetOrCreateDefaultSession(), true); if (go != null) { createdGOs.Add(go); } } // Select the created assets HEU_EditorUtility.SelectObjects(createdGOs.ToArray()); } } dragEvent.Use(); } } }
public static void CloseAllSessions() { HEU_SessionManager.CloseAllSessions(); Debug.Log("Houdini Engine Sessions closed!"); }