protected virtual GameObject CreateMeshPrimitive(MeshPrimitive primitive, int meshID, int primitiveIndex) { var primitiveObj = new GameObject("Primitive"); var meshFilter = primitiveObj.AddComponent <MeshFilter>(); if (_assetCache.MeshCache[meshID][primitiveIndex] == null) { _assetCache.MeshCache[meshID][primitiveIndex] = new MeshCacheData(); } if (_assetCache.MeshCache[meshID][primitiveIndex].LoadedMesh == null) { if (_assetCache.MeshCache[meshID][primitiveIndex].MeshAttributes.Count == 0) { BuildMeshAttributes(primitive, meshID, primitiveIndex); } var meshAttributes = _assetCache.MeshCache[meshID][primitiveIndex].MeshAttributes; var vertexCount = primitive.Attributes[SemanticProperties.POSITION].Value.Count; // todo optimize: There are multiple copies being performed to turn the buffer data into mesh data. Look into reducing them UnityEngine.Mesh mesh = new UnityEngine.Mesh { vertices = primitive.Attributes.ContainsKey(SemanticProperties.POSITION) ? meshAttributes[SemanticProperties.POSITION].AccessorContent.AsVertices.ToUnityVector3() : null, normals = primitive.Attributes.ContainsKey(SemanticProperties.NORMAL) ? meshAttributes[SemanticProperties.NORMAL].AccessorContent.AsNormals.ToUnityVector3() : null, uv = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(0)) ? meshAttributes[SemanticProperties.TexCoord(0)].AccessorContent.AsTexcoords.ToUnityVector2() : null, uv2 = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(1)) ? meshAttributes[SemanticProperties.TexCoord(1)].AccessorContent.AsTexcoords.ToUnityVector2() : null, uv3 = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(2)) ? meshAttributes[SemanticProperties.TexCoord(2)].AccessorContent.AsTexcoords.ToUnityVector2() : null, uv4 = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(3)) ? meshAttributes[SemanticProperties.TexCoord(3)].AccessorContent.AsTexcoords.ToUnityVector2() : null, colors = primitive.Attributes.ContainsKey(SemanticProperties.Color(0)) ? meshAttributes[SemanticProperties.Color(0)].AccessorContent.AsColors.ToUnityColor() : null, triangles = primitive.Indices != null ? meshAttributes[SemanticProperties.INDICES].AccessorContent.AsTriangles : MeshPrimitive.GenerateTriangles(vertexCount), tangents = primitive.Attributes.ContainsKey(SemanticProperties.TANGENT) ? meshAttributes[SemanticProperties.TANGENT].AccessorContent.AsTangents.ToUnityVector4() : null }; _assetCache.MeshCache[meshID][primitiveIndex].LoadedMesh = mesh; } meshFilter.sharedMesh = _assetCache.MeshCache[meshID][primitiveIndex].LoadedMesh; var materialWrapper = CreateMaterial( primitive.Material != null ? primitive.Material.Value : DefaultMaterial, primitive.Material != null ? primitive.Material.Id : -1 ); var meshRenderer = primitiveObj.AddComponent <MeshRenderer>(); meshRenderer.material = materialWrapper.GetContents(primitive.Attributes.ContainsKey(SemanticProperties.Color(0))); if (_addColliders) { var meshCollider = primitiveObj.AddComponent <MeshCollider>(); meshCollider.sharedMesh = meshFilter.mesh; } return(primitiveObj); }
protected virtual void CreateMeshPrimitive(MeshPrimitive primitive, string meshName, int meshID, int primitiveIndex) { var meshAttributes = BuildMeshAttributes(primitive, meshID, primitiveIndex); var vertexCount = primitive.Attributes[SemanticProperties.POSITION].Value.Count; UnityEngine.Mesh mesh = new UnityEngine.Mesh { vertices = primitive.Attributes.ContainsKey(SemanticProperties.POSITION) ? meshAttributes[SemanticProperties.POSITION].AccessorContent.AsVertices.ToUnityVector3() : null, normals = primitive.Attributes.ContainsKey(SemanticProperties.NORMAL) ? meshAttributes[SemanticProperties.NORMAL].AccessorContent.AsNormals.ToUnityVector3() : null, uv = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(0)) ? meshAttributes[SemanticProperties.TexCoord(0)].AccessorContent.AsTexcoords.ToUnityVector2() : null, uv2 = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(1)) ? meshAttributes[SemanticProperties.TexCoord(1)].AccessorContent.AsTexcoords.ToUnityVector2() : null, uv3 = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(2)) ? meshAttributes[SemanticProperties.TexCoord(2)].AccessorContent.AsTexcoords.ToUnityVector2() : null, uv4 = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(3)) ? meshAttributes[SemanticProperties.TexCoord(3)].AccessorContent.AsTexcoords.ToUnityVector2() : null, colors = primitive.Attributes.ContainsKey(SemanticProperties.Color(0)) ? meshAttributes[SemanticProperties.Color(0)].AccessorContent.AsColors.ToUnityColor() : null, triangles = primitive.Indices != null ? meshAttributes[SemanticProperties.INDICES].AccessorContent.AsTriangles : MeshPrimitive.GenerateTriangles(vertexCount), tangents = primitive.Attributes.ContainsKey(SemanticProperties.TANGENT) ? meshAttributes[SemanticProperties.TANGENT].AccessorContent.AsTangents.ToUnityVector4(true) : null }; if (primitive.Attributes.ContainsKey(SemanticProperties.JOINT) && primitive.Attributes.ContainsKey(SemanticProperties.WEIGHT)) { Vector4[] bones = new Vector4[1]; Vector4[] weights = new Vector4[1]; LoadSkinnedMeshAttributes(meshID, primitiveIndex, ref bones, ref weights); if (bones.Length != mesh.vertices.Length || weights.Length != mesh.vertices.Length) { Debug.LogError("Not enough skinning data (bones:" + bones.Length + " weights:" + weights.Length + " verts:" + mesh.vertices.Length + ")"); return; } BoneWeight[] bws = new BoneWeight[mesh.vertices.Length]; int maxBonesIndex = 0; for (int i = 0; i < bws.Length; ++i) { // Unity seems expects the the sum of weights to be 1. float[] normalizedWeights = GLTFUtils.normalizeBoneWeights(weights[i]); bws[i].boneIndex0 = (int)bones[i].x; bws[i].weight0 = normalizedWeights[0]; bws[i].boneIndex1 = (int)bones[i].y; bws[i].weight1 = normalizedWeights[1]; bws[i].boneIndex2 = (int)bones[i].z; bws[i].weight2 = normalizedWeights[2]; bws[i].boneIndex3 = (int)bones[i].w; bws[i].weight3 = normalizedWeights[3]; maxBonesIndex = (int)Mathf.Max(maxBonesIndex, bones[i].x, bones[i].y, bones[i].z, bones[i].w); } mesh.boneWeights = bws; // initialize inverseBindMatrix array with identity matrix in order to output a valid mesh object Matrix4x4[] bindposes = new Matrix4x4[maxBonesIndex + 1]; for (int j = 0; j <= maxBonesIndex; ++j) { bindposes[j] = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one); } mesh.bindposes = bindposes; } if (primitive.Targets != null && primitive.Targets.Count > 0) { for (int b = 0; b < primitive.Targets.Count; ++b) { Vector3[] deltaVertices = new Vector3[primitive.Targets[b]["POSITION"].Value.Count]; Vector3[] deltaNormals = new Vector3[primitive.Targets[b]["POSITION"].Value.Count]; Vector3[] deltaTangents = new Vector3[primitive.Targets[b]["POSITION"].Value.Count]; if (primitive.Targets[b].ContainsKey("POSITION")) { NumericArray num = new NumericArray(); deltaVertices = primitive.Targets[b]["POSITION"].Value.AsVector3Array(ref num, _assetCache.BufferCache[0], false).ToUnityVector3(true); } if (primitive.Targets[b].ContainsKey("NORMAL")) { NumericArray num = new NumericArray(); deltaNormals = primitive.Targets[b]["NORMAL"].Value.AsVector3Array(ref num, _assetCache.BufferCache[0], true).ToUnityVector3(true); } //if (primitive.Targets[b].ContainsKey("TANGENT")) //{ // deltaTangents = primitive.Targets[b]["TANGENT"].Value.AsVector3Array(ref num, _assetCache.BufferCache[0], true).ToUnityVector3(true); //} mesh.AddBlendShapeFrame(GLTFUtils.buildBlendShapeName(meshID, b), 1.0f, deltaVertices, deltaNormals, deltaTangents); } } mesh.RecalculateBounds(); mesh.RecalculateTangents(); mesh = _assetManager.saveMesh(mesh, meshName + "_" + meshID + "_" + primitiveIndex); UnityEngine.Material material = primitive.Material != null && primitive.Material.Id >= 0 ? getMaterial(primitive.Material.Id) : defaultMaterial; _assetManager.addPrimitiveMeshData(meshID, primitiveIndex, mesh, material); }