Пример #1
0
        public static Mesh FromGLTF(AssetSource source,
                                    UniGLTF.glTFMesh m, List <D3D11Material> materials)
        {
            var mesh = new Mesh();

            mesh.Submeshes.AddRange(FromGLTF(source, m.primitives, materials));
            return(mesh);
        }
Пример #2
0
 public static Skin FromGLTF(AssetSource source, UniGLTF.glTFSkin skin)
 {
     return(new Skin
     {
         RootIndex = skin.skeleton,
         _bindMatrices = source.GLTF.GetArrayFromAccessor <Matrix>(source.IO, skin.inverseBindMatrices),
         _joints = skin.joints,
     });
 }
Пример #3
0
        void Add <T>(ref List <KeyFrame <T> > target, AssetSource source, UniGLTF.glTFAnimationSampler sampler) where T : struct
        {
            var interpolation = ParseInterpolation(sampler.interpolation);
            var input         = source.GLTF.GetArrayFromAccessor <float>(source.IO, sampler.input);
            var output        = source.GLTF.GetArrayFromAccessor <T>(source.IO, sampler.output);

            target = new List <KeyFrame <T> >(input.Length);
            for (int i = 0; i < input.Length; ++i)
            {
                LastSeconds = Math.Max(LastSeconds, input[i]);
                target.Add(new KeyFrame <T>(input[i], output[i]));
            }
        }
Пример #4
0
        public void Add(AnimationTarget target, AssetSource source, UniGLTF.glTFAnimationSampler sampler)
        {
            switch (target)
            {
            case AnimationTarget.Translation:
                Add(ref Translation, source, sampler);
                break;

            case AnimationTarget.Rotation:
                Add(ref Rotation, source, sampler);
                break;

            case AnimationTarget.Scale:
                Add(ref Scale, source, sampler);
                break;

            default:
                throw new NotImplementedException();
            }
        }
Пример #5
0
        public static Animation FromGLTF(AssetSource source, UniGLTF.glTFAnimation src)
        {
            var animation = new Animation();

            foreach (var channel in src.channels)
            {
                NodeAnimation nodeAnimation;
                if (!animation._nodeMap.TryGetValue(channel.target.node, out nodeAnimation))
                {
                    nodeAnimation = new NodeAnimation();
                    animation._nodeMap.Add(channel.target.node, nodeAnimation);
                }

                var target  = ParseChannelTargetPath(channel.target.path);
                var sampler = src.samplers[channel.sampler];
                nodeAnimation.Add(target, source, sampler);

                animation.Length = Math.Max(animation.Length, nodeAnimation.LastSeconds);
            }

            return(animation);
        }
Пример #6
0
 public static IEnumerable <Submesh> FromGLTF(AssetSource source,
                                              List <UniGLTF.glTFPrimitives> primitives, List <D3D11Material> materials)
 {
     if (source.HasSameBuffer(primitives))
     {
         var mesh = FromGLTF(source, primitives[0]);
         foreach (var prim in primitives)
         {
             var indices = source.GLTF.accessors[prim.indices];
             var offset  = indices.byteOffset / indices.ElementSize;
             yield return(new Submesh(materials[prim.material],
                                      mesh, offset, indices.count));
         }
     }
     else
     {
         foreach (var prim in primitives)
         {
             yield return(new Submesh(materials[prim.material],
                                      FromGLTF(source, prim)));
         }
     }
 }
Пример #7
0
        public static AssetContext Load(AssetSource source)
        {
            var sw = System.Diagnostics.Stopwatch.StartNew();

            var asset = new AssetContext(source);

            var gltf = source.GLTF;

            foreach (var texture in gltf.textures)
            {
                var image = gltf.images[texture.source];
                var bytes = source.GetImageBytes(image);
                asset._textureImages.Add(new ImageBytes(bytes));
            }

            foreach (var material in gltf.materials)
            {
                var shader = material.IsUnlit
                    ? ShaderLoader.Instance.CreateShader(ShaderType.Unlit)
                    : ShaderLoader.Instance.CreateShader(ShaderType.Standard)
                ;

                var texture = default(ImageBytes);
                var color   = Color4.White;
                var pbr     = material.pbrMetallicRoughness;
                if (pbr != null)
                {
                    if (pbr.baseColorTexture != null)
                    {
                        texture = asset._textureImages[pbr.baseColorTexture.index];
                    }

                    if (pbr.baseColorFactor != null)
                    {
                        color.Red   = pbr.baseColorFactor[0];
                        color.Green = pbr.baseColorFactor[1];
                        color.Blue  = pbr.baseColorFactor[2];
                        color.Alpha = pbr.baseColorFactor[3];
                    }
                }
                asset._materials.Add(new D3D11Material(material.name, shader, true, texture, color));
            }

            foreach (var mesh in gltf.meshes)
            {
                asset._meshes.Add(Mesh.FromGLTF(source, mesh, asset._materials));
            }

            foreach (var skin in gltf.skins)
            {
                asset._skins.Add(Skin.FromGLTF(source, skin));
            }

            foreach (var animation in gltf.animations)
            {
                asset._animations.Add(Animation.FromGLTF(source, animation));
            }

            Logger.Info($"LoadAsset: {sw.Elapsed.TotalSeconds} sec");

            asset.BuildHierarchy();

            return(asset);
        }
Пример #8
0
 AssetContext(AssetSource source)
 {
     _source = source;
 }
Пример #9
0
        public static AssetSource Load(string path)
        {
            var sw = System.Diagnostics.Stopwatch.StartNew();

            IStorage folder    = new FileSystemStorage(System.IO.Path.GetDirectoryName(path));
            var      fileBytes = File.ReadAllBytes(path);

            var zip = LoadZip(fileBytes);

            if (zip != null)
            {
                var found = false;
                foreach (var x in zip.Entries)
                {
                    var ext = System.IO.Path.GetExtension(x.FileName).ToLower();
                    if (ext == ".gltf" ||
                        ext == ".glb" ||
                        ext == ".vrm")
                    {
                        folder    = zip;
                        fileBytes = zip.Extract(x);
                        if (fileBytes.Length == 0)
                        {
                            throw new Exception("empty bytes");
                        }
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    throw new Exception("no model file in zip");
                }
            }

            var source = new AssetSource
            {
                Path = path
            };

            try
            {
                // try GLB

                var it = glbImporter.ParseGlbChanks(fileBytes).GetEnumerator();

                if (!it.MoveNext())
                {
                    throw new FormatException();
                }
                var jsonChunk = it.Current;
                if (jsonChunk.ChunkType != GlbChunkType.JSON)
                {
                    throw new FormatException();
                }

                if (!it.MoveNext())
                {
                    throw new FormatException();
                }
                var bytesChunk = it.Current;
                if (bytesChunk.ChunkType != GlbChunkType.BIN)
                {
                    throw new FormatException();
                }

                source.JSON = JsonParser.Parse(new Utf8String(jsonChunk.Bytes));
                source.IO   = new SimpleStorage(bytesChunk.Bytes);
            }
            catch (Exception)
            {
                // try GLTF
                source.JSON = JsonParser.Parse(new Utf8String(fileBytes));
                source.IO   = folder;
            }
            Logger.Info($"Parse: {sw.Elapsed.TotalSeconds} sec");
            sw = System.Diagnostics.Stopwatch.StartNew();

            glTF gltf = null;

            source.JSON.Deserialize(ref gltf);
            source.GLTF = gltf;

            Logger.Info($"Deserialize: {sw.Elapsed.TotalSeconds} sec");

            return(source);
        }
Пример #10
0
        static D3D11Mesh FromGLTF(AssetSource source,
                                  UniGLTF.glTFPrimitives primitive)
        {
            var       gltf     = source.GLTF;
            D3D11Mesh drawable = null;
            {
                var   accessor = gltf.accessors[primitive.indices];
                int[] indices  = null;
                switch (accessor.componentType)
                {
                case UniGLTF.glComponentType.UNSIGNED_BYTE:
                case UniGLTF.glComponentType.BYTE:
                    indices = gltf.GetArrayFromAccessor <byte>(source.IO, primitive.indices).Select(x => (int)x).ToArray();
                    break;

                case UniGLTF.glComponentType.UNSIGNED_SHORT:
                    indices = gltf.GetArrayFromAccessor <ushort>(source.IO, primitive.indices).Select(x => (int)x).ToArray();
                    break;

                case UniGLTF.glComponentType.UNSIGNED_INT:
                    indices = gltf.GetArrayFromAccessor <int>(source.IO, primitive.indices);
                    break;

                default:
                    throw new NotImplementedException();
                }

                drawable = new D3D11Mesh(SharpDX.Direct3D.PrimitiveTopology.TriangleList,
                                         indices);
            }

            var attribs = primitive.attributes;

            {
                var positions = gltf.GetBytesFromAccessor(source.IO, primitive.attributes.POSITION);
                if (positions.Count == 0)
                {
                    throw new Exception();
                }
                drawable.SetAttribute(Semantics.POSITION, new VertexAttribute(positions, 4 * 3));
            }

            if (primitive.attributes.TEXCOORD_0 != -1)
            {
                var uv = gltf.GetBytesFromAccessor(source.IO, primitive.attributes.TEXCOORD_0);
                drawable.SetAttribute(Semantics.TEXCOORD, new VertexAttribute(uv, 4 * 2));
            }

            if (primitive.attributes.JOINTS_0 != -1)
            {
                var accessor = gltf.accessors[primitive.attributes.JOINTS_0];
                switch (accessor.componentType)
                {
                case UniGLTF.glComponentType.BYTE:
                {
                    var joints = gltf.GetBytesFromAccessor(source.IO, primitive.attributes.JOINTS_0);
                    drawable.SetJoints(joints.Select(x => (ushort)x).ToArray());
                }
                break;

                case UniGLTF.glComponentType.UNSIGNED_SHORT:
                {
                    var joints = gltf.GetArrayFromAccessorAs <ushort>(source.IO, primitive.attributes.JOINTS_0);
                    drawable.SetJoints(joints);
                }
                break;

                default:
                    throw new NotImplementedException();
                }
            }

            if (primitive.attributes.WEIGHTS_0 != -1)
            {
                var accessor = gltf.accessors[primitive.attributes.WEIGHTS_0];
                switch (accessor.componentType)
                {
                case UniGLTF.glComponentType.BYTE:
                {
                    var weights = gltf.GetBytesFromAccessor(source.IO, primitive.attributes.WEIGHTS_0);
                    drawable.SetWeights(weights.Select(x => ((float)x) / byte.MaxValue).ToArray());
                }
                break;

                case UniGLTF.glComponentType.UNSIGNED_SHORT:
                {
                    var weights = gltf.GetArrayFromAccessorAs <ushort>(source.IO, primitive.attributes.WEIGHTS_0);
                    drawable.SetWeights(weights.Select(x => ((float)x) / ushort.MaxValue).ToArray());
                }
                break;

                case UniGLTF.glComponentType.FLOAT:
                {
                    var weights = gltf.GetArrayFromAccessorAs <float>(source.IO, primitive.attributes.WEIGHTS_0);
                    drawable.SetWeights(weights);
                }
                break;

                default:
                    throw new NotImplementedException();
                }
            }

            return(drawable);
        }