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

Detect dimensions/size of 3D model and scale accordingly? #36

Closed
kelvinwatson opened this issue Mar 8, 2022 · 7 comments
Closed

Detect dimensions/size of 3D model and scale accordingly? #36

kelvinwatson opened this issue Mar 8, 2022 · 7 comments

Comments

@kelvinwatson
Copy link

kelvinwatson commented Mar 8, 2022

Is there a way to detect the size (dimensions) of a loaded GLB file and calculate a scale factor so that the 3D model fits on the Android screen? Filament has a method called transformToUnitCube() which "tells the model viewer to transform the root node of the scene such that it fits into a 1x1x1 cube centered at the origin".
Could we build something like that for SceneView?

private fun loadGlb(name: String) {
   val buffer = readAsset("models/${name}.glb")
   modelViewer.loadModelGlb(buffer)
   modelViewer.transformToUnitCube()
}

Source: https://medium.com/@philiprideout/getting-started-with-filament-on-android-d10b16f0ec67

@ThomasGorisse
Copy link
Contributor

ThomasGorisse commented Mar 9, 2022

Here is what you are looking for:

/**
* ### Sets up a root transform on the current model to make it fit into a unit cube
*
* @param units the number of units of the cube to scale into.
*/
fun scaleModel(units: Float = 1.0f) {
modelInstance?.filamentAsset?.let { asset ->
val halfExtent = asset.boundingBox.halfExtent.let { v -> Float3(v[0], v[1], v[2]) }
modelScale = Scale(units / max(halfExtent))
}
}

It will scale your model to your desired units cube.

You can also call it at the loading time with the autoScale parameter which will make your model fit into a 1 unit cube.

/**
* ### Loads a monolithic binary glTF and add it to the Node
*
* @param glbFileLocation the glb file location:
* - A relative asset file location *models/mymodel.glb*
* - An android resource from the res folder *context.getResourceUri(R.raw.mymodel)*
* - A File path *Uri.fromFile(myModelFile).path*
* - An http or https url *https://mydomain.com/mymodel.glb*
* @param autoAnimate Plays the animations automatically if the model has one
* @param autoScale Scale the model to fit a unit cube
* @param centerOrigin Center the model origin to this unit cube position
* - null = Keep the original model center point
* - (0, -1, 0) = Center the model horizontally and vertically
* - (0, -1, 0) = center horizontal | bottom aligned
* - (-1, 1, 0) = left | top aligned
* - ...
*/
suspend fun loadModel(
context: Context,
glbFileLocation: String,
autoAnimate: Boolean = true,
autoScale: Boolean = false,
centerOrigin: Position? = null,
onError: ((error: Exception) -> Unit)? = null
): RenderableInstance? {

You can also use the centerOrigin​:​ ​Position​ which will center the model at your desired position within the unit cube.
Exemple: centerOrigin = Position(y = -1.0f) will make your model bottom aligned within the node.

@ThomasGorisse
Copy link
Contributor

ThomasGorisse commented Mar 9, 2022

You could encounter some issues if your model is animated due to an actual wrong bounding box calculation returned by Filament.
If it's your case, please create an issue within the Filament repo and link it here.

@ThomasGorisse
Copy link
Contributor

ThomasGorisse commented Mar 9, 2022

BTW, that's the kind of things that makes me love the kotlin-math integration within SceneView:

val halfExtent = asset.boundingBox.halfExtent.let { v -> Float3(v[0], v[1], v[2]) }
modelScale = Scale(units / max(halfExtent))

@kelvinwatson
Copy link
Author

kelvinwatson commented Mar 9, 2022

Really appreciate your help @ThomasGorisse Thank you! I'll give these a try.

@kelvinwatson
Copy link
Author

@ThomasGorisse Would it be possible for you to explain how I can use this to have the model fit the max screen width?

@ThomasGorisse
Copy link
Contributor

Sorry. I won't be able to answer you on the deprecated/archived version of Google Sceneform within those repositories issues context.

@kelvinwatson
Copy link
Author

No worries, I will be migrating over to SceneView.

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

No branches or pull requests

2 participants