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); }
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; } }