Exemplo n.º 1
0
    static RenderModel LoadRenderModel(string renderModelName)
    {
        var error = HmdError.None;

        if (!SteamVR.active)
        {
            OpenVR.Init(ref error);
            if (error != HmdError.None)
            {
                return(null);
            }
        }

        var pRenderModels = OpenVR.GetGenericInterface(OpenVR.IVRRenderModels_Version, ref error);

        if (pRenderModels == System.IntPtr.Zero || error != HmdError.None)
        {
            if (!SteamVR.active)
            {
                OpenVR.Shutdown();
            }
            return(null);
        }

        var renderModels = new CVRRenderModels(pRenderModels);

        var renderModel = new RenderModel_t();

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

            if (!SteamVR.active)
            {
                OpenVR.Shutdown();
            }
            return(null);
        }

        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;

        var textureMapData = new byte[renderModel.diffuseTexture.unWidth * renderModel.diffuseTexture.unHeight * 4];         // RGBA

        Marshal.Copy(renderModel.diffuseTexture.rubTextureMapData, textureMapData, 0, textureMapData.Length);

        var colors = new Color32[renderModel.diffuseTexture.unWidth * renderModel.diffuseTexture.unHeight];
        int iColor = 0;

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

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

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

        //texture.hideFlags = HideFlags.DontUnloadUnusedAsset;

        renderModels.FreeRenderModel(ref renderModel);

        if (!SteamVR.active)
        {
            OpenVR.Shutdown();
        }

        return(new RenderModel(mesh, texture));
    }
    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));
    }