using System.Collections.Generic;
using UnityEngine;
namespace Unity.MLAgents.Extensions.Sensors
{
///
/// Utility class to track a hierarchy of RigidBodies. These are assumed to have a root node,
/// and child nodes are connect to their parents via Joints.
///
public class RigidBodyPoseExtractor : PoseExtractor
{
Rigidbody[] m_Bodies;
///
/// Initialize given a root RigidBody.
///
///
public RigidBodyPoseExtractor(Rigidbody rootBody, GameObject rootGameObject = null)
{
if (rootBody == null)
{
return;
}
Rigidbody[] rbs;
if (rootGameObject == null)
{
rbs = rootBody.GetComponentsInChildren();
}
else
{
rbs = rootGameObject.GetComponentsInChildren();
}
var bodyToIndex = new Dictionary(rbs.Length);
var parentIndices = new int[rbs.Length];
if (rbs[0] != rootBody)
{
Debug.Log("Expected root body at index 0");
return;
}
for (var i = 0; i < rbs.Length; i++)
{
bodyToIndex[rbs[i]] = i;
}
var joints = rootBody.GetComponentsInChildren ();
foreach (var j in joints)
{
var parent = j.connectedBody;
var child = j.GetComponent();
var parentIndex = bodyToIndex[parent];
var childIndex = bodyToIndex[child];
parentIndices[childIndex] = parentIndex;
}
m_Bodies = rbs;
SetParentIndices(parentIndices);
}
///
protected override Vector3 GetLinearVelocityAt(int index)
{
return m_Bodies[index].velocity;
}
///
protected override Pose GetPoseAt(int index)
{
var body = m_Bodies[index];
return new Pose { rotation = body.rotation, position = body.position };
}
internal Rigidbody[] Bodies => m_Bodies;
}
}