Skip to content

Commit

Permalink
Fix for terrain generation through PDGAssetLink where the source Terr…
Browse files Browse the repository at this point in the history
…ainData and

TerrainLayers were being overwritten on generate by HEU_GeoSync. It will always create copies
of the TerrainData in a cache folder. TerrainLayers are only copied if their properties are
changed from source. The cache folder is named PDGCache and is a subfolder under the
linked HDA's working folder. The generated terrain files will get deleted on dirty.
  • Loading branch information
Seelan Vamatheva committed Aug 20, 2019
1 parent cb95fcc commit d795c19
Show file tree
Hide file tree
Showing 8 changed files with 255 additions and 72 deletions.
2 changes: 2 additions & 0 deletions Plugins/HoudiniEngineUnity/Editor/UI/HEU_GeoSyncUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ public override void OnInspectorGUI()
{
_geoSync._filePath = EditorGUILayout.DelayedTextField(_geoSync._filePath);

// TODO: add field for output cache directory

GUIStyle buttonStyle = HEU_EditorUI.GetNewButtonStyle_MarginPadding(0, 0);
if (GUILayout.Button("...", buttonStyle, GUILayout.Width(30), GUILayout.Height(18)))
{
Expand Down
65 changes: 65 additions & 0 deletions Plugins/HoudiniEngineUnity/Scripts/Core/HEU_AssetDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,23 @@ public static void DeleteAsset(Object asset)
#endif
}

/// <summary>
/// Delete the asset object.
/// </summary>
/// <param name="asset">The asset object to delete</param>
public static void DeleteAssetAtPath(string path)
{
#if UNITY_EDITOR
if (!string.IsNullOrEmpty(path))
{
AssetDatabase.DeleteAsset(path);
}
#else
// TODO RUNTIME: AssetDatabase is not supported at runtime. Do we need to support this for runtime?
Debug.LogWarning(HEU_Defines.HEU_USERMSG_NONEDITOR_NOT_SUPPORTED);
#endif
}

public static void DeleteAssetIfInBakedFolder(Object asset)
{
#if UNITY_EDITOR
Expand Down Expand Up @@ -593,6 +610,54 @@ public static Object CopyAndLoadAssetAtAnyPath(Object srcAsset, string copyPath,
#endif
}

/// <summary>
/// Creates a unique copy of the srcAsset at copyPath, and loads it.
/// If another asset is at copyPath, it creates another (unique) file name.
/// </summary>
/// <param name="srcAsset">The source asset object</param>
/// <param name="copyPath">The full path to the copy</param>
/// <param name="type">The type of source asset</param>
/// <returns>Returns loaded copy if exists or created, otherwise null</returns>
public static Object CopyUniqueAndLoadAssetAtAnyPath(Object srcAsset, string copyPath, System.Type type)
{
#if UNITY_EDITOR
string srcAssetPath = GetAssetPath(srcAsset);
if (!string.IsNullOrEmpty(srcAssetPath))
{
CreatePathWithFolders(copyPath);

string fileName = HEU_Platform.GetFileName(srcAssetPath);
string fullCopyPath = HEU_Platform.BuildPath(copyPath, fileName);

if (HEU_Platform.DoesFileExist(fullCopyPath))
{
fullCopyPath = GetUniqueAssetPath(fullCopyPath);
if (HEU_Platform.DoesFileExist(fullCopyPath))
{
Debug.LogErrorFormat("Failed to get unique path to make copy for {0} at {1}!", srcAssetPath, fullCopyPath);
return null;
}
}

if (CopyAsset(srcAssetPath, fullCopyPath))
{
// Refresh database as otherwise we won't be able to load it in the next line.
SaveAndRefreshDatabase();

return LoadAssetAtPath(fullCopyPath, type);
}
else
{
Debug.LogErrorFormat("Failed to copy and load asset from {0} to {1}!", srcAssetPath, fullCopyPath);
}
}
return null;
#else
// TODO RUNTIME: AssetDatabase is not supported at runtime. Do we need to support this for runtime?
Debug.LogWarning(HEU_Defines.HEU_USERMSG_NONEDITOR_NOT_SUPPORTED);
return null;
#endif
}

/// <summary>
/// Create the given object inside the asset cache folder path, with relative folder path.
Expand Down
9 changes: 9 additions & 0 deletions Plugins/HoudiniEngineUnity/Scripts/PDG/HEU_PDGAssetLink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ public void Setup(HEU_HoudiniAsset hdaAsset)
_assetPath = _heu.AssetPath;
_assetName = _heu.AssetName;

// Use the HDAs cache folder for generating output files
string hdaCachePath = _heu.GetValidAssetCacheFolderPath();
_outputCachePathRoot = HEU_Platform.BuildPath(hdaCachePath, "PDGCache");

Reset();
Refresh();
}
Expand Down Expand Up @@ -817,6 +821,7 @@ public void LoadResults(HEU_SessionBase session, HEU_TOPNodeData topNode, HAPI_P
if (geoSync != null)
{
geoSync._filePath = path;
geoSync.SetOutputCacheDirectory(_outputCachePathRoot);
geoSync.StartSync();
}
}
Expand Down Expand Up @@ -1020,6 +1025,10 @@ public enum LinkState

// The root gameobject to place all loaded geometry under
public GameObject _loadRootGameObject;

// The root directory for generated output
[SerializeField]
private string _outputCachePathRoot;
}

} // HoudiniEngineUnity
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ public class HEU_LoadBufferVolumeLayer
public Vector3 _center;

public string _layerPath;

public bool _hasLayerAttributes;
}

public class HEU_LoadBufferInstancer : HEU_LoadBufferBase
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -439,17 +439,22 @@ public bool GenerateTerrainBuffers(HEU_SessionBase session, HAPI_NodeId nodeID,
layer._layerPath = HEU_GeneralUtility.GetAttributeStringValueSingle(session, nodeID, volumeParts[i].id,
HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_TERRAINLAYER_FILE_ATTR, HAPI_AttributeOwner.HAPI_ATTROWNER_PRIM);

LoadStringFromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_TEXTURE_DIFFUSE_ATTR, ref layer._diffuseTexturePath);
LoadStringFromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_TEXTURE_MASK_ATTR, ref layer._maskTexturePath);
LoadStringFromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_TEXTURE_NORMAL_ATTR, ref layer._normalTexturePath);
layer._hasLayerAttributes = HEU_TerrainUtility.VolumeLayerHasAttributes(session, nodeID, volumeParts[i].id);

LoadFloatFromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_NORMAL_SCALE_ATTR, ref layer._normalScale);
LoadFloatFromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_METALLIC_ATTR, ref layer._metallic);
LoadFloatFromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_SMOOTHNESS_ATTR, ref layer._smoothness);
if (layer._hasLayerAttributes)
{
LoadStringFromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_TEXTURE_DIFFUSE_ATTR, ref layer._diffuseTexturePath);
LoadStringFromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_TEXTURE_MASK_ATTR, ref layer._maskTexturePath);
LoadStringFromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_TEXTURE_NORMAL_ATTR, ref layer._normalTexturePath);

LoadFloatFromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_NORMAL_SCALE_ATTR, ref layer._normalScale);
LoadFloatFromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_METALLIC_ATTR, ref layer._metallic);
LoadFloatFromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_SMOOTHNESS_ATTR, ref layer._smoothness);

LoadLayerColorFromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_SPECULAR_ATTR, ref layer._specularColor);
LoadLayerVector2FromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_TILE_OFFSET_ATTR, ref layer._tileOffset);
LoadLayerVector2FromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_TILE_SIZE_ATTR, ref layer._tileSize);
LoadLayerColorFromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_SPECULAR_ATTR, ref layer._specularColor);
LoadLayerVector2FromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_TILE_OFFSET_ATTR, ref layer._tileOffset);
LoadLayerVector2FromAttribute(session, nodeID, volumeParts[i].id, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_TILE_SIZE_ATTR, ref layer._tileSize);
}

// Get the height values from Houdini along with the min and max height range.
layer._normalizedHeights = HEU_TerrainUtility.GetNormalizedHeightmapFromPartWithMinMax(_session, nodeID, volumeParts[i].id, volumeInfo.xLength, volumeInfo.yLength, ref layer._minHeight, ref layer._maxHeight, ref layer._heightRange);
Expand Down
Loading

0 comments on commit d795c19

Please sign in to comment.