Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Unity-plugin] Context menu for creating Unity terrain components #1504

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions unity/Editor/Components/MjGeomEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,26 @@ private static void AddMatchingGeom(MenuCommand menuCommand) {
GameObject.DestroyImmediate(geom);
}
}

void OnEnable() {
// Ensure we only subscribe handler once
EditorApplication.contextualPropertyMenu -= OnHeightFieldContextMenu;
EditorApplication.contextualPropertyMenu += OnHeightFieldContextMenu;
}

void OnDestroy() {
EditorApplication.contextualPropertyMenu -= OnHeightFieldContextMenu;
}

void OnHeightFieldContextMenu(GenericMenu menu, SerializedProperty property) {
if (property.type != nameof(MjHeightFieldShape))
return;

menu.AddItem(new GUIContent("Add Unity Terrain"), false, () =>
{
var geom = target as MjGeom;
geom.HField.AddTerrain();
});
}
}
}
27 changes: 25 additions & 2 deletions unity/Runtime/Components/Shapes/MjHeightFieldShape.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,24 @@
using System.Linq;
using System.Xml;
using UnityEngine;

// internal imports
namespace Mujoco {

[Serializable]
public class MjHeightFieldShape : IMjShape {
[Tooltip("Terrain's heightmap should have a minimum value of zero (fully black).")]
[Tooltip("Terrain's heightmap should have a minimum value of zero (fully black). Right click HField to add Unity Terrain."),
ContextMenuItem("Add Unity Terrain", "AddTerrain")]
public Terrain Terrain;

[Tooltip("The path, relative to Application.dataPath, where the heightmap " +
"data will be saved/exported in PNG format. Leave blank if hfield data should " +
"be set instead programmatically (faster).")]
public string HeightMapExportPath;

[Tooltip("This thickness will be added below the 0 height in the hfield, to prevent penetration. ")]
public float BaseHeight = 0.1f;

public bool ExportImage => !string.IsNullOrEmpty(HeightMapExportPath);

public string FullHeightMapPath => Path.GetFullPath(Path.Combine(Application.dataPath,
Expand Down Expand Up @@ -75,7 +80,7 @@ public unsafe void ToMjcf(XmlElement mjcf, Transform transform) {
var assetName = scene.GenerationContext.AddHeightFieldAsset(this);

if (Application.isPlaying) {
scene.postInitEvent += (unused_first, unused_second) =>
erez-tom marked this conversation as resolved.
Show resolved Hide resolved
scene.postInitEvent += (_, _) =>
HeightFieldId =
MujocoLib.mj_name2id(scene.Model, (int)MujocoLib.mjtObj.mjOBJ_HFIELD, assetName);
}
Expand Down Expand Up @@ -160,5 +165,23 @@ public Tuple<Vector3[], int[]> BuildMesh() {
}

public void DebugDraw(Transform transform) {}

public void AddTerrain() {
GameObject terrainObject = new GameObject("Terrain");
Terrain newTerrain = terrainObject.AddComponent<Terrain>();
newTerrain.terrainData = new TerrainData();
newTerrain.terrainData.size = new Vector3(100, 1, 100);

var transform = GameObject
.FindObjectsByType<MjGeom>(FindObjectsInactive.Include, FindObjectsSortMode.None)
.First(g => g.HField == this).transform;

terrainObject.transform.parent = transform;
newTerrain.materialTemplate = new Material(Shader.Find("Nature/Terrain/Diffuse"));
var coll = newTerrain.gameObject.AddComponent<TerrainCollider>();
coll.terrainData = newTerrain.terrainData;
Terrain = newTerrain;
terrainObject.transform.localPosition = new Vector3(-50, 0, -50);
}
}
}
8 changes: 2 additions & 6 deletions unity/Runtime/Tools/MjcfGenerationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,8 @@ private static void GenerateHeightFieldMjcf(MjHeightFieldShape hFieldComponent,
mjcf.SetAttribute("ncol", hFieldComponent.HeightMapWidth.ToString());
}

var baseHeight = hFieldComponent.Terrain.transform.localPosition.y +
hFieldComponent.MinimumHeight;
var heightRange = Mathf.Clamp(
hFieldComponent.MaximumHeight - hFieldComponent.MinimumHeight,
0.00001f,
Mathf.Infinity);
var baseHeight = hFieldComponent.BaseHeight;
var heightRange = hFieldComponent.HeightMapScale.y;
mjcf.SetAttribute(
"size",
MjEngineTool.MakeLocaleInvariant(
Expand Down
Loading