コード例 #1
0
ファイル: SteamVR_RenderModel.cs プロジェクト: 8701s/VRMuseum
    RenderModel LoadRenderModel(CVRRenderModels renderModels, string renderModelName, string baseName)
    {
        var pRenderModel = System.IntPtr.Zero;

        EVRRenderModelError error;

        while (true)
        {
            error = renderModels.LoadRenderModel_Async(renderModelName, ref pRenderModel);
            if (error != EVRRenderModelError.Loading)
            {
                break;
            }

            System.Threading.Thread.Sleep(1);
        }

        if (error != EVRRenderModelError.None)
        {
            Debug.LogError(string.Format("Failed to load render model {0} - {1}", renderModelName, error.ToString()));
            return(null);
        }

        var renderModel = (RenderModel_t)Marshal.PtrToStructure(pRenderModel, typeof(RenderModel_t));

        var vertices = new Vector3[renderModel.unVertexCount];
        var normals  = new Vector3[renderModel.unVertexCount];
        var uv       = new Vector2[renderModel.unVertexCount];

        var type = typeof(RenderModel_Vertex_t);

        for (int iVert = 0; iVert < renderModel.unVertexCount; iVert++)
        {
            var ptr  = new System.IntPtr(renderModel.rVertexData.ToInt64() + iVert * Marshal.SizeOf(type));
            var vert = (RenderModel_Vertex_t)Marshal.PtrToStructure(ptr, type);

            vertices[iVert] = new Vector3(vert.vPosition.v0, vert.vPosition.v1, -vert.vPosition.v2);
            normals[iVert]  = new Vector3(vert.vNormal.v0, vert.vNormal.v1, -vert.vNormal.v2);
            uv[iVert]       = new Vector2(vert.rfTextureCoord0, vert.rfTextureCoord1);
        }

        int indexCount = (int)renderModel.unTriangleCount * 3;
        var indices    = new short[indexCount];

        Marshal.Copy(renderModel.rIndexData, indices, 0, indices.Length);

        var triangles = new int[indexCount];

        for (int iTri = 0; iTri < renderModel.unTriangleCount; iTri++)
        {
            triangles[iTri * 3 + 0] = (int)indices[iTri * 3 + 2];
            triangles[iTri * 3 + 1] = (int)indices[iTri * 3 + 1];
            triangles[iTri * 3 + 2] = (int)indices[iTri * 3 + 0];
        }

        var mesh = new Mesh();

        mesh.vertices  = vertices;
        mesh.normals   = normals;
        mesh.uv        = uv;
        mesh.triangles = triangles;

#if (UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0)
        mesh.Optimize();
#endif
        //mesh.hideFlags = HideFlags.DontUnloadUnusedAsset;

        // Check cache before loading texture.
        var material = materials[renderModel.diffuseTextureId] as Material;
        if (material == null || material.mainTexture == null)
        {
            var pDiffuseTexture = System.IntPtr.Zero;

            while (true)
            {
                error = renderModels.LoadTexture_Async(renderModel.diffuseTextureId, ref pDiffuseTexture);
                if (error != EVRRenderModelError.Loading)
                {
                    break;
                }

                System.Threading.Thread.Sleep(1);
            }

            if (error == EVRRenderModelError.None)
            {
                var diffuseTexture = (RenderModel_TextureMap_t)Marshal.PtrToStructure(pDiffuseTexture, typeof(RenderModel_TextureMap_t));
                var texture        = new Texture2D(diffuseTexture.unWidth, diffuseTexture.unHeight, TextureFormat.ARGB32, false);
                if (SystemInfo.graphicsDeviceType == UnityEngine.Rendering.GraphicsDeviceType.Direct3D11)
                {
                    texture.Apply();

                    while (true)
                    {
                        error = renderModels.LoadIntoTextureD3D11_Async(renderModel.diffuseTextureId, texture.GetNativeTexturePtr());
                        if (error != EVRRenderModelError.Loading)
                        {
                            break;
                        }

                        System.Threading.Thread.Sleep(1);
                    }
                }
                else
                {
                    var textureMapData = new byte[diffuseTexture.unWidth * diffuseTexture.unHeight * 4];                     // RGBA
                    Marshal.Copy(diffuseTexture.rubTextureMapData, textureMapData, 0, textureMapData.Length);

                    var colors = new Color32[diffuseTexture.unWidth * diffuseTexture.unHeight];
                    int iColor = 0;
                    for (int iHeight = 0; iHeight < diffuseTexture.unHeight; iHeight++)
                    {
                        for (int iWidth = 0; iWidth < diffuseTexture.unWidth; iWidth++)
                        {
                            var r = textureMapData[iColor++];
                            var g = textureMapData[iColor++];
                            var b = textureMapData[iColor++];
                            var a = textureMapData[iColor++];
                            colors[iHeight * diffuseTexture.unWidth + iWidth] = new Color32(r, g, b, a);
                        }
                    }

                    texture.SetPixels32(colors);
                    texture.Apply();
                }

                material             = new Material(shader != null ? shader : Shader.Find("Standard"));
                material.mainTexture = texture;
                //material.hideFlags = HideFlags.DontUnloadUnusedAsset;

                materials[renderModel.diffuseTextureId] = material;

                renderModels.FreeTexture(pDiffuseTexture);
            }
            else
            {
                Debug.Log("Failed to load render model texture for render model " + renderModelName);
            }
        }

        // Delay freeing when we can since we'll often get multiple requests for the same model right
        // after another (e.g. two controllers or two basestations).
#if UNITY_EDITOR
        if (!Application.isPlaying)
        {
            renderModels.FreeRenderModel(pRenderModel);
        }
        else
#endif
        StartCoroutine(FreeRenderModel(pRenderModel));

        return(new RenderModel(mesh, material));
    }
コード例 #2
0
    public void UpdateComponents(CVRRenderModels renderModels)
    {
        if (renderModels == null)
        {
            return;
        }

        var t = transform;

        if (t.childCount == 0)
        {
            return;
        }

        var controllerState = (index != SteamVR_TrackedObject.EIndex.None)
      ? SteamVR_Controller.Input((int)index).GetState()
      : new VRControllerState_t();

        if (nameCache == null)
        {
            nameCache = new Dictionary <int, string>();
        }

        for (int i = 0; i < t.childCount; i++)
        {
            var child = t.GetChild(i);

            // Cache names since accessing an object's name allocate memory.
            string name;
            if (!nameCache.TryGetValue(child.GetInstanceID(), out name))
            {
                name = child.name;
                nameCache.Add(child.GetInstanceID(), name);
            }

            var componentState = new RenderModel_ComponentState_t();
            if (
                !renderModels.GetComponentState(renderModelName, name, ref controllerState, ref controllerModeState,
                                                ref componentState))
            {
                continue;
            }

            var componentTransform = new SteamVR_Utils.RigidTransform(componentState.mTrackingToComponentRenderModel);
            child.localPosition = componentTransform.pos;
            child.localRotation = componentTransform.rot;

            var attach = child.Find(k_localTransformName);
            if (attach != null)
            {
                var attachTransform = new SteamVR_Utils.RigidTransform(componentState.mTrackingToComponentLocal);
                attach.position = t.TransformPoint(attachTransform.pos);
                attach.rotation = t.rotation * attachTransform.rot;
            }

            bool visible = (componentState.uProperties & (uint)EVRComponentProperty.IsVisible) != 0;
            if (visible != child.gameObject.activeSelf)
            {
                child.gameObject.SetActive(visible);
            }
        }
    }
コード例 #3
0
            // return true if is done
            private bool DoLoadModelJob(CVRRenderModels vrRenderModels, string modelName, Dictionary <int, Texture2D> texturesCache, ref IntPtr modelPtr, ref IntPtr texturePtr, ref IntPtr d3d11TexturePtr)
            {
                if (string.IsNullOrEmpty(modelName))
                {
                    return(true);
                }

                EVRRenderModelError error;
                Model model;

                if (!s_modelsCache.TryGetValue(modelName, out model))
                {
                    switch (error = vrRenderModels.LoadRenderModel_Async(modelName, ref modelPtr))
                    {
                    default:
                        Debug.LogError("[" + m_jobID + "]+" + (Time.frameCount - m_startFrame) + " LoadRenderModel_Async failed! " + System.IO.Path.GetFileName(modelName) + " EVRRenderModelError=" + error);
                        return(true);

                    case EVRRenderModelError.Loading:
                        if (s_verbose)
                        {
                            Debug.Log("[" + m_jobID + "]+" + (Time.frameCount - m_startFrame) + " LoadRenderModel_Async loading... " + System.IO.Path.GetFileName(modelName));
                        }
                        return(false);

                    case EVRRenderModelError.None:
                        if (s_verbose)
                        {
                            Debug.Log("[" + m_jobID + "]+" + (Time.frameCount - m_startFrame) + " LoadRenderModel_Async succeed! " + System.IO.Path.GetFileName(modelName));
                        }
                        RenderModel_t modelData = MarshalRenderModel(modelPtr);

                        var vertices = new Vector3[modelData.unVertexCount];
                        var normals  = new Vector3[modelData.unVertexCount];
                        var uv       = new Vector2[modelData.unVertexCount];

                        Type type = typeof(RenderModel_Vertex_t);
                        for (int iVert = 0; iVert < modelData.unVertexCount; iVert++)
                        {
                            var ptr  = new IntPtr(modelData.rVertexData.ToInt64() + iVert * Marshal.SizeOf(type));
                            var vert = (RenderModel_Vertex_t)Marshal.PtrToStructure(ptr, type);

                            vertices[iVert] = new Vector3(vert.vPosition.v0, vert.vPosition.v1, -vert.vPosition.v2);
                            normals[iVert]  = new Vector3(vert.vNormal.v0, vert.vNormal.v1, -vert.vNormal.v2);
                            uv[iVert]       = new Vector2(vert.rfTextureCoord0, vert.rfTextureCoord1);
                        }

                        var indexCount = (int)modelData.unTriangleCount * 3;
                        var indices    = new short[indexCount];
                        Marshal.Copy(modelData.rIndexData, indices, 0, indices.Length);

                        var triangles = new int[indexCount];
                        for (int iTri = 0; iTri < modelData.unTriangleCount; iTri++)
                        {
                            triangles[iTri * 3 + 0] = indices[iTri * 3 + 2];
                            triangles[iTri * 3 + 1] = indices[iTri * 3 + 1];
                            triangles[iTri * 3 + 2] = indices[iTri * 3 + 0];
                        }

                        model = new Model()
                        {
                            textureID = modelData.diffuseTextureId,
                            mesh      = new Mesh()
                            {
                                hideFlags = HideFlags.HideAndDontSave,
                                vertices  = vertices,
                                normals   = normals,
                                uv        = uv,
                                triangles = triangles,
                            },
                        };

                        s_modelsCache.Add(modelName, model);
                        break;
                    }
                }

                Texture2D texture;

                if (!texturesCache.TryGetValue(model.textureID, out texture))
                {
                    switch (error = vrRenderModels.LoadTexture_Async(model.textureID, ref texturePtr))
                    {
                    default:
                        Debug.LogError("[" + m_jobID + "]+" + (Time.frameCount - m_startFrame) + " LoadTexture_Async failed! " + System.IO.Path.GetFileName(modelName) + "[" + model.textureID + "] EVRRenderModelError=" + error);
                        return(true);

                    case EVRRenderModelError.Loading:
                        if (s_verbose)
                        {
                            Debug.Log("[" + m_jobID + "]+" + (Time.frameCount - m_startFrame) + " LoadTexture_Async loading... " + System.IO.Path.GetFileName(modelName) + "[" + model.textureID + "]");
                        }
                        return(false);

                    case EVRRenderModelError.None:
                        if (s_verbose)
                        {
                            Debug.Log("[" + m_jobID + "]+" + (Time.frameCount - m_startFrame) + " LoadTexture_Async succeed! " + System.IO.Path.GetFileName(modelName) + "[" + model.textureID + "]");
                        }
                        var textureMap = MarshalRenderModelTextureMap(texturePtr);
                        texture = new Texture2D(textureMap.unWidth, textureMap.unHeight, TextureFormat.RGBA32, false);

                        if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D11)
                        {
                            texture.Apply();
                            d3d11TexturePtr = texture.GetNativeTexturePtr();
                        }
                        else
                        {
                            var textureMapData = new byte[textureMap.unWidth * textureMap.unHeight * 4];     // RGBA
                            Marshal.Copy(textureMap.rubTextureMapData, textureMapData, 0, textureMapData.Length);

                            var colors = new Color32[textureMap.unWidth * textureMap.unHeight];
                            int iColor = 0;
                            for (int iHeight = 0; iHeight < textureMap.unHeight; iHeight++)
                            {
                                for (int iWidth = 0; iWidth < textureMap.unWidth; iWidth++)
                                {
                                    var r = textureMapData[iColor++];
                                    var g = textureMapData[iColor++];
                                    var b = textureMapData[iColor++];
                                    var a = textureMapData[iColor++];
                                    colors[iHeight * textureMap.unWidth + iWidth] = new Color32(r, g, b, a);
                                }
                            }

                            texture.SetPixels32(colors);
                            texture.Apply();
                        }

                        texturesCache.Add(model.textureID, texture);
                        break;
                    }
                }

                if (d3d11TexturePtr != IntPtr.Zero)
                {
                    while (true)
                    {
                        switch (error = vrRenderModels.LoadIntoTextureD3D11_Async(model.textureID, d3d11TexturePtr))
                        {
                        default:
                            Debug.LogError("[" + m_jobID + "]+" + (Time.frameCount - m_startFrame) + " LoadIntoTextureD3D11_Async failed! " + System.IO.Path.GetFileName(modelName) + " EVRRenderModelError=" + error);
                            d3d11TexturePtr = IntPtr.Zero;
                            return(true);

                        case EVRRenderModelError.Loading:
                            if (s_verbose)
                            {
                                Debug.Log("[" + m_jobID + "]+" + (Time.frameCount - m_startFrame) + " LoadIntoTextureD3D11_Async loading... " + System.IO.Path.GetFileName(modelName) + "[" + model.textureID + "]");
                            }
                            break;

                        case EVRRenderModelError.None:
                            if (s_verbose)
                            {
                                Debug.Log("[" + m_jobID + "]+" + (Time.frameCount - m_startFrame) + " LoadIntoTextureD3D11_Async succeed! " + System.IO.Path.GetFileName(modelName));
                            }
                            d3d11TexturePtr = IntPtr.Zero;
                            return(true);
                        }
                        // FIXME: LoadIntoTextureD3D11_Async blocks main thread? Crashes when not calling it in while loop
#if !UNITY_METRO
                        System.Threading.Thread.Sleep(1);
#endif
                    }
                }

                return(true);
            }
コード例 #4
0
    static RenderModel LoadRenderModel(CVRRenderModels renderModels, string renderModelName, string baseName)
    {
        var pRenderModel = System.IntPtr.Zero;

        if (!renderModels.LoadRenderModel(renderModelName, ref pRenderModel))
        {
            Debug.LogError("Failed to load render model " + renderModelName);
            return(null);
        }

        var renderModel = (RenderModel_t)Marshal.PtrToStructure(pRenderModel, typeof(RenderModel_t));

        var vertices = new Vector3[renderModel.unVertexCount];
        var normals  = new Vector3[renderModel.unVertexCount];
        var uv       = new Vector2[renderModel.unVertexCount];

        var type = typeof(RenderModel_Vertex_t);

        for (int iVert = 0; iVert < renderModel.unVertexCount; iVert++)
        {
            var ptr  = new System.IntPtr(renderModel.rVertexData.ToInt64() + iVert * Marshal.SizeOf(type));
            var vert = (RenderModel_Vertex_t)Marshal.PtrToStructure(ptr, type);

            vertices[iVert] = new Vector3(vert.vPosition.v[0], vert.vPosition.v[1], -vert.vPosition.v[2]);
            normals[iVert]  = new Vector3(vert.vNormal.v[0], vert.vNormal.v[1], -vert.vNormal.v[2]);
            uv[iVert]       = new Vector2(vert.rfTextureCoord[0], vert.rfTextureCoord[1]);
        }

        int indexCount = (int)renderModel.unTriangleCount * 3;
        var indices    = new short[indexCount];

        Marshal.Copy(renderModel.rIndexData, indices, 0, indices.Length);

        var triangles = new int[indexCount];

        for (int iTri = 0; iTri < renderModel.unTriangleCount; iTri++)
        {
            triangles[iTri * 3 + 0] = (int)indices[iTri * 3 + 2];
            triangles[iTri * 3 + 1] = (int)indices[iTri * 3 + 1];
            triangles[iTri * 3 + 2] = (int)indices[iTri * 3 + 0];
        }

        var mesh = new Mesh();

        mesh.vertices  = vertices;
        mesh.normals   = normals;
        mesh.uv        = uv;
        mesh.triangles = triangles;

        mesh.Optimize();
        //mesh.hideFlags = HideFlags.DontUnloadUnusedAsset;

        // Check cache before loading texture.
        var material = materials[baseName + renderModel.diffuseTextureId] as Material;

        if (material == null || material.mainTexture == null)
        {
            var pDiffuseTexture = System.IntPtr.Zero;
            if (renderModels.LoadTexture(renderModel.diffuseTextureId, ref pDiffuseTexture))
            {
                var diffuseTexture = (RenderModel_TextureMap_t)Marshal.PtrToStructure(pDiffuseTexture, typeof(RenderModel_TextureMap_t));

                var textureMapData = new byte[diffuseTexture.unWidth * diffuseTexture.unHeight * 4];                 // RGBA
                Marshal.Copy(diffuseTexture.rubTextureMapData, textureMapData, 0, textureMapData.Length);

                var colors = new Color32[diffuseTexture.unWidth * diffuseTexture.unHeight];
                int iColor = 0;
                for (int iHeight = 0; iHeight < diffuseTexture.unHeight; iHeight++)
                {
                    for (int iWidth = 0; iWidth < diffuseTexture.unWidth; iWidth++)
                    {
                        var r = textureMapData[iColor++];
                        var g = textureMapData[iColor++];
                        var b = textureMapData[iColor++];
                        var a = textureMapData[iColor++];
                        colors[iHeight * diffuseTexture.unWidth + iWidth] = new Color32(r, g, b, a);
                    }
                }

                var texture = new Texture2D(diffuseTexture.unWidth, diffuseTexture.unHeight, TextureFormat.ARGB32, true);
                texture.SetPixels32(colors);
                texture.Apply();

                material             = new Material(Shader.Find("Standard"));
                material.mainTexture = texture;
                //material.hideFlags = HideFlags.DontUnloadUnusedAsset;

                materials[baseName + renderModel.diffuseTextureId] = material;
            }
            else
            {
                Debug.Log("Failed to load render model texture for render model " + renderModelName);
            }
        }

        renderModels.FreeRenderModel(ref renderModel);

        return(new RenderModel(mesh, material));
    }