Beispiel #1
0
    private OVRMeshData ProcessMesh(JSONNode meshNode, bool loadMips)
    {
        OVRMeshData meshData = new OVRMeshData();

        int totalVertexCount = 0;
        var primitives       = meshNode["primitives"];

        int[] primitiveVertexCounts = new int[primitives.Count];
        for (int i = 0; i < primitives.Count; i++)
        {
            var jsonPrimitive = primitives[i];
            var jsonAttrbite  = jsonPrimitive["attributes"]["POSITION"];
            var jsonAccessor  = m_jsonData["accessors"][jsonAttrbite.AsInt];

            primitiveVertexCounts[i] = jsonAccessor["count"];
            totalVertexCount        += primitiveVertexCounts[i];
        }

        int[][]   indicies = new int[primitives.Count][];
        Vector3[] vertices = new Vector3[totalVertexCount];

        Vector3[] normals = null;
        if (primitives[0]["attributes"]["NORMAL"] != null)
        {
            normals = new Vector3[totalVertexCount];
        }

        Vector4[] tangents = null;
        if (primitives[0]["attributes"]["TANGENT"] != null)
        {
            tangents = new Vector4[totalVertexCount];
        }

        Vector2[] texcoords = null;
        if (primitives[0]["attributes"]["TEXCOORD_0"] != null)
        {
            texcoords = new Vector2[totalVertexCount];
        }

        Color[] colors = null;
        if (primitives[0]["attributes"]["COLOR_0"] != null)
        {
            colors = new Color[totalVertexCount];
        }

        BoneWeight[] boneWeights = null;
        if (primitives[0]["attributes"]["WEIGHTS_0"] != null)
        {
            boneWeights = new BoneWeight[totalVertexCount];
        }

        // Begin async processing of material and its texture
        OVRMaterialData matData       = default(OVRMaterialData);
        Task            transcodeTask = null;
        var             jsonMaterial  = primitives[0]["material"];

        if (jsonMaterial != null)
        {
            matData         = ProcessMaterial(jsonMaterial.AsInt);
            matData.texture = ProcessTexture(matData.textureId);
            transcodeTask   = Task.Run(() => { TranscodeTexture(ref matData.texture); });
        }

        int vertexOffset = 0;

        for (int i = 0; i < primitives.Count; i++)
        {
            var jsonPrimitive = primitives[i];

            int             indicesAccessorId = jsonPrimitive["indices"].AsInt;
            var             jsonAccessor      = m_jsonData["accessors"][indicesAccessorId];
            OVRGLTFAccessor indicesReader     = new OVRGLTFAccessor(jsonAccessor, m_jsonData);

            indicies[i] = new int[indicesReader.GetDataCount()];
            indicesReader.ReadAsInt(m_binaryChunk, ref indicies[i], 0);
            FlipTraingleIndices(ref indicies[i]);

            var jsonAttribute = jsonPrimitive["attributes"]["POSITION"];
            if (jsonAttribute != null)
            {
                jsonAccessor = m_jsonData["accessors"][jsonAttribute.AsInt];
                OVRGLTFAccessor dataReader = new OVRGLTFAccessor(jsonAccessor, m_jsonData);
                dataReader.ReadAsVector3(m_binaryChunk, ref vertices, vertexOffset, GLTFToUnitySpace);
            }

            jsonAttribute = jsonPrimitive["attributes"]["NORMAL"];
            if (jsonAttribute != null)
            {
                jsonAccessor = m_jsonData["accessors"][jsonAttribute.AsInt];
                OVRGLTFAccessor dataReader = new OVRGLTFAccessor(jsonAccessor, m_jsonData);
                dataReader.ReadAsVector3(m_binaryChunk, ref normals, vertexOffset, GLTFToUnitySpace);
            }

            jsonAttribute = jsonPrimitive["attributes"]["TANGENT"];
            if (jsonAttribute != null)
            {
                jsonAccessor = m_jsonData["accessors"][jsonAttribute.AsInt];
                OVRGLTFAccessor dataReader = new OVRGLTFAccessor(jsonAccessor, m_jsonData);
                dataReader.ReadAsVector4(m_binaryChunk, ref tangents, vertexOffset, GLTFToUnityTangent);
            }

            jsonAttribute = jsonPrimitive["attributes"]["TEXCOORD_0"];
            if (jsonAttribute != null)
            {
                jsonAccessor = m_jsonData["accessors"][jsonAttribute.AsInt];
                OVRGLTFAccessor dataReader = new OVRGLTFAccessor(jsonAccessor, m_jsonData);
                dataReader.ReadAsVector2(m_binaryChunk, ref texcoords, vertexOffset);
            }

            jsonAttribute = jsonPrimitive["attributes"]["COLOR_0"];
            if (jsonAttribute != null)
            {
                jsonAccessor = m_jsonData["accessors"][jsonAttribute.AsInt];
                OVRGLTFAccessor dataReader = new OVRGLTFAccessor(jsonAccessor, m_jsonData);
                dataReader.ReadAsColor(m_binaryChunk, ref colors, vertexOffset);
            }

            jsonAttribute = jsonPrimitive["attributes"]["WEIGHTS_0"];
            if (jsonAttribute != null)
            {
                jsonAccessor = m_jsonData["accessors"][jsonAttribute.AsInt];
                OVRGLTFAccessor weightReader = new OVRGLTFAccessor(jsonAccessor, m_jsonData);

                var             jointAttribute = jsonPrimitive["attributes"]["JOINTS_0"];
                var             jointAccessor  = m_jsonData["accessors"][jointAttribute.AsInt];
                OVRGLTFAccessor jointReader    = new OVRGLTFAccessor(jointAccessor, m_jsonData);

                Vector4[] weights = new Vector4[weightReader.GetDataCount()];
                Vector4[] joints  = new Vector4[jointReader.GetDataCount()];

                weightReader.ReadAsBoneWeights(m_binaryChunk, ref weights, 0);
                jointReader.ReadAsVector4(m_binaryChunk, ref joints, 0, Vector4.one);

                for (int w = 0; w < weights.Length; w++)
                {
                    boneWeights[vertexOffset + w].boneIndex0 = (int)joints[w].x;
                    boneWeights[vertexOffset + w].boneIndex1 = (int)joints[w].y;
                    boneWeights[vertexOffset + w].boneIndex2 = (int)joints[w].z;
                    boneWeights[vertexOffset + w].boneIndex3 = (int)joints[w].w;

                    boneWeights[vertexOffset + w].weight0 = weights[w].x;
                    boneWeights[vertexOffset + w].weight1 = weights[w].y;
                    boneWeights[vertexOffset + w].weight2 = weights[w].z;
                    boneWeights[vertexOffset + w].weight3 = weights[w].w;
                }
            }

            vertexOffset += primitiveVertexCounts[i];
        }

        Mesh mesh = new Mesh();

        mesh.vertices     = vertices;
        mesh.normals      = normals;
        mesh.tangents     = tangents;
        mesh.colors       = colors;
        mesh.uv           = texcoords;
        mesh.boneWeights  = boneWeights;
        mesh.subMeshCount = primitives.Count;

        int baseVertex = 0;

        for (int i = 0; i < primitives.Count; i++)
        {
            mesh.SetIndices(indicies[i], MeshTopology.Triangles, i, false, baseVertex);
            baseVertex += primitiveVertexCounts[i];
        }

        mesh.RecalculateBounds();
        meshData.mesh = mesh;

        if (transcodeTask != null)
        {
            transcodeTask.Wait();
            meshData.material = CreateUnityMaterial(matData, loadMips);
        }
        return(meshData);
    }
Beispiel #2
0
    private void ProcessNode(JSONNode node, int nodeId, bool loadMips)
    {
        // Process the child nodes first
        var childNodes = node["children"];

        if (childNodes.Count > 0)
        {
            for (int i = 0; i < childNodes.Count; i++)
            {
                int childId = childNodes[i].AsInt;
                m_Nodes[childId].transform.SetParent(m_Nodes[nodeId].transform);
                ProcessNode(m_jsonData["nodes"][childId], childId, loadMips);
            }
        }

        if (node["mesh"] != null)
        {
            var         meshId   = node["mesh"].AsInt;
            OVRMeshData meshData = ProcessMesh(m_jsonData["meshes"][meshId], loadMips);

            if (node["skin"] != null)
            {
                var renderer = m_Nodes[nodeId].AddComponent <SkinnedMeshRenderer>();
                renderer.sharedMesh     = meshData.mesh;
                renderer.sharedMaterial = meshData.material;

                var skinId = node["skin"].AsInt;
                ProcessSkin(m_jsonData["skins"][skinId], renderer);
            }
            else
            {
                var filter = m_Nodes[nodeId].AddComponent <MeshFilter>();
                filter.sharedMesh = meshData.mesh;
                var renderer = m_Nodes[nodeId].AddComponent <MeshRenderer>();
                renderer.sharedMaterial = meshData.material;
            }
        }

        var translation = node["translation"].AsArray;
        var rotation    = node["rotation"].AsArray;
        var scale       = node["scale"].AsArray;

        if (translation.Count > 0)
        {
            Vector3 position = new Vector3(
                translation[0] * GLTFToUnitySpace.x,
                translation[1] * GLTFToUnitySpace.y,
                translation[2] * GLTFToUnitySpace.z);
            m_Nodes[nodeId].transform.position = position;
        }

        if (rotation.Count > 0)
        {
            Vector3 rotationAxis = new Vector3(
                rotation[0] * GLTFToUnitySpace.x,
                rotation[1] * GLTFToUnitySpace.y,
                rotation[2] * GLTFToUnitySpace.z);
            rotationAxis *= -1.0f;
            m_Nodes[nodeId].transform.rotation = new Quaternion(rotationAxis.x, rotationAxis.y, rotationAxis.z, rotation[3]);
        }

        if (scale.Count > 0)
        {
            Vector3 scaleVec = new Vector3(scale[0], scale[1], scale[2]);
            m_Nodes[nodeId].transform.localScale = scaleVec;
        }
    }