webots icon indicating copy to clipboard operation
webots copied to clipboard

Slot breaks: If the field that references this asset is visible from the scene tree then it must be provided relative to the world.

Open BenjaminDeleze opened this issue 3 years ago • 4 comments

Steps to Reproduce

  1. Open or create a world.
  2. Add a TruckSimple proto.
  3. Change the url of the baseColorMap ImageTexture of the TruckTrailer to textures/truck_trailer_webots.jpg.
  4. See that it works.

Expected behavior Webots should not been able to find the texture as textures/truck_trailer_webots.jpg is relative to the TruckTrailer proto and not to the world

BenjaminDeleze avatar Aug 08 '22 15:08 BenjaminDeleze

Unfortunately it's the worst case scenario, although the url field of the ImageTexture node is clearly visible from the scene tree, when querying for the visibility WbNodeUtilities::isVisible() returns false, hence why it searches it relative to the PROTO rather than the world. The issue is likely due to WbNodeUtilities::isVisible() itself, perhaps it gets stuck somewhere due to there being a Slot node involved.

ad-daniel avatar Aug 08 '22 15:08 ad-daniel

I remarked another problem: if I modify something in the slot, for example the color of the TruckTrailerSimple, it does not trigger the proto regeneration. I have to save and reload for the changes to be applied

BenjaminDeleze avatar Aug 09 '22 06:08 BenjaminDeleze

This latter problem was already existing in R2022a

BenjaminDeleze avatar Aug 09 '22 06:08 BenjaminDeleze

Concerning the first issue, it seems that the slot is not the problem, the structure of the truck is:

  • TruckSimple.proto: normal proto (robot)
    • TruckTrailerSimple.proto: normal proto (slot)
      • TruckTrailerMesh.proto: hidden proto (shape)

The appearance parameter of the TruckTrailerSimple.proto is not used in this proto but in the TruckTrailerMesh.proto which is hidden.

So when trying to resolve the path to the texture, we conclude that the texture is not visible in the sceneTree as TruckTrailerMesh is not visible, so that the texture must be relative to the proto

If I replace TruckTrailerMesh by:

Shape {
  geometry Box{}
  appearance IS appearance
}

Then I get the correct behavior: the texture is visible in the SceneTree and thus must be defined relatively to the world

BenjaminDeleze avatar Aug 09 '22 07:08 BenjaminDeleze

Here is a summary to help me keep track with this issue.

I have three simple PROTOS:

TestAncestor:

#VRML_SIM R2022b utf8
# license: Copyright Cyberbotics Ltd. Licensed for use only with Webots.
# license url: https://cyberbotics.com/webots_assets_license

EXTERNPROTO "TestParent.proto"

PROTO TestAncestor [
  field     MFNode     test           TestParent{}
]
{
  Transform {
    children [
      Transform {
        children IS test
      }
    ]
    translation 0 0 2
  }
}

TestParent:

#VRML_SIM R2022b utf8
# license: Copyright Cyberbotics Ltd. Licensed for use only with Webots.
# license url: https://cyberbotics.com/webots_assets_license

EXTERNPROTO "Test.proto"

PROTO TestParent [
  field     SFNode     TEST_PARENT_APP           PBRAppearance { metalness 0 roughness 0.4 baseColorMap ImageTexture { url [ "textures/truck_trailer_webots.jpg" ] } }
]
{
  Transform {
    children [
      Test {
        TEST_APP IS TEST_PARENT_APP
      }
    ]
  }
}

Test:

#VRML_SIM R2022b utf8
# license: Copyright Cyberbotics Ltd. Licensed for use only with Webots.
# license url: https://cyberbotics.com/webots_assets_license

PROTO Test [
  field SFNode    TEST_APP      PBRAppearance { metalness 0 roughness 0.4 baseColorMap ImageTexture { url [ "textures/truck_trailer_webots.jpg" ] } }
]
{
  Transform {
    children [
      Shape {
        appearance IS TEST_APP
        geometry Box {}
      }
    ]
  }
}

If I insert TestParent in the world, there is no problem, the texture is found relatively to the world.

However, if I insert TestAncestor, it searches the texture in the protos folder and so failed to load the texture.

As @ad-daniel tought, it is because in the WbNodeUtilities::isVisible function, the ImageTexture is once determined as visible (when loading TestParent) and once as not visible (when loading TestAncestor).

This issue arise because in the first (correct) case, the parent of the WbPbrApperance node is the TestParent node itself and thus is visible. But in the other (wrong) case, the parent of the WbPbrAppearnce node is the internal WbShape of Test that is not visible.

After further investigation it seems that the url field misses a redirect connection. When bugging, we enter this condition: https://github.com/cyberbotics/webots/blob/50c3f419b5da49a2af606297049ee91e8adbc92e/src/webots/vrml/WbNode.cpp#L239 that prevents the redirection to be made.

According to the comment, the redirection is supposed to be made later, in this function: https://github.com/cyberbotics/webots/blob/50c3f419b5da49a2af606297049ee91e8adbc92e/src/webots/vrml/WbNode.cpp#L1406

However, when we reached the function, the node is not flagged as a nested proto and thus we miss the condition that would allow the redirection to be made.

BenjaminDeleze avatar Aug 15 '22 15:08 BenjaminDeleze