I'd like to know the location of the pivot point of a ModelEntity, is there any way to get this? Alternatively can I get it from a USDZ file?
I want to place models in a specific location and some models have the pivot in the center while others have it at the bottom. If I can detect this I can adjust accordingly and place them correctly. I don't have control over the models, alas. Thanks, Spiff
Hi,
as far as I know there is currently no way to retrieve the pivot point directly. What you can do though is to query the bounding box and then calculate a Y-Offset based on the min and max positions of the bounding boxes corners and set that as the position of the entity. Now when you wrap it into another empty parent entity, you should have the desired effect.
public extension Entity {
enum PivotPosition {
case top
case center
case bottom
}
func wrapEntityAndSetPivotPosition(to targetPosition: PivotPosition) -> Entity {
setPivotPosition(to: targetPosition, animated: false)
let entity = Entity()
entity.addChild(self)
return entity
}
func setPivotPosition(to targetPosition: PivotPosition, animated: Bool = false) {
let boundingBox = visualBounds(relativeTo: nil)
let min = boundingBox.min
let max = boundingBox.max
let yTranslation: Float
switch targetPosition {
case .top:
yTranslation = -max.y
case .center:
yTranslation = -(min.y + (max.y - min.y) / 2)
case .bottom:
yTranslation = -min.y
}
let targetPosition = simd_float3(
x: boundingBox.center.x * -1,
y: yTranslation,
z: boundingBox.center.z * -1
)
guard animated else {
position = targetPosition
return
}
guard isAnchored, parent != nil else {
print("Warning: to set the Entities pivot position animated make sure it is already anchored and has a parent set.")
return
}
var translationTransform = transform
translationTransform.translation = targetPosition
move(to: translationTransform, relativeTo: parent, duration: 0.3, timingFunction: .easeOut)
}
}
And the whole thing in action:
let boxModel = ModelEntity(mesh: .generateBox(size: 0.3))
let wrappedBoxEntity = boxModel.wrapEntityAndSetPivotPosition(to: .bottom)
let boxAnchor = AnchorEntity(plane: .horizontal)
boxAnchor.addChild(wrappedBoxEntity)
arView.scene.anchors.append(boxAnchor)
I agree though that there should be a dedicated API for this – as we have in SceneKit. I filed feedback a while ago.