Skip to content

Conversation

ghost
Copy link

@ghost ghost commented Oct 27, 2021

Adds Variant selection to Material editor

@ghost ghost requested review from elalish and samaneh-kazemi October 27, 2021 21:43
import '@material/mwc-icon-button';

import {$gltfIndex, Material} from '@google/model-viewer/lib/features/scene-graph/material';
import {$primitivesList} from '@google/model-viewer/lib/features/scene-graph/model';
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd like to consider our editor as built on top of model-viewer, meaning on its public API. If the feature we want in the editor can't be implemented with MV's public API, we should use that as feedback for changing its public API. Can we do this without accessing our private symbols?

Copy link
Author

Choose a reason for hiding this comment

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

This is something that I keep wishing I had when working on other material features, I finally added it here because it makes the whole thing so much cleaner, but I agree in general, I do think this should have already been a thing which is why I felt ok adding it; we have this info just not in as useful a form.

</me-dropdown>
<div slot="content">
${this.renderVariantsSelector()}
<me-section-row label="Material">
Copy link
Contributor

Choose a reason for hiding this comment

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

This all seems to be nicely functional; let's tweak the CSS to make it a little nicer to look at. We can discuss at our next meeting.

Copy link
Author

Choose a reason for hiding this comment

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

No problem, just keep in mind the 'create variant' functionality will be coming in next so that UI should be taken into account as well

getModelViewer().addEventListener('pointermove', () => drag = true);
getModelViewer().addEventListener('pointerup', (event) => {
if (!drag) {
this.onClick(event);
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks interesting; care to describe?

Copy link
Author

Choose a reason for hiding this comment

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

This simply prevents selecting a material while dragging the object.

this.selectableMaterials = Array.from(selectableSet);
this.selectableMaterials.sort((a, b) => {
return a[$gltfIndex] - b[$gltfIndex];
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these not sorted to begin with? I thought we get things back in insertion order?

Copy link
Author

Choose a reason for hiding this comment

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

because the list is based on the order a material is encountered in the list primitives the materials will not be in order. Per our conversation isActive is being added to Material in order to provide the same information publicly without exposing primitive-node

Uses the new API in material_panel to implement variant selection, and to filter materials by active material.
@ghost ghost requested a review from elalish October 28, 2021 19:53
Copy link
Contributor

@elalish elalish left a comment

Choose a reason for hiding this comment

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

Looking pretty close, just a few things.

return (this[$sourceObject] as DefaultedMaterial).emissiveFactor;
}

get gltfIndex(): number {
Copy link
Contributor

Choose a reason for hiding this comment

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

I might just call this index, since our materials index is the same. Also looks like this wasn't added to the API?

Copy link
Author

Choose a reason for hiding this comment

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

Sounds good.
Added.




export interface VariantToMaterialMapping {
Copy link
Contributor

Choose a reason for hiding this comment

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

vestigial?

Copy link
Author

Choose a reason for hiding this comment

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

removed.

}

get selectedVariant(): string|null {
if (!getModelViewer()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think for consistency you can remove this. In fact I think the getModelViewer() return type doesn't even include null/undefined now.

Copy link
Author

Choose a reason for hiding this comment

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

done.

}

updateSelectableMaterials() {
if (getModelViewer() != null && getModelViewer()!.model != null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Elsewhere we just assert these are not null. I think that's fine here since I believe the whole panel gets hidden if there's no model loaded.

Copy link
Author

Choose a reason for hiding this comment

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

done.

getModelViewer().addEventListener('variant-applied', () => {
onVariantApplied();
getModelViewer().removeEventListener(
'variant-applied', onVariantApplied);
Copy link
Contributor

Choose a reason for hiding this comment

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

A simpler version of this is getModelViewer().addEventListener('variant-applied', onVariantApplied, { once: true });

Copy link
Author

Choose a reason for hiding this comment

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

nice

await panel.updateComplete;

const selector = panel.shadowRoot?.getElementById('variant-selector');
expect(selector!.id).toEqual('variant-selector');
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a bit tautological; maybe check that the selector is visible?

Copy link
Author

Choose a reason for hiding this comment

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

done

</me-section-row label>
`;
}
return html``;
Copy link
Contributor

Choose a reason for hiding this comment

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

I've been trying to get away from this style we had a lot of where we would conditionally remove html. It makes a lot of things difficult (you never know if an element exists, etc). Let's instead change the visibility of the element when availableVariants changes; like set display: "none" or add a class that does that. There should be plenty of examples around the code base to follow.

Copy link
Author

Choose a reason for hiding this comment

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

Setting display: none if you could verify that this code looks ok, everything works fine but...

@ghost ghost requested a review from elalish October 29, 2021 20:36
Copy link
Contributor

@elalish elalish left a comment

Choose a reason for hiding this comment

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

Almost there, let's just fix the last of the CSS (since this will be public as soon as we click merge).

metallicFactorSlider!: SliderWithInputElement;
@query('me-dropdown#material-selector') materialSelector!: Dropdown;
@query('me-dropdown#variant-selector') variantSelector!: Dropdown;
@query('me-dropdown#create-variant-selector')
Copy link
Contributor

Choose a reason for hiding this comment

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

vestigial?

<me-section-row
label="Variant"
style='display: ${
getModelViewer().availableVariants.length > 0 ? 'block' : 'none'}'>
Copy link
Contributor

Choose a reason for hiding this comment

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

This is fine until you add create variant functionality. Then this length will change without updating any @property, which means it won't cause render to run. You can cross that bridge when you come to it. Generally I do CSS changes like this outside of the render function to avoid this, since it's cheaper than calling render more often.

Copy link
Author

Choose a reason for hiding this comment

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

I see, so you can just update CSS and it will respond without having to 're-render' the html?

Copy link
Author

Choose a reason for hiding this comment

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

Yeah gonna leave this here until I have the button, which will provide the hooks to update the CSS display state

'Unnamed Material'}</paper-item>`)}
</me-dropdown>
<div slot="content">
<me-section-row>
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this can just remain unchanged from master, right? Are these divs and rows doing anything useful? Seems to be causing unwanted centering too.

Copy link
Author

Choose a reason for hiding this comment

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

ahhh yes


renderSelectMaterialTab() {
return html`
<me-expandable-tab tabName="Selected Material" .open=${true} .sticky=${
Copy link
Contributor

Choose a reason for hiding this comment

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

If you open enough tabs under this so it scrolls, you'll see that having a sticky one below a not sticky one is very weird. Let's go with neither is sticky. Hopefully that will make their styles match better too.

Copy link
Author

Choose a reason for hiding this comment

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

Done.
Looks pretty good IMO.

@ghost ghost requested a review from elalish October 29, 2021 22:25
elalish
elalish previously approved these changes Oct 29, 2021
Copy link
Contributor

@elalish elalish left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@ghost ghost merged commit b1ad269 into master Oct 29, 2021
@ghost ghost deleted the variants-editor branch October 29, 2021 22:54
This pull request was closed.
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.

2 participants