Change ModelEntity rotation axis to to that of the child entity

Hi, I'm trying to have an entity (and some attachments to it) to rotate. If I add the entity to content, add the attachment as a child entity, and set the entity as InputTargetComponent, then when I add a gesture ONLY the entity rotates and NOT the attachments (added as child entities).

If I add a parent entity with let parentEntity = ModelEntity(), add my entity to the parentEntity, then add the attachments to an entity (which is now a child of the ModelEntity) and set the ModelEntity as InputTargetComponent then the whole thing rotates (including attachments)

I'm sure there must be a bug, why would it work only with an added ModelEntity?

Anyway, bug or not a bug, the problem I have now is that it rotates around the axes of the ModelEntity, not my primary entity, which is what I want.

Is there a way to set the ModelEntity axes to be the axes of my primary child entity so it rotates like I want?

What call should I use to move the axes where would I find the axes of the first child entity which should be the focus of my app?

Here is my code:

var body: some View {
        RealityView { content, attachments in
            // Add the initial RealityKit content
            if let specimenentity = try? await Entity(named: "Immersive", in: realityKitContentBundle) {
                
                let parentEntity = ModelEntity()
                parentEntity.addChild(specimenentity)
                content.add(parentEntity)
                
                
                let entityBounds = specimenentity.visualBounds(relativeTo: parentEntity)
                parentEntity.collision = CollisionComponent(shapes: [ShapeResource.generateBox(size: entityBounds.extents).offsetBy(translation: entityBounds.center)])

                parentEntity.generateCollisionShapes (recursive: true)
                parentEntity.components.set(InputTargetComponent())
                 
                if let Left_Hemisphere = attachments.entity(for: "Left_Hemisphere") {
                    //4. Position the Attachment and add it to the RealityViewContent
                    Left_Hemisphere.position = [-0.5, 1, 0]
                    specimenentity.addChild(Left_Hemisphere)
                }
            }
        } attachments: {
            Attachment(id: "Left_Hemisphere") {
                //2. Define the SwiftUI View
                Text("Left_Hemisphere")
                    .font(.extraLargeTitle)
                    .padding()
                    .glassBackgroundEffect()
            }
        }
       .gesture(
                    DragGesture()
                                .targetedToAnyEntity()
                                .onChanged { value in
                                    let entity = value.entity
                                    var orientation = Rotation3D(entity.orientation(relativeTo: nil))
                                    var newOrientation: Rotation3D
                                    if (value.location.x >= lastGestureValueX) {
                                        newOrientation = orientation.rotated(by: .init(angle: .degrees(0.5), axis: .y))
                                    } else {
                                        newOrientation = orientation.rotated(by: .init(angle: .degrees(-0.5), axis: .y))
                                    }
                                    entity.setOrientation(.init(newOrientation), relativeTo: nil)
                                    lastGestureValueX = value.location.x
                                    orientation = Rotation3D(entity.orientation(relativeTo: nil))
                                    if (value.location.y >= lastGestureValueY) {
                                        newOrientation = orientation.rotated(by: .init(angle: .degrees(0.5), axis: .x))
                                    } else {
                                        newOrientation = orientation.rotated(by: .init(angle: .degrees(-0.5), axis: .x))
                                    }
                                    entity.setOrientation(.init(newOrientation), relativeTo: nil)
                                    lastGestureValueY = value.location.y
                                 }
                )
    }
}

Replies

Hello @michelefu,

I recommend that you take a look at the new Transforming RealityKit entities using gestures sample code. You may want to tweak its behavior a little depending on your specific use-case, but it is a good starting point!

@gchiste

Thanks, that's very useful code. I'm still confused about how to add attachments that rotate with the primary entity.

Do you have any examples?

Thanks Michele

Hello @michelefu,

Children can rotate with their parents, here is a small modification to the RealityView in the sample code I linked above that demonstrates this for an attachment:

        RealityView { content, attachments in
                // Add the initial RealityKit content
                if let scene = try? await Entity(named: "Scene", in: realityKitContentBundle) {
                    content.add(scene)
                    
                    let blueCyliner = scene.findEntity(named: "Cylinder")!
                    
                    let myAttachmentEntity = attachments.entity(for: "MyAttachment")!
                    // Offsetting the attachment a little bit so that it's easily visible in this example.
                    myAttachmentEntity.position.x = 0.2
                    
                    blueCyliner.addChild(myAttachmentEntity)
                    
                }
            } update: { content, attachments in

            } attachments: {
                Attachment(id: "MyAttachment") {
                    Text("Hello World.")
                }
            }
            .installGestures()

If you replace the RealityView in that sample code with this one, and then rotate the blue cylinder, you should see the attachment rotate with the cylinder.

@gchiste It works well!! Thanks! I was also able to move the entity from a window to an immersive view.

Now, I'm trying to merge this code with the example Work with RealityComposer Pro content in Xcode so that the attachments stay facing the user. If you have any pointers or suggestions, I'd welcome them.

I'm attaching a screenshot of what my initial app

  • Hey Michelefu, I recommend that you open a new thread to address this new topic, it just helps people that might be having the same issue as you find the answers!

Add a Comment