Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Adding color options to entities #992

Closed
wants to merge 3 commits into from

Conversation

ewei2406
Copy link
Contributor

@ewei2406 ewei2406 commented Dec 27, 2024

Based on #166, I was playing around with options for adding color. Here's a basic implementation of a simple approach to just modify the contents of meshes object3D to have a color property on their materials.

  • Since each entity has multiple meshes it is hard to determine which one corresponds with which part (i.e. the Sedan has one mesh for the body, one mesh for the windows), I left an index field so that the user can specify which mesh to change the color for (though this requires a bit of guessing, and leave it to -1 for no color applied).
  • The data for the coloring is saved in the accent-color component which has the color and index values, and is grouped under the "advanced" section.
  • The color field doesn't really work as a true color change but more of a tint. So it isn't exactly ideal, but it works for all entities without any changes to the model files.
Screenshot 2024-12-27 at 12 03 41 AM Screenshot 2024-12-26 at 11 58 55 PM

this.meshes = [];
// The group children aren't ready when the component is initialized, so wait a bit.
// TODO: Find a better way to time this.
setTimeout(() => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a workaround since the entity children aren't visible when the component is initialized. I'm curious which event is fired that can be used to time this correctly.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gltf-model component fires a model-loaded event, so you probably want to listen to that.

if (this.el.getObject3D('mesh')) {
  // do your thing
} else {
  this.el.addEventListener('model-loaded', () => {
    this.meshes.length = 0; // be sure to not keep previous gtlf meshes if we switched the model
    // do your thing
  })`
}

I wouldn't keep meshes in an array on the component, that's source of issues, for example if you remove the gtlf-model component, you currently keep meshes in the array that aren't garbage collected. I would just do the traverse in update, without storing an array of meshes on the component.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, I tried the model-loaded and it works perfect!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The this.el.getObject3D('mesh') check is needed if the accent-color component is added later, so after you got that model-loaded event. gltf-model set the loaded glb with el.setObject3D('mesh', model)

'accent-color': {
index: -1
}
}
Copy link
Collaborator

@vincentfretin vincentfretin Dec 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't add the component by default, that's not needed unless you use it. I would create a button in the Sidebar for example "customize color" (for mixins that makes sense) that adds the component to the entity. You can do that with AFRAME.INSPECTOR.execute('componentadd', {entity: entity, component: 'accent-color', value: ''})

const mesh = meshes.at(this.data.index);
if (mesh) {
mesh.material.color.set(this.data.color);
mesh.material.color.multiplyScalar(255);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you multiply by 255?

@vincentfretin
Copy link
Collaborator

In the UI, the index field is not really understandable by the user. I would dynamically get all material names of the model and show a select here. Not sure what are the names currently in the models, it may be nice to rename them in each model to have something clean.
It would be even better if you can make the component multiple: true so you can add several to change the colors of different materials. See my more generalist material-values component here as an example akbartus/A-Frame-Component-GLTF-Manipulator#2

@kfarr
Copy link
Collaborator

kfarr commented Dec 30, 2024

  • In the ideal world, each vehicle has named nodes explicitly for this purpose such as "body color" and someday perhaps also an "accent color"
  • We target updates specifically to this node using a method like Vincent's suggestion to actually change the color, not just tint the existing material.
  • I would suggest inspecting a few of our models in Blender and/or a tool like https://playcanvas.com/model-viewer for the glbs. In my 1 minute review it looks like the compressed GLB have not retained any specific named nodes that can be addressed in the file. In blender source files, some models like isuzu truck have body color, but many such as prius or waymo do not.
  • So likely we need to modify the assets to facilitate this feature.

@ewei2406
Copy link
Contributor Author

Hmm, I agree - the use of an index is unintuitive to most users, but since many assets don't support vertex colorings nor have names for meshes the scope of this will have to include changes to the model files themselves. Then these are the steps I will take

  1. Give all meshes a name by modifying their blender file
  • A quicker alternative could be to create a mapping of mesh names, like catalog.json, since it seems that the order of meshes within each entity is always the same. But I think this isn't a great long-term solution to have the names be in a separate file.
  1. Create the component that saves the mapping of meshes and their colors (if applied)
  • On the editor side, maybe we could have a dropdown selection to pick which mesh, then a boolean for whether there is a custom color applied, and then if the boolean is true, a field for custom color. Sorta like this:
    menu

What do you think?

@vincentfretin
Copy link
Collaborator

You're both talking about mesh names. I was talking about material names. Some models can have several meshes that uses the same material, so that doesn't make sense to me to chose a mesh. Tools like gltf-transform lose the mesh names, but keep the material name if you add --palette false option otherwise it merges simple materials into a single palette material, not what you want when you want the colors to be configurable.

@kfarr
Copy link
Collaborator

kfarr commented Dec 31, 2024

Thanks for the clarification Vincent. It may make sense to have the original artist help with the conversion, perhaps we could put a list together of which files and what are the modifications we want. I can then get a quote and see if it's something we can afford in the short term or if we should do it ourselves.

Unrelated but part of the same files, we also discussed earlier removing rigging for wheels and instead using named meshes for wheel to allow rotation when animating. (rigging was overkill)

@kfarr
Copy link
Collaborator

kfarr commented Dec 31, 2024

Another idea @ewei2406 , the Isuzu truck model in blender appears to have the named material "vehicle-body" already in a way that we might want. Perhaps you could experiment with exporting in compressed glb but in a way that retains that material name so we can target it in the color component. If it can work in this one model then we can apply the same changes to other vehicle models?

image

https://github.com/3DStreet/3dstreet-assets-source/blob/main/models/vehicles/Isuzu_truck_v01.blend

@ewei2406
Copy link
Contributor Author

ewei2406 commented Jan 1, 2025

Sounds good, I will try to draft up what is discussed. I will take a look at using blender to modify the meshes - I was able to transform the prius-sedan model to use a solid color material for the car body instead of a UV map.

@gnansai
Copy link
Collaborator

gnansai commented Jan 1, 2025

Hi @ewei2406
I have made the 3dStreet vehicle models in Blender. I see that you are trying to add the separate material "vehicle-body" to the vehicles in Blender. Do let me know if you need any help with blender and exporting exporting glb files from blender.

@ewei2406 ewei2406 mentioned this pull request Jan 2, 2025
@ewei2406
Copy link
Contributor Author

ewei2406 commented Jan 2, 2025

See #1005

@ewei2406 ewei2406 closed this Jan 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants