Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rotate RenderInstance Translations if Created from a Gltf Template #7653

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

andremig-bentley
Copy link
Contributor

@andremig-bentley andremig-bentley commented Feb 4, 2025

This PR addresses this issue: #7454

When instancing an element from a gltf template, currently the instances will be placed incorrectly. This is due to gltf having a y-up axis orientation while our viewer has z-up. Currently, we are rotating the instance to be facing the correct direction, but the instance's translation is not oriented correctly. This PR fixes this issue by adding a rotation to the instance's translation within createGraphicFromTemplate in System.ts. This rotation will only apply to instances created from a gltf template.

@andremig-bentley andremig-bentley marked this pull request as ready for review February 4, 2025 17:31
@andremig-bentley
Copy link
Contributor Author

/azp run iTwin.js

@andremig-bentley
Copy link
Contributor Author

/azp run iTwin.js Docs - YAML

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@andremig-bentley
Copy link
Contributor Author

/azp run iTwin.js Integration - GitHub

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

1 similar comment
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@@ -2178,7 +2180,8 @@ export async function readGltfGraphics(args: ReadGltfGraphicsArgs): Promise<Rend
*/
export async function readGltfTemplate(args: ReadGltfGraphicsArgs): Promise<GltfTemplate | undefined> {
const baseUrl = typeof args.baseUrl === "string" ? new URL(args.baseUrl) : args.baseUrl;
const props = GltfReaderProps.create(args.gltf, true, baseUrl); // glTF supports exactly one coordinate system with y axis up.
const yAxisUp = args.yAxisUp ?? true; // default to true
const props = GltfReaderProps.create(args.gltf, yAxisUp, baseUrl); // glTF supports exactly one coordinate system with y axis up.
Copy link
Member

@pmconne pmconne Feb 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// glTF supports exactly one coordinate system with y axis up.

Per the comment, y is always up in glTF. Presumably the problem is in our attempt to align it to our z-up coordinate system. Caller should not have to fix that for us.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the latest commit, this has been addressed. A new rotation has been added to the instance's translation which is handled in createGraphicFromTeplate in System.ts. It is handled there so that we can check whether or not the template from which the instance is created is a gltf template. This way, the caller does not have to specify any option to fix this for us.

Copy link
Contributor

mergify bot commented Feb 12, 2025

This pull request is now in conflicts. Could you fix it @andremig-bentley? 🙏
To fixup this pull request, you can check out it locally. See documentation: https://help.github.com/articles/checking-out-pull-requests-locally/

@andremig-bentley andremig-bentley changed the title Add yAxisUp to ReadGltfGraphicsArgs Rotate RenderInstance Translations if Created from a Gltf Template Feb 12, 2025
@andremig-bentley
Copy link
Contributor Author

Latest commit includes fixes to recreation of instances within createGraphicsFromTemplate, and the addition of a test in RenderInstances.test.ts.

transforms[instanceIdx + 11] = -instanceY;
}

// recreate instances
Copy link
Member

@pmconne pmconne Feb 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding all these extra, redundant properties to RenderInstancesImpl so you can "recreate" the instances after computing incorrect transforms seems wrong. Can't you fix the transform earlier, and avoid having to recreate anything?

Copy link
Member

@eringram eringram Feb 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A suggestion from looking around a bit, maybe this could be done in instanceGltfModel() in Instancing.ts, where it looks like the transform is initially calculated

Scratch that, somehow when I was doing a search I found that file but missed that it's example code...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately instanceGltfModel() is an example code snippet so I can't edit anything there to fix the issue. That being said, it does show the expected work flow of creating instances from a gltf template and it can show the issue I'm having here. Link to the function here.

The expected work flow for creating these instances is essentially:
1 - Obtain a Gltf template
2 - Create RenderInstances (including their transforms, important to this PR)
3 - Call createGraphicFromTemplate passing in the template and the instances.

Now we generally want to avoid making the caller pass in any information to tell us when to rotate the transforms. If we want to avoid this, we need to know that what we are instancing is a gltf template. This means that the earliest possible point to know if we need to rotate the transforms is when we also have access to the gltf template, so in createGraphicFromTemplate() which is what is being done here. Unfortunately, this means that they need to be recreated since at this point the instances' transforms are held in a BufferHandle in a readonly property of InstanceBuffersData.

This leaves to me, three options:
1 - Have the caller pass in a flag when creating the instances that tells us to rotate their transforms.
2 - Change InstanceBuffersData.transforms to be able to be written to, and then change the methods within createGraphicFromTemplate() to recreate that one BufferHandle and reassign it.
3 - Recreate the instances as we are doing here.

IMO, it makes the most sense to recreate the instances so that we can avoid relying on a caller to tell us to fix the issue, and so that we can avoid changing properties away from readonly. That being said, I think all three options could be valid solutions, and I'm open to any suggestions/discussion.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 is not an option because the instances can be shared by multiple graphics - if you mutate them you'll affect other graphics that are also using them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants