1

I have a fanfare.reality model in my arView from Reality Composer. I do raycast by entity(at:location) and enable the ModelDebugOptionsComponent(visualizationMode: .lightingDiffuse) of the objects hit, which make the appearance of objects turns grey. However, I found only the fanfare itself turns grey and the flag above the fanfare does not change at all.

enter image description here

I load the fanfare.reality by LoadAsync() and print the returned value as follows. The reason is that the flag, star and fanfare itself are divded into 3 ModelEntity. In RealityKit, raycast searches the entities with CollisionComponent.only can be added to entities that have ModelComponent.

enter image description here

Therefore, my question how can I turn the entire reality model grey (fanfare+flag+star) when I tap the model on screen(by raycast).

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
Bob
  • 55
  • 3

1 Answers1

1

Separate-parts-model approach

You can easily retrieve all 3 models. But you have to specify this whole long hierarchical path:

let scene = try! Experience.loadFanfare()

// Fanfare – .children[0].children[0]
let fanfare = scene.children[0] ..... children[0].children[0] as! ModelEntity
fanfare.model?.materials[0] = UnlitMaterial(color: .darkGray)
    
// Flag – .children[1].children[0]
let flag = scene.children[0] ..... children[1].children[0] as! ModelEntity
flag.model?.materials[0] = UnlitMaterial(color: .darkGray)

// Star – .children[2].children[0]
let star = scene.children[0] ..... children[2].children[0] as! ModelEntity
star.model?.materials[0] = UnlitMaterial(color: .darkGray)

I don't see much difference when retrieving model entities from .rcproject, .reality or .usdz files. According to the printed diagram, all three model-entities are located at the same level of hierarchy, they are offsprings of the same entity. The condition in the if statement can be set to its simplest form – if a ray hits a collision shape of fanfare or (||) flag or (||) star, then all three models must be recolored.

Mono-model approach

The best solution for interacting with 3D models through raycasting is the mono-model approach. A mono-model is a solid 3D object that does not have separate parts – all parts are combined into a whole model. Textures for mono-models are always mapped in UV editors. The mono-model can be made in 3D authoring apps like Maya or Blender.


P.S.

All seasoned AR developers know that Wow! AR experience isn't about code but rather about 3D content. You understand that there is no "miracle pill" for an easy solution if your 3D model consists of many parts. Competently made AR model is 75% of success when working with code.

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
  • Oh! The problem is that I have lots of reality models, e.g. `crown.reality`, `card.reality`, etc. I want to load and process them in a generic way. So I choose to use `LoadAsync(URL)` instead of `Experience.loadFanfare()`. Furthermore, I only can retrieve the `modelEntity` hit by ray (one of `fanfare `, `flag`, `star`). According to your method, I have to find the parent (`scene`) of the hit `modelEntity`(e.g. fanfare) then retrieve other `modelEntity`(e.g. flag, star). Do I understand you correctly? – Bob Nov 26 '21 at 03:00
  • Yes. The method you mentioned works fine when the number of models is 1 or 2. However, If I have more than 3 `.reality` models and the user can place them any number of times in the `arView`. Firstly, I have to hardcode for each `.reality` model. For example, If the user places a `fanfare.reality`, I have to hardcode to get several `modelEntity` (`fanfare`, `flag`, `star`) of `fanfare.reality`. If `card.reality`, get several `modelEntity` (`cover`, `bookmark`, etc) of `card.reality`. If `crown.reality`, get `head`, `body` of it. This is quite a lot of work if there are 10 or more models. – Bob Nov 28 '21 at 02:59
  • Therefore, the problem is that when the ray hits `flag` and I can not get the other `ModelEntity`(`fanfare`, `star`) in the same `.reality` model in advance, how can I retrieve the other `ModelEntity`(`fanfare`, `star`) by `flag` and make them grey? Is there a great solution? – Bob Nov 28 '21 at 03:07
  • 1
    Valuable advice – Bob Dec 01 '21 at 03:44