/// <summary>
		/// Draw asset options for given asset.
		/// </summary>
		/// <param name="asset">The HDA asset</param>
		/// <param name="assetObject">Serialized HDA asset object</param>
		private void DrawAssetOptions(HEU_HoudiniAsset asset, SerializedObject assetObject)
		{
			GUIStyle buttonStyle = new GUIStyle(GUI.skin.button);
			buttonStyle.fontSize = 11;
			buttonStyle.alignment = TextAnchor.MiddleCenter;
			buttonStyle.fixedHeight = 24;
			buttonStyle.margin.left = 34;

			HEU_EditorUI.BeginSection();
			{
				SerializedProperty showHDAOptionsProperty = assetObject.FindProperty("_showHDAOptions");

				showHDAOptionsProperty.boolValue = HEU_EditorUI.DrawFoldOut(showHDAOptionsProperty.boolValue, "ASSET OPTIONS");
				if (showHDAOptionsProperty.boolValue)
				{
					EditorGUI.indentLevel++;
					HEU_EditorUI.DrawPropertyField(assetObject, "_autoCookOnParameterChange", "Auto-Cook On Parameter Change", "Automatically cook when a parameter changes. If off, must use Recook to cook.");
					HEU_EditorUI.DrawPropertyField(assetObject, "_pushTransformToHoudini", "Push Transform To Houdini", "Send the asset's transform to Houdini and apply to object.");
					HEU_EditorUI.DrawPropertyField(assetObject, "_transformChangeTriggersCooks", "Transform Change Triggers Cooks", "Changing the transform (e.g. moving) the asset in Unity will invoke cook in Houdini.");
					HEU_EditorUI.DrawPropertyField(assetObject, "_cookingTriggersDownCooks", "Cooking Triggers Downstream Cooks", "Cooking this asset will trigger dependent assets' to also cook.");
					HEU_EditorUI.DrawPropertyField(assetObject, "_generateUVs", "Generate UVs", "Force Unity to generate UVs for output geometry.");
					HEU_EditorUI.DrawPropertyField(assetObject, "_generateTangents", "Generate Tangents", "Generate tangents in Unity for output geometry.");
					HEU_EditorUI.DrawPropertyField(assetObject, "_generateNormals", "Generate Normals", "Generate normals in Unity for output geometry.");
					HEU_EditorUI.DrawPropertyField(assetObject, "_generateMeshUsingPoints", "Generate Mesh Using Points", "Use point attributes instead of vertex attributes for geometry. Ignores vertex attributes.");
					HEU_EditorUI.DrawPropertyField(assetObject, "_useLODGroups", "Use LOD Groups", "Automatically create Unity LOD group if found.");
					HEU_EditorUI.DrawPropertyField(assetObject, "_ignoreNonDisplayNodes", "Ignore NonDisplay Nodes", "Only display node geometry will be created.");

					if (asset.NumAttributeStores() > 0)
					{
						HEU_EditorUI.DrawPropertyField(assetObject, "_editableNodesToolsEnabled", "Enable Editable Node Tools", "Displays Editable Node Tools and generates the node's geometry, if asset has editable nodes.");
					}

					if (asset.NumHandles() > 0)
					{
						HEU_EditorUI.DrawPropertyField(assetObject, "_handlesEnabled", "Enable Handles", "Creates Houdini Handles if asset has them.");
					}

					EditorGUILayout.Space();

					using (var hs = new EditorGUILayout.HorizontalScope())
					{
						if (GUILayout.Button(_savePresetButton, buttonStyle, GUILayout.MaxWidth(160)))
						{
							string fileName = asset.AssetName;
							string filePattern = "preset";
							string newPath = EditorUtility.SaveFilePanel("Save HDA preset", "", fileName + "." + filePattern, filePattern);
							if (newPath != null && !string.IsNullOrEmpty(newPath))
							{
								HEU_AssetPresetUtility.SaveAssetPresetToFile(asset, newPath);
							}
						}

						if (GUILayout.Button(_loadPresetButton, buttonStyle, GUILayout.MaxWidth(160)))
						{
							string fileName = asset.AssetName;
							string filePattern = "preset";
							string newPath = EditorUtility.OpenFilePanel("Load HDA preset", "", filePattern);
							if (newPath != null && !string.IsNullOrEmpty(newPath))
							{
								HEU_AssetPresetUtility.LoadPresetFileIntoAssetAndCook(asset, newPath);
							}
						}
					}

					EditorGUILayout.Space();

					if(GUILayout.Button(_resetMaterialOverridesButton, buttonStyle, GUILayout.MaxWidth(160)))
					{
						asset.ResetMaterialOverrides();
					}

					EditorGUI.indentLevel--;
				}
			}
			HEU_EditorUI.EndSection();

			HEU_EditorUI.DrawSeparator();
		}
		private void DrawTerrainSection(HEU_HoudiniAsset asset, SerializedObject assetObject)
		{
			int numVolumes = asset.GetVolumeCacheCount();
			if(numVolumes <= 0)
			{
				return;
			}

			HEU_EditorUI.BeginSection();
			{
				SerializedProperty showTerrainProperty = HEU_EditorUtility.GetSerializedProperty(assetObject, "_showTerrainSection");
				if (showTerrainProperty != null)
				{
					showTerrainProperty.boolValue = HEU_EditorUI.DrawFoldOut(showTerrainProperty.boolValue, "TERRAIN");
					if (showTerrainProperty.boolValue)
					{
						// Draw each volume layer
						List<HEU_VolumeCache> volumeCaches = asset.GetVolumeCaches();
						int numCaches = volumeCaches.Count;
						for (int i = 0; i < numCaches; ++i)
						{
							SerializedObject cacheObjectSerialized = new SerializedObject(volumeCaches[i]);
							bool bChanged = false;
							bool bStrengthChanged = false;

							SerializedProperty layersProperty = cacheObjectSerialized.FindProperty("_layers");
							if (layersProperty == null || layersProperty.arraySize == 0)
							{
								continue;
							}

							string heading = string.Format("{0}-{1}:", volumeCaches[i].ObjectName, volumeCaches[i].GeoName);

							if (HEU_EditorUI.DrawFoldOutSerializedProperty(HEU_EditorUtility.GetSerializedProperty(cacheObjectSerialized, "_uiExpanded"), heading, ref bChanged))
							{
								EditorGUI.indentLevel++;

								int numlayers = layersProperty.arraySize;
								for (int j = 0; j < numlayers; ++j)
								{
									SerializedProperty layerProperty = layersProperty.GetArrayElementAtIndex(j);
									if (layerProperty == null)
									{
										continue;
									}

									// Skipping "height" layer on UI since its treated as Houdini-specific layer
									string layerName = layerProperty.FindPropertyRelative("_layerName").stringValue;
									if (layerName.Equals(HEU_Defines.HAPI_HEIGHTFIELD_LAYERNAME_HEIGHT))
									{
										continue;
									}
									layerName = string.Format("Layer: {0}", layerName);

									SerializedProperty uiExpandedProperty = layerProperty.FindPropertyRelative("_uiExpanded");
									bool bExpanded = uiExpandedProperty != null ? uiExpandedProperty.boolValue : true;
									bool bNewExpanded = HEU_EditorUI.DrawFoldOut(bExpanded, layerName);
									if (uiExpandedProperty != null && bExpanded != bNewExpanded)
									{
										bChanged = true;
										uiExpandedProperty.boolValue = bNewExpanded;
									}

									if (!bNewExpanded)
									{
										continue;
									}

									if (HEU_EditorUtility.EditorDrawFloatSliderProperty(layerProperty, "_strength", "Strength", "Amount to multiply the layer values by on import."))
									{
										bStrengthChanged = true;
									}

									HEU_EditorUI.DrawSeparator();
								}

								EditorGUI.indentLevel--;
							}

							if (bStrengthChanged)
							{
								SerializedProperty dirtyProperty = cacheObjectSerialized.FindProperty("_isDirty");
								if (dirtyProperty != null)
								{
									dirtyProperty.boolValue = true;
									bChanged = true;
								}
							}

							if(bChanged)
							{
								cacheObjectSerialized.ApplyModifiedProperties();
							}
						}
					}
				}
			}
			HEU_EditorUI.EndSection();

			HEU_EditorUI.DrawSeparator();
		}
		/// <summary>
		/// Draw the Object Instance Inputs section for given asset.
		/// </summary>
		/// <param name="asset">The HDA asset</param>
		/// <param name="assetObject">Serialized HDA asset object</param>
		private void DrawInstanceInputs(HEU_HoudiniAsset asset, SerializedObject assetObject)
		{
			HEU_EditorUI.DrawSeparator();

			// Get list of object input fields
			List<HEU_ObjectInstanceInfo> objInstanceInfos = new List<HEU_ObjectInstanceInfo>();
			asset.PopulateObjectInstanceInfos(objInstanceInfos);

			int numObjInstances = objInstanceInfos.Count;

			// Display input section if at least have 1 input field
			if (numObjInstances > 0)
			{
				HEU_EditorUI.BeginSection();

				SerializedProperty showInstanceInputsProperty = assetObject.FindProperty("_showInstanceInputs");

				showInstanceInputsProperty.boolValue = HEU_EditorUI.DrawFoldOut(showInstanceInputsProperty.boolValue, "INSTANCE INPUTS");
				if (showInstanceInputsProperty.boolValue)
				{
					EditorGUI.BeginChangeCheck();

					// Draw each instanced input info
					for (int i = 0; i < numObjInstances; ++i)
					{
						EditorGUILayout.BeginVertical();

						string inputName = objInstanceInfos[i]._partTarget.PartName + "_" + i;

						SerializedObject objInstanceSerialized = new SerializedObject(objInstanceInfos[i]);

						SerializedProperty instancedInputsProperty = HEU_EditorUtility.GetSerializedProperty(objInstanceSerialized, "_instancedInputs");
						if (instancedInputsProperty != null)
						{
							int inputCount = instancedInputsProperty.arraySize;
							EditorGUILayout.PropertyField(instancedInputsProperty, new GUIContent(inputName), true);

							// When input size increases, Unity creates default values for HEU_InstancedInput which results in
							// zero value for scale offset. This fixes it up.
							int newInputCount = instancedInputsProperty.arraySize;
							if (inputCount < newInputCount)
							{
								for (int inputIndex = inputCount; inputIndex < newInputCount; ++inputIndex)
								{
									SerializedProperty scaleProperty = instancedInputsProperty.GetArrayElementAtIndex(inputIndex).FindPropertyRelative("_scaleOffset");
									scaleProperty.vector3Value = Vector3.one;
								}
							}
						}

						objInstanceSerialized.ApplyModifiedProperties();

						EditorGUILayout.EndVertical();
					}

					if(EditorGUI.EndChangeCheck())
					{
						asset.RequestCook(bCheckParametersChanged: true, bAsync: true, bSkipCookCheck: false, bUploadParameters: true);
					}
				}

				HEU_EditorUI.EndSection();
			}
		}
		private void DrawCurvesSection(HEU_HoudiniAsset asset, SerializedObject assetObject)
		{
			if (asset.GetEditableCurveCount() <= 0)
			{
				return;
			}

			GUIStyle buttonStyle = new GUIStyle(GUI.skin.button);
			buttonStyle.fontSize = 11;
			buttonStyle.alignment = TextAnchor.MiddleCenter;
			buttonStyle.fixedHeight = 24;
			buttonStyle.margin.left = 34;

			HEU_EditorUI.BeginSection();
			{
				SerializedProperty showCurvesProperty = HEU_EditorUtility.GetSerializedProperty(assetObject, "_showCurvesSection");
				if (showCurvesProperty != null)
				{
					showCurvesProperty.boolValue = HEU_EditorUI.DrawFoldOut(showCurvesProperty.boolValue, "CURVES");
					if (showCurvesProperty.boolValue)
					{
						SerializedProperty curveEditorProperty = HEU_EditorUtility.GetSerializedProperty(assetObject, "_curveEditorEnabled");
						if (curveEditorProperty != null)
						{
							EditorGUILayout.PropertyField(curveEditorProperty);
						}

						HEU_EditorUI.DrawHeadingLabel("Collision Settings");
						EditorGUI.indentLevel++;

						string projectLabel = "Project Curves To ";
						List<HEU_Curve> curves = asset.GetCurves();

						SerializedProperty curveCollisionProperty = HEU_EditorUtility.GetSerializedProperty(assetObject, "_curveDrawCollision");
						if (curveCollisionProperty != null)
						{
							EditorGUILayout.PropertyField(curveCollisionProperty, new GUIContent("Collision Type"));
							if (curveCollisionProperty.enumValueIndex == (int)HEU_Curve.CurveDrawCollision.COLLIDERS)
							{
								HEU_EditorUtility.EditorDrawSerializedProperty(assetObject, "_curveDrawColliders", label: "Colliders");
								projectLabel += "Colliders";
							}
							else if (curveCollisionProperty.enumValueIndex == (int)HEU_Curve.CurveDrawCollision.LAYERMASK)
							{
								HEU_EditorUtility.EditorDrawSerializedProperty(assetObject, "_curveDrawLayerMask", label: "Layer Mask");
								projectLabel += "Layer";
							}

							HEU_EditorUI.DrawSeparator();

							EditorGUI.indentLevel--;
							HEU_EditorUI.DrawHeadingLabel("Projection Settings");
							EditorGUI.indentLevel++;

							HEU_EditorUtility.EditorDrawSerializedProperty(assetObject, "_curveProjectDirection", label: "Project Direction", tooltip: "The ray cast direction for projecting the curve points.");
							HEU_EditorUtility.EditorDrawFloatProperty(assetObject, "_curveProjectMaxDistance", label: "Project Max Distance", tooltip: "The maximum ray cast distance for projecting the curve points.");

							_projectCurvePointsButton.text = projectLabel;
							if (GUILayout.Button(_projectCurvePointsButton, buttonStyle, GUILayout.MaxWidth(180)))
							{
								SerializedProperty projectDirProperty = HEU_EditorUtility.GetSerializedProperty(assetObject, "_curveProjectDirection");
								SerializedProperty maxDistanceProperty = HEU_EditorUtility.GetSerializedProperty(assetObject, "_curveProjectMaxDistance");

								Vector3 projectDir = projectDirProperty != null ? projectDirProperty.vector3Value : Vector3.down;
								float maxDistance = maxDistanceProperty != null ? maxDistanceProperty.floatValue : 0;

								for (int i = 0; i < curves.Count; ++i)
								{
									curves[i].ProjectToColliders(asset, projectDir, maxDistance);
								}
							}
						}

						EditorGUI.indentLevel--;

						HEU_EditorUI.DrawSeparator();

						for (int i = 0; i < curves.Count; ++i)
						{
							if (curves[i].Parameters != null)
							{
								DrawParameters(curves[i].Parameters, ref _curveParameterEditor);
							}
						}
					}
				}
			}
			HEU_EditorUI.EndSection();

			HEU_EditorUI.DrawSeparator();
		}
		/// <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;
						}

						// 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;
						}
					}
				}
			}
			
			if (EditorGUI.EndChangeCheck())
			{
				assetRootSerializedObject.ApplyModifiedProperties();
				assetObject.ApplyModifiedProperties();
			}

			return bSkipDrawing;
		}
	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.BeginSimpleSection("Bake Update");
			HEU_EditorUI.DrawPropertyField(assetObject, "_bakeUpdateKeepPreviousTransformValues", "Keep Previous Transform Values", "Copy previous transform values when doing a Bake Update.");
			HEU_EditorUI.EndSimpleSection();
		    }
		}
	    }
	    HEU_EditorUI.EndSection();

	    HEU_EditorUI.DrawSeparator();

	    return bSkipAutoCook;
	}
	/// <summary>
	/// Draw the Generate section.
	/// </summary>
	private static bool DrawGenerateSection(HEU_HoudiniAssetRoot assetRoot, 
	    SerializedObject assetRootSerializedObject, 
	    HEU_HoudiniAsset asset, SerializedObject assetObject,
	    ref HEU_HoudiniAsset.AssetBuildAction pendingBuildAction)
	{
	    bool bSkipAutoCook = false;

	    CreateMainButtonStyle();

	    _recookhdaContent.text = "  Recook";

	    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], _mainPromptStyle))
		    {
			selectedIndex = i;
			break;
		    }

		    EditorGUILayout.Separator();
		}

		if (selectedIndex >= 0)
		{
		    SerializedProperty selectedIndexProperty = HEU_EditorUtility.GetSerializedProperty(assetObject, "_selectedSubassetIndex");
		    if (selectedIndexProperty != null)
		    {
			selectedIndexProperty.intValue = selectedIndex;
		    }
		}

		bSkipAutoCook = 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)
		    {
			HEU_EditorUI.DrawSeparator();

			using (var hs = new EditorGUILayout.HorizontalScope(_mainBoxStyle))
			{
			    if (GUILayout.Button(_reloadhdaContent, _mainButtonStyle))
			    {
				pendingBuildAction = HEU_HoudiniAsset.AssetBuildAction.RELOAD;
				bSkipAutoCook = true;
			    }

			    GUILayout.Space(_mainButtonSeparatorDistance);

			    if (!bSkipAutoCook && GUILayout.Button(_recookhdaContent, _mainButtonStyle))
			    {
				pendingBuildAction = HEU_HoudiniAsset.AssetBuildAction.COOK;
				bSkipAutoCook = true;
			    }
			}

			using (var hs = new EditorGUILayout.HorizontalScope(_mainBoxStyle))
			{
			    if (GUILayout.Button(_duplicateContent, _mainButtonStyle))
			    {
				pendingBuildAction = HEU_HoudiniAsset.AssetBuildAction.DUPLICATE;
				bSkipAutoCook = true;
			    }

			    GUILayout.Space(_mainButtonSeparatorDistance);

			    if (GUILayout.Button(_resetParamContent, _mainButtonStyle))
			    {
				pendingBuildAction = HEU_HoudiniAsset.AssetBuildAction.RESET_PARAMS;
				bSkipAutoCook = true;
			    }
			}
		    }
		}

		HEU_EditorUI.EndSection();
	    }

	    HEU_EditorUI.DrawSeparator();

	    return bSkipAutoCook;
	}
Beispiel #8
0
		/// <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);

			Texture2D reloadhdaIcon = Resources.Load("heu_reloadhdaIcon") as Texture2D;
			Texture2D recookhdaIcon = Resources.Load("heu_recookhdaIcon") as Texture2D;
			Texture2D bakegameobjectIcon = Resources.Load("heu_bakegameobjectIcon") as Texture2D;
			Texture2D bakeprefabIcon = Resources.Load("heu_bakeprefabIcon") as Texture2D;
			Texture2D bakeandreplaceIcon = Resources.Load("heu_bakeandreplaceIcon") as Texture2D;
			Texture2D removeheIcon = Resources.Load("heu_removeheIcon") as Texture2D;
			Texture2D duplicateAssetIcon = Resources.Load("heu_duplicateassetIcon") as Texture2D;

			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;

			GUIContent reloadhdaContent = new GUIContent("  Reload Asset", reloadhdaIcon);
			GUIContent recookhdaContent = new GUIContent("  Recook Asset", recookhdaIcon);
			GUIContent bakegameobjectContent = new GUIContent("  Bake GameObject", bakegameobjectIcon);
			GUIContent bakeprefabContent = new GUIContent("  Bake Prefab", bakeprefabIcon);
			GUIContent bakeandreplaceContent = new GUIContent("  Bake Update", bakeandreplaceIcon);
			GUIContent removeheContent = new GUIContent("  Keep Only Output", removeheIcon);
			GUIContent duplicateContent = new GUIContent("  Duplicate Asset", duplicateAssetIcon);

			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_EditorUI.BeginSection();
			{
				HEU_HoudiniAsset.AssetCookStatus cookStatus = HEU_HoudiniAsset.AssetCookStatus.NONE;

				SerializedProperty cookStatusProperty = HEU_EditorUtility.GetSerializedProperty(assetObject, "_cookStatus");
				if (cookStatusProperty != null)
				{
					cookStatus = (HEU_HoudiniAsset.AssetCookStatus)cookStatusProperty.enumValueIndex;

					if(cookStatus == HEU_HoudiniAsset.AssetCookStatus.COOKING || cookStatus == HEU_HoudiniAsset.AssetCookStatus.POSTCOOK)
					{
						recookhdaContent.text = "  Cooking Asset";
					}
					else if (cookStatus == HEU_HoudiniAsset.AssetCookStatus.LOADING || cookStatus == HEU_HoudiniAsset.AssetCookStatus.POSTLOAD)
					{
						reloadhdaContent.text = "  Loading Asset";
					}
				}

				SerializedProperty showGenerateProperty = assetObject.FindProperty("_showGenerateSection");

				showGenerateProperty.boolValue = HEU_EditorUI.DrawFoldOut(showGenerateProperty.boolValue, "GENERATE");
				if (showGenerateProperty.boolValue)
				{
					bool bHasPendingAction = (pendingBuildAction != HEU_HoudiniAsset.AssetBuildAction.NONE) || (cookStatus != HEU_HoudiniAsset.AssetCookStatus.NONE);

					HEU_EditorUI.DrawSeparator();

					EditorGUI.BeginDisabledGroup(bHasPendingAction);

					using (var hs = new EditorGUILayout.HorizontalScope(boxStyle))
					{
						if (GUILayout.Button(reloadhdaContent, buttonStyle, GUILayout.Width(singleButtonWidth)))
						{
							pendingBuildAction = HEU_HoudiniAsset.AssetBuildAction.RELOAD;
							bSkipDrawing = true;
						}

						GUILayout.Space(separatorDistance);

						if (!bSkipDrawing && GUILayout.Button(recookhdaContent, buttonStyle, GUILayout.Width(singleButtonWidth)))
						{
							pendingBuildAction = HEU_HoudiniAsset.AssetBuildAction.COOK;
							bSkipDrawing = true;
						}
					}

					using (var hs = new EditorGUILayout.HorizontalScope(boxStyle))
					{
						if (GUILayout.Button(removeheContent, buttonStyle, GUILayout.Width(singleButtonWidth)))
						{
							pendingBuildAction = HEU_HoudiniAsset.AssetBuildAction.STRIP_HEDATA;
							bSkipDrawing = true;
						}

						GUILayout.Space(separatorDistance);

						if (GUILayout.Button(duplicateContent, buttonStyle, GUILayout.Width(singleButtonWidth)))
						{
							pendingBuildAction = HEU_HoudiniAsset.AssetBuildAction.DUPLICATE;
							bSkipDrawing = true;
						}
					}

					EditorGUI.EndDisabledGroup();

					HEU_EditorUI.DrawSeparator();
				}
			}
			
			HEU_EditorUI.EndSection();
			
			HEU_EditorUI.DrawSeparator();

			HEU_EditorUI.BeginSection();
			{
				SerializedProperty showBakeProperty = assetObject.FindProperty("_showBakeSection");

				showBakeProperty.boolValue = HEU_EditorUI.DrawFoldOut(showBakeProperty.boolValue, "BAKE");
				if (showBakeProperty.boolValue)
				{
					if (!bSkipDrawing)
					{
						// Bake -> New Instance, New Prefab, Existing instance or prefab

						using (var vs = new EditorGUILayout.HorizontalScope(boxStyle))
						{
							if (GUILayout.Button(bakegameobjectContent, buttonStyle, GUILayout.Width(singleButtonWidth)))
							{
								asset.BakeToNewStandalone();
							}

							GUILayout.Space(separatorDistance);

							if (GUILayout.Button(bakeprefabContent, buttonStyle, GUILayout.Width(singleButtonWidth)))
							{
								asset.BakeToNewPrefab();
							}
						}

						HEU_EditorUI.DrawSeparator();

						using (var hs2 = new EditorGUILayout.VerticalScope(boxStyle))
						{
							if (GUILayout.Button(bakeandreplaceContent, centredButtonStyle, GUILayout.Width(doubleButtonWidth)))
							{
								if (assetRoot._bakeTargets == null || assetRoot._bakeTargets.Count == 0)
								{
									// No bake target means user probably forgot to set one. So complain!
									HEU_EditorUtility.DisplayDialog("No Bake Targets", "Bake Update requires atleast one valid GameObject.\n\nDrag a GameObject or Prefab onto the Drag and drop GameObjects / Prefabs field!", "OK");
								}
								else
								{
									int numTargets = assetRoot._bakeTargets.Count;
									for(int i = 0; i < numTargets; ++i)
									{
										GameObject bakeGO = assetRoot._bakeTargets[i];
										if (bakeGO != null)
										{
											if (HEU_EditorUtility.IsPrefabOriginal(bakeGO))
											{
												// Prefab original means its true prefab, and not an instance of it
												// TODO: allow user to cancel
												asset.BakeToExistingPrefab(bakeGO);
											}
											else
											{
												// This is for all standalone (including prefab instances)
												asset.BakeToExistingStandalone(bakeGO);
											}
										}
										else
										{
											Debug.LogWarning("Unable to bake to null target at index " + i);
										}
									}
								}
							}

							using (var hs = new EditorGUILayout.VerticalScope(buttonSetStyle))
							{
								SerializedProperty bakeTargetsProp = assetRootSerializedObject.FindProperty("_bakeTargets");
								if (bakeTargetsProp != null)
								{
									EditorGUILayout.PropertyField(bakeTargetsProp, new GUIContent("Drag & drop GameObjects / Prefabs:"), true, GUILayout.Width(doubleButtonWidth - 9f));
								}
							}
						}
					}
				}
			}
			HEU_EditorUI.EndSection();

			HEU_EditorUI.DrawSeparator();

			if(pendingBuildAction != HEU_HoudiniAsset.AssetBuildAction.NONE)
			{
				// Sanity check to make sure the asset is part of the AssetUpater
				HEU_AssetUpdater.AddAssetForUpdate(asset);

				// Apply pending build action based on user UI interaction above
				pendingBuildProperty.enumValueIndex = (int)pendingBuildAction;

				if (pendingBuildAction == HEU_HoudiniAsset.AssetBuildAction.COOK)
				{
					// Forcing recook without checking for changes allows users to do a semi-reset on the output, 
					// without needing to reload (loose changes) or change parameter then undo.
					SerializedProperty checkParameterChange = HEU_EditorUtility.GetSerializedProperty(assetObject, "_checkParameterChangeForCook");
					if (checkParameterChange != null)
					{
						checkParameterChange.boolValue = false;
					}
				}
			}
			
			if (EditorGUI.EndChangeCheck())
			{
				assetRootSerializedObject.ApplyModifiedProperties();
				assetObject.ApplyModifiedProperties();
			}

			return bSkipDrawing;
		}