auto-git:
[add] src/commands/update-custom-material-command.ts
This commit is contained in:
95
src/commands/update-custom-material-command.ts
Normal file
95
src/commands/update-custom-material-command.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import { createOpaqueId } from "../core/ids";
|
||||
import {
|
||||
cloneMaterialDef,
|
||||
type CustomMaterialDef,
|
||||
type CustomMaterialTextureRefs
|
||||
} from "../materials/starter-material-library";
|
||||
|
||||
import type { EditorCommand } from "./command";
|
||||
|
||||
type CustomMaterialUpdate = Partial<
|
||||
Pick<
|
||||
CustomMaterialDef,
|
||||
| "name"
|
||||
| "swatchColorHex"
|
||||
| "tags"
|
||||
| "albedoColorHex"
|
||||
| "opacity"
|
||||
| "roughness"
|
||||
| "metallic"
|
||||
| "normalStrength"
|
||||
>
|
||||
> & {
|
||||
textures?: CustomMaterialTextureRefs;
|
||||
};
|
||||
|
||||
interface UpdateCustomMaterialCommandOptions {
|
||||
materialId: string;
|
||||
update: CustomMaterialUpdate;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
export function createUpdateCustomMaterialCommand(
|
||||
options: UpdateCustomMaterialCommandOptions
|
||||
): EditorCommand {
|
||||
let previousMaterial: CustomMaterialDef | null = null;
|
||||
|
||||
return {
|
||||
id: createOpaqueId("command"),
|
||||
label: options.label ?? "Update custom material",
|
||||
execute(context) {
|
||||
const currentDocument = context.getDocument();
|
||||
const currentMaterial = currentDocument.materials[options.materialId];
|
||||
|
||||
if (currentMaterial === undefined) {
|
||||
throw new Error(`Material ${options.materialId} does not exist.`);
|
||||
}
|
||||
|
||||
if (currentMaterial.kind !== "custom") {
|
||||
throw new Error("Starter materials are read-only.");
|
||||
}
|
||||
|
||||
if (previousMaterial === null) {
|
||||
previousMaterial = cloneMaterialDef(currentMaterial) as CustomMaterialDef;
|
||||
}
|
||||
|
||||
const nextAlbedoColorHex =
|
||||
options.update.albedoColorHex ?? currentMaterial.albedoColorHex;
|
||||
const nextMaterial: CustomMaterialDef = {
|
||||
...currentMaterial,
|
||||
...options.update,
|
||||
swatchColorHex:
|
||||
options.update.swatchColorHex ??
|
||||
(options.update.albedoColorHex === undefined
|
||||
? currentMaterial.swatchColorHex
|
||||
: nextAlbedoColorHex),
|
||||
albedoColorHex: nextAlbedoColorHex,
|
||||
tags: options.update.tags ?? currentMaterial.tags,
|
||||
textures: options.update.textures ?? currentMaterial.textures
|
||||
};
|
||||
|
||||
context.setDocument({
|
||||
...currentDocument,
|
||||
materials: {
|
||||
...currentDocument.materials,
|
||||
[options.materialId]: cloneMaterialDef(nextMaterial)
|
||||
}
|
||||
});
|
||||
},
|
||||
undo(context) {
|
||||
if (previousMaterial === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentDocument = context.getDocument();
|
||||
|
||||
context.setDocument({
|
||||
...currentDocument,
|
||||
materials: {
|
||||
...currentDocument.materials,
|
||||
[options.materialId]: cloneMaterialDef(previousMaterial)
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user