Coder Social home page Coder Social logo

sharpgltf's People

Contributors

aleksandarcebov avatar bertt avatar emackey avatar gentilinigm avatar meltyplayer avatar otsoa avatar ptasev avatar tragamota avatar vpenades 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

sharpgltf's Issues

Update NuGet package

Hi @vpenades!

Could you update nuget package with the changes you have made recently?
Would love to use the mesh builder additions :)

is invalid or does not exist. (Parameter 'dirPath')

When upgrading from Alpha-0014 to Alpha-0015 I see a new error on saving GLB with ModelRoot.SaveGLB: 'is invalid or does not exist. (Parameter 'dirPath')'
The model contains a ChannelImage I think it could be related.

Tried to add the image using a fully specified path (instead of relative path), but same error occurs.

Incorrect image buffer data

There's a difference between Image.GetImageContent() between gltf and glb. When loading a glb, the entire buffer is returned

Exception with very small triangles

Hi', I've noticed an ArgumentOutOfRangeException (Non-negative number required.
Parameter name: count
) occurs when adding very small triangles (area <0.0000002) on model.CreateMeshes(mesh);

As the exception occurs in the final step it's a bit puzzling what's going on. Suggestion: improve error handling for this case?

Unit test LoadUniVRM fails

Hi, I've noticed the unit test LoadUniVRM() fails. think because the tested file AliciaSolid_vrm-0.40.vrm has validation errors.

Read GLB with glTF extension

I'm trying to read an GLB with 'CESIUM_RTC' extension (using ModelRoot.Load(f)), but got an InvalidDataException - The chunk must be padded to 4 bytes: 67554. See attachment for the GLB file.

Basically the extension adds an '_BATCHID' attribute to the vertices.

Is there any sample code how to read/write these files?
with_batch.glb.zip

Add a skinned mesh to an existing node

Currently it's possible to set a rigid mesh to an existing node with SceneBuilder.AddRigidMesh(MeshBuilder, NodeBuilder).

However, I haven't found a way to do this with SceneBuilder.AddSkinnedMesh. How can I accomplish this?

Less textures than expected

I create 8 nodes with each having a mesh, material and texture. However, in the resulting gltf file, I see 8 nodes, 8 meshes, 8 materials but only 6 textures. Could you give me a hint where I miss something?

Multiple objects exported as one object in wrong location

I am trying to write a very simple exporter for Revit and this is the code.
I can't attach a screenshot but basically the objects are exported properly in terms of shape but they are all in wrong locations.
I would like to export each object as a separate object and the coordinate system should be the World Coordinate System with Origin in 0,0,0 and with Z Axis point to the top.

Any help will be much appreciated.

#region Namespaces
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Numerics;
using System.Threading;
using System.Threading.Tasks;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using SharpGLTF.Geometry;
using SharpGLTF.Geometry.VertexTypes;
using SharpGLTF.Materials;
using SharpGLTF.Schema2;
#endregion

namespace GLTFManager
{
    using VERTEX = SharpGLTF.Geometry.VertexTypes.VertexPosition;

    [Transaction(TransactionMode.Manual)]
    public class Command : IExternalCommand
    {
        public Result Execute(
          ExternalCommandData commandData,
          ref string message,
          ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Application app = uiapp.Application;
            Document doc = uidoc.Document;

            // Access current selection

            IList<Reference> sel = uidoc.Selection.PickObjects(ObjectType.Element);
            Options opt = new Options()
            {
                ComputeReferences = true,
                DetailLevel = ViewDetailLevel.Fine,
                IncludeNonVisibleObjects = false
            };
            
            var scene = new SharpGLTF.Scenes.SceneBuilder("Default");
            var material = new MaterialBuilder("Default")
                .WithDoubleSide(true)
                .WithChannelParam(KnownChannel.BaseColor, new System.Numerics.Vector4((float)0.5, (float)0.5, (float)0.5, 1));

            var model = ModelRoot.CreateModel();

            int count = 0;
            int countEl = 0;
            Stopwatch sp = new Stopwatch();
            sp.Start();

            foreach (Reference reference in sel)
            {
                
                Element el = doc.GetElement(reference);
                try {
                    var mesh = new MeshBuilder<VERTEX>(string.Format("msh_{0}_{1}", el.Name, countEl + 1));
                    var prim = mesh.UsePrimitive(material);
                    GeometryElement ge = el.get_Geometry(opt);
                    count += GetGeometryObjects(ge, ref prim);
                    scene.AddRigidMesh(mesh, Matrix4x4.Identity);
                    countEl++;
                } 
                catch { continue;}
            }
            sp.Stop();

            model = scene.ToGltf2();
            model.SaveAsWavefront("mesh.obj");
            model.SaveGLTF("mesh.gltf");

            TaskDialog.Show("Number of triangles ", string.Format("{0} triangles for {1} elements exported in {2}ms",count.ToString(), countEl, sp.ElapsedMilliseconds));
            return Result.Succeeded;
        }

        private int GetGeometryObjects(GeometryElement geomElem, ref PrimitiveBuilder<MaterialBuilder, VERTEX, VertexEmpty, VertexEmpty> prim)
        {
            int count = 0;
            foreach (GeometryObject geomObj in geomElem)
            {
                Curve curve = geomObj as Autodesk.Revit.DB.Curve;
                if (null != curve) continue;
                Solid solid = geomObj as Solid;
                if (null != solid){
                    count += GetFacesArray(solid, ref prim);
                    continue;
                }
                //If this GeometryObject is Instance, call AddCurvesAndSolids
                GeometryInstance geomInst = geomObj as GeometryInstance;
                if (null != geomInst){
                    count += GetGeometryObjects(geomInst.GetSymbolGeometry(), ref prim);
                }
            }
            return count;
        }

        private int GetFacesArray(Solid solid, ref PrimitiveBuilder<MaterialBuilder, VERTEX, VertexEmpty, VertexEmpty> prim, double lod = 1)
        {
            int count = 0;
            FaceArray faces = solid.Faces;
            foreach (Face face in faces)
            {
                Autodesk.Revit.DB.Mesh m = face.Triangulate(lod);
                int numTriangles = m.NumTriangles;
                for (int i=0; i<numTriangles; i++)
                {
                    MeshTriangle triangle = m.get_Triangle(i);
                    XYZ v1 = triangle.get_Vertex(0); 
                    XYZ v2 = triangle.get_Vertex(1);
                    XYZ v3 = triangle.get_Vertex(2);
                    prim.AddTriangle(
                        new VERTEX((float)v1.X, (float)v1.Y, (float)v1.Z),
                        new VERTEX((float)v2.X, (float)v2.Y, (float)v2.Z),
                        new VERTEX((float)v3.X, (float)v3.Y, (float)v3.Z)
                        );
                    count++;
                }
            }

            return count;
        }
    }
}

Make error message more explicit ?

Hello,
First, thank you for this library which is great.
I have run into an error that I don't know how to tackle :

I'm building a "complicated" scene and exporting it to GLTF/GLB.
Most of the time it works great, but some scene will generate a SemanticException:

SharpGLTF.Validation.SemanticException: Mesh[78] Count
SharpGLTF.IO.ReadContext._ReadFromDictionary(String fileName) in \\SharpGLTF.Core\\IO\\ReadContext.cs:line 147
SharpGLTF.IO.WriteContext._PreprocessSchema2(ModelRoot model, Boolean imagesAsBufferViews, Boolean mergeBuffers) in SharpGLTF.Core\\IO\\WriteContext.cs:line 229
SharpGLTF.IO.WriteContext.WriteBinarySchema2(String baseName, ModelRoot model) in SharpGLTF.Core\\IO\\WriteContext.cs:line 181

I cannot figure out what is wrong in my scene, and the exception message is really not helping.

FYI, I recompiled the library with .Net Framework 4.7.2 (needed for my project)
It does work in most case, so I'm not sure that it matters.

M.

No way to add a dummy (empty) node

It seems that currently there is no way to add a dummy node into scene. There are several methods to add a node:
AddMesh
AddCamera
AddLight
AddSkinnedMesh

but there is no way to add just a node.

Consider strong-naming assemblies

Would you mind strong-naming the SharpGLTF assemblies?

This would allow users like me that have to develop on the old .NET Framework, where strong-named assemblies cannot reference assemblies that aren't strong-named too. At the moment our application refuses to load the assembly at all.

See also Microsoft's recommendations here.

Draco?

Hi, whats the status of using Draco compression? I see 5-8 times size reduction when using Draco, so ideally would like to enable it when saving to glb file.

Rendering in Cesium

Hi, I'm evaluating this library and comparing to another one (glTF-CSharp-Loader).

One thing I noticed when rendering in Cesium (my target platform) the model boundaries are not rendered when using this library:

sharpgltf

When using glTF-CSharp-Loader rendering is better:

loader

I'm using VSCode with glTF Tools Extension to inspect the glTF's in Cesium.

Question: How can I render the model just like when using using glTF-CSharp-Loader?

I've attached the 2 glb's to inspect (building_sharp_gltf.glb and building_gltf-csharp_loader.glb)

Thanks!
models.zip

experimental code see https://github.com/bertt/GltfExperiment

Can't compile example due to Monogame constructor reference

I am trying to get the example to work, however am running into an issue in SharpGLTF.Runtime.MonoGame.LoaderContext

Specifically, line 68 generates a compile error:

        var dstMesh = new ModelMesh(_Device, Enumerable.Range(0, srcPrims.Count).Select(item => new ModelMeshPart()).ToList())

The compiler complains that there is no empty contructor for ModelMeshPart(). It looks like the constructor is declared as internal.

Note, this is using the 3.7.8 dev build of Monogame.

Getting Animation Frame Times (Sampler Input)

I'm working on converting gltf to a custom game format using your library. Is there an easy way to get all the frame times of an animation? I'll need to be able to do that both for the entire animation regardless of which node it is for, and also per node as well. Once I have that, I can get snapshots of the data at the exact frame times that the artist intended.

pbrSpecularGlossiness sample?

Hi, is there maybe an example available how to use pbrSpecularGlossiness shaders? For example to create 'best practice' json https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness#best-practices

{
    "materials": [
        {
            "name": "gold",
            "pbrMetallicRoughness": {
                "baseColorfactor": [ 1.0, 0.766, 0.336, 1.0 ],
                "roughnessFactor": 0.1
            },
            "extensions": {
                "KHR_materials_pbrSpecularGlossiness": {
                    "diffuseFactor": [ 0.0, 0.0, 0.0, 1.0 ],
                    "specularFactor": [ 1.0, 0.766, 0.336 ],
                    "glossinessFactor": 0.9
                }
            }
        }
    ]
}

NodeBuilder infinite recursion when setting WorldMatrix, then calling UseTrans/Rot/Scale

On the latest master there is an infinite recursion if you do the following resulting in a StackOverflowException.

var nb = nodeBuilder.CreateNode();
nb.WorldMatrix = worldMatrix; // Comment out this line to fix bug
var ttb = nb.UseTranslation().UseTrackBuilder(TrackName);
var rtb = nb.UseRotation().UseTrackBuilder(TrackName);
var stb = nb.UseScale().UseTrackBuilder(TrackName);

Sketchfab model validation failes

How to reproduce:

Read the generated gltf file available from:
https://sketchfab.com/3d-models/littlest-tokyo-94b24a60dc1b48248de50bf087c0f042
(License: CC Attribution)

SharpGLTF throws an exception:
SharpGLTF.Validation.ModelException: 'Accessor[104] TANGENT[1364] length 0 is not unit length'

I don't think it's required to have Tangent or Normal as a unit length vector. There are cases when special effects can be achieved with custom values in the data. The library shouldn't try guess what user want.

Ability to get path of images

When loading a model I want to be able to get the raw path of the image and load it myself, manually. With the current implementation I can't see a way to do that.

System.NotFiniteNumberException: Normal is invalid

Hi vpenades,

Could you please have a look at the issue that I currently struggling with?

I found one object that produces SYstem.NotFiniteNumberException

It occurs on model.CreateMeshes(meshBuilder) method.
" at SharpGLTF._Extensions.ValidateNormal(Vector3 normal, String msg)\r\n at SharpGLTF.Geometry.VertexTypes.VertexPositionNormal.Validate()\r\n at SharpGLTF.Geometry.Vertex3.Validate()\r\n at SharpGLTF.Geometry.PrimitiveBuilder4.Validate()\r\n at SharpGLTF.Geometry.MeshBuilder4.Validate()\r\n at SharpGLTF.Schema2.Schema2Toolkit.CreateMeshes[TMaterial,TvP,TvM,TvS](ModelRoot root, Func2 materialEvaluator, MeshBuilder`4[] meshBuilders)\r\n at GltfExporter.GLTFExporter.<>c__DisplayClass8_0.b__0(MaterialObejct3D materialObject3D, Object context) in C:\Work\Dev\Source\GltfExporter\GLTFExporter.cs:line 662"

I debugged the normals that are going in while method
primitive.AddTriangle(vertexPositionNormal1, vertexPositionNormal2, vertexPositionNormal3);
is executing, and found no infinite float values or Nan value.
All normals are normalized to 1 before passed to this method.

Attaching the file with normal output.
NormalAddLog.txt

Could you please add validate to primitive.AddTriangle method? So that it will be easier to debug.
With current workflow, I am adding all triangles first and then validate method throws an exception
on model.CreateMeshes(meshBuilder)

If validation was checked on AddTriangle method, it would be easier to see the exact incorrect normal

Also, it is quite strange that this exception is happening because Normals look good

Provide an API for users who don't know the glTF API

A simpler (and limited) API surface for users who do not know glTF should be provided for usability.

A user should be able to provide a list of vertices, zero or more materials, textures, and triangles, and be able to get a glTF file without further interaction with your API.

This API surface should be limited; there are only so many things that such an API would make sense for, to me. Animation would not be supported, and clearly static meshes would.

I don't know if this is within the scope of this API, and I wanted to suggest this in case it is.

How to disable buffer interleaving?

Hello,
is it possible to use separate buffers? In this issue it is said that

by default, sharpGLTF stores all vertex buffers in interleaved mode

, but I couldn't find an option to disable this default behavior. Setting WriteSettings.MergeBuffers = false didn't help

model.SaveGLB(saveFileName, new WriteSettings { MergeBuffers = false });

This isn't very urgent for us since our post-processing steps will write the final result with separate buffers anyway, but it would be nice to be able to skip that step for quick testing.

Thanks and good work!

Validation before write

Hi,

There should be a way to select the validation strictness before write because it is so slow.
Something similar like during read. I wrote a gltf export for Revit and I have models to take more than an hour export time.

Thnx
Zolee

ReadGLB infinite recursion bug

The following code has infinite recursion:
if (chunks.ContainsKey(glb.CHUNKBIN)) { settings.FileReader = key => string.IsNullOrEmpty(key) ? new BYTES(chunks[glb.CHUNKBIN]) : settings.FileReader.Invoke(key); }

Instead original value of settings.FileReader should be saved in a local variable and then references from the code. Something like

var originalReader = settings.FileReader; settings.FileReader = key => string.IsNullOrEmpty(key) ? new BYTES(chunks[glb.CHUNKBIN]) : originalReader.Invoke(key);

Terrain Example

This package looks great. Can you please give an example of building a simple terrain.
Say a grid of 10 by 10 vertices.

Could not load file or assembly System.Numeric.Vectors exception

Could you please kindly solve the issue with the dependencies? I have it reproduced after successfully installed NuGet packages and trying to run the program. This is a runtime error, the project compiles successfully.

Could not load file or assembly 'System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Fix SatelliteFile to use existing files on disk

The SatelliteFile option on saving a model writes new textures when the existing material links to a valid texture file.

It would be nice to fix it so that it checks and uses the correct path and doesn't create extra texture files when not needed.

Morphing support in MeshBuilder

I've been considering different options to provide morphing support for MeshBuilder... adding support for morphing targets would add a lot of complexity to the API and to the underlaying code, and I am not sure if it's worth the burden, given that morphing is a feature that is rearely used.

Also, MeshBuilder is designed to play nice with gltf, by creating strided vertex buffers from the very beginning.

But, in gltf, I think the vertex buffers layout is slightly different than standard stride when morphing is supported.

So, given these contraints, I believe the best approach would be to create a new class called MeshBuilderMorphModifier that would encapsulate static MeshBuilders, adding the extra methods for morphing.

Additionally, a CreateMorphableMeshes would be required to fill them in the destination model. this would allow to create separate vertex buffers for the geometry fragments.

Separate JSON and Binary

Is it possible to save a scene as separate files where the scene graph that defines each mesh instance is saved in single gltf JSON and each mesh vertices, normals etc. are saved in separate binary files, one for each mesh?

System.Text.Json instead of Newtonsoft.Json

Microsoft is in the process of delivering a new Json library called System.Text.Json

Given that currently, SharpGLTF only uses low level json parsing and writing, it might be worth to use System.Text.Json, which seems to be more lightweight that newtonsoft

Valid MorphPrimitivesTest.glb file fails to load

Repro steps:
Get the file from kronos samples
glTF-Sample-Models\2.0\MorphPrimitivesTest\glTF-Draco\MorphPrimitivesTest.glb

ModelRoot.Read throws an exception:
SharpGLTF.Validation.SchemaException: 'Accessor[0] Accessor[0]BufferView must be defined.'

It fails on version 1.0.0-alpha0013

Animations

Hi, is there a simple sample for getting started with animations? Like moving a box or so. I've looked in the unit tests but couldn't find it so quickly.

Append node

Hi @vpenades !

What's the reasoning for building the node hierarchy exclusively via CreateNode()?

I'm traversing my application's DOM depth first, and I would like to create nodes independently from it's parent.

So say we have a DOM like this:

A
- B
   - C

I would like to:

  • create node C
  • create node B, and add node C to its children
  • create node A, and add node B to its children

So, I need something like AppendNode(), which would append the node to a node's children.

Is this something we could add?

FindAnimationChannels(Node) always returns the channels of one specific animation

When importing this file...
https://www.dropbox.com/s/cby5htymjfm8kop/trump_3anims.gltf?dl=0
... and iterating through its animations, each animation object seems to link to the channels of the first animation instead to the channels of the actual animation of the iteration cycle:

This is a debug log of the Quaternion of a leg (left upper leg bone) rotation.
Animation #: Timestamp in seconds => Quaternion(XYZW)

`0: 0 => -1|-0,09|0|0,02
0: 0,1 => -1|-0,09|0|0,02
0: 0,1 => -1|-0,09|0|0,02
0: 0,1 => -1|-0,09|0|0,02
0: 0,2 => -1|-0,09|0|0,02
0: 0,2 => -1|-0,09|0|0,02
0: 0,2 => -1|-0,09|0|0,02
0: 0,3 => -1|-0,09|0|0,02
0: 0,3 => -1|-0,09|0|0,02
0: 0,3 => -1|-0,09|0|0,02
0: 0,4 => -1|-0,09|0|0,02
0: 0,4 => -1|-0,09|0|0,02
0: 0,4 => -1|-0,09|0|0,02
0: 0,5 => -1|-0,09|0|0,02
0: 0,5 => -1|-0,09|0|0,02
0: 0,5 => -1|-0,09|0|0,02
0: 0,6 => -1|-0,09|0|0,02
0: 0,6 => -1|-0,09|0|0,02
0: 0,6 => -1|-0,09|0|0,02
0: 0,7 => -1|-0,09|0|0,02
0: 0,7 => -1|-0,09|0|0,02
0: 0,7 => -1|-0,09|0|0,02
0: 0,8 => -1|-0,09|0|0,02
0: 0,8 => -1|-0,09|0|0,02
0: 0,8 => -1|-0,09|0|0,02
0: 0,9 => -1|-0,09|0|0,02
0: 0,9 => -1|-0,09|0|0,02
0: 0,9 => -1|-0,09|0|0,02

1: 0 => -1|-0,09|0|0,02
1: 0,1 => -1|-0,09|0|0,02
1: 0,1 => -1|-0,09|0|0,02
1: 0,1 => -1|-0,09|0|0,02
1: 0,2 => -1|-0,09|0|0,02
1: 0,2 => -1|-0,09|0|0,02
1: 0,2 => -1|-0,09|0|0,02
1: 0,3 => -1|-0,09|0|0,02
1: 0,3 => -1|-0,09|0|0,02
1: 0,3 => -1|-0,09|0|0,02
1: 0,4 => -1|-0,09|0|0,02
1: 0,4 => -1|-0,09|0|0,02
1: 0,4 => -1|-0,09|0|0,02
1: 0,5 => -1|-0,09|0|0,02
1: 0,5 => -1|-0,09|0|0,02
1: 0,5 => -1|-0,09|0|0,02
1: 0,6 => -1|-0,09|0|0,02
1: 0,6 => -1|-0,09|0|0,02
1: 0,6 => -1|-0,09|0|0,02
1: 0,7 => -1|-0,09|0|0,02
1: 0,7 => -1|-0,09|0|0,02
1: 0,7 => -1|-0,09|0|0,02
1: 0,8 => -1|-0,09|0|0,02
1: 0,8 => -1|-0,09|0|0,02
1: 0,8 => -1|-0,09|0|0,02
1: 0,9 => -1|-0,09|0|0,02
1: 0,9 => -1|-0,09|0|0,02
1: 0,9 => -1|-0,09|0|0,02

2: 0 => -1|-0,09|0|0,02
2: 0,1 => -1|-0,09|0|0,02
2: 0,1 => -1|-0,09|0|0,02
2: 0,1 => -1|-0,09|0|0,02
2: 0,2 => -1|-0,09|0|0,02
2: 0,2 => -1|-0,09|0|0,02
2: 0,2 => -1|-0,09|0|0,02
2: 0,3 => -1|-0,09|0|0,02
2: 0,3 => -1|-0,09|0|0,02
2: 0,3 => -1|-0,09|0|0,02
2: 0,4 => -1|-0,09|0|0,02
2: 0,4 => -1|-0,09|0|0,02
2: 0,4 => -1|-0,09|0|0,02
2: 0,5 => -1|-0,09|0|0,02
2: 0,5 => -1|-0,09|0|0,02
2: 0,5 => -1|-0,09|0|0,02
2: 0,6 => -1|-0,09|0|0,02
2: 0,6 => -1|-0,09|0|0,02
2: 0,6 => -1|-0,09|0|0,02
2: 0,7 => -1|-0,09|0|0,02
2: 0,7 => -1|-0,09|0|0,02
2: 0,7 => -1|-0,09|0|0,02
2: 0,8 => -1|-0,09|0|0,02
2: 0,8 => -1|-0,09|0|0,02
2: 0,8 => -1|-0,09|0|0,02
2: 0,9 => -1|-0,09|0|0,02
2: 0,9 => -1|-0,09|0|0,02`

The rotations are the same for each animation. It always rotates according to the "idle" animation. The animations #1 and #2 should be different, especially because #2 is a walking animation which definitely rotates the leg differently.

My guess:
FindRotationChannels(Node) needs an update concerning the LINQ-selector, or the channels are not imported correctly in the first place.

Greetings,
Karoon!

Struggling with Invalid Matrix

I've been struggling with matrices lately, and I'm wondering whether Matrix4x4.Decompose is too strict or the matrix is truly poorly formed.

I'm using the SceneBuilder API to put together a node hierarchy. For each node, I set the local matrix like so:

var nb = nodeBuilder.CreateNode(bone.Name);
nb.UseTranslation().Value = bone.Position;
nb.UseRotation().Value = bone.Rotation;
nb.UseScale().Value = bone.Scale;

Then, I create a mesh, and calculate the inverse bind matrices:

var nb = nodeBuilders[bb.BoneIndex];
var wm = nb.WorldMatrix;
Matrix4x4.Invert(wm, out Matrix4x4 wmi);
wmi.M44 = 1; // force to be one
return (nb, wmi);

Note: Somehow M44 becomes 0.999999, which is probably due to a precision error caused during the Invert method, and the gltf validator doesn't like this so I forced it to a 1.

Now when I save the gltf file, I get a complaint that a matrix is invalid. I commented out the part that throws the exception just to force the file to save and I can inspect it on my own.

I believe this is due to the Matrix4x4.Decompose function returning false. I think it returns false because the determinant of the rotation part of the matrix is <0.985 as opposed to 1.0 and that's enough to fail the "DecomposeEpsilon" threshold. When I use the gltf validator provided by Khronos, it says the file is valid.

I guess the question is whether these matrices are good enough and the Decompose method is too strict. I also wonder where the imprecison comes from. The local matrices are created from proper position, rotation, and scale data. Maybe if the hierarchy is deep enough, then computing the world matrix loses precision after so many local matrices are multiplied together.

I just wanted to get your thoughts on this, and what we can do about this. I have attached an example gltf.
grnGltf.zip

Thanks!

I also posted a similar issue in the dotnet repo where Decompose returns false in an even simpler example. I was hoping someone could explain how precision was lost, and what to do about it. Initially I thought it was a bug, but now I think either the threshold is too strict, or there are precision problems.
dotnet/runtime#34874

Extract a submesh ?

Hi !

It's a great project !

I was wondering if it's possible to extract a sub mesh ? I mean, for instance, create a ModelRoot from a Mesh (and save it ..) ?

Thanks in advance
Eric

Is there a way to specify Metallness and Roughness map?

Hi vpenades,
Could you please let me know if there is a way to specify metalness and roughness texture?

I saw that metallic and roughness factor can be specified using code:
.WithChannelParam(KnownChannels.MetallicRoughness, metallicFactor, roughnessFactor, 0, 0);

So it looks like I need to programatically combine a special map that has metlalicFactor in R channel and Roughness factor in G channel and then somehow specify it. Is my assumption correct?

You help is very much appreciated

Add normals to a MeshBuilder<VertexPosition>

Hello and thank you for this library,

I am trying to convert a STL file into a GLTF file.

So I create a mesh like this :

            var mesh = new MeshBuilder<VertexPosition>();
            var prim = mesh.UsePrimitive(material, 3);

            foreach (var stlMesh in reader.ReadFile())
            {
                var vertice1 = VERTEX.Create(new System.Numerics.Vector3(stlMesh.vert1.x, stlMesh.vert1.y, stlMesh.vert1.z));
                var vertice2 = VERTEX.Create(new System.Numerics.Vector3(stlMesh.vert2.x, stlMesh.vert2.y, stlMesh.vert2.z));
                var vertice3 = VERTEX.Create(new System.Numerics.Vector3(stlMesh.vert3.x, stlMesh.vert3.y, stlMesh.vert3.z));
                prim.AddTriangle(vertice1, vertice2, vertice3);
            }

So far so good, the conversion is ok and I am able to see the 3D object in a gltf viewer (https://gltf-viewer.donmccurdy.com/).

But now I would like to add normals to the mesh and I am stuck here.
Is there any way to do it?

Triangulate polygons?

Can this library triangulate polygons (as list of vertex(x,y,z)) too? Or is there a method like primitive.AddPolygon?

If not, is there a recommended library to do triangulation?

Provide indices

Hey @vpenades !

I'm currently porting some code from BabylonJS's polygonMesh class to C#, actually this piece of code here: https://github.com/BabylonJS/Babylon.js/blob/8aae1ec1c954c8e7a5dd5062dfabf33334db437b/src/Meshes/polygonMesh.ts#L245

It is extruding a polygon. They set positions, normals, uvs and indices.

From what I understand, the MeshBuilder allows us to use VertexPositionNormal (positions and normals), but that does not include indices. Is there any way to provide indices in the MeshBuilder? Or could you perhaps point me in the right direction?

Thnx,

Michel

Get color information from textures ?

Is it possible to get color information from a texture by using "TexCoord" ?
(SharpGLTF.Geometry.VertexTypes.VertexColor1Texture1.TexCoord)

Thank you.

Is there a way to add normal information while using PrimitiveBuilder.AddTriangle method?

Hi vpenades,

Could you please kindly let me know if there is a way to add normal information while using
PrimitiveBuilder.AddTriangle method?

I tested code from your examples and it worked perfectly with AddTriangle method.
However, when I am trying to create Vertex with VertexPositionNormal component and pass it to AddTriangle method, it is not working at the moment.
3d models look good, but normal information is not there. I also tried to add some obvious 0,0,1 vectors to check if normal information is transferred, there were no visual changes.

Please refer to the attached file for code example.

If I am doing it wrong, could you please let me know how I can specify the normal information using AddTriangle method with a somewhat similar approach?
TestGltf.txt

I am not sure if this is an issue but have no other way to reach you. Your help is very much appreciated.

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.