Closed lz852153492 closed 3 years ago
try this code and let me know if it works for you:
var terrain = SceneBuilder.Load("terrain.glb");
var boat = SceneBuilder.Load("boat.glb");
var merged = new SceneBuilder();
merged.AddScene(terrain, Matrix4x4.Identity);
merged.AddScene(boat, Matrix4x4.CreateFromTranslation(50,30,0) );
merged.ToGltf2().Save("merged.glb");
Sorry, this code is not suitable, MATRIX4X4.CreateFromTranslation was not found.
I can’t find MATRIX4X4.CreateFromTranslation in the latest code base. Is there an update in the code base?
Matrix4x4 is System.Numerics.Matrix4x4
Sorry, I mean there is no MATRIX4X4.CreateFromTranslation method, I think you might want to use the MATRIX4X4.CreateTranslation method, right?
Thank you, but your code is still not suitable, ToSchema2 needs to provide corresponding actual parameters
Sorry, the example is from an older version:
Use to ToGltf2 instead of ToSchema2
Hello there! Using the modified code, you can merge but there are some errors, such as the position of some pictures changed
Can I add my own attribute values to extensions under Meshes? I tried to add and found that it seems to be read-only
by Attributes, you mean, vertex attributes? it is not possible to add a new vertex attribute to an existing mesh, but it is possible to create a new one, and copy the data from the previous mesh to the new mesh,
Sorry, I did not express it clearly, I mean I want to add our custom attributes to the "extensions" under "Meshes", the final structure may be: "meshes" : [{ "name" : "test", "primitives" : [{ "attributes" : { "indices" : 0, "material" : 0 } } ], "extensions" : { “digihail” : { "id" : "C5A80287", "children" : [{}], "isCatingShadow" : false } } } ] "extensions" is our custom.
Ah, a custom extension...
Short answer:
Right now custom (user) extensions are not supported.
Long answer:
Extensions need to be registered into SharpGLTF library before loading/saving a model:
namespace SharpGLTF.Schema2
{
static class ExtensionsFactory
{
public static void RegisterExtension<TParent, TExtension>(string persistentName);
}
}
Notice that this is a PRIVATE method that is meant to be used internally by the library. Public extensions support is something that I need to review extensively before making it public, and I don't plan to support it any time soon.
The reason is because in practice most extensions require additional work around the library and it's not enough to simply register them.
If you are in a hurry, or you absolutely need this feature, there's a number of options you have:
ExtensionsFactory.RegisterExtension<>()
, although it's private, it can still be called using reflection.Writing your own extension and registering it is unsupported and undocumented, you'll have to dig into the code and see how other extensions are registered and used.
If your extension just stores data and it doesn't affect the document in any way, an alternative is to use the Extras field.
Thank you, we adopted your suggestion. Use the "Extras" field to store data. Now we need to add our data after the "Extras" field has data. Any suggestions?
As a matter of fact, I've been refactoring how to add custom content to Extras, so from Alpha20 to Alpha21 there will be a breaking change. So depending if you're using the latest development branch or the Alpha20 nuget, the way of writing Extras is different.
Both version boil down to creating a Dictionary<string,Object> and assigning it to the Extras properties. In what they differ is in the way of adding the dictionary to the extras.
The breaking change is required because in future versions I would like to add direct object serialization support... but that's still WIP... so for now the safest approach is to use Dictionaries and Lists.
Our needs have been perfectly solved, thank you very much! Congratulations on your results getting better and better.
Hello there! We want to take out the relevant data of a "name: Test" from the "Mashes" in a glb file, this data includes other attributes such as: "Nodes", etc., and then add it to another glb file, in order to achieve , I may need to traverse all the relevant data of "name: Test", then take it out, and assign it to the matching attribute of another glb file. Is there a better solution or interface implementation, such as automatically extracting all of the specified name in the glb file Attribute data
if you want to add only a part of a model to another model, with the current API, I would do this:
var terrain = SceneBuilder.Load("terrain.glb");
var boat = SceneBuilder.Load("boat.glb");
// filter out the parts you don't want
foreach(var instance in boat.Instances.ToArray())
{
if (instance.Name.StartsWith("Test")) instance.Remove(); // remove this instance from the boat scene.
}
var merged = new SceneBuilder();
merged.AddScene(terrain, Matrix4x4.Identity);
merged.AddScene(boat, Matrix4x4.CreateFromTranslation(50,30,0) );
merged.ToGltf2().Save("merged.glb");
Or, you can look at the "AddScene" and see how it works, so you can write a custom version of it.
Hello there! Is there a way to increase the running speed of SceneBuilder.Load? For 8M files, it takes more than 1 minute to run once
Most of the load time is expended in model validation. If you trust the model is correct, you can disable validation on load.
var model = ModelRoot.Load(f, SharpGLTF.Validation.ValidationMode.Skip);
GLB files are merged using SceneBuilder.Load, can it be achieved by replacing it with ModelRoot.Load?
GLB files are merged using SceneBuilder.Load, can it be achieved by replacing it with ModelRoot.Load?
Yes, ValidationMode implicitly converts to settings.
Sorry, I didn’t understand what you mean, this is the code I replaced, but it’s wrong `var terrain = ModelRoot.Load("terrain.glb"); var boat = ModelRoot.Load("boat.glb");
var merged = new SceneBuilder(); merged.AddScene(terrain, Matrix4x4.Identity); merged.AddScene(boat, Matrix4x4.CreateFromTranslation(50,30,0) );
merged.ToGltf2().Save("merged.glb");`
ModelRoot.Load("terrain.glb", SharpGLTF.Validation.ValidationMode.Skip);
SceneBuilder's Load also works in the same way.
` var terrain = ModelRoot.Load("terrain.glb", SharpGLTF.Validation.ValidationMode.Skip); var boat = ModelRoot.Load("boat.glb", SharpGLTF.Validation.ValidationMode.Skip);
var merged = new SceneBuilder(); merged.AddScene(terrain, Matrix4x4.Identity); merged.AddScene(boat, Matrix4x4.CreateFromTranslation(50,30,0) );
merged.ToGltf2().Save("merged.glb"); ` At merged.AddScene(terrain, Matrix4x4.Identity), an error is prompted, and the error content is as follows: Cannot convert from "SharpGLTF.Schema2.ModelRoot" to "SharpGLTF.Scenes.SceneBuilder" ;
I tried before: SceneBuilder sceneBuilder = terrain.DefaultScene.ToSceneBuilder(); But this piece of code does not increase the speed, and the running time is still more than 1 minute.
you can also apply the skip when saving:
merged.ToGltf2().Save("merged.glb", SharpGLTF.Validation.ValidationMode.Skip);
Also, keep in mind that all the steps involved are computationally expensive:
Except validation, all these steps are needed, and depending on the complexity of the model, it can take its time.
Hello there! Is there an API interface for successfully merging multiple gltf or glb files into one file? I have tried to convert to MODEL and then merge, but unfortunately it failed