Fix rendering of tendons
This commit is contained in:
@@ -15,7 +15,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices.ComTypes;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Mujoco {
|
namespace Mujoco {
|
||||||
@@ -38,6 +40,9 @@ public class MjSpatialTendon : MjBaseTendon {
|
|||||||
[Tooltip("In meters.")]
|
[Tooltip("In meters.")]
|
||||||
public float RangeUpper;
|
public float RangeUpper;
|
||||||
|
|
||||||
|
[Tooltip("Scales with UI points. 0.003 is mapped to 1 UI point.")]
|
||||||
|
public float Width = 0.003f;
|
||||||
|
|
||||||
public List<SpatialTendonEntry> ViapointsList = new List<SpatialTendonEntry>() {};
|
public List<SpatialTendonEntry> ViapointsList = new List<SpatialTendonEntry>() {};
|
||||||
|
|
||||||
protected override void FromMjcf(XmlElement mjcf) {
|
protected override void FromMjcf(XmlElement mjcf) {
|
||||||
@@ -50,6 +55,7 @@ public class MjSpatialTendon : MjBaseTendon {
|
|||||||
ViapointsList.Add(viapoint);
|
ViapointsList.Add(viapoint);
|
||||||
}
|
}
|
||||||
var rangeValues = mjcf.GetFloatArrayAttribute("range", defaultValue: new float[] { 0, 0 });
|
var rangeValues = mjcf.GetFloatArrayAttribute("range", defaultValue: new float[] { 0, 0 });
|
||||||
|
Width = mjcf.GetFloatAttribute("width", defaultValue: 0.003f);
|
||||||
RangeLower = rangeValues[0];
|
RangeLower = rangeValues[0];
|
||||||
RangeUpper = rangeValues[1];
|
RangeUpper = rangeValues[1];
|
||||||
}
|
}
|
||||||
@@ -100,31 +106,37 @@ public class MjSpatialTendon : MjBaseTendon {
|
|||||||
throw new ArgumentException("Lower range value can't be bigger than Higher");
|
throw new ArgumentException("Lower range value can't be bigger than Higher");
|
||||||
}
|
}
|
||||||
mjcf.SetAttribute("range", MjEngineTool.MakeLocaleInvariant($"{RangeLower} {RangeUpper}"));
|
mjcf.SetAttribute("range", MjEngineTool.MakeLocaleInvariant($"{RangeLower} {RangeUpper}"));
|
||||||
|
mjcf.SetAttribute("width", MjEngineTool.MakeLocaleInvariant($"{Width}"));
|
||||||
|
|
||||||
return mjcf;
|
return mjcf;
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void OnDrawGizmos() {
|
public unsafe void OnDrawGizmosSelected() {
|
||||||
if (Application.isPlaying) {
|
if (Application.isPlaying && MjScene.InstanceExists) {
|
||||||
var scene = MjScene.Instance;
|
// Lifted from src/engine/engine_vis_visualize.c
|
||||||
var segmentCount = scene.Model->nwrap - 1;
|
var d = MjScene.Instance.Data;
|
||||||
var data = scene.Data;
|
var m = MjScene.Instance.Model;
|
||||||
int readHead = 0;
|
int i = MujocoId;
|
||||||
for (int i = 0; i < segmentCount; ++i) {
|
double sz;
|
||||||
// Skip drawing of pulley:
|
for (int j = d->ten_wrapadr[i]; j < d->ten_wrapadr[i] + d->ten_wrapnum[i] - 1; j++) {
|
||||||
if (data->wrap_obj[readHead] == -2 || data->wrap_obj[readHead + 1] == -2) {
|
if (d->wrap_obj[j] != -2 && d->wrap_obj[j + 1] != -2) {
|
||||||
readHead += 1;
|
// determine width: smaller for segments inside wrapping objects
|
||||||
} else {
|
if (d->wrap_obj[j] >= 0 && d->wrap_obj[j + 1] >= 0) {
|
||||||
Vector3 start = MjEngineTool.UnityVector3(
|
sz = 0.5 * m->tendon_width[i];
|
||||||
MjEngineTool.MjVector3AtEntry(data->wrap_xpos, readHead));
|
} else {
|
||||||
Vector3 end = MjEngineTool.UnityVector3(
|
sz = m->tendon_width[i];
|
||||||
MjEngineTool.MjVector3AtEntry(data->wrap_xpos, readHead + 1));
|
|
||||||
Gizmos.DrawLine(start, end);
|
|
||||||
if (data->wrap_obj[readHead + 1] >= 0) { // a wrap geom
|
|
||||||
readHead += 2;
|
|
||||||
} else { // site or pulley
|
|
||||||
readHead += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var startPos = MjEngineTool.UnityVector3(d->wrap_xpos + 3 * j);
|
||||||
|
var endPos = MjEngineTool.UnityVector3(d->wrap_xpos + 3 * j + 3);
|
||||||
|
|
||||||
|
// Construct line
|
||||||
|
// At the moment we use handles instead of Gizmos (to be able to set width).
|
||||||
|
// This means rendering won't be performed outside editor; We could implement a "TendonRenderer" component
|
||||||
|
// (added using a context tool) that uses a LineRenderer. Then we could have nice features such as updating
|
||||||
|
// tendon colors or width based on length or tension. That would also allow in-build rendering.
|
||||||
|
Handles.color = Color.magenta; // Currently we ignore tendon material.
|
||||||
|
Handles.DrawLine(startPos, endPos, (float)sz/0.003f); // Handle width in UI points. We map the default width to 1 pixel.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user