Exemplo n.º 1
0
            public ImportTask(List <GLTFImage> images, string directoryRoot, GLTFBufferView.ImportTask bufferViewTask) : base(bufferViewTask)
            {
                task = new Task(() => {
                    // No images
                    if (images == null)
                    {
                        return;
                    }

                    Result = new ImportResult[images.Count];
                    for (int i = 0; i < images.Count; i++)
                    {
                        string fullUri = directoryRoot + images[i].uri;
                        if (!string.IsNullOrEmpty(images[i].uri))
                        {
                            if (File.Exists(fullUri))
                            {
                                // If the file is found at fullUri, read it
                                byte[] bytes = File.ReadAllBytes(fullUri);
                                Result[i]    = new ImportResult(bytes, fullUri);
                            }
                            else if (images[i].uri.StartsWith("data:"))
                            {
                                // If the image is embedded, find its Base64 content and save as byte array
                                string content    = images[i].uri.Split(',').Last();
                                byte[] imageBytes = Convert.FromBase64String(content);
                                Result[i]         = new ImportResult(imageBytes);
                            }
                        }
                        else if (images[i].bufferView.HasValue && !string.IsNullOrEmpty(images[i].mimeType))
                        {
                            GLTFBufferView.ImportResult view = bufferViewTask.Result[images[i].bufferView.Value];
                            byte[] bytes         = new byte[view.byteLength];
                            view.stream.Position = view.byteOffset;
                            view.stream.Read(bytes, 0, view.byteLength);
                            Result[i] = new ImportResult(bytes);
                        }
                        else
                        {
                            Debug.Log("Couldn't find texture at " + fullUri);
                        }
                    }
                });
            }
Exemplo n.º 2
0
                public MeshData(GLTFMesh gltfMesh, GLTFAccessor.ImportResult[] accessors, GLTFBufferView.ImportResult[] bufferViews)
                {
                    name = gltfMesh.name;
                    if (gltfMesh.primitives.Count == 0)
                    {
                        Debug.LogWarning("0 primitives in mesh");
                    }
                    else
                    {
                        for (int i = 0; i < gltfMesh.primitives.Count; i++)
                        {
                            GLTFPrimitive primitive = gltfMesh.primitives[i];
                            // Load draco mesh
                            if (primitive.extensions != null && primitive.extensions.KHR_draco_mesh_compression != null)
                            {
                                GLTFPrimitive.DracoMeshCompression draco      = primitive.extensions.KHR_draco_mesh_compression;
                                GLTFBufferView.ImportResult        bufferView = bufferViews[draco.bufferView];
                                GLTFUtilityDracoLoader             loader     = new GLTFUtilityDracoLoader();
                                byte[] buffer = new byte[bufferView.byteLength];
                                bufferView.stream.Seek(bufferView.byteOffset, System.IO.SeekOrigin.Begin);

                                bufferView.stream.Read(buffer, 0, bufferView.byteLength);

                                GLTFUtilityDracoLoader.MeshAttributes attribs = new GLTFUtilityDracoLoader.MeshAttributes(
                                    primitive.extensions.KHR_draco_mesh_compression.attributes.POSITION ?? -1,
                                    primitive.extensions.KHR_draco_mesh_compression.attributes.NORMAL ?? -1,
                                    primitive.extensions.KHR_draco_mesh_compression.attributes.TEXCOORD_0 ?? -1,
                                    primitive.extensions.KHR_draco_mesh_compression.attributes.JOINTS_0 ?? -1,
                                    primitive.extensions.KHR_draco_mesh_compression.attributes.WEIGHTS_0 ?? -1,
                                    primitive.extensions.KHR_draco_mesh_compression.attributes.COLOR_0 ?? -1
                                    );

                                //Mesh mesh = loader.LoadMesh(buffer, attribs);

                                GLTFUtilityDracoLoader.AsyncMesh asyncMesh = loader.LoadMesh(buffer, attribs);
                                if (asyncMesh == null)
                                {
                                    Debug.LogWarning("Draco mesh couldn't be loaded");
                                }

                                submeshTrisMode.Add(primitive.mode);

                                // Tris
                                int vertCount = verts.Count();
                                submeshTris.Add(asyncMesh.tris.Reverse().Select(x => x + vertCount).ToList());

                                verts.AddRange(asyncMesh.verts.Select(x => new Vector3(-x.x, x.y, x.z)));

                                if (asyncMesh.norms != null)
                                {
                                    normals.AddRange(asyncMesh.norms.Select(v => { v.x = -v.x; return(v); }));
                                }
                                //tangents.AddRange(asyncMesh.tangents.Select(v => { v.y = -v.y; v.z = -v.z; return v; }));

                                // Weights
                                if (asyncMesh.boneWeights != null)
                                {
                                    if (weights == null)
                                    {
                                        weights = new List <BoneWeight>();
                                    }
                                    weights.AddRange(asyncMesh.boneWeights);
                                }

                                // BlendShapes not supported yet

                                /* for (int k = 0; k < mesh.blendShapeCount; k++) {
                                 *      int frameCount = mesh.GetBlendShapeFrameCount(k);
                                 *      BlendShape blendShape = new BlendShape();
                                 *      blendShape.pos = new Vector3[frameCount];
                                 *      blendShape.norm = new Vector3[frameCount];
                                 *      blendShape.tan = new Vector3[frameCount];
                                 *      for (int o = 0; o < frameCount; o++) {
                                 *              mesh.GetBlendShapeFrameVertices(k, o, blendShape.pos, blendShape.norm, blendShape.tan);
                                 *      }
                                 *      blendShapes.Add(blendShape);
                                 * } */

                                // UVs
                                if (asyncMesh.uv != null)
                                {
                                    if (uv1 == null)
                                    {
                                        uv1 = new List <Vector2>();
                                    }
                                    uv1.AddRange(asyncMesh.uv.Select(x => new Vector2(x.x, -x.y)));
                                }
                            }
                            // Load normal mesh
                            else
                            {
                                int vertStartIndex = verts.Count;
                                submeshVertexStart.Add(vertStartIndex);

                                // Verts - (X points left in GLTF)
                                if (primitive.attributes.POSITION.HasValue)
                                {
                                    IEnumerable <Vector3> newVerts = accessors[primitive.attributes.POSITION.Value].ReadVec3(true).Select(v => { v.x = -v.x; return(v); });
                                    verts.AddRange(newVerts);
                                }

                                int vertCount = verts.Count;

                                // Tris - (Invert all triangles. Instead of flipping each triangle, just flip the entire array. Much easier)
                                if (primitive.indices.HasValue)
                                {
                                    submeshTris.Add(new List <int>(accessors[primitive.indices.Value].ReadInt().Reverse().Select(x => x + vertStartIndex)));
                                    submeshTrisMode.Add(primitive.mode);
                                }

                                /// Normals - (X points left in GLTF)
                                if (primitive.attributes.NORMAL.HasValue)
                                {
                                    normals.AddRange(accessors[primitive.attributes.NORMAL.Value].ReadVec3(true).Select(v => { v.x = -v.x; return(v); }));
                                }

                                // Tangents - (X points left in GLTF)
                                if (primitive.attributes.TANGENT.HasValue)
                                {
                                    tangents.AddRange(accessors[primitive.attributes.TANGENT.Value].ReadVec4(true).Select(v => { v.y = -v.y; v.z = -v.z; return(v); }));
                                }

                                // Vertex colors
                                if (primitive.attributes.COLOR_0.HasValue)
                                {
                                    colors.AddRange(accessors[primitive.attributes.COLOR_0.Value].ReadColor());
                                }

                                // Weights
                                if (primitive.attributes.WEIGHTS_0.HasValue && primitive.attributes.JOINTS_0.HasValue)
                                {
                                    Vector4[] weights0 = accessors[primitive.attributes.WEIGHTS_0.Value].ReadVec4(true);
                                    Vector4[] joints0  = accessors[primitive.attributes.JOINTS_0.Value].ReadVec4();
                                    if (joints0.Length == weights0.Length)
                                    {
                                        BoneWeight[] boneWeights = new BoneWeight[weights0.Length];
                                        for (int k = 0; k < boneWeights.Length; k++)
                                        {
                                            NormalizeWeights(ref weights0[k]);
                                            boneWeights[k].weight0    = weights0[k].x;
                                            boneWeights[k].weight1    = weights0[k].y;
                                            boneWeights[k].weight2    = weights0[k].z;
                                            boneWeights[k].weight3    = weights0[k].w;
                                            boneWeights[k].boneIndex0 = Mathf.RoundToInt(joints0[k].x);
                                            boneWeights[k].boneIndex1 = Mathf.RoundToInt(joints0[k].y);
                                            boneWeights[k].boneIndex2 = Mathf.RoundToInt(joints0[k].z);
                                            boneWeights[k].boneIndex3 = Mathf.RoundToInt(joints0[k].w);
                                        }
                                        if (weights == null)
                                        {
                                            weights = new List <BoneWeight>(new BoneWeight[vertCount - boneWeights.Length]);
                                        }
                                        weights.AddRange(boneWeights);
                                    }
                                    else
                                    {
                                        Debug.LogWarning("WEIGHTS_0 and JOINTS_0 not same length. Skipped");
                                    }
                                }
                                else
                                {
                                    if (weights != null)
                                    {
                                        weights.AddRange(new BoneWeight[vertCount - weights.Count]);
                                    }
                                }

                                // UVs
                                ReadUVs(ref uv1, accessors, primitive.attributes.TEXCOORD_0, vertCount);
                                ReadUVs(ref uv2, accessors, primitive.attributes.TEXCOORD_1, vertCount);
                                ReadUVs(ref uv3, accessors, primitive.attributes.TEXCOORD_2, vertCount);
                                ReadUVs(ref uv4, accessors, primitive.attributes.TEXCOORD_3, vertCount);
                                ReadUVs(ref uv5, accessors, primitive.attributes.TEXCOORD_4, vertCount);
                                ReadUVs(ref uv6, accessors, primitive.attributes.TEXCOORD_5, vertCount);
                                ReadUVs(ref uv7, accessors, primitive.attributes.TEXCOORD_6, vertCount);
                                ReadUVs(ref uv8, accessors, primitive.attributes.TEXCOORD_7, vertCount);
                            }
                        }

                        bool hasTargetNames = gltfMesh.extras != null && gltfMesh.extras.targetNames != null;
                        if (hasTargetNames)
                        {
                            if (gltfMesh.primitives.All(x => x.targets.Count != gltfMesh.extras.targetNames.Length))
                            {
                                Debug.LogWarning("Morph target names found in mesh " + name + " but array length does not match primitive morph target array length");
                                hasTargetNames = false;
                            }
                        }
                        // Read blend shapes after knowing final vertex count
                        int finalVertCount = verts.Count;

                        for (int i = 0; i < gltfMesh.primitives.Count; i++)
                        {
                            GLTFPrimitive primitive = gltfMesh.primitives[i];
                            if (primitive.targets != null)
                            {
                                for (int k = 0; k < primitive.targets.Count; k++)
                                {
                                    BlendShape blendShape = new BlendShape();
                                    blendShape.pos  = GetMorphWeights(primitive.targets[k].POSITION, submeshVertexStart[i], finalVertCount, accessors);
                                    blendShape.norm = GetMorphWeights(primitive.targets[k].NORMAL, submeshVertexStart[i], finalVertCount, accessors);
                                    blendShape.tan  = GetMorphWeights(primitive.targets[k].TANGENT, submeshVertexStart[i], finalVertCount, accessors);
                                    if (hasTargetNames)
                                    {
                                        blendShape.name = gltfMesh.extras.targetNames[k];
                                    }
                                    else
                                    {
                                        blendShape.name = "morph-" + blendShapes.Count;
                                    }
                                    blendShapes.Add(blendShape);
                                }
                            }
                        }
                    }
                }