Version 2.1.2: Python bindings, OBJ assets support, bugfixes.

PiperOrigin-RevId: 434731612
Change-Id: I0cfda3e7a3d1c72036764986efc252ffa1b8c6b0
This commit is contained in:
Saran Tunyasuvunakool
2022-03-15 14:04:44 +00:00
parent 175d25cd9f
commit 3577e2cf8b
304 changed files with 23906 additions and 1013 deletions
@@ -0,0 +1,174 @@
// Copyright 2019 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools.Utils;
namespace Mujoco {
[TestFixture]
public class MeshGeneratorsEditorTests {
[Test]
public void FirstAndLastVerticalSlicesContainVerticesLocatedInTheSamePlace() {
var meshData = MeshGenerators.BuildSphere(scale: Vector3.one, numVerticalSlices: 4,
numHorizontalSlices: 3);
var vertices = meshData.Item1;
Assert.That(vertices[0], Is.EqualTo(vertices[1]));
Assert.That(vertices[1], Is.EqualTo(vertices[2]));
Assert.That(vertices[2], Is.EqualTo(vertices[3]));
Assert.That(vertices[8], Is.EqualTo(vertices[9]));
Assert.That(vertices[9], Is.EqualTo(vertices[10]));
Assert.That(vertices[10], Is.EqualTo(vertices[11]));
}
[Test]
public void GeneratedSphereWithProperScaling() {
var scale = new Vector3(0.5f, 2, 3);
var meshData =
MeshGenerators.BuildSphere(scale: scale, numVerticalSlices: 4, numHorizontalSlices: 3);
var vertices = meshData.Item1;
// One of the vertices of the bottom cap.
Assert.That(vertices[0], Is.EqualTo(Vector3.down * scale.y).Using(Vector3ComparerWithEqualsOperator.Instance));
// One of the vertices of the top cap.
Assert.That(vertices[8], Is.EqualTo(Vector3.up * scale.y).Using(Vector3ComparerWithEqualsOperator.Instance));
// The sides.
Assert.That(vertices[4], Is.EqualTo(Vector3.right * scale.x).Using(Vector3ComparerWithEqualsOperator.Instance));
Assert.That(vertices[5], Is.EqualTo(Vector3.back * scale.z).Using(Vector3ComparerWithEqualsOperator.Instance));
Assert.That(vertices[6], Is.EqualTo(Vector3.left * scale.x).Using(Vector3ComparerWithEqualsOperator.Instance));
Assert.That(vertices[7],
Is.EqualTo(Vector3.forward * scale.z).Using(Vector3ComparerWithEqualsOperator.Instance));
}
[Test]
public void GeneratedCylinderHasCorrectHeight() {
var meshData = MeshGenerators.BuildCylinder(radius: 1.0f, height: 5.0f, numVerticalSlices: 4);
var bottomVertex =
meshData.Item1.Aggregate((result, item) => result.y < item.y ? result : item);
var topVertex = meshData.Item1.Aggregate((result, item) => result.y > item.y ? result : item);
Assert.That(topVertex.y - bottomVertex.y, Is.EqualTo(5.0f).Within(1e-3f));
}
[Test]
public void GeneratedCylinderHasCorrectRadius() {
var meshData = MeshGenerators.BuildCylinder(radius: 2.0f, height: 1.0f, numVerticalSlices: 4);
var averageRadius =
meshData.Item1.Select(v => new Vector3(v.x, 0, v.z).magnitude).Average(radius => radius);
Assert.That(averageRadius, Is.EqualTo(2.0f).Within(1e-3f));
}
[Test]
public void GeneratedCapsuleHasCorrectHeight() {
var meshData = MeshGenerators.BuildCapsule(radius: 1.0f, height: 5.0f, numVerticalSlices: 4,
numHorizontalSlices: 3);
var bottomVertex =
meshData.Item1.Aggregate((result, item) => result.y < item.y ? result : item);
var topVertex = meshData.Item1.Aggregate((result, item) => result.y > item.y ? result : item);
// The height of the capsule is the height of the body plus the diameter of the sphere that
// forms the bases.
Assert.That(topVertex.y - bottomVertex.y, Is.EqualTo(5.0f).Within(1e-3f));
}
[Test]
public void GeneratedCapsuleHasCorrectRadius() {
var meshData = MeshGenerators.BuildCapsule(radius: 2.0f, height: 3.0f, numVerticalSlices: 4,
numHorizontalSlices: 3);
var averageRadius = meshData.Item1.Where(v => Math.Abs(v.y) <= 0.5f)
.Select(v => new Vector3(v.x, 0, v.z).magnitude)
.Average(radius => radius);
Assert.That(averageRadius, Is.EqualTo(2.0f).Within(1e-3f));
}
[Test]
public void GeneratedBoxHasCorrectExtents() {
var extents = new Vector3(0.5f, 2, 3);
var meshData = MeshGenerators.BuildBox(extents: extents);
var minVertex = meshData.Item1.Aggregate(
(result, item) =>
(result.x + result.y + result.z) < (item.x + item.y + item.z) ? result : item);
var maxVertex = meshData.Item1.Aggregate(
(result, item) =>
(result.x + result.y + result.z) > (item.x + item.y + item.z) ? result : item);
Assert.That(minVertex, Is.EqualTo(extents * -1.0f).Using(Vector3ComparerWithEqualsOperator.Instance));
Assert.That(maxVertex, Is.EqualTo(extents).Using(Vector3ComparerWithEqualsOperator.Instance));
}
[Test]
public void GeneratedBoxTriangleMapIsAListOfConsecutiveIntegers() {
var meshData = MeshGenerators.BuildBox(extents: Vector3.one);
Assert.That(meshData.Item2, Has.Length.EqualTo(36));
for (var i = 0; i < 36; ++i) {
Assert.That(meshData.Item2[i], Is.EqualTo(i));
}
}
[Test]
public void GeneratedPlaneHasCorrectExtents() {
var meshData = MeshGenerators.BuildPlane(width: 2, height: 3);
var minVertex = meshData.Item1.Aggregate(
(result, item) => (result.x + result.z) < (item.x + item.z) ? result : item);
var maxVertex = meshData.Item1.Aggregate(
(result, item) => (result.x + result.z) > (item.x + item.z) ? result : item);
Assert.That(minVertex, Is.EqualTo(new Vector3(-1, 0, -1.5f)).Using(Vector3ComparerWithEqualsOperator.Instance));
Assert.That(maxVertex, Is.EqualTo(new Vector3(1, 0, 1.5f)).Using(Vector3ComparerWithEqualsOperator.Instance));
}
}
[TestFixture]
public class MeshMergerEditorTests {
private MeshMerger _meshMerger;
[SetUp]
public void SetUp() {
_meshMerger = new MeshMerger();
}
[Test]
public void AddingMeshVerticesAggregatesThem() {
_meshMerger.Add(vertices: new Vector3[] { Vector3.one }, triangles: new int[] {});
Assert.That(_meshMerger.Vertices, Has.Length.EqualTo(1));
_meshMerger.Add(vertices: new Vector3[] { Vector3.forward }, triangles: new int[] {});
Assert.That(_meshMerger.Vertices, Has.Length.EqualTo(2));
Assert.That(_meshMerger.Vertices[0], Is.EqualTo(Vector3.one));
Assert.That(_meshMerger.Vertices[1], Is.EqualTo(Vector3.forward));
}
[Test]
public void TriangleIndicesAreOffsetToPointAtTheCorrespondingMeshes() {
_meshMerger.Add(vertices: new Vector3[] { Vector3.right, Vector3.up },
triangles: new int[] { 0, 1 });
_meshMerger.Add(vertices: new Vector3[] { Vector3.forward, Vector3.zero },
triangles: new int[] { 0, 1 });
Assert.That(_meshMerger.Triangles, Has.Length.EqualTo(4));
Assert.That(_meshMerger.Vertices[_meshMerger.Triangles[0]], Is.EqualTo(Vector3.right));
Assert.That(_meshMerger.Vertices[_meshMerger.Triangles[1]], Is.EqualTo(Vector3.up));
Assert.That(_meshMerger.Vertices[_meshMerger.Triangles[2]], Is.EqualTo(Vector3.forward));
Assert.That(_meshMerger.Vertices[_meshMerger.Triangles[3]], Is.EqualTo(Vector3.zero));
}
[Test]
public void TranslatingAddedVertices() {
_meshMerger.AddAndTranslate(vertices: new Vector3[] { Vector3.zero }, triangles: new int[] {},
translation: Vector3.right);
_meshMerger.AddAndTranslate(vertices: new Vector3[] { Vector3.zero }, triangles: new int[] {},
translation: Vector3.up);
Assert.That(_meshMerger.Vertices[0], Is.EqualTo(Vector3.right));
Assert.That(_meshMerger.Vertices[1], Is.EqualTo(Vector3.up));
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d757196bb4bbd7d0d8eddc399cfeddef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,104 @@
// Copyright 2019 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using NUnit.Framework;
using UnityEngine;
namespace Mujoco {
[TestFixture]
public class MjBoxShapeTests {
private GameObject _owner;
private MjShapeComponent _shape;
private XmlDocument _doc;
[SetUp]
public void SetUp() {
_owner = new GameObject("owner");
_shape = _owner.AddComponent<MjSite>();
_shape.ShapeType = MjShapeComponent.ShapeTypes.Box;
_shape.Box.Extents = Vector3.one;
_doc = new XmlDocument();
}
[TearDown]
public void TearDown() {
UnityEngine.Object.DestroyImmediate(_owner);
}
[TestCase(1, 2, 3, "1 3 2")]
public void BoxSize(float x, float y, float z, string expectedResult) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
_shape.Box.Extents = new Vector3(x, y, z);
_shape.ShapeToMjcf(mjcf, _owner.transform);
Assert.That(_doc.OuterXml, Does.Contain("size=\"" + expectedResult + "\""));
}
[TestCase(0.5f, "0.5 0.5 0.5")]
[TestCase(2.0f, "2 2 2")]
public void EffectOfUniformScaling(float uniformScale, string expectedResult) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
_owner.transform.localScale = Vector3.one * uniformScale;
_shape.ShapeToMjcf(mjcf, _owner.transform);
Assert.That(_doc.OuterXml, Does.Contain("size=\"" + expectedResult + "\""));
}
[TestCase(2, 3, 4, "2 4 3")]
public void EffectOfNonUniformScaling(float x, float y, float z, string expectedResult) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
_owner.transform.localScale = new Vector3(x, y, z);
_shape.ShapeToMjcf(mjcf, _owner.transform);
Assert.That(_doc.OuterXml, Does.Contain("size=\"" + expectedResult + "\""));
}
[Test]
public void ParsingSettings() {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
mjcf.SetAttribute("type", "box");
mjcf.SetAttribute("size", "0.1 0.2 0.3");
_shape.ShapeFromMjcf(mjcf);
Assert.That(_shape.ShapeType, Is.EqualTo(MjShapeComponent.ShapeTypes.Box));
Assert.That(_shape.Box.Extents, Is.EqualTo(new Vector3(0.1f, 0.3f, 0.2f)));
}
[TestCase("0 0 0 0 0 1", 0.5f, 0.5f, 0.5f)]
[TestCase("0 0 0 0 1 0", 0.5f, 0.5f, 0.5f)]
[TestCase("0 0 0 1 0 0", 0.5f, 0.5f, 0.5f)]
[TestCase("0 0 -1 0 0 1", 1, 1, 1)]
[TestCase("0 -1 0 0 1 0", 1, 1, 1)]
[TestCase("-1 0 0 1 0 0", 1, 1, 1)]
public void FromToSizeSpecificationIsOrientationAgnostic(string fromToStr, float x, float y,
float z) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
mjcf.SetAttribute("type", "box");
mjcf.SetAttribute("fromto", fromToStr);
_shape.ShapeFromMjcf(mjcf);
Assert.That(_shape.Box.Extents, Is.EqualTo(new Vector3(x, y, z)));
}
[Test]
public void FromToSizeSpecificationUsesMagnitudeOfVectorAsSizeBase() {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
mjcf.SetAttribute("type", "box");
mjcf.SetAttribute("fromto", "-1 0 0 0 0 1");
_shape.ShapeFromMjcf(mjcf);
Assert.That((_shape.Box.Extents - new Vector3(0.707f, 0.707f, 0.707f)).magnitude,
Is.EqualTo(0).Within(1e-3f));
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: aec19e8fe359a4415a24f826721d003c
timeCreated: 1547644312
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,96 @@
// Copyright 2019 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using NUnit.Framework;
using UnityEngine;
namespace Mujoco {
[TestFixture]
public class MjCapsuleShapeTests {
private GameObject _owner;
private MjShapeComponent _shape;
private XmlDocument _doc;
[SetUp]
public void SetUp() {
_owner = new GameObject("owner");
_shape = _owner.AddComponent<MjSite>();
_shape.ShapeType = MjShapeComponent.ShapeTypes.Capsule;
_doc = new XmlDocument();
}
[TearDown]
public void TearDown() {
UnityEngine.Object.DestroyImmediate(_owner);
}
[TestCase(0.5f, 0.5f, "0.5 0.5")]
[TestCase(1.5f, 1.5f, "1.5 1.5")]
public void CapsuleSize(float radius, float halfHeight, string expectedResult) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
_shape.Capsule.Radius = radius;
_shape.Capsule.HalfHeight = halfHeight;
_shape.ShapeToMjcf(mjcf, _owner.transform);
Assert.That(_doc.OuterXml, Does.Contain("size=\"" + expectedResult + "\""));
}
[TestCase(0.5f, "0.5 1")]
[TestCase(2.0f, "2 4")]
public void EffectOfUniformScaling(float uniformScale, string expectedResult) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
_shape.Capsule.Radius = 1.0f;
_shape.Capsule.HalfHeight = 2.0f;
_owner.transform.localScale = Vector3.one * uniformScale;
_shape.ShapeToMjcf(mjcf, _owner.transform);
Assert.That(_doc.OuterXml, Does.Contain("size=\"" + expectedResult + "\""));
}
[Test]
public void ParsingSettings() {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
mjcf.SetAttribute("type", "capsule");
mjcf.SetAttribute("size", "1.5 2.4");
_shape.ShapeFromMjcf(mjcf);
Assert.That(_shape.ShapeType, Is.EqualTo(MjShapeComponent.ShapeTypes.Capsule));
Assert.That(_shape.Capsule.Radius, Is.EqualTo(1.5f));
Assert.That(_shape.Capsule.HalfHeight, Is.EqualTo(2.4f));
}
[Test]
public void FromToSizeSpecificationOverridesHeightOnly() {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
mjcf.SetAttribute("type", "capsule");
mjcf.SetAttribute("size", "5 1");
mjcf.SetAttribute("fromto", "0 0 0 0 0 3");
_shape.ShapeFromMjcf(mjcf);
Assert.That(_shape.Capsule.Radius, Is.EqualTo(5));
Assert.That(_shape.Capsule.HalfHeight, Is.EqualTo(1.5f));
}
[TestCase("0 0 -1 0 0 2", 1.5f)]
[TestCase("1 0 0 3 0 0", 1)]
public void FromToHeightMeasuredAsSegmentLength(string fromToStr, float expectedHeight) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
mjcf.SetAttribute("type", "capsule");
mjcf.SetAttribute("fromto", fromToStr);
_shape.ShapeFromMjcf(mjcf);
Assert.That(_shape.Capsule.HalfHeight, Is.EqualTo(expectedHeight));
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 9871b9790c4594f638a5bd00d660e897
timeCreated: 1547635214
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,96 @@
// Copyright 2019 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using NUnit.Framework;
using UnityEngine;
namespace Mujoco {
[TestFixture]
public class MjCylinderShapeTests {
private GameObject _owner;
private MjShapeComponent _shape;
private XmlDocument _doc;
[SetUp]
public void SetUp() {
_owner = new GameObject("owner");
_shape = _owner.AddComponent<MjSite>();
_shape.ShapeType = MjShapeComponent.ShapeTypes.Cylinder;
_doc = new XmlDocument();
}
[TearDown]
public void TearDown() {
UnityEngine.Object.DestroyImmediate(_owner);
}
[TestCase(0.5f, 0.5f, "0.5 0.5")]
[TestCase(1.5f, 1.5f, "1.5 1.5")]
public void CylinderSize(float radius, float height, string expectedResult) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
_shape.Cylinder.Radius = radius;
_shape.Cylinder.HalfHeight = height;
_shape.ShapeToMjcf(mjcf, _owner.transform);
Assert.That(_doc.OuterXml, Does.Contain("size=\"" + expectedResult + "\""));
}
[TestCase(0.5f, "0.5 1")]
[TestCase(2.0f, "2 4")]
public void EffectOfUniformScaling(float uniformScale, string expectedResult) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
_shape.Cylinder.Radius = 1.0f;
_shape.Cylinder.HalfHeight = 2.0f;
_owner.transform.localScale = Vector3.one * uniformScale;
_shape.ShapeToMjcf(mjcf, _owner.transform);
Assert.That(_doc.OuterXml, Does.Contain("size=\"" + expectedResult + "\""));
}
[Test]
public void ParsingSettings() {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
mjcf.SetAttribute("type", "cylinder");
mjcf.SetAttribute("size", "1.5 2.4");
_shape.ShapeFromMjcf(mjcf);
Assert.That(_shape.ShapeType, Is.EqualTo(MjShapeComponent.ShapeTypes.Cylinder));
Assert.That(_shape.Cylinder.Radius, Is.EqualTo(1.5f));
Assert.That(_shape.Cylinder.HalfHeight, Is.EqualTo(2.4f));
}
[Test]
public void FromToSizeSpecificationOverridesHeightOnly() {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
mjcf.SetAttribute("type", "cylinder");
mjcf.SetAttribute("size", "5 1");
mjcf.SetAttribute("fromto", "0 0 0 0 0 3");
_shape.ShapeFromMjcf(mjcf);
Assert.That(_shape.Cylinder.Radius, Is.EqualTo(5));
Assert.That(_shape.Cylinder.HalfHeight, Is.EqualTo(1.5f));
}
[TestCase("0 0 -1 0 0 2", 1.5f)]
[TestCase("1 0 0 3 0 0", 1)]
public void FromToHeightMeasuredAsSegmentLength(string fromToStr, float expectedHeight) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
mjcf.SetAttribute("type", "cylinder");
mjcf.SetAttribute("fromto", fromToStr);
_shape.ShapeFromMjcf(mjcf);
Assert.That(_shape.Cylinder.HalfHeight, Is.EqualTo(expectedHeight));
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: cb7edb2ed8966435991a52ed46024185
timeCreated: 1547729698
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,104 @@
// Copyright 2019 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using NUnit.Framework;
using UnityEngine;
namespace Mujoco {
[TestFixture]
public class MjEllipsoidShapeTests {
private GameObject _owner;
private MjShapeComponent _shape;
private XmlDocument _doc;
[SetUp]
public void SetUp() {
_owner = new GameObject("owner");
_shape = _owner.AddComponent<MjSite>();
_shape.ShapeType = MjShapeComponent.ShapeTypes.Ellipsoid;
_shape.Ellipsoid.Radiuses = Vector3.one;
_doc = new XmlDocument();
}
[TearDown]
public void TearDown() {
UnityEngine.Object.DestroyImmediate(_owner);
}
[TestCase(1, 2, 3, "1 3 2")]
public void EllipsoidSize(float x, float y, float z, string expectedResult) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
_shape.Ellipsoid.Radiuses = new Vector3(x, y, z);
_shape.ShapeToMjcf(mjcf, _owner.transform);
Assert.That(_doc.OuterXml, Does.Contain("size=\"" + expectedResult + "\""));
}
[TestCase(0.5f, "0.5 0.5 0.5")]
[TestCase(2.0f, "2 2 2")]
public void EffectOfUniformScaling(float uniformScale, string expectedResult) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
_owner.transform.localScale = Vector3.one * uniformScale;
_shape.ShapeToMjcf(mjcf, _owner.transform);
Assert.That(_doc.OuterXml, Does.Contain("size=\"" + expectedResult + "\""));
}
[TestCase(2, 3, 4, "2 4 3")]
public void EffectOfNonUniformScaling(float x, float y, float z, string expectedResult) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
_owner.transform.localScale = new Vector3(x, y, z);
_shape.ShapeToMjcf(mjcf, _owner.transform);
Assert.That(_doc.OuterXml, Does.Contain("size=\"" + expectedResult + "\""));
}
[Test]
public void ParsingSettings() {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
mjcf.SetAttribute("type", "ellipsoid");
mjcf.SetAttribute("size", "0.1 0.2 0.3");
_shape.ShapeFromMjcf(mjcf);
Assert.That(_shape.ShapeType, Is.EqualTo(MjShapeComponent.ShapeTypes.Ellipsoid));
Assert.That(_shape.Ellipsoid.Radiuses, Is.EqualTo(new Vector3(0.1f, 0.3f, 0.2f)));
}
[TestCase("0 0 0 0 0 1", 0.5f, 0.5f, 0.5f)]
[TestCase("0 0 0 0 1 0", 0.5f, 0.5f, 0.5f)]
[TestCase("0 0 0 1 0 0", 0.5f, 0.5f, 0.5f)]
[TestCase("0 0 -1 0 0 1", 1, 1, 1)]
[TestCase("0 -1 0 0 1 0", 1, 1, 1)]
[TestCase("-1 0 0 1 0 0", 1, 1, 1)]
public void FromToSizeSpecificationIsOrientationAgnostic(string fromToStr, float x, float y,
float z) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
mjcf.SetAttribute("type", "ellipsoid");
mjcf.SetAttribute("fromto", fromToStr);
_shape.ShapeFromMjcf(mjcf);
Assert.That(_shape.Ellipsoid.Radiuses, Is.EqualTo(new Vector3(x, y, z)));
}
[Test]
public void FromToSizeSpecificationUsesMagnitudeOfVectorAsSizeBase() {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
mjcf.SetAttribute("type", "ellipsoid");
mjcf.SetAttribute("fromto", "-1 0 0 0 0 1");
_shape.ShapeFromMjcf(mjcf);
Assert.That((_shape.Ellipsoid.Radiuses - new Vector3(0.707f, 0.707f, 0.707f)).magnitude,
Is.EqualTo(0).Within(1e-3f));
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 8fe14b804de054f709bd186df6160648
timeCreated: 1547644312
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,270 @@
// Copyright 2019 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
namespace Mujoco {
[TestFixture]
public class MjGizmosDrawArcTests {
[SetUp]
public void SetUp() {
MjGizmos.DrawLine = MockDrawLine;
MjGizmos.NumCircleSegments = 4;
_lineFrom = new List<Vector3>();
_lineTo = new List<Vector3>();
}
[TearDown]
public void TearDown() {
MjGizmos.DrawLine = Gizmos.DrawLine;
MjGizmos.NumCircleSegments = 32;
}
private List<Vector3> _lineFrom;
private List<Vector3> _lineTo;
private void MockDrawLine(Vector3 from, Vector3 to) {
_lineFrom.Add(from);
_lineTo.Add(to);
}
[Test]
public void LineCountOfDrawnCircle() {
MjGizmos.DrawArc(Vector3.zero, 1.0f, Vector3.up, 1.0f, 0.0f);
Assert.That(_lineFrom, Has.Count.EqualTo(MjGizmos.NumCircleSegments));
Assert.That(_lineTo, Has.Count.EqualTo(MjGizmos.NumCircleSegments));
}
[Test]
public void LineAdjacencyOfDrawnCircle() {
MjGizmos.DrawArc(Vector3.zero, 1.0f, Vector3.up, 1.0f, 0.0f);
Assert.That((_lineFrom[0] - _lineTo[3]).magnitude, Is.LessThan(1e-3f));
Assert.That((_lineFrom[1] - _lineTo[0]).magnitude, Is.LessThan(1e-3f));
Assert.That((_lineFrom[2] - _lineTo[1]).magnitude, Is.LessThan(1e-3f));
Assert.That((_lineFrom[3] - _lineTo[2]).magnitude, Is.LessThan(1e-3f));
}
[Test]
public void CircleVertexPositions() {
MjGizmos.DrawArc(Vector3.zero, 1.0f, Vector3.up, 1.0f, 0.0f);
Assert.That((_lineFrom[0] - new Vector3(0, 0, -1)).magnitude, Is.LessThan(1e-3f));
Assert.That((_lineFrom[1] - new Vector3(-1, 0, 0)).magnitude, Is.LessThan(1e-3f));
Assert.That((_lineFrom[2] - new Vector3(0, 0, 1)).magnitude, Is.LessThan(1e-3f));
Assert.That((_lineFrom[3] - new Vector3(1, 0, 0)).magnitude, Is.LessThan(1e-3f));
}
[Test]
public void VerticesOfOffsetCircle() {
MjGizmos.DrawArc(Vector3.one, 1.0f, Vector3.up, 1.0f, 0.0f);
Assert.That((_lineFrom[0] - new Vector3(1, 1, 0)).magnitude, Is.LessThan(1e-3f));
Assert.That((_lineFrom[1] - new Vector3(0, 1, 1)).magnitude, Is.LessThan(1e-3f));
Assert.That((_lineFrom[2] - new Vector3(1, 1, 2)).magnitude, Is.LessThan(1e-3f));
Assert.That((_lineFrom[3] - new Vector3(2, 1, 1)).magnitude, Is.LessThan(1e-3f));
}
[Test]
public void DrawingRotatedCircle() {
MjGizmos.DrawArc(Vector3.zero, 1.0f, Vector3.right, 1.0f, 0.0f);
Assert.That((_lineFrom[0] - new Vector3(0, 0, 1)).magnitude, Is.LessThan(1e-3f));
Assert.That((_lineFrom[1] - new Vector3(0, -1, 0)).magnitude, Is.LessThan(1e-3f));
Assert.That((_lineFrom[2] - new Vector3(0, 0, -1)).magnitude, Is.LessThan(1e-3f));
Assert.That((_lineFrom[3] - new Vector3(0, 1, 0)).magnitude, Is.LessThan(1e-3f));
}
[Test]
public void DrawingHalfCircle() {
MjGizmos.DrawArc(Vector3.zero, 1.0f, Vector3.up, 0.25f, 0.0f);
Assert.That(_lineFrom, Has.Count.EqualTo(1));
Assert.That(_lineTo, Has.Count.EqualTo(1));
Assert.That((_lineFrom[0] - new Vector3(0, 0, -1)).magnitude, Is.LessThan(1e-3f));
Assert.That((_lineTo[0] - new Vector3(-1, 0, 0)).magnitude, Is.LessThan(1e-3f));
}
[Test]
public void DrawingHalfCircleWithOffsetCircumference() {
MjGizmos.DrawArc(Vector3.zero, 1.0f, Vector3.up, 0.25f, 90);
Assert.That((_lineFrom[0] - new Vector3(-1, 0, 0)).magnitude, Is.LessThan(1e-3f));
Assert.That((_lineTo[0] - new Vector3(0, 0, 1)).magnitude, Is.LessThan(1e-3f));
}
}
[TestFixture]
public class MjGizmosCapsuleTests {
[SetUp]
public void SetUp() {
MjGizmos.DrawLine = MockDrawLine;
MjGizmos.DrawArc = MockDrawArc;
MjGizmos.NumCircleSegments = 4;
_arc = new List<Tuple<Vector3, float, Vector3, float, float>>();
}
[TearDown]
public void TearDown() {
MjGizmos.DrawLine = Gizmos.DrawLine;
MjGizmos.DrawArc = MjGizmos.DrawArcInternal;
MjGizmos.NumCircleSegments = 32;
}
private List<Tuple<Vector3, float, Vector3, float, float>> _arc;
private void MockDrawLine(Vector3 from, Vector3 to) {}
private void MockDrawArc(Vector3 position, float radius, Vector3 axis, float length,
float startAngle) {
_arc.Add(Tuple.Create(position, radius, axis, length, startAngle));
}
[Test]
public void NumberOfArcsUsedToDrawCapsule() {
MjGizmos.DrawWireCapsule(Vector3.zero, 0.5f, 1.0f);
Assert.That(_arc, Has.Count.EqualTo(6));
}
[Test]
public void CapsuleBaseCirclesOrigins() {
MjGizmos.DrawWireCapsule(Vector3.zero, 0.5f, 1.0f);
Assert.That((_arc[0].Item1 - new Vector3(0, 0.5f, 0)).magnitude, Is.LessThan(1e-3f));
Assert.That((_arc[1].Item1 - new Vector3(0, -0.5f, 0)).magnitude, Is.LessThan(1e-3f));
}
[Test]
public void CapsuleBaseCirclesRadiuses() {
MjGizmos.DrawWireCapsule(Vector3.zero, 0.5f, 1.0f);
Assert.That(_arc[0].Item2, Is.EqualTo(0.5f));
Assert.That(_arc[1].Item2, Is.EqualTo(0.5f));
}
[Test]
public void CapsuleBaseArcsOrigins() {
MjGizmos.DrawWireCapsule(Vector3.zero, 0.5f, 1.0f);
Assert.That((_arc[2].Item1 - new Vector3(0, -0.5f, 0)).magnitude, Is.LessThan(1e-3f));
Assert.That((_arc[3].Item1 - new Vector3(0, 0.5f, 0)).magnitude, Is.LessThan(1e-3f));
Assert.That((_arc[4].Item1 - new Vector3(0, 0.5f, 0)).magnitude, Is.LessThan(1e-3f));
Assert.That((_arc[5].Item1 - new Vector3(0, -0.5f, 0)).magnitude, Is.LessThan(1e-3f));
}
[Test]
public void CapsuleBaseArcsRadiuses() {
MjGizmos.DrawWireCapsule(Vector3.zero, 0.5f, 1.0f);
Assert.That(_arc[2].Item2, Is.EqualTo(0.5f));
Assert.That(_arc[3].Item2, Is.EqualTo(0.5f));
Assert.That(_arc[4].Item2, Is.EqualTo(0.5f));
Assert.That(_arc[5].Item2, Is.EqualTo(0.5f));
}
}
[TestFixture]
public class MjGizmosCylinderTests {
[SetUp]
public void SetUp() {
MjGizmos.DrawLine = MockDrawLine;
MjGizmos.DrawArc = MockDrawArc;
MjGizmos.NumCircleSegments = 4;
_arc = new List<Tuple<Vector3, float, Vector3, float, float>>();
}
[TearDown]
public void TearDown() {
MjGizmos.DrawLine = Gizmos.DrawLine;
MjGizmos.DrawArc = MjGizmos.DrawArcInternal;
MjGizmos.NumCircleSegments = 32;
}
private List<Tuple<Vector3, float, Vector3, float, float>> _arc;
private void MockDrawLine(Vector3 from, Vector3 to) {}
private void MockDrawArc(Vector3 position, float radius, Vector3 axis, float length,
float startAngle) {
_arc.Add(Tuple.Create(position, radius, axis, length, startAngle));
}
[Test]
public void NumberOfArcsUsedToDrawCylinder() {
MjGizmos.DrawWireCylinder(Vector3.zero, 0.5f, 1.0f);
Assert.That(_arc, Has.Count.EqualTo(2));
}
[Test]
public void CylinderBaseCirclesOrigins() {
MjGizmos.DrawWireCylinder(Vector3.zero, 0.5f, 1.0f);
Assert.That((_arc[0].Item1 - new Vector3(0, 0.5f, 0)).magnitude, Is.LessThan(1e-3f));
Assert.That((_arc[1].Item1 - new Vector3(0, -0.5f, 0)).magnitude, Is.LessThan(1e-3f));
}
[Test]
public void CylinderBaseCirclesRadiuses() {
MjGizmos.DrawWireCylinder(Vector3.zero, 0.5f, 1.0f);
Assert.That(_arc[0].Item2, Is.EqualTo(0.5f));
Assert.That(_arc[1].Item2, Is.EqualTo(0.5f));
}
}
[TestFixture]
public class MjGizmosPlaneTests {
[SetUp]
public void SetUp() {
MjGizmos.DrawLine = MockDrawLine;
_lines = new List<Tuple<Vector3, Vector3>>();
}
[TearDown]
public void TearDown() {
MjGizmos.DrawLine = Gizmos.DrawLine;
_lines.Clear();
}
private List<Tuple<Vector3, Vector3>> _lines;
private void MockDrawLine(Vector3 start, Vector3 end) {
_lines.Add(Tuple.Create(start, end));
}
[Test]
public void DrawingPlaneAroundArbitraryCenter() {
MjGizmos.DrawWirePlane(new Vector3(1, 2, 3), 1, 1);
Assert.That(_lines, Has.Count.EqualTo(5));
Assert.That(_lines[0].Item1, Is.EqualTo(new Vector3(0.5f, 2, 2.5f)));
Assert.That(_lines[0].Item2, Is.EqualTo(new Vector3(1.5f, 2, 2.5f)));
Assert.That(_lines[1].Item1, Is.EqualTo(new Vector3(1.5f, 2, 2.5f)));
Assert.That(_lines[1].Item2, Is.EqualTo(new Vector3(1.5f, 2, 3.5f)));
Assert.That(_lines[2].Item1, Is.EqualTo(new Vector3(1.5f, 2, 3.5f)));
Assert.That(_lines[2].Item2, Is.EqualTo(new Vector3(0.5f, 2, 3.5f)));
Assert.That(_lines[3].Item1, Is.EqualTo(new Vector3(0.5f, 2, 3.5f)));
Assert.That(_lines[3].Item2, Is.EqualTo(new Vector3(0.5f, 2, 2.5f)));
Assert.That(_lines[4].Item1, Is.EqualTo(new Vector3(0.5f, 2, 2.5f)));
Assert.That(_lines[4].Item2, Is.EqualTo(new Vector3(1.5f, 2, 3.5f)));
}
[Test]
public void DrawingPlaneWithCorrectDimensions() {
MjGizmos.DrawWirePlane(Vector3.zero, width: 2, height: 4);
Assert.That(_lines[0].Item1, Is.EqualTo(new Vector3(-1, 0, -2)));
Assert.That(_lines[0].Item2, Is.EqualTo(new Vector3(1, 0, -2)));
Assert.That(_lines[1].Item1, Is.EqualTo(new Vector3(1, 0, -2)));
Assert.That(_lines[1].Item2, Is.EqualTo(new Vector3(1, 0, 2)));
Assert.That(_lines[2].Item1, Is.EqualTo(new Vector3(1, 0, 2)));
Assert.That(_lines[2].Item2, Is.EqualTo(new Vector3(-1, 0, 2)));
Assert.That(_lines[3].Item1, Is.EqualTo(new Vector3(-1, 0, 2)));
Assert.That(_lines[3].Item2, Is.EqualTo(new Vector3(-1, 0, -2)));
Assert.That(_lines[4].Item1, Is.EqualTo(new Vector3(-1, 0, -2)));
Assert.That(_lines[4].Item2, Is.EqualTo(new Vector3(1, 0, 2)));
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: a8a01c1e2d4304ce78d8efc6150f2f87
timeCreated: 1536937372
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,78 @@
// Copyright 2019 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using NUnit.Framework;
using UnityEngine;
namespace Mujoco {
[TestFixture]
public class MjPlaneShapeTests {
private GameObject _owner;
private MjShapeComponent _shape;
private XmlDocument _doc;
[SetUp]
public void SetUp() {
_owner = new GameObject("owner");
_shape = _owner.AddComponent<MjSite>();
_shape.ShapeType = MjShapeComponent.ShapeTypes.Plane;
_doc = new XmlDocument();
}
[TearDown]
public void TearDown() {
UnityEngine.Object.DestroyImmediate(_owner);
}
[TestCase(1, 2, "1 2 1")]
public void PlaneSize(float x, float y, string expectedResult) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
_shape.Plane.Extents = new Vector2(x, y);
_shape.ShapeToMjcf(mjcf, _owner.transform);
Assert.That(_doc.OuterXml, Does.Contain("size=\"" + expectedResult + "\""));
}
[TestCase(0.5f, "0.5 0.5 0.5")]
[TestCase(2.0f, "2 2 2")]
public void EffectOfUniformScaling(float uniformScale, string expectedResult) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
_owner.transform.localScale = Vector3.one * uniformScale;
_shape.ShapeToMjcf(mjcf, _owner.transform);
Assert.That(_doc.OuterXml, Does.Contain("size=\"" + expectedResult + "\""));
}
[TestCase(2, 3, 4, "2 3 4")]
public void EffectOfNonUniformScaling(float x, float y, float z, string expectedResult) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
_owner.transform.localScale = new Vector3(x, y, z);
_shape.ShapeToMjcf(mjcf, _owner.transform);
Assert.That(_doc.OuterXml, Does.Contain("size=\"" + expectedResult + "\""));
}
[Test]
public void ParsingSettings() {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
mjcf.SetAttribute("type", "plane");
mjcf.SetAttribute("size", "0.1 0.2 0.3");
_shape.ShapeFromMjcf(mjcf);
Assert.That(_shape.ShapeType, Is.EqualTo(MjShapeComponent.ShapeTypes.Plane));
Assert.That(_shape.Plane.Extents, Is.EqualTo(new Vector2(0.1f, 0.2f)));
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: b37384fec57304bfbb4edd50d7f2f80a
timeCreated: 1547644312
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,72 @@
// Copyright 2019 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using NUnit.Framework;
using UnityEngine;
namespace Mujoco {
[TestFixture]
public class MjSphereShapeTests {
private GameObject _owner;
private MjShapeComponent _shape;
private XmlDocument _doc;
[SetUp]
public void SetUp() {
_owner = new GameObject("owner");
_shape = _owner.AddComponent<MjSite>();
_shape.ShapeType = MjShapeComponent.ShapeTypes.Sphere;
_shape.Sphere.Radius = 1.0f;
_doc = new XmlDocument();
}
[TearDown]
public void TearDown() {
UnityEngine.Object.DestroyImmediate(_owner);
}
[TestCase(2.0f, "2")]
[TestCase(1.5f, "1.5")]
public void XmlSizeForUnscaledSphere(float radius, string expectedResult) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
_shape.Sphere.Radius = radius;
_shape.ShapeToMjcf(mjcf, _owner.transform);
Assert.That(_doc.OuterXml, Does.Contain("size=\"" + expectedResult + "\""));
}
[TestCase(0.5f, "0.5")]
[TestCase(2.0f, "2")]
public void EffectOfUniformScaling(float uniformScale, string expectedResult) {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
_owner.transform.localScale = Vector3.one * uniformScale;
_shape.ShapeToMjcf(mjcf, _owner.transform);
Assert.That(_doc.OuterXml, Does.Contain("size=\"" + expectedResult + "\""));
}
[Test]
public void ParsingSettings() {
var mjcf = (XmlElement)_doc.AppendChild(_doc.CreateElement("test"));
mjcf.SetAttribute("type", "sphere");
mjcf.SetAttribute("size", "0.75");
_shape.ShapeFromMjcf(mjcf);
Assert.That(_shape.ShapeType, Is.EqualTo(MjShapeComponent.ShapeTypes.Sphere));
Assert.That(_shape.Sphere.Radius, Is.EqualTo(0.75f));
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 11e6a66435b9b4c79b38438dfe92b14d
timeCreated: 1547635214
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: