1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
// 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.Xml;
using UnityEngine;
namespace Mujoco {
// The base class for all components that represent Mujoco scene nodes.
[DisallowMultipleComponent]
public abstract class MjComponent : MonoBehaviour {
// Unique name assigned to each Mujoco component.
public string MujocoName { get; private set; }
// Id of the geom in Mujoco's internal data structures.
public int MujocoId { get; protected set; }
public abstract MujocoLib.mjtObj ObjectType { get; }
// Some components (Inertial frames for example) cannot have the name attribute
// added to the generated Mjcf.
protected virtual bool _suppressNameAttribute => false;
// Binds this component to the compiled Mujoco model.
public unsafe void BindToRuntime(MujocoLib.mjModel_* model, MujocoLib.mjData_* data) {
MujocoId = MujocoLib.mj_name2id(model, (int)ObjectType, MujocoName);
if (MujocoId == -1 && !_suppressNameAttribute) {
throw new NullReferenceException($"element name {MujocoName} not found");
}
OnBindToRuntime(model, data);
}
// Generates the XML element that corresponds to this scene node.
public XmlElement GenerateMjcf(string name, XmlDocument doc) {
MujocoName = name;
var mjcf = OnGenerateMjcf(doc);
if (!_suppressNameAttribute) {
mjcf.SetAttribute("name", name);
}
return mjcf;
}
// Parse the component settings from an external Mjcf.
public void ParseMjcf(XmlElement mjcf) {
// I would like to preserve the naming dualism - external mechanisms
// calling a method, and the internal implementation implementing
// the method with an "On" prefix.
OnParseMjcf(mjcf);
}
// Parse the component settings from an external Mjcf.
protected abstract void OnParseMjcf(XmlElement mjcf);
// Generate implementation specific XML element.
protected abstract XmlElement OnGenerateMjcf(XmlDocument doc);
// Perform bind time initialization of the component.
protected virtual unsafe void OnBindToRuntime(MujocoLib.mjModel_* model, MujocoLib.mjData_* data) {}
// Synchronize the state of the component.
public virtual unsafe void OnSyncState(MujocoLib.mjData_* data) {}
private bool _sceneExcludesMe = false;
protected unsafe virtual void Start() {
if (MjScene.Instance == null) {
throw new Exception("MuJoCo Scene not found");
}
if (MjScene.Instance.Model != null) {
_sceneExcludesMe = true;
}
}
protected void Update() {
if (_sceneExcludesMe) {
MjScene.Instance.SceneRecreationAtLateUpdateRequested = true;
_sceneExcludesMe = false;
}
}
private bool _exiting = false;
public void OnApplicationQuit() {
_exiting = true;
}
public void OnDisable() {
if (!_exiting) {
MjScene.Instance.SceneRecreationAtLateUpdateRequested = true;
}
}
}
}
|