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); }
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, }); }
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])); } }
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(); } }
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); }
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))); } } }
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); }
AssetContext(AssetSource source) { _source = source; }
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); }
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); }