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

Viewer: add a way to match POV of other cameras (from gltf file loaded for example) #16076

Merged
merged 29 commits into from
Jan 30, 2025

Conversation

cournoll
Copy link
Contributor

@cournoll cournoll commented Jan 16, 2025

This change introduces a way to interpolate the viewer's default camera to other existing cameras in the scene. The primary goal of this feature is to enable matching the POV of cameras defined in a GLTF file, without switching the active camera to try to keep a "simple" experience for non-expert users.

  • _cameraToHotSpot function compute the alpha, beta, and radius angles, as well as the target point for a camera that is not an ArcRotateCamera.
  • For target selection, I used a straightforward approach, the target point is determined based on the camera's forward ray. If an intersection with the meshes from AssetContainer is found, the first hit point is used as the target. If no intersection is detected, a fallback target is calculated by projecting the distance between the camera and the AssetContainer world center along the forward ray.

@cournoll cournoll force-pushed the viewer-select-cameras branch from 1a18638 to 471b841 Compare January 16, 2025 16:45
@bjsplat
Copy link
Collaborator

bjsplat commented Jan 16, 2025

Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s).
To prevent this PR from going to the changelog marked it with the "skip changelog" label.

@bjsplat
Copy link
Collaborator

bjsplat commented Jan 16, 2025

@bjsplat
Copy link
Collaborator

bjsplat commented Jan 16, 2025

@bjsplat
Copy link
Collaborator

bjsplat commented Jan 16, 2025

@ryantrem
Copy link
Member

I was thinking from our initial discussions that we would simply translate these cameras directly to hotspot entries on the element (rather than adding a new cameras concept). Any reason not to go that route? If we do, then I think a few changes to this PR would be good:

  1. getArcRotateCameraInfos can be a private function in ViewerElement (just an internal implementation detail for now).
  2. ViewerDetails could be updated such that the model property returns an object of type Model rather than AssetContainer (breaking change on Viewer, but I still think this is ok since it is @experimental and lower level with minimal current use outside of ViewerElement). Alternatively we could just add more properties to ViewerDetails that are model specific, like the model's bounding center point.
  3. If we only want hotspots for the active model, then in ViewerElements onModelChanged handler, add to the hotspot collection camera-based hotspots for that model (and remove any previous camera-based hotspots).
  4. If we want hotspots for all cameras from all loaded models, then I think it is a little trickier because we need to add camera-based hotspots any time a model is loaded and remove them any time a previously loaded model is removed from the scene.

Which behavior between #3 and #4 are you guys aiming for?

@cournoll
Copy link
Contributor Author

cournoll commented Jan 17, 2025

I was thinking from our initial discussions that we would simply translate these cameras directly to hotspot entries on the element (rather than adding a new cameras concept). Any reason not to go that route?

Not really any specific reason. Initially, during development, I wanted a distinct visual indication so the user could understand that this behavior in the viewer was tied to the cameras in the scene. But once I finished my code and realized that focusing on a hotspot or matching a camera’s POV ultimately relies on the same principle (an interpolation) I understood that we could merge the two. :)

That said, I’m still wondering how we could clarify for users where the names and values of these "undeclared hotspots" originate.

@cournoll
Copy link
Contributor Author

cournoll commented Jan 17, 2025

1. `getArcRotateCameraInfos` can be a private function in `ViewerElement` (just an internal implementation detail for now).

I had a similar feeling about that, so it works perfectly for me.

2. `ViewerDetails` could be updated such that the `model` property returns an object of type `Model` rather than `AssetContainer` (breaking change on `Viewer`, but I still think this is ok since it is @experimental and lower level with minimal current use outside of `ViewerElement`). Alternatively we could just add more properties to `ViewerDetails` that are model specific, like the model's bounding center point.

Yes, yes, yes! Having the bounding info in ViewerDetails would be very nice for the user. Got it, I’ll add that to this PR.

3. If we only want hotspots for the active model, then in `ViewerElement`s `onModelChanged` handler, add to the hotspot collection camera-based hotspots for that model (and remove any previous camera-based hotspots).

4. If we want hotspots for all cameras from all loaded models, then I think it is a little trickier because we need to add camera-based hotspots any time a model is loaded and remove them any time a previously loaded model is removed from the scene.

We will aiming for behavior 4, so i'll try to do something that stay consistent with the Babylon viewer approach and let us fit with our needed 👍

packages/tools/viewer/src/viewer.ts Outdated Show resolved Hide resolved
packages/tools/viewer/src/viewer.ts Outdated Show resolved Hide resolved
packages/tools/viewer/src/viewer.ts Outdated Show resolved Hide resolved
packages/tools/viewer/src/viewer.ts Outdated Show resolved Hide resolved
@ryantrem
Copy link
Member

We will aiming for behavior 4, so i'll try to do something that stay consistent with the Babylon viewer approach and let us fit with our needed 👍

Ok, I guess in this case we can just check Scene.cameras and watch Scene.onNewCameraAddedObservable and Scene.onCameraRemovedObservable. I think we should probably also have a new property/attribute like cameras-as-hotspots that is disabled by default (e.g. you have to explicitly opt into this behavior).

Remove useless ray parameters
Factor code on radius calculation
Use _tempVectors for computation
Handle mesh predicate as parameter of function getArcRotateCameraInfos
Add property camerasAsHotSpots to active cameras hot spots
Fix camera forward ray
packages/dev/core/src/Cameras/arcRotateCamera.ts Outdated Show resolved Hide resolved
packages/tools/viewer/src/viewer.ts Outdated Show resolved Hide resolved
packages/tools/viewer/src/viewerElement.ts Outdated Show resolved Hide resolved
packages/tools/viewer/src/viewerElement.ts Outdated Show resolved Hide resolved
packages/tools/viewer/src/viewerElement.ts Outdated Show resolved Hide resolved
packages/tools/viewer/src/viewerElement.ts Outdated Show resolved Hide resolved
packages/tools/viewer/src/viewer.ts Outdated Show resolved Hide resolved
packages/tools/viewer/src/viewer.ts Outdated Show resolved Hide resolved
Improve type ModelBoundingInfo and mode bounding infos
Move getArcRotateCameraInfos into viewerElement and switch it to private
Split basic hot spots to hot spots from cameras
Rename _getArcRotateCameraInfos into _cameraToHotSpot
Factorise the code to add or remove a camera hot spot
Rename _updateModelBoundingInfo into computeBoundingInfos
packages/tools/viewer/src/viewerElement.ts Outdated Show resolved Hide resolved
packages/tools/viewer/src/viewer.ts Outdated Show resolved Hide resolved
packages/tools/viewer/src/viewerElement.ts Outdated Show resolved Hide resolved
Now worldBounds array is a function getWorldBounds
Add resetWorldBounds function in case of model transformations
Remove camerasHotSpots
Fix _toggleCamerasAsHotSpots
Factorise code for toggle cameras as hot spots
@bjsplat
Copy link
Collaborator

bjsplat commented Jan 24, 2025

Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s).
To prevent this PR from going to the changelog marked it with the "skip changelog" label.

@bjsplat
Copy link
Collaborator

bjsplat commented Jan 24, 2025

@bjsplat
Copy link
Collaborator

bjsplat commented Jan 24, 2025

@bjsplat
Copy link
Collaborator

bjsplat commented Jan 24, 2025

@bjsplat
Copy link
Collaborator

bjsplat commented Jan 28, 2025

@bjsplat
Copy link
Collaborator

bjsplat commented Jan 28, 2025

@bjsplat
Copy link
Collaborator

bjsplat commented Jan 28, 2025

@bjsplat
Copy link
Collaborator

bjsplat commented Jan 28, 2025

@cournoll cournoll requested a review from ryantrem January 30, 2025 08:46
@bjsplat
Copy link
Collaborator

bjsplat commented Jan 30, 2025

@bjsplat
Copy link
Collaborator

bjsplat commented Jan 30, 2025

@ryantrem ryantrem merged commit de390eb into BabylonJS:master Jan 30, 2025
14 checks passed
@cournoll cournoll deleted the viewer-select-cameras branch February 3, 2025 09:09
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