implementation of drecon in unity 2022 lts
forked from:
https://github.com/joanllobera/marathon-envs
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
195 lines
7.1 KiB
195 lines
7.1 KiB
9 months ago
|
using System.Linq;
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace Unity.MLAgents
|
||
|
{
|
||
|
public static class MarathonHelper
|
||
|
{
|
||
|
static readonly bool FlipMarathonX = false;
|
||
|
|
||
|
public static Vector3 RightToLeft(Vector3 rightHanded, bool hackFlipZ = false)
|
||
|
{
|
||
|
if (FlipMarathonX)
|
||
|
return new Vector3(rightHanded.x, rightHanded.z,
|
||
|
rightHanded.y); // use if fliping marathon's X direction
|
||
|
return new Vector3(-rightHanded.x, rightHanded.z, -rightHanded.y); // use to maintain marathon's X direction
|
||
|
}
|
||
|
|
||
|
static char[] _delimiterChars = {' ', ',', ':', '\t'};
|
||
|
|
||
|
static string RemoveDuplicateWhitespace(string input)
|
||
|
{
|
||
|
while (input.Contains(" "))
|
||
|
input = input.Replace(" ", " ");
|
||
|
while (input.Contains("\t\t"))
|
||
|
input = input.Replace("\t\t", "\t");
|
||
|
return input;
|
||
|
}
|
||
|
|
||
|
static float Evaluate(string expression)
|
||
|
{
|
||
|
var doc = new System.Xml.XPath.XPathDocument(new System.IO.StringReader("<r/>"));
|
||
|
var nav = doc.CreateNavigator();
|
||
|
var newString = expression;
|
||
|
newString = (new System.Text.RegularExpressions.Regex(@"([\+\-\*])")).Replace(newString, " ${1} ");
|
||
|
newString = newString.Replace("/", " div ").Replace("%", " mod ");
|
||
|
var res = nav.Evaluate("number(" + newString + ")");
|
||
|
double d = (double) res;
|
||
|
return (float) d;
|
||
|
}
|
||
|
|
||
|
|
||
|
static public Vector3 ParseVector3NoFlipYZ(string str)
|
||
|
{
|
||
|
str = RemoveDuplicateWhitespace(str);
|
||
|
string[] words = str.Split(_delimiterChars);
|
||
|
float x = Evaluate(words[0]);
|
||
|
float y = Evaluate(words[1]);
|
||
|
float z = Evaluate(words[2]);
|
||
|
var vec3 = new Vector3(x, y, z);
|
||
|
return vec3;
|
||
|
}
|
||
|
|
||
|
static public Quaternion ParseQuaternion(string str)
|
||
|
{
|
||
|
str = RemoveDuplicateWhitespace(str);
|
||
|
string[] words = str.Split(_delimiterChars);
|
||
|
float w = Evaluate(words[0]);
|
||
|
float x = Evaluate(words[1]);
|
||
|
float y = Evaluate(words[2]);
|
||
|
float z = Evaluate(words[3]);
|
||
|
var q = new Quaternion(x, y, z, w);
|
||
|
return q;
|
||
|
}
|
||
|
|
||
|
static public Vector3 ParseAxis(string str)
|
||
|
{
|
||
|
var axis = MarathonHelper.ParseVector3NoFlipYZ(str);
|
||
|
if (FlipMarathonX)
|
||
|
axis = new Vector3(-axis.x, -axis.z, -axis.y); // use if fliping marathon's X direction
|
||
|
else
|
||
|
axis = new Vector3(axis.x, -axis.z, axis.y); // use to maintain marathon's X direction
|
||
|
return axis;
|
||
|
}
|
||
|
|
||
|
static public Vector3 JointParsePosition(string str, bool hackFlipZ)
|
||
|
{
|
||
|
str = RemoveDuplicateWhitespace(str);
|
||
|
string[] words = str.Split(_delimiterChars);
|
||
|
float x = Evaluate(words[0]);
|
||
|
float y = Evaluate(words[1]);
|
||
|
float z = Evaluate(words[2]);
|
||
|
Vector3 vec3 = new Vector3(x, y, z);
|
||
|
return RightToLeft(vec3, hackFlipZ);
|
||
|
}
|
||
|
|
||
|
public static Vector3 ParsePosition(string str)
|
||
|
{
|
||
|
str = RemoveDuplicateWhitespace(str);
|
||
|
string[] words = str.Split(_delimiterChars);
|
||
|
float x = Evaluate(words[0]);
|
||
|
float y = Evaluate(words[1]);
|
||
|
float z = Evaluate(words[2]);
|
||
|
Vector3 vec3 = new Vector3(x, y, z);
|
||
|
return RightToLeft(vec3);
|
||
|
}
|
||
|
|
||
|
public static Vector3 ParseFrom(string fromTo)
|
||
|
{
|
||
|
return ParseVector3NoFlipYZ(fromTo);
|
||
|
}
|
||
|
|
||
|
public static Vector3 ParseTo(string fromTo)
|
||
|
{
|
||
|
fromTo = RemoveDuplicateWhitespace(fromTo);
|
||
|
string[] words = fromTo.Split(_delimiterChars);
|
||
|
float x = Evaluate(words[3]);
|
||
|
float y = Evaluate(words[4]);
|
||
|
float z = Evaluate(words[5]);
|
||
|
Vector3 vec3 = new Vector3(x, y, z);
|
||
|
return vec3;
|
||
|
}
|
||
|
|
||
|
public static Vector2 ParseVector2(string str)
|
||
|
{
|
||
|
str = RemoveDuplicateWhitespace(str);
|
||
|
string[] words = str.Split(_delimiterChars);
|
||
|
float x = Evaluate(words[0]);
|
||
|
float y = Evaluate(words[1]);
|
||
|
var vec2 = new Vector2(x, y);
|
||
|
return vec2;
|
||
|
}
|
||
|
|
||
|
public static float ParseGetMin(string rangeAsText)
|
||
|
{
|
||
|
rangeAsText = RemoveDuplicateWhitespace(rangeAsText);
|
||
|
string[] words = rangeAsText.Split(_delimiterChars);
|
||
|
var range = words.Select(x => Evaluate(x));
|
||
|
return range.Min();
|
||
|
}
|
||
|
|
||
|
public static float ParseGetMax(string rangeAsText)
|
||
|
{
|
||
|
rangeAsText = RemoveDuplicateWhitespace(rangeAsText);
|
||
|
string[] words = rangeAsText.Split(_delimiterChars);
|
||
|
var range = words.Select(x => Evaluate(x));
|
||
|
return range.Max();
|
||
|
}
|
||
|
|
||
|
|
||
|
public static GameObject CreateBetweenPoints(this GameObject parent, Vector3 start, Vector3 end, float width,
|
||
|
bool useWorldSpace, GameObject root)
|
||
|
{
|
||
|
start = RightToLeft(start);
|
||
|
end = RightToLeft(end);
|
||
|
var instance = new GameObject();
|
||
|
var procCap = instance.AddComponent<ProceduralCapsule>();
|
||
|
var handleOverlap = instance.AddComponent<HandleOverlap>();
|
||
|
handleOverlap.Parent = root;
|
||
|
var collider = instance.AddComponent<CapsuleCollider>();
|
||
|
var offset = start - end;
|
||
|
var position = start - (offset / 2.0f);
|
||
|
var height = offset.magnitude;
|
||
|
collider.height = height + (width * 2) * .90f;
|
||
|
collider.radius = width * .90f;
|
||
|
procCap.height = height + (width);
|
||
|
procCap.radius = width;
|
||
|
procCap.CreateMesh();
|
||
|
|
||
|
instance.transform.parent = root.transform;
|
||
|
instance.transform.up = offset;
|
||
|
if (useWorldSpace)
|
||
|
{
|
||
|
instance.transform.position = position;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
instance.transform.position = position + parent.transform.position;
|
||
|
instance.transform.rotation = instance.transform.rotation * parent.transform.rotation;
|
||
|
}
|
||
|
|
||
|
// UnityEngine.GameObject.Destroy(handleOverlap);
|
||
|
return instance;
|
||
|
}
|
||
|
|
||
|
public static GameObject CreateAtPoint(this GameObject parent, Vector3 position, float width,
|
||
|
bool useWorldSpace, GameObject root)
|
||
|
{
|
||
|
var scale = new Vector3(width, width, width);
|
||
|
var instance = GameObject.CreatePrimitive(PrimitiveType.Sphere);
|
||
|
instance.transform.parent = root.transform;
|
||
|
instance.transform.localScale = scale * 2;
|
||
|
if (useWorldSpace)
|
||
|
{
|
||
|
instance.transform.position = position;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
instance.transform.position = position + parent.transform.position;
|
||
|
instance.transform.rotation = instance.transform.rotation * parent.transform.rotation;
|
||
|
}
|
||
|
|
||
|
return instance;
|
||
|
}
|
||
|
}
|
||
|
}
|