123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617 |
- using System;
- using System.Collections;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Threading;
- using UnityEngine;
- using Valve.VR;
- [ExecuteInEditMode]
- public class SteamVR_RenderModel : MonoBehaviour
- {
- public string renderModelName { get; private set; }
- private void OnModelSkinSettingsHaveChanged(params object[] args)
- {
- if (!string.IsNullOrEmpty(this.renderModelName))
- {
- this.renderModelName = string.Empty;
- this.UpdateModel();
- }
- }
- private void OnHideRenderModels(params object[] args)
- {
- bool flag = (bool)args[0];
- MeshRenderer component = base.GetComponent<MeshRenderer>();
- if (component != null)
- {
- component.enabled = !flag;
- }
- foreach (MeshRenderer meshRenderer in base.transform.GetComponentsInChildren<MeshRenderer>())
- {
- meshRenderer.enabled = !flag;
- }
- }
- private void OnDeviceConnected(params object[] args)
- {
- int num = (int)args[0];
- if (num != (int)this.index)
- {
- return;
- }
- bool flag = (bool)args[1];
- if (flag)
- {
- this.UpdateModel();
- }
- }
- public void UpdateModel()
- {
- CVRSystem system = OpenVR.System;
- if (system == null)
- {
- return;
- }
- ETrackedPropertyError etrackedPropertyError = ETrackedPropertyError.TrackedProp_Success;
- uint stringTrackedDeviceProperty = system.GetStringTrackedDeviceProperty((uint)this.index, ETrackedDeviceProperty.Prop_RenderModelName_String, null, 0u, ref etrackedPropertyError);
- if (stringTrackedDeviceProperty <= 1u)
- {
- Debug.LogError("Failed to get render model name for tracked object " + this.index);
- return;
- }
- StringBuilder stringBuilder = new StringBuilder((int)stringTrackedDeviceProperty);
- system.GetStringTrackedDeviceProperty((uint)this.index, ETrackedDeviceProperty.Prop_RenderModelName_String, stringBuilder, stringTrackedDeviceProperty, ref etrackedPropertyError);
- string text = stringBuilder.ToString();
- if (this.renderModelName != text)
- {
- this.renderModelName = text;
- base.StartCoroutine(this.SetModelAsync(text));
- }
- }
- private IEnumerator SetModelAsync(string renderModelName)
- {
- if (string.IsNullOrEmpty(renderModelName))
- {
- yield break;
- }
- using (SteamVR_RenderModel.RenderModelInterfaceHolder holder = new SteamVR_RenderModel.RenderModelInterfaceHolder())
- {
- CVRRenderModels renderModels = holder.instance;
- if (renderModels == null)
- {
- yield break;
- }
- uint count = renderModels.GetComponentCount(renderModelName);
- string[] renderModelNames;
- if (count > 0u)
- {
- renderModelNames = new string[count];
- int num = 0;
- while ((long)num < (long)((ulong)count))
- {
- uint num2 = renderModels.GetComponentName(renderModelName, (uint)num, null, 0u);
- if (num2 != 0u)
- {
- StringBuilder stringBuilder = new StringBuilder((int)num2);
- if (renderModels.GetComponentName(renderModelName, (uint)num, stringBuilder, num2) != 0u)
- {
- num2 = renderModels.GetComponentRenderModelName(renderModelName, stringBuilder.ToString(), null, 0u);
- if (num2 != 0u)
- {
- StringBuilder stringBuilder2 = new StringBuilder((int)num2);
- if (renderModels.GetComponentRenderModelName(renderModelName, stringBuilder.ToString(), stringBuilder2, num2) != 0u)
- {
- string text = stringBuilder2.ToString();
- SteamVR_RenderModel.RenderModel renderModel = SteamVR_RenderModel.models[text] as SteamVR_RenderModel.RenderModel;
- if (renderModel == null || renderModel.mesh == null)
- {
- renderModelNames[num] = text;
- }
- }
- }
- }
- }
- num++;
- }
- }
- else
- {
- SteamVR_RenderModel.RenderModel renderModel2 = SteamVR_RenderModel.models[renderModelName] as SteamVR_RenderModel.RenderModel;
- if (renderModel2 == null || renderModel2.mesh == null)
- {
- renderModelNames = new string[]
- {
- renderModelName
- };
- }
- else
- {
- renderModelNames = new string[0];
- }
- }
- for (;;)
- {
- bool loading = false;
- foreach (string text2 in renderModelNames)
- {
- if (!string.IsNullOrEmpty(text2))
- {
- IntPtr zero = IntPtr.Zero;
- EVRRenderModelError evrrenderModelError = renderModels.LoadRenderModel_Async(text2, ref zero);
- if (evrrenderModelError == EVRRenderModelError.Loading)
- {
- loading = true;
- }
- else if (evrrenderModelError == EVRRenderModelError.None)
- {
- RenderModel_t renderModel_t = (RenderModel_t)Marshal.PtrToStructure(zero, typeof(RenderModel_t));
- Material material = SteamVR_RenderModel.materials[renderModel_t.diffuseTextureId] as Material;
- if (material == null || material.mainTexture == null)
- {
- IntPtr zero2 = IntPtr.Zero;
- evrrenderModelError = renderModels.LoadTexture_Async(renderModel_t.diffuseTextureId, ref zero2);
- if (evrrenderModelError == EVRRenderModelError.Loading)
- {
- loading = true;
- }
- }
- }
- }
- }
- if (!loading)
- {
- break;
- }
- yield return new WaitForSeconds(0.1f);
- }
- }
- bool success = this.SetModel(renderModelName);
- SteamVR_Utils.Event.Send("render_model_loaded", new object[]
- {
- this,
- success
- });
- yield break;
- }
- private bool SetModel(string renderModelName)
- {
- this.StripMesh(base.gameObject);
- using (SteamVR_RenderModel.RenderModelInterfaceHolder renderModelInterfaceHolder = new SteamVR_RenderModel.RenderModelInterfaceHolder())
- {
- if (this.createComponents)
- {
- if (this.LoadComponents(renderModelInterfaceHolder, renderModelName))
- {
- this.UpdateComponents();
- return true;
- }
- Debug.Log("[" + base.gameObject.name + "] Render model does not support components, falling back to single mesh.");
- }
- if (!string.IsNullOrEmpty(renderModelName))
- {
- SteamVR_RenderModel.RenderModel renderModel = SteamVR_RenderModel.models[renderModelName] as SteamVR_RenderModel.RenderModel;
- if (renderModel == null || renderModel.mesh == null)
- {
- CVRRenderModels instance = renderModelInterfaceHolder.instance;
- if (instance == null)
- {
- return false;
- }
- if (this.verbose)
- {
- Debug.Log("Loading render model " + renderModelName);
- }
- renderModel = this.LoadRenderModel(instance, renderModelName, renderModelName);
- if (renderModel == null)
- {
- return false;
- }
- SteamVR_RenderModel.models[renderModelName] = renderModel;
- }
- base.gameObject.AddComponent<MeshFilter>().mesh = renderModel.mesh;
- base.gameObject.AddComponent<MeshRenderer>().sharedMaterial = renderModel.material;
- return true;
- }
- }
- return false;
- }
- private SteamVR_RenderModel.RenderModel LoadRenderModel(CVRRenderModels renderModels, string renderModelName, string baseName)
- {
- IntPtr zero = IntPtr.Zero;
- EVRRenderModelError evrrenderModelError;
- for (;;)
- {
- evrrenderModelError = renderModels.LoadRenderModel_Async(renderModelName, ref zero);
- if (evrrenderModelError != EVRRenderModelError.Loading)
- {
- break;
- }
- Thread.Sleep(1);
- }
- if (evrrenderModelError != EVRRenderModelError.None)
- {
- Debug.LogError(string.Format("Failed to load render model {0} - {1}", renderModelName, evrrenderModelError.ToString()));
- return null;
- }
- RenderModel_t renderModel_t = (RenderModel_t)Marshal.PtrToStructure(zero, typeof(RenderModel_t));
- Vector3[] array = new Vector3[renderModel_t.unVertexCount];
- Vector3[] array2 = new Vector3[renderModel_t.unVertexCount];
- Vector2[] array3 = new Vector2[renderModel_t.unVertexCount];
- Type typeFromHandle = typeof(RenderModel_Vertex_t);
- int num = 0;
- while ((long)num < (long)((ulong)renderModel_t.unVertexCount))
- {
- IntPtr ptr = new IntPtr(renderModel_t.rVertexData.ToInt64() + (long)(num * Marshal.SizeOf(typeFromHandle)));
- RenderModel_Vertex_t renderModel_Vertex_t = (RenderModel_Vertex_t)Marshal.PtrToStructure(ptr, typeFromHandle);
- array[num] = new Vector3(renderModel_Vertex_t.vPosition.v0, renderModel_Vertex_t.vPosition.v1, -renderModel_Vertex_t.vPosition.v2);
- array2[num] = new Vector3(renderModel_Vertex_t.vNormal.v0, renderModel_Vertex_t.vNormal.v1, -renderModel_Vertex_t.vNormal.v2);
- array3[num] = new Vector2(renderModel_Vertex_t.rfTextureCoord0, renderModel_Vertex_t.rfTextureCoord1);
- num++;
- }
- int num2 = (int)(renderModel_t.unTriangleCount * 3u);
- short[] array4 = new short[num2];
- Marshal.Copy(renderModel_t.rIndexData, array4, 0, array4.Length);
- int[] array5 = new int[num2];
- int num3 = 0;
- while ((long)num3 < (long)((ulong)renderModel_t.unTriangleCount))
- {
- array5[num3 * 3] = (int)array4[num3 * 3 + 2];
- array5[num3 * 3 + 1] = (int)array4[num3 * 3 + 1];
- array5[num3 * 3 + 2] = (int)array4[num3 * 3];
- num3++;
- }
- Mesh mesh = new Mesh();
- mesh.vertices = array;
- mesh.normals = array2;
- mesh.uv = array3;
- mesh.triangles = array5;
- Material material = SteamVR_RenderModel.materials[renderModel_t.diffuseTextureId] as Material;
- if (material == null || material.mainTexture == null)
- {
- IntPtr zero2 = IntPtr.Zero;
- for (;;)
- {
- evrrenderModelError = renderModels.LoadTexture_Async(renderModel_t.diffuseTextureId, ref zero2);
- if (evrrenderModelError != EVRRenderModelError.Loading)
- {
- break;
- }
- Thread.Sleep(1);
- }
- if (evrrenderModelError == EVRRenderModelError.None)
- {
- RenderModel_TextureMap_t renderModel_TextureMap_t = (RenderModel_TextureMap_t)Marshal.PtrToStructure(zero2, typeof(RenderModel_TextureMap_t));
- Texture2D texture2D = new Texture2D((int)renderModel_TextureMap_t.unWidth, (int)renderModel_TextureMap_t.unHeight, TextureFormat.ARGB32, false);
- if (SystemInfo.graphicsDeviceVersion.StartsWith("OpenGL"))
- {
- byte[] array6 = new byte[(int)(renderModel_TextureMap_t.unWidth * renderModel_TextureMap_t.unHeight * '\u0004')];
- Marshal.Copy(renderModel_TextureMap_t.rubTextureMapData, array6, 0, array6.Length);
- Color32[] array7 = new Color32[(int)(renderModel_TextureMap_t.unWidth * renderModel_TextureMap_t.unHeight)];
- int num4 = 0;
- for (int i = 0; i < (int)renderModel_TextureMap_t.unHeight; i++)
- {
- for (int j = 0; j < (int)renderModel_TextureMap_t.unWidth; j++)
- {
- byte r = array6[num4++];
- byte g = array6[num4++];
- byte b = array6[num4++];
- byte a = array6[num4++];
- array7[i * (int)renderModel_TextureMap_t.unWidth + j] = new Color32(r, g, b, a);
- }
- }
- texture2D.SetPixels32(array7);
- texture2D.Apply();
- }
- else
- {
- texture2D.Apply();
- for (;;)
- {
- evrrenderModelError = renderModels.LoadIntoTextureD3D11_Async(renderModel_t.diffuseTextureId, texture2D.GetNativeTexturePtr());
- if (evrrenderModelError != EVRRenderModelError.Loading)
- {
- break;
- }
- Thread.Sleep(1);
- }
- }
- material = new Material((!(this.shader != null)) ? Shader.Find("Standard") : this.shader);
- material.mainTexture = texture2D;
- SteamVR_RenderModel.materials[renderModel_t.diffuseTextureId] = material;
- renderModels.FreeTexture(zero2);
- }
- else
- {
- Debug.Log("Failed to load render model texture for render model " + renderModelName);
- }
- }
- base.StartCoroutine(this.FreeRenderModel(zero));
- return new SteamVR_RenderModel.RenderModel(mesh, material);
- }
- private IEnumerator FreeRenderModel(IntPtr pRenderModel)
- {
- yield return new WaitForSeconds(1f);
- using (SteamVR_RenderModel.RenderModelInterfaceHolder renderModelInterfaceHolder = new SteamVR_RenderModel.RenderModelInterfaceHolder())
- {
- CVRRenderModels instance = renderModelInterfaceHolder.instance;
- instance.FreeRenderModel(pRenderModel);
- }
- yield break;
- }
- public Transform FindComponent(string componentName)
- {
- Transform transform = base.transform;
- for (int i = 0; i < transform.childCount; i++)
- {
- Transform child = transform.GetChild(i);
- if (child.name == componentName)
- {
- return child;
- }
- }
- return null;
- }
- private void StripMesh(GameObject go)
- {
- MeshRenderer component = go.GetComponent<MeshRenderer>();
- if (component != null)
- {
- UnityEngine.Object.DestroyImmediate(component);
- }
- MeshFilter component2 = go.GetComponent<MeshFilter>();
- if (component2 != null)
- {
- UnityEngine.Object.DestroyImmediate(component2);
- }
- }
- private bool LoadComponents(SteamVR_RenderModel.RenderModelInterfaceHolder holder, string renderModelName)
- {
- Transform transform = base.transform;
- for (int i = 0; i < transform.childCount; i++)
- {
- Transform child = transform.GetChild(i);
- child.gameObject.SetActive(false);
- this.StripMesh(child.gameObject);
- }
- if (string.IsNullOrEmpty(renderModelName))
- {
- return true;
- }
- CVRRenderModels instance = holder.instance;
- if (instance == null)
- {
- return false;
- }
- uint componentCount = instance.GetComponentCount(renderModelName);
- if (componentCount == 0u)
- {
- return false;
- }
- int num = 0;
- while ((long)num < (long)((ulong)componentCount))
- {
- uint num2 = instance.GetComponentName(renderModelName, (uint)num, null, 0u);
- if (num2 != 0u)
- {
- StringBuilder stringBuilder = new StringBuilder((int)num2);
- if (instance.GetComponentName(renderModelName, (uint)num, stringBuilder, num2) != 0u)
- {
- transform = this.FindComponent(stringBuilder.ToString());
- if (transform != null)
- {
- transform.gameObject.SetActive(true);
- }
- else
- {
- transform = new GameObject(stringBuilder.ToString()).transform;
- transform.parent = base.transform;
- transform.gameObject.layer = base.gameObject.layer;
- Transform transform2 = new GameObject("attach").transform;
- transform2.parent = transform;
- transform2.localPosition = Vector3.zero;
- transform2.localRotation = Quaternion.identity;
- transform2.localScale = Vector3.one;
- transform2.gameObject.layer = base.gameObject.layer;
- }
- transform.localPosition = Vector3.zero;
- transform.localRotation = Quaternion.identity;
- transform.localScale = Vector3.one;
- num2 = instance.GetComponentRenderModelName(renderModelName, stringBuilder.ToString(), null, 0u);
- if (num2 != 0u)
- {
- StringBuilder stringBuilder2 = new StringBuilder((int)num2);
- if (instance.GetComponentRenderModelName(renderModelName, stringBuilder.ToString(), stringBuilder2, num2) != 0u)
- {
- SteamVR_RenderModel.RenderModel renderModel = SteamVR_RenderModel.models[stringBuilder2] as SteamVR_RenderModel.RenderModel;
- if (renderModel == null || renderModel.mesh == null)
- {
- if (this.verbose)
- {
- Debug.Log("Loading render model " + stringBuilder2);
- }
- renderModel = this.LoadRenderModel(instance, stringBuilder2.ToString(), renderModelName);
- if (renderModel == null)
- {
- goto IL_265;
- }
- SteamVR_RenderModel.models[stringBuilder2] = renderModel;
- }
- transform.gameObject.AddComponent<MeshFilter>().mesh = renderModel.mesh;
- transform.gameObject.AddComponent<MeshRenderer>().sharedMaterial = renderModel.material;
- }
- }
- }
- }
- IL_265:
- num++;
- }
- return true;
- }
- private void OnEnable()
- {
- if (!string.IsNullOrEmpty(this.modelOverride))
- {
- Debug.Log("Model override is really only meant to be used in the scene view for lining things up; using it at runtime is discouraged. Use tracked device index instead to ensure the correct model is displayed for all users.");
- base.enabled = false;
- return;
- }
- CVRSystem system = OpenVR.System;
- if (system != null && system.IsTrackedDeviceConnected((uint)this.index))
- {
- this.UpdateModel();
- }
- SteamVR_Utils.Event.Listen("device_connected", new SteamVR_Utils.Event.Handler(this.OnDeviceConnected));
- SteamVR_Utils.Event.Listen("hide_render_models", new SteamVR_Utils.Event.Handler(this.OnHideRenderModels));
- SteamVR_Utils.Event.Listen("ModelSkinSettingsHaveChanged", new SteamVR_Utils.Event.Handler(this.OnModelSkinSettingsHaveChanged));
- }
- private void OnDisable()
- {
- SteamVR_Utils.Event.Remove("device_connected", new SteamVR_Utils.Event.Handler(this.OnDeviceConnected));
- SteamVR_Utils.Event.Remove("hide_render_models", new SteamVR_Utils.Event.Handler(this.OnHideRenderModels));
- SteamVR_Utils.Event.Remove("ModelSkinSettingsHaveChanged", new SteamVR_Utils.Event.Handler(this.OnModelSkinSettingsHaveChanged));
- }
- private void Update()
- {
- if (this.updateDynamically)
- {
- this.UpdateComponents();
- }
- }
- public void UpdateComponents()
- {
- Transform transform = base.transform;
- if (transform.childCount == 0)
- {
- return;
- }
- using (SteamVR_RenderModel.RenderModelInterfaceHolder renderModelInterfaceHolder = new SteamVR_RenderModel.RenderModelInterfaceHolder())
- {
- VRControllerState_t vrcontrollerState_t = (this.index == SteamVR_TrackedObject.EIndex.None) ? default(VRControllerState_t) : SteamVR_Controller.Input((int)this.index).GetState();
- for (int i = 0; i < transform.childCount; i++)
- {
- Transform child = transform.GetChild(i);
- CVRRenderModels instance = renderModelInterfaceHolder.instance;
- if (instance == null)
- {
- break;
- }
- RenderModel_ComponentState_t renderModel_ComponentState_t = default(RenderModel_ComponentState_t);
- if (instance.GetComponentState(this.renderModelName, child.name, ref vrcontrollerState_t, ref this.controllerModeState, ref renderModel_ComponentState_t))
- {
- SteamVR_Utils.RigidTransform rigidTransform = new SteamVR_Utils.RigidTransform(renderModel_ComponentState_t.mTrackingToComponentRenderModel);
- child.localPosition = rigidTransform.pos;
- child.localRotation = rigidTransform.rot;
- Transform transform2 = child.Find("attach");
- if (transform2 != null)
- {
- SteamVR_Utils.RigidTransform rigidTransform2 = new SteamVR_Utils.RigidTransform(renderModel_ComponentState_t.mTrackingToComponentLocal);
- transform2.position = transform.TransformPoint(rigidTransform2.pos);
- transform2.rotation = transform.rotation * rigidTransform2.rot;
- }
- bool flag = (renderModel_ComponentState_t.uProperties & 2u) != 0u;
- if (flag != child.gameObject.activeSelf)
- {
- child.gameObject.SetActive(flag);
- }
- }
- }
- }
- }
- public void SetDeviceIndex(int index)
- {
- this.index = (SteamVR_TrackedObject.EIndex)index;
- this.modelOverride = string.Empty;
- if (base.enabled)
- {
- this.UpdateModel();
- }
- }
- public SteamVR_TrackedObject.EIndex index = SteamVR_TrackedObject.EIndex.None;
- public string modelOverride;
- public Shader shader;
- public bool verbose;
- public bool createComponents = true;
- public bool updateDynamically = true;
- public RenderModel_ControllerMode_State_t controllerModeState;
- public const string k_localTransformName = "attach";
- public static Hashtable models = new Hashtable();
- public static Hashtable materials = new Hashtable();
- public class RenderModel
- {
- public RenderModel(Mesh mesh, Material material)
- {
- this.mesh = mesh;
- this.material = material;
- }
- public Mesh mesh { get; private set; }
- public Material material { get; private set; }
- }
- public sealed class RenderModelInterfaceHolder : IDisposable
- {
- public CVRRenderModels instance
- {
- get
- {
- if (this._instance == null && !this.failedLoadInterface)
- {
- if (!SteamVR.active && !SteamVR.usingNativeSupport)
- {
- EVRInitError evrinitError = EVRInitError.None;
- OpenVR.Init(ref evrinitError, EVRApplicationType.VRApplication_Other);
- this.needsShutdown = true;
- }
- this._instance = OpenVR.RenderModels;
- if (this._instance == null)
- {
- Debug.LogError("Failed to load IVRRenderModels interface version IVRRenderModels_005");
- this.failedLoadInterface = true;
- }
- }
- return this._instance;
- }
- }
- public void Dispose()
- {
- if (this.needsShutdown)
- {
- OpenVR.Shutdown();
- }
- }
- private bool needsShutdown;
- private bool failedLoadInterface;
- private CVRRenderModels _instance;
- }
- }
|