在 Sceneform 1.16.0 中将 GLB 模型居中
Centering a GLB model in Sceneform 1.16.0
现在 RenderableSource.Builder().setRecenterMode()
已被删除,如何以编程方式将 GLB 模型置于 Android 设备屏幕的中心?
这是我以前在 Sceneform 1.15/1.17.1 中的做法。
ModelRenderable.builder()
.setSource(
context,
RenderableSource.Builder().setSource(context, Uri.parse(uri), RenderableSource.SourceType.GLB)
.setScale(1f)
.setRecenterMode(RenderableSource.RecenterMode.CENTER)
.build()
)
.setRegistryId(uri)
.build()
.thenAccept { modelRenderable: ModelRenderable ->
改编自 SceneView 的工作解决方案:https://github.com/SceneView/sceneview-android/blob/5ede719cf10c6b72764500366802147d7323aa3f/sceneview/src/main/java/io/github/sceneview/node/ModelNode.kt#L361-L377
/**
* Centers the 3D model.
*
* @param origin Coordinate inside the model unit cube from where it is centered
* - defaults to [0, 0, 0], which will center the model on the origin
* - center horizontal | bottom aligned = [0, -1, 0]
* - left | top aligned: [-1, 1, 0]
*/
fun Node.setCenter(origin: Float3 = Float3(0f, 0f, 0f)) {
renderableInstance?.filamentAsset?.let { asset ->
val center = asset.boundingBox.center.let { v -> Float3(v[0], v[1], v[2]) }
val halfExtent = asset.boundingBox.halfExtent.let { v -> Float3(v[0], v[1], v[2]) }
val fCenter = -(center + halfExtent * origin) * Float3(1f, 1f, 1f)
localPosition = Vector3(fCenter.x, fCenter.y, fCenter.z)
}
}
object Constants {
const val DEFAULT_RADIUS = 1f
}
operator fun Float3.plus(v: Float3) = Float3(x + v.x, y + v.y, z + v.z)
operator fun Float3.minus(v: Float3) = Float3(x - v.x, y - v.y, z - v.z)
operator fun Float3.times(v: Float3) = Float3(x * v.x, y * v.y, z * v.z)
operator fun Float3.unaryMinus() = Float3(-x, -y, -z)
现在 RenderableSource.Builder().setRecenterMode()
已被删除,如何以编程方式将 GLB 模型置于 Android 设备屏幕的中心?
这是我以前在 Sceneform 1.15/1.17.1 中的做法。
ModelRenderable.builder()
.setSource(
context,
RenderableSource.Builder().setSource(context, Uri.parse(uri), RenderableSource.SourceType.GLB)
.setScale(1f)
.setRecenterMode(RenderableSource.RecenterMode.CENTER)
.build()
)
.setRegistryId(uri)
.build()
.thenAccept { modelRenderable: ModelRenderable ->
改编自 SceneView 的工作解决方案:https://github.com/SceneView/sceneview-android/blob/5ede719cf10c6b72764500366802147d7323aa3f/sceneview/src/main/java/io/github/sceneview/node/ModelNode.kt#L361-L377
/**
* Centers the 3D model.
*
* @param origin Coordinate inside the model unit cube from where it is centered
* - defaults to [0, 0, 0], which will center the model on the origin
* - center horizontal | bottom aligned = [0, -1, 0]
* - left | top aligned: [-1, 1, 0]
*/
fun Node.setCenter(origin: Float3 = Float3(0f, 0f, 0f)) {
renderableInstance?.filamentAsset?.let { asset ->
val center = asset.boundingBox.center.let { v -> Float3(v[0], v[1], v[2]) }
val halfExtent = asset.boundingBox.halfExtent.let { v -> Float3(v[0], v[1], v[2]) }
val fCenter = -(center + halfExtent * origin) * Float3(1f, 1f, 1f)
localPosition = Vector3(fCenter.x, fCenter.y, fCenter.z)
}
}
object Constants {
const val DEFAULT_RADIUS = 1f
}
operator fun Float3.plus(v: Float3) = Float3(x + v.x, y + v.y, z + v.z)
operator fun Float3.minus(v: Float3) = Float3(x - v.x, y - v.y, z - v.z)
operator fun Float3.times(v: Float3) = Float3(x * v.x, y * v.y, z * v.z)
operator fun Float3.unaryMinus() = Float3(-x, -y, -z)