GithubHelp home page GithubHelp logo

gltf-csharp-loader's Introduction

This is a C# reference loader for glTF. It's as simple to use as Interface.LoadModel("PathToModel.gltf"). You can use this loader in your project by importing the "glTF2Loader" NuGet package. Additional examples can be found in the gltfLoaderUnitTests project.

Build Instructions

Prerequisites

This solution requires access to the glTF schema to compile and the sample models to test. It assumes that the glTF and glTF-Sample-Models repos have been cloned under the same root directory that the glTF-CSharp-Loader repo was cloned.

repos
+-- glTF
|   +-- README.md
+-- glTF-CSharp-Loader
|   +-- README.md
+-- glTF-Sample-Models
|   +-- README.md

Building

To build the project, load the CSharp.sln solution. Click "Start". This will build glTFLoader_Shared, GeneratorLib, and Generator. It will then run the Generator. The generator reads the .spec files defining the glTF standard and generates a set of classes that will be used as the schema for loading your models. The glTFLoader project can now be built. You will need glTFLoader.dll and glTFLoader_shared.dll in order to use the loader in any subsequent project.

gltf-csharp-loader's People

Contributors

beardedgnome avatar bghgary avatar doerge avatar emackey avatar ericwj avatar ibober avatar ido-cu avatar mattmcmullan avatar panzerhandschuh avatar vpenades avatar xfischer avatar yukicode avatar ziriax avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gltf-csharp-loader's Issues

Suggestion for versioning when releasing packages.

Right now, the project is set to version 1.0.0, even if that particular version has already been released.

I would like to propose this procedure for releasing final and pre-release packages:

  1. Immediately before releasing a final package, set the version to the appropiate value, let's say "1.1.0"
  2. Compile and do the release.
  3. Immediately after the release, change the version to "1.2.0-Alpha" and commit that change, so this version will stay in place for all subsequent commits.
  4. When a new release is ready, repeat from step 1

It could be interesting to upload pre-release packages too...

Use System.Text.Json

Is it planned to move from Newtonsoft.Json to System.Text.Json for >= netstandard2.0 ?

System.NotSupportedException on Xamarin Android 8 project

When calling Interface Interface.LoadModel(streamobject); on my Xamarin Android 8 project, I get an the System.NotSupportedException (using the .NET Standard library).

Is this because I only use the gltfloader.dll? The gltfloader_shared.dll does not get generated, so I do not have it.

Plans to update the NuGet package?

Any plans on updating the NuGet package? The 1.0 release was September 8th of last year. There's been a few changes since then (e.g. Interface.cs OpenImageFile), and it'd be great to not have to build from source to get that.

NuGet for Net.Standard

Is there any reason why this library is only available for Net.Framework 4.5.2?

As I understand it, it could be much more useful if it was available for net.standard 1.0 , since we could use it in multiple platforms and not only windows desktop.

Furthermore, it's only dependency is Newtonsoft, which is also available for net.standard...

Saving GLTF to stream closes the stream.

GltfLoader/Interface.cs has this method:

  public static void SaveModel(this Gltf model, Stream stream)
        {
            string fileData = SerializeModel(model);

            using (var ts = new StreamWriter(stream))
            {
                ts.Write(fileData);
            }
        }

This method closes the stream in a way that reading from it is impossible.

This can be fixed by creating the StreamWriter like this:
new StreamWriter(stream, leaveOpen: true)

Support for Khronos Extensions

Is there a plan for including the Khronos Extensions schemas (e.g. KHR_materials_pbrSpecularGlossiness.schema.json) or should these be handled like custom extensions?

Add loader to NuGet

It would be great, if someone upload this loader to Nuget as official library from KhronosGroup account. Not like this one from noname

Support for compiling with "Trim unused code"

My C# application uses glTFLoader for loading gltf models.
I'd like to be able to publish the code with the "Trim unused code" compiler option as it drastically reduces binary size.

However when running the exectuable I get this exception.

Unhandled exception. Newtonsoft.Json.JsonSerializationException: Unable to find a constructor to use for type glTFLoader.Schema.Gltf. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'asset', line 2, position 10.
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader, JsonObjectContract, JsonProperty, JsonProperty, String, Boolean& )
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader, Type, JsonContract, JsonProperty, JsonContainerContract, JsonProperty, Object)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader, Type, JsonContract, JsonProperty, JsonContainerContract, JsonProperty, Object)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader, Type, Boolean)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader, Type)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader, Type)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String, Type, JsonSerializerSettings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String, JsonSerializerSettings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String)
   at glTFLoader.Interface.LoadModel(Stream)
   at glTFLoader.Interface.LoadModel(String)

This only happens when compiling with "Trim unused code".

"Is there an open-source C# viewer example developed using the glTF-CSharp-Loader library?"

"I'm new to glTF. Currently,
I'm compiling the library and analyzing the values
using 'var Model = interface.LoadModel.'
I'm trying to create Entities one by one based on Scenes and Nodes.
It seems like I need to create Primitives from the Mesh within the nodes,
but the mesh only contains Attribute values, which are POSITON, NORMAL, TANGENT, TEXCOORD_0.
I'm not sure how to create from these.
I'm currently planning to develop with Eyeshot, but I'm having trouble understanding.
Are there any C# viewer examples developed using the loader library?"

[Discussion] Considering to add an F# example too

I've played around with F# and the json files of glTF. Result is that I can generate easily a single support file which reduces manual work of schema mapping without loosing control.

For the source code see my gist here.


With F# it's a lot easier to parse glTF without loosing much flexibility. To achieve this it's needed to use a JsonTypeProvider plus a auto generated support file which provides both an abstract visitor class and schema classes depending on the specification.

The dependencies of the generated file just consist of FSharp.Data and the standard library.
An example output of the generator would be:

module GeneratedSchemaDefinitions

open FSharp.Data
open System.IO

type AccessorSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\accessor.schema.json">
type AccessorSparseIndicesSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\accessor.sparse.indices.schema.json">
type AccessorSparseSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\accessor.sparse.schema.json">
type AccessorSparseValuesSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\accessor.sparse.values.schema.json">
type AnimationChannelSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\animation.channel.schema.json">
type AnimationChannelTargetSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\animation.channel.target.schema.json">
type AnimationSamplerSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\animation.sampler.schema.json">
type AnimationSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\animation.schema.json">
type AssetSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\asset.schema.json">
type BufferSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\buffer.schema.json">
type BufferViewSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\bufferView.schema.json">
type CameraOrthographicSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\camera.orthographic.schema.json">
type CameraPerspectiveSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\camera.perspective.schema.json">
type CameraSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\camera.schema.json">
type ExtensionSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\extension.schema.json">
type ExtrasSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\extras.schema.json">
type GlTFSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\glTF.schema.json">
type GlTFChildOfRootPropertySchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\glTFChildOfRootProperty.schema.json">
type GlTFidSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\glTFid.schema.json">
type GlTFPropertySchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\glTFProperty.schema.json">
type ImageSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\image.schema.json">
type MaterialNormalTextureInfoSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\material.normalTextureInfo.schema.json">
type MaterialOcclusionTextureInfoSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\material.occlusionTextureInfo.schema.json">
type MaterialPbrMetallicRoughnessSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\material.pbrMetallicRoughness.schema.json">
type MaterialSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\material.schema.json">
type MeshPrimitiveSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\mesh.primitive.schema.json">
type MeshSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\mesh.schema.json">
type NodeSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\node.schema.json">
type SamplerSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\sampler.schema.json">
type SceneSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\scene.schema.json">
type SkinSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\skin.schema.json">
type TextureSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\texture.schema.json">
type TextureInfoSchema = JsonProvider< @"E:\Development\glTF\specification\2.0\schema\textureInfo.schema.json">
[<AbstractClass>]
type Generator () =
    abstract member VisitAccessorSchema : AccessorSchema.Root -> unit
    abstract member VisitAccessorSparseIndicesSchema : AccessorSparseIndicesSchema.Root -> unit
    abstract member VisitAccessorSparseSchema : AccessorSparseSchema.Root -> unit
    abstract member VisitAccessorSparseValuesSchema : AccessorSparseValuesSchema.Root -> unit
    abstract member VisitAnimationChannelSchema : AnimationChannelSchema.Root -> unit
    abstract member VisitAnimationChannelTargetSchema : AnimationChannelTargetSchema.Root -> unit
    abstract member VisitAnimationSamplerSchema : AnimationSamplerSchema.Root -> unit
    abstract member VisitAnimationSchema : AnimationSchema.Root -> unit
    abstract member VisitAssetSchema : AssetSchema.Root -> unit
    abstract member VisitBufferSchema : BufferSchema.Root -> unit
    abstract member VisitBufferViewSchema : BufferViewSchema.Root -> unit
    abstract member VisitCameraOrthographicSchema : CameraOrthographicSchema.Root -> unit
    abstract member VisitCameraPerspectiveSchema : CameraPerspectiveSchema.Root -> unit
    abstract member VisitCameraSchema : CameraSchema.Root -> unit
    abstract member VisitExtensionSchema : ExtensionSchema.Root -> unit
    abstract member VisitExtrasSchema : ExtrasSchema.Root -> unit
    abstract member VisitGlTFSchema : GlTFSchema.Root -> unit
    abstract member VisitGlTFChildOfRootPropertySchema : GlTFChildOfRootPropertySchema.Root -> unit
    abstract member VisitGlTFidSchema : GlTFidSchema.Root -> unit
    abstract member VisitGlTFPropertySchema : GlTFPropertySchema.Root -> unit
    abstract member VisitImageSchema : ImageSchema.Root -> unit
    abstract member VisitMaterialNormalTextureInfoSchema : MaterialNormalTextureInfoSchema.Root -> unit
    abstract member VisitMaterialOcclusionTextureInfoSchema : MaterialOcclusionTextureInfoSchema.Root -> unit
    abstract member VisitMaterialPbrMetallicRoughnessSchema : MaterialPbrMetallicRoughnessSchema.Root -> unit
    abstract member VisitMaterialSchema : MaterialSchema.Root -> unit
    abstract member VisitMeshPrimitiveSchema : MeshPrimitiveSchema.Root -> unit
    abstract member VisitMeshSchema : MeshSchema.Root -> unit
    abstract member VisitNodeSchema : NodeSchema.Root -> unit
    abstract member VisitSamplerSchema : SamplerSchema.Root -> unit
    abstract member VisitSceneSchema : SceneSchema.Root -> unit
    abstract member VisitSkinSchema : SkinSchema.Root -> unit
    abstract member VisitTextureSchema : TextureSchema.Root -> unit
    abstract member VisitTextureInfoSchema : TextureInfoSchema.Root -> unit
    member self.VisitSchemaDir (pathToSchemaDir:string) =
        let accessorschema = Path.Combine(pathToSchemaDir, @"accessor.schema.json" ) |> AccessorSchema.Load
        let accessorsparseindicesschema = Path.Combine(pathToSchemaDir, @"accessor.sparse.indices.schema.json" ) |> AccessorSparseIndicesSchema.Load
        let accessorsparseschema = Path.Combine(pathToSchemaDir, @"accessor.sparse.schema.json" ) |> AccessorSparseSchema.Load
        let accessorsparsevaluesschema = Path.Combine(pathToSchemaDir, @"accessor.sparse.values.schema.json" ) |> AccessorSparseValuesSchema.Load
        let animationchannelschema = Path.Combine(pathToSchemaDir, @"animation.channel.schema.json" ) |> AnimationChannelSchema.Load
        let animationchanneltargetschema = Path.Combine(pathToSchemaDir, @"animation.channel.target.schema.json" ) |> AnimationChannelTargetSchema.Load
        let animationsamplerschema = Path.Combine(pathToSchemaDir, @"animation.sampler.schema.json" ) |> AnimationSamplerSchema.Load
        let animationschema = Path.Combine(pathToSchemaDir, @"animation.schema.json" ) |> AnimationSchema.Load
        let assetschema = Path.Combine(pathToSchemaDir, @"asset.schema.json" ) |> AssetSchema.Load
        let bufferschema = Path.Combine(pathToSchemaDir, @"buffer.schema.json" ) |> BufferSchema.Load
        let bufferviewschema = Path.Combine(pathToSchemaDir, @"bufferView.schema.json" ) |> BufferViewSchema.Load
        let cameraorthographicschema = Path.Combine(pathToSchemaDir, @"camera.orthographic.schema.json" ) |> CameraOrthographicSchema.Load
        let cameraperspectiveschema = Path.Combine(pathToSchemaDir, @"camera.perspective.schema.json" ) |> CameraPerspectiveSchema.Load
        let cameraschema = Path.Combine(pathToSchemaDir, @"camera.schema.json" ) |> CameraSchema.Load
        let extensionschema = Path.Combine(pathToSchemaDir, @"extension.schema.json" ) |> ExtensionSchema.Load
        let extrasschema = Path.Combine(pathToSchemaDir, @"extras.schema.json" ) |> ExtrasSchema.Load
        let gltfschema = Path.Combine(pathToSchemaDir, @"glTF.schema.json" ) |> GlTFSchema.Load
        let gltfchildofrootpropertyschema = Path.Combine(pathToSchemaDir, @"glTFChildOfRootProperty.schema.json" ) |> GlTFChildOfRootPropertySchema.Load
        let gltfidschema = Path.Combine(pathToSchemaDir, @"glTFid.schema.json" ) |> GlTFidSchema.Load
        let gltfpropertyschema = Path.Combine(pathToSchemaDir, @"glTFProperty.schema.json" ) |> GlTFPropertySchema.Load
        let imageschema = Path.Combine(pathToSchemaDir, @"image.schema.json" ) |> ImageSchema.Load
        let materialnormaltextureinfoschema = Path.Combine(pathToSchemaDir, @"material.normalTextureInfo.schema.json" ) |> MaterialNormalTextureInfoSchema.Load
        let materialocclusiontextureinfoschema = Path.Combine(pathToSchemaDir, @"material.occlusionTextureInfo.schema.json" ) |> MaterialOcclusionTextureInfoSchema.Load
        let materialpbrmetallicroughnessschema = Path.Combine(pathToSchemaDir, @"material.pbrMetallicRoughness.schema.json" ) |> MaterialPbrMetallicRoughnessSchema.Load
        let materialschema = Path.Combine(pathToSchemaDir, @"material.schema.json" ) |> MaterialSchema.Load
        let meshprimitiveschema = Path.Combine(pathToSchemaDir, @"mesh.primitive.schema.json" ) |> MeshPrimitiveSchema.Load
        let meshschema = Path.Combine(pathToSchemaDir, @"mesh.schema.json" ) |> MeshSchema.Load
        let nodeschema = Path.Combine(pathToSchemaDir, @"node.schema.json" ) |> NodeSchema.Load
        let samplerschema = Path.Combine(pathToSchemaDir, @"sampler.schema.json" ) |> SamplerSchema.Load
        let sceneschema = Path.Combine(pathToSchemaDir, @"scene.schema.json" ) |> SceneSchema.Load
        let skinschema = Path.Combine(pathToSchemaDir, @"skin.schema.json" ) |> SkinSchema.Load
        let textureschema = Path.Combine(pathToSchemaDir, @"texture.schema.json" ) |> TextureSchema.Load
        let textureinfoschema = Path.Combine(pathToSchemaDir, @"textureInfo.schema.json" ) |> TextureInfoSchema.Load
        self.VisitAccessorSchema accessorschema
        self.VisitAccessorSparseIndicesSchema accessorsparseindicesschema
        self.VisitAccessorSparseSchema accessorsparseschema
        self.VisitAccessorSparseValuesSchema accessorsparsevaluesschema
        self.VisitAnimationChannelSchema animationchannelschema
        self.VisitAnimationChannelTargetSchema animationchanneltargetschema
        self.VisitAnimationSamplerSchema animationsamplerschema
        self.VisitAnimationSchema animationschema
        self.VisitAssetSchema assetschema
        self.VisitBufferSchema bufferschema
        self.VisitBufferViewSchema bufferviewschema
        self.VisitCameraOrthographicSchema cameraorthographicschema
        self.VisitCameraPerspectiveSchema cameraperspectiveschema
        self.VisitCameraSchema cameraschema
        self.VisitExtensionSchema extensionschema
        self.VisitExtrasSchema extrasschema
        self.VisitGlTFSchema gltfschema
        self.VisitGlTFChildOfRootPropertySchema gltfchildofrootpropertyschema
        self.VisitGlTFidSchema gltfidschema
        self.VisitGlTFPropertySchema gltfpropertyschema
        self.VisitImageSchema imageschema
        self.VisitMaterialNormalTextureInfoSchema materialnormaltextureinfoschema
        self.VisitMaterialOcclusionTextureInfoSchema materialocclusiontextureinfoschema
        self.VisitMaterialPbrMetallicRoughnessSchema materialpbrmetallicroughnessschema
        self.VisitMaterialSchema materialschema
        self.VisitMeshPrimitiveSchema meshprimitiveschema
        self.VisitMeshSchema meshschema
        self.VisitNodeSchema nodeschema
        self.VisitSamplerSchema samplerschema
        self.VisitSceneSchema sceneschema
        self.VisitSkinSchema skinschema
        self.VisitTextureSchema textureschema
        self.VisitTextureInfoSchema textureinfoschema

now it would be just needed to inherit from the abstract class to get such sourcefile (currently unfilled).

type FSharpLoaderGenerator() =
    inherit GeneratedSchemaDefinitions.Generator()
    override __.VisitAccessorSchema schema =
        
        ()

    override __.VisitAccessorSparseIndicesSchema schema =

        ()

    override __.VisitAccessorSparseSchema schema =

        ()

    override __.VisitAccessorSparseValuesSchema schema =

        ()

    override __.VisitAnimationChannelSchema schema =

        ()

    override __.VisitAnimationChannelTargetSchema schema =

        ()

    override __.VisitAnimationSamplerSchema schema =

        ()

    override __.VisitAnimationSchema schema =

        ()

    override __.VisitAssetSchema schema =

        ()

    override __.VisitBufferSchema schema =

        ()

    override __.VisitBufferViewSchema schema =

        ()

    override __.VisitCameraOrthographicSchema schema =

        ()

    override __.VisitCameraPerspectiveSchema schema =

        ()

    override __.VisitCameraSchema schema =

        ()

    override __.VisitExtensionSchema schema =

        ()

    override __.VisitExtrasSchema schema =

        ()

    override __.VisitGlTFSchema schema =

        ()

    override __.VisitGlTFChildOfRootPropertySchema schema =

        ()

    override __.VisitGlTFidSchema schema =

        ()

    override __.VisitGlTFPropertySchema schema =

        ()

    override __.VisitImageSchema schema =

        ()

    override __.VisitMaterialNormalTextureInfoSchema schema =

        ()

    override __.VisitMaterialOcclusionTextureInfoSchema schema =

        ()

    override __.VisitMaterialPbrMetallicRoughnessSchema schema =

        ()

    override __.VisitMaterialSchema schema =

        ()

    override __.VisitMeshPrimitiveSchema schema =

        ()

    override __.VisitMeshSchema schema =

        ()

    override __.VisitNodeSchema schema =

        ()

    override __.VisitSamplerSchema schema =

        ()

    override __.VisitSceneSchema schema =

        ()

    override __.VisitSkinSchema schema =

        ()

    override __.VisitTextureSchema schema =

        ()

    override __.VisitTextureInfoSchema schema =

        ()

To start the generation people just need to call the VisitSchemaDir method with the path to the schema directory as parameter.


This was a proof of concept and also a showcase of how easily such stuff can be written in F# without even touching a single json file manually. My question is, what do you think? Would you like to see more implementation examples? (just note down here, although it's written in F# the visitor class can also be used for generating C# code).

Deserializing the .Extras perperties?

What is the intended method of serializing/deserializing to/from the .Extras objects in the various properties of GLTF? Inherit from your base Extras object? I've been attempting to store some custom properties by doing that and writing the GLTF file works, but when calling LoadModel, the .Extras objects have nothing in them. Is there an example or "best practices" for how you intended this to work?

Perhaps these .Extras properties should have been "dynamic" object types so the Json Serializer could at least give us our information back?

Disable Accessor.Count and BufferView.ByteStride validation

Some models exported from Google Poly have ´Accessor.Count´ and ´BufferView.ByteStride´ values set to 0 (zero).
Even tho, majority of GLTF 2 viewers are able to load these files, while C# loader throws an error.

It is easy to compute the final stride when these values aren't given by calculating it using the ´accessor.ComponentType´ and ´accessor.Type´ fields.

Can we make these validations optional or remove them at all?

There is a model exported from Google Poly attached.
archive (3).zip

Build from source does not work. Missing glTF subdirectory

specifically following the build directions, clicking "start" generates this error:
(Generator.exe is successfully built, then this exception is output:)

Unhandled Exception: System.IO.DirectoryNotFoundException: Could not find a part of the path ".\glTF-CSharp-Loader-master\glTF\specification\2.0\schema\glTF.schema.json

Please rename default branch from 'master' to 'main' per Khronos policy

To repository owners: please rename the default branch of this repository from 'master' to 'main', using the Github renaming tool. This request is per policy set by the Khronos Promoters in May 2021, to follow Github community practice for respectful naming.

The Github renaming tool sets up URL redirections and retargets outstanding pull requests, so the impact on repository users is minimal. The most visible issue is that people with local repo clones will probably want to rename their clone's 'master' branch, following the popup instructions that will be seen when browsing the github repository after the change; or just delete 'master' and pull the new 'main', if it's purely a tracker with no local content.

You may wish to coordinate with @outofcontrol if you are doing auto-updates from this repository to another location, whether via push/pull mirroring or other mechanisms. The redirects setup by Github should accommodate most such uses transparently, but it's still good practice.

Based on experience with other KhronosGroup repositories which have undergone this renaming already, this is a reasonable approach:

  • Agree on a date for the renaming within the Working Group or other owners of the repository, and document that date here.
    • Date can be adjusted to avoid interaction with major releases in flight.
  • Provide notice to repository users outside Khronos, insofar as possible (adding a comment in the repo README with the switchover date is one way).
  • Once the renaming is done, edit the new 'main' branch to replace hardwired references to 'master' with (preferably) 'default branch' or 'main'.
  • Update the repo README to note the change.

If you have questions or issues about this, please raise them on Khronos internal gitlab 'khronos-general' issue 106 if possible. If not possible, you can @-tag me here.

While we will not force any WG into acting precipitously, this is our agreed policy. Please try to accommodate renaming relatively soon.

Note that this issue is automatically generated, due to the large number of KhronosGroup repositories it's being raised in.

Change Buffer.Uri type from string to byte[]

C# char is ALWAYS 2 bytes long (UTF-16). Therefore, in cases of loading GLTF files with embedded data (buffer's URI cares model data within it), when you treat the buffer as an array of bytes/ints/floats/etc - the data you read is wrong. The reason is that every second byte's value that you read from such a buffer is zero. Not only data is ill-formatted, but the buffer itself is twice the necessary size.

Please fix it.

P.s. I know it is annoying :) #blame_microsoft. This bug will always haunt people who port C/C++ code to C#.

Proper way of reading MSFT_lod

What is the proper way of reading the MSFT_lod extension with this loader? See the readme here

Strangely, I am able to load the "MSFT_lod" extension part, but I cannot figure out how to access the data for the "MSFT_screencoverage" extras part.

Buffer created from GLB file is null.

The GLB file support is incomplete. The loader is able to parse the JSON structure, however, the resulting buffer is null. So you have a file structure, but you don't have data.

Please fix it.

More Documentation

I like this handy loader and would love to use it per default in my future projects. However during using it there came some simple questions up which would normally be in the documentation. Would be nice if you add some further documentation here on github 😃!

When saving as binary, how do I embed the textures into the model ?

Hi ! And thanks for that helpful library.
I'm trying to save a model with associated texture. But I cannot see in the API how I can embed the texture inside the generated binary file.
I see the loader can load such models (avocado for example), but I cannot see any sample generating them.
I'll meanwhile try to add it myself into bufferview and set proper index and offset and clear the Uri, but I wonder if there's something obvious I'm missing.

further development of this loader

Hi just wondering if this is has a plan to be maintain and push to a new nuget package for more recent features? I am currently checking the feasibility of glTF for a game production as we have a tool in c# that may end up needing this. It appears this library doesn't currently return a list of verts and indices from the binary file. Is this something this library would want? I have added some more features to test.

edit: Is there a roadmap for features wanted/expected for the various loaders?

Test failure on "Box with Spaces"

The Box with Spaces model is causing a unit test failure here, specifically with a normal map.

System.IO.FileNotFoundException : Could not find file 'glTF-Sample-Models\2.0\Box With Spaces\glTF\Normal%20Map.png'.

The string Normal%20Map.png needs to be URI-decoded before use on a local filesystem.

Can't load files with EmissiveFactor greater than 1.0

I'm using the 1.1.4-alpha package from nuget and it fails to load certain files (like the one linked in the issue below). The exception I get is:

Unhandled Exception: Newtonsoft.Json.JsonSerializationException: Error setting value to 'EmissiveFactor' on 'glTFLoader.Schema.Material'.
 ---> System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
   at glTFLoader.Schema.Material.set_EmissiveFactor(Single[] value)
   at Newtonsoft.Json.Serialization.ExpressionValueProvider.SetValue(Object target, Object value)
   --- End of inner exception stack trace ---
   at Newtonsoft.Json.Serialization.ExpressionValueProvider.SetValue(Object target, Object value)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at glTFLoader.Interface.LoadModel(Stream stream)
   at glTFLoader.Interface.LoadModel(String filePath)

I found this issue (closed) in glTF repository:
KhronosGroup/glTF#1193

The range is checked here in the code (autogenerated):

if ((value[index] > 1D)) {

It seems this has not been updated to the latest version. Please review the schema version and validation, thanks!

LoadBinaryBuffer is not taking bufferView.byteOffset into account

When loading embedded data, the entire buffer is returned by the LoadBinaryBuffer method without taking into account the bufferView.byteOffset.

Changing the code to:

public static byte[] LoadBinaryBuffer(this Gltf model, int bufferIndex, Func<string, byte[]> externalReferenceSolver, int bufferViewByteOffset = 0)
        {
            var buffer = model.Buffers[bufferIndex];

            var bufferData = LoadBinaryBufferUnchecked(buffer, externalReferenceSolver);

            // As per https://github.com/KhronosGroup/glTF/issues/1026
            // Due to buffer padding, buffer length can be equal or larger than expected length by only 3 bytes
            if (bufferData.Length < buffer.ByteLength || (bufferData.Length - buffer.ByteLength) > 3)
            {
                throw new InvalidDataException($"The buffer length is {bufferData.Length}, expected {buffer.ByteLength}");
            }

            if (bufferViewByteOffset > 0)
            {
                var newBufferData = new byte[bufferData.Length - bufferViewByteOffset];
                for (var i = 0; i < newBufferData.Length; i++)
                {
                    newBufferData[i] = bufferData[bufferViewByteOffset + i];
                }
                bufferData = newBufferData;
            }

            return bufferData;
        }

Fixes it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.