From ae3dc3bcffc3966d725cb51cb0ade2ba1d010cc2 Mon Sep 17 00:00:00 2001 From: miramocha <96218694+miramocha@users.noreply.github.com> Date: Sun, 26 Nov 2023 19:06:49 -0500 Subject: [PATCH 1/3] working file export to vrm0 --- packages/extensions/src/vrm/VRM0/constants.ts | 1 + .../vrm0-humanoid-human-bone-prop.ts | 8 + .../vrm/VRM0/properties/vrm0-humanoid-prop.ts | 11 + .../properties/vrm0-material-mtoon-prop.ts | 11 + .../src/vrm/VRM0/properties/vrm0-meta-prop.ts | 11 + .../src/vrm/VRM0/properties/vrm0-vrm-prop.ts | 154 +++++ packages/extensions/src/vrm/VRM0/vrm0-vrm.ts | 584 ++++++++++++++++++ packages/extensions/src/vrm/VRM1/constants.ts | 3 + .../properties/vrm1-material-mtoon-prop.ts | 16 + .../src/vrm/VRM1/vrm1-materials-mtoon.ts | 50 ++ .../src/vrm/VRM1/vrm1-springbone.ts | 17 + packages/extensions/src/vrm/VRM1/vrm1-vrm.ts | 18 + packages/extensions/src/vrm/constants.ts | 280 +++++++++ .../src/vrm/humanoid-human-bone-prop.ts | 27 + packages/extensions/src/vrm/humanoid-prop.ts | 153 +++++ .../extensions/src/vrm/material-mtoon-prop.ts | 429 +++++++++++++ packages/extensions/src/vrm/meta-prop.ts | 253 ++++++++ 17 files changed, 2026 insertions(+) create mode 100644 packages/extensions/src/vrm/VRM0/constants.ts create mode 100644 packages/extensions/src/vrm/VRM0/properties/vrm0-humanoid-human-bone-prop.ts create mode 100644 packages/extensions/src/vrm/VRM0/properties/vrm0-humanoid-prop.ts create mode 100644 packages/extensions/src/vrm/VRM0/properties/vrm0-material-mtoon-prop.ts create mode 100644 packages/extensions/src/vrm/VRM0/properties/vrm0-meta-prop.ts create mode 100644 packages/extensions/src/vrm/VRM0/properties/vrm0-vrm-prop.ts create mode 100644 packages/extensions/src/vrm/VRM0/vrm0-vrm.ts create mode 100644 packages/extensions/src/vrm/VRM1/constants.ts create mode 100644 packages/extensions/src/vrm/VRM1/properties/vrm1-material-mtoon-prop.ts create mode 100644 packages/extensions/src/vrm/VRM1/vrm1-materials-mtoon.ts create mode 100644 packages/extensions/src/vrm/VRM1/vrm1-springbone.ts create mode 100644 packages/extensions/src/vrm/VRM1/vrm1-vrm.ts create mode 100644 packages/extensions/src/vrm/constants.ts create mode 100644 packages/extensions/src/vrm/humanoid-human-bone-prop.ts create mode 100644 packages/extensions/src/vrm/humanoid-prop.ts create mode 100644 packages/extensions/src/vrm/material-mtoon-prop.ts create mode 100644 packages/extensions/src/vrm/meta-prop.ts diff --git a/packages/extensions/src/vrm/VRM0/constants.ts b/packages/extensions/src/vrm/VRM0/constants.ts new file mode 100644 index 000000000..4f5332f42 --- /dev/null +++ b/packages/extensions/src/vrm/VRM0/constants.ts @@ -0,0 +1 @@ +export const VRM0 = "VRM"; diff --git a/packages/extensions/src/vrm/VRM0/properties/vrm0-humanoid-human-bone-prop.ts b/packages/extensions/src/vrm/VRM0/properties/vrm0-humanoid-human-bone-prop.ts new file mode 100644 index 000000000..7177cdaf4 --- /dev/null +++ b/packages/extensions/src/vrm/VRM0/properties/vrm0-humanoid-human-bone-prop.ts @@ -0,0 +1,8 @@ +import { PropertyType as VRMPropertyType } from "../../constants.ts"; +import { HumanoidHumanBoneProp } from "../../humanoid-human-bone-prop.ts"; + +export default class VRM0HumanoidHumanBoneProp extends HumanoidHumanBoneProp { + protected init(): void { + this.propertyType = VRMPropertyType.HUMANOID_HUMAN_BONE; + } +} diff --git a/packages/extensions/src/vrm/VRM0/properties/vrm0-humanoid-prop.ts b/packages/extensions/src/vrm/VRM0/properties/vrm0-humanoid-prop.ts new file mode 100644 index 000000000..3acfc8523 --- /dev/null +++ b/packages/extensions/src/vrm/VRM0/properties/vrm0-humanoid-prop.ts @@ -0,0 +1,11 @@ +import { PropertyType } from "@gltf-transform/core"; +import { VRM0 as NAME } from "../constants.ts"; +import { HumanoidProp } from "../../humanoid-prop.ts"; + +export default class VRM0HumanoidProp extends HumanoidProp { + protected init(): void { + this.extensionName = NAME; + this.propertyType = "VRMC_vrm.humanoid"; + this.parentTypes = [PropertyType.ROOT]; + } +} diff --git a/packages/extensions/src/vrm/VRM0/properties/vrm0-material-mtoon-prop.ts b/packages/extensions/src/vrm/VRM0/properties/vrm0-material-mtoon-prop.ts new file mode 100644 index 000000000..411fc7640 --- /dev/null +++ b/packages/extensions/src/vrm/VRM0/properties/vrm0-material-mtoon-prop.ts @@ -0,0 +1,11 @@ +import { PropertyType } from "@gltf-transform/core"; +import MaterialMToonProp from "../../material-mtoon-prop.ts"; +import { VRM0 as NAME } from "../constants.ts"; + +export default class VRM0MaterialMToonProp extends MaterialMToonProp { + protected init(): void { + this.extensionName = NAME; + this.propertyType = "VRMC_materialsMToon"; + this.parentTypes = [PropertyType.MATERIAL]; + } +} diff --git a/packages/extensions/src/vrm/VRM0/properties/vrm0-meta-prop.ts b/packages/extensions/src/vrm/VRM0/properties/vrm0-meta-prop.ts new file mode 100644 index 000000000..6871f18cc --- /dev/null +++ b/packages/extensions/src/vrm/VRM0/properties/vrm0-meta-prop.ts @@ -0,0 +1,11 @@ +import { PropertyType } from "@gltf-transform/core"; +import { MetaProp } from "../../meta-prop.ts"; +import { VRM0 as NAME } from "../constants.ts"; + +export default class VRM0MetaProp extends MetaProp { + protected init(): void { + this.extensionName = NAME; + this.propertyType = "VRMC_vrm"; + this.parentTypes = [PropertyType.ROOT]; + } +} diff --git a/packages/extensions/src/vrm/VRM0/properties/vrm0-vrm-prop.ts b/packages/extensions/src/vrm/VRM0/properties/vrm0-vrm-prop.ts new file mode 100644 index 000000000..700da3afd --- /dev/null +++ b/packages/extensions/src/vrm/VRM0/properties/vrm0-vrm-prop.ts @@ -0,0 +1,154 @@ +import { + ExtensionProperty, + IProperty, + Nullable, + PropertyType, +} from "@gltf-transform/core"; +import * as VRM0Type from "@pixiv/types-vrm-0.0"; +import { VRM0 as NAME } from "../constants.ts"; +import VRM0MetaProp from "./vrm0-meta-prop.ts"; +import VRM0HumanoidProp from "./vrm0-humanoid-prop.ts"; + +interface IVRM0Prop extends IProperty { + metaProp: VRM0MetaProp; + // specVersion?: "0.0"; + exporterVersion: string; + humanoidProp: VRM0HumanoidProp; + serializedHumanoid: string; + serializedFirstPerson: string; + serializedBlendShapeMaster: string; + serializedSecondaryAnimation: string; + serializedMaterialProperties: string; +} + +export default class VRM0Prop extends ExtensionProperty { + public static EXTENSION_NAME = NAME; + public declare extensionName: typeof NAME; + public declare propertyType: "VRM"; + public declare parentTypes: [PropertyType.ROOT]; + + protected init(): void { + this.extensionName = NAME; + this.propertyType = "VRM"; + this.parentTypes = [PropertyType.ROOT]; + } + + protected getDefaults(): Nullable { + return Object.assign(super.getDefaults() as IProperty, { + metaProp: null, + exporterVersion: "VRM Sparks 0.0", + humanoidProp: null, + serializedHumanoid: "{}", + serializedFirstPerson: "{}", + serializedBlendShapeMaster: "{}", + serializedSecondaryAnimation: "{}", + serializedMaterialProperties: "[]", + }); + } + + public setExporterVersion(exporterVersion: string): this { + return this.set("exporterVersion", exporterVersion); + } + + public getExporterVersion() { + return this.get("exporterVersion"); + } + + public setMetaProp(meta: VRM0MetaProp): this { + return this.setRef("metaProp", meta); + } + public getMetaProp(): VRM0MetaProp | null { + return this.getRef("metaProp"); + } + + public setHumanoid(humanoid: VRM0Type.Humanoid): this { + return this.set("serializedHumanoid", JSON.stringify(humanoid)); + } + public getHumanoid(): VRM0Type.Humanoid | undefined { + const serializedHumanoid = this.get("serializedHumanoid"); + if (serializedHumanoid) { + return JSON.parse(serializedHumanoid) as VRM0Type.Humanoid; + } + return undefined; + } + + public setHumanoidProp(humanoidProp: VRM0HumanoidProp): this { + return this.setRef("humanoidProp", humanoidProp); + } + public getHumanoidProp(): VRM0HumanoidProp | null { + return this.getRef("humanoidProp"); + } + + public setFirstPerson(firstPerson: VRM0Type.FirstPerson): this { + return this.set("serializedFirstPerson", JSON.stringify(firstPerson)); + } + + public getFirstPerson(): VRM0Type.FirstPerson | undefined { + const serializedFirstPerson = this.get("serializedFirstPerson"); + + if (serializedFirstPerson) { + return JSON.parse(serializedFirstPerson) as VRM0Type.FirstPerson; + } + + return undefined; + } + + public setBlendShapeMaster(blendShapeMaster: VRM0Type.BlendShape): this { + return this.set( + "serializedBlendShapeMaster", + JSON.stringify(blendShapeMaster) + ); + } + + public getBlendShapeMaster(): VRM0Type.BlendShape | undefined { + const serializedBlendShapeMaster = this.get("serializedBlendShapeMaster"); + + if (serializedBlendShapeMaster) { + return JSON.parse(serializedBlendShapeMaster) as VRM0Type.BlendShape; + } + + return undefined; + } + + public setSecondaryAnimation( + secondaryAnimation: VRM0Type.SecondaryAnimation + ) { + return this.set( + "serializedSecondaryAnimation", + JSON.stringify(secondaryAnimation) + ); + } + + public getSecondaryAnimation(): VRM0Type.SecondaryAnimation | undefined { + const serializedSecondaryAnimation = this.get( + "serializedSecondaryAnimation" + ); + + if (serializedSecondaryAnimation) { + return JSON.parse( + serializedSecondaryAnimation + ) as VRM0Type.SecondaryAnimation; + } + + return undefined; + } + + public setMaterialProperties(materialProperties: VRM0Type.Material[]): this { + return this.set( + "serializedMaterialProperties", + JSON.stringify(materialProperties) + ); + } + + public getMaterialProperties(): VRM0Type.Material[] | undefined { + const serializedMaterialProperties = this.get( + "serializedMaterialProperties" + ); + + if (serializedMaterialProperties) { + return JSON.parse(serializedMaterialProperties) as VRM0Type.Material[]; + } + + return undefined; + } +} diff --git a/packages/extensions/src/vrm/VRM0/vrm0-vrm.ts b/packages/extensions/src/vrm/VRM0/vrm0-vrm.ts new file mode 100644 index 000000000..c84035808 --- /dev/null +++ b/packages/extensions/src/vrm/VRM0/vrm0-vrm.ts @@ -0,0 +1,584 @@ +import { + Extension, + ReaderContext, + TextureInfo, + WriterContext, +} from "@gltf-transform/core"; +import * as VRM0Type from "@pixiv/types-vrm-0.0"; +import * as VRM1Type from "@pixiv/types-vrmc-vrm-1.0"; +import VRM0Prop from "./properties/vrm0-vrm-prop.ts"; +import { VRM0 as NAME } from "./constants.ts"; +import * as VRMConstants from "../constants.ts"; +import VRM0MaterialMToonProp from "./properties/vrm0-material-mtoon-prop.ts"; +import VRM0MetaProp from "./properties/vrm0-meta-prop.ts"; +import VRM0HumanoidProp from "./properties/vrm0-humanoid-prop.ts"; +import VRM0HumanoidHumanBoneProp from "./properties/vrm0-humanoid-human-bone-prop.ts"; + +export default class VRM0VRM extends Extension { + public readonly extensionName = NAME; + public static readonly EXTENSION_NAME = NAME; + + public createVRM0MaterialMToonProp(): VRM0MaterialMToonProp { + return new VRM0MaterialMToonProp(this.document.getGraph()); + } + + public createVRM0HumanoidHumanBoneProp(): VRM0HumanoidHumanBoneProp { + return new VRM0HumanoidHumanBoneProp(this.document.getGraph()); + } + + public read(context: ReaderContext): this { + const jsonDoc = context.jsonDoc; + + if (jsonDoc.json.extensions && jsonDoc.json.extensions[NAME]) { + const vrmDef = jsonDoc.json.extensions[NAME] as VRM0Type.VRM; + const textureDefs = jsonDoc.json.textures || []; + + const vrmProp = new VRM0Prop(this.document.getGraph()); + this.document.getRoot().setExtension(NAME, vrmProp); + + if (vrmDef.exporterVersion) { + vrmProp.setExporterVersion(vrmDef.exporterVersion as string); + } + + if (vrmDef.meta) { + console.log("READ META", vrmDef.meta); + const vrmMetaProp = new VRM0MetaProp(this.document.getGraph()); + vrmProp.setMetaProp(vrmMetaProp); + const metaDef = vrmDef.meta; + + if (metaDef.title !== undefined) { + vrmMetaProp.setName(metaDef.title); + } + if (metaDef.version !== undefined) { + vrmMetaProp.setVersion(metaDef.version); + } + if (metaDef.author !== undefined) { + vrmMetaProp.setAuthors([metaDef.author]); + } + if (metaDef.contactInformation !== undefined) { + vrmMetaProp.setContactInformation(metaDef.contactInformation); + } + if (metaDef.reference !== undefined) { + vrmMetaProp.setReferences([metaDef.reference]); + } + if (metaDef.texture !== undefined) { + const texture = + context.textures[textureDefs[metaDef.texture].source!]; + vrmMetaProp.setThumbnailImageTexture(texture); + context.setTextureInfo(vrmMetaProp.getThumbnailImageTextureInfo()!, { + index: metaDef.texture, + }); + } + if (metaDef.allowedUserName !== undefined) { + if (metaDef.allowedUserName === "ExplicitlyLicensedPerson") { + vrmMetaProp.setAvatarPermission("onlySeparatelyLicensedPerson"); + } else if (metaDef.allowedUserName === "OnlyAuthor") { + vrmMetaProp.setAvatarPermission("onlyAuthor"); + } else if (metaDef.allowedUserName === "Everyone") { + vrmMetaProp.setAvatarPermission("everyone"); + } + } + if (metaDef.violentUssageName !== undefined) { + vrmMetaProp.setAllowExcessivelyViolentUsage( + metaDef.violentUssageName === "Allow" + ); + } + if (metaDef.sexualUssageName !== undefined) { + vrmMetaProp.setAllowExcessivelySexualUsage( + metaDef.sexualUssageName === "Allow" + ); + } + if (metaDef.commercialUssageName !== undefined) { + if (metaDef.commercialUssageName === "Allow") { + vrmMetaProp.setCommercialUsage("personalProfit"); + } + if (metaDef.commercialUssageName === "Disallow") { + vrmMetaProp.setCommercialUsage("personalNonProfit"); + } + // Not sure about corporation commercial usage in VRM0. Will disallow for now if it's converted to VRM1 + } + if (metaDef.licenseName !== undefined) { + vrmMetaProp.setAllowRedistribution( + metaDef.licenseName !== "Redistribution_Prohibited" + ); + + vrmMetaProp.setLicenseUrl( + VRMConstants.LICENSE_TO_URL_MAP.get(metaDef.licenseName)! + ); + } + if (metaDef.otherLicenseUrl !== undefined) { + vrmMetaProp.setOtherLicenseUrl(metaDef.otherLicenseUrl); + } + } + + if (vrmDef.humanoid) { + console.log("READ HUMANOID", vrmDef.humanoid); + vrmProp.setHumanoid(vrmDef.humanoid); // TEMP + + const vrmHumanoidProp = new VRM0HumanoidProp(this.document.getGraph()); + vrmProp.setHumanoidProp(vrmHumanoidProp); + + vrmDef.humanoid.humanBones?.forEach((humanbone) => { + const humanBoneProp = this.createVRM0HumanoidHumanBoneProp(); + const node = context.nodes[humanbone.node!]; + humanBoneProp.setNode(node!); + + const normalizedBoneName = VRMConstants.VRM0_BONE_TO_VRM1_BONE.get( + humanbone.bone! + ); + + if (normalizedBoneName) { + vrmHumanoidProp.setHumanoidHumanBoneProp( + normalizedBoneName, + humanBoneProp + ); + } + }); + } + + if (vrmDef.firstPerson) { + vrmProp.setFirstPerson(vrmDef.firstPerson); + } + + if (vrmDef.blendShapeMaster) { + vrmProp.setBlendShapeMaster(vrmDef.blendShapeMaster); + } + + if (vrmDef.secondaryAnimation) { + vrmProp.setSecondaryAnimation(vrmDef.secondaryAnimation); + } + + if (vrmDef.materialProperties) { + vrmProp.setMaterialProperties(vrmDef.materialProperties); + + vrmDef.materialProperties.forEach( + ( + materialPropertiesDef: VRM0Type.Material, + materialPropertiesDefIndex: number + ) => { + const materialMToon = this.createVRM0MaterialMToonProp(); + const material = context.materials[materialPropertiesDefIndex]; + material.setExtension(NAME, materialMToon); + + const texturePropertiesDef = + materialPropertiesDef.textureProperties || {}; + + // PBR Textures Sync + if (texturePropertiesDef._MainTex !== undefined) { + const texture = + context.textures[ + textureDefs[texturePropertiesDef._MainTex].source! + ]; + + material.setBaseColorTexture(texture); + context.setTextureInfo( + new TextureInfo(material.getGraph(), "baseColorTextureInfo"), + { + index: texturePropertiesDef._MainTex, + } + ); + } + + if (texturePropertiesDef._BumpMap !== undefined) { + const texture = + context.textures[ + textureDefs[texturePropertiesDef._BumpMap].source! + ]; + + material.setNormalTexture(texture); + context.setTextureInfo( + new TextureInfo(material.getGraph(), "normalTextureInfo"), + { + index: texturePropertiesDef._BumpMap, + } + ); + } + + if (texturePropertiesDef._EmissionMap !== undefined) { + const texture = + context.textures[ + textureDefs[texturePropertiesDef._EmissionMap].source! + ]; + + material.setEmissiveTexture(texture); + context.setTextureInfo( + new TextureInfo(material.getGraph(), "emissiveTextureInfo"), + { + index: texturePropertiesDef._EmissionMap, + } + ); + } + + // Textures + if (texturePropertiesDef._ShadeTexture !== undefined) { + const texture = + context.textures[ + textureDefs[texturePropertiesDef._ShadeTexture].source! + ]; + + materialMToon.setShadeMultiplyTexture(texture); + context.setTextureInfo( + materialMToon.getShadeMultiplyTextureInfo()!, + { + index: texturePropertiesDef._ShadeTexture, + } + ); + } + + if (texturePropertiesDef._SphereAdd !== undefined) { + const texture = + context.textures[ + textureDefs[texturePropertiesDef._SphereAdd].source! + ]; + + materialMToon.setMatcapTexture(texture); + context.setTextureInfo(materialMToon.getMatcapTextureInfo()!, { + index: texturePropertiesDef._SphereAdd, + }); + } + + if (texturePropertiesDef._RimTexture !== undefined) { + const texture = + context.textures[ + textureDefs[texturePropertiesDef._RimTexture].source! + ]; + + materialMToon.setRimMultiplyTexture(texture); + context.setTextureInfo( + materialMToon.getRimMultiplyTextureInfo()!, + { + index: texturePropertiesDef._RimTexture, + } + ); + } + + if (texturePropertiesDef._OutlineWidthTexture !== undefined) { + const texture = + context.textures[ + textureDefs[texturePropertiesDef._OutlineWidthTexture].source! + ]; + + materialMToon.setOutlineWidthMultiplyTexture(texture); + context.setTextureInfo( + materialMToon.getOutlineWidthMultiplyTextureInfo()!, + { + index: texturePropertiesDef._OutlineWidthTexture, + } + ); + } + + const vectorPropertiesDef = + materialPropertiesDef.vectorProperties || {}; + + // Vectors + if (vectorPropertiesDef._Color !== undefined) { + material.setBaseColorFactor(vectorPropertiesDef._Color); + } + + if (vectorPropertiesDef._EmissionColor !== undefined) { + material.setEmissiveFactor( + vectorPropertiesDef._EmissionColor.slice(0, 3) + ); + } + + if (vectorPropertiesDef._ShadeColor !== undefined) { + materialMToon.setShadeColorFactor( + vectorPropertiesDef._ShadeColor.slice(0, 3) + ); + } + + if (vectorPropertiesDef._RimColor !== undefined) { + materialMToon.setParametricRimColorFactor( + vectorPropertiesDef._RimColor.slice(0, 3) + ); + } + + if (vectorPropertiesDef._OutlineColor !== undefined) { + materialMToon.setOutlineColorFactor( + vectorPropertiesDef._OutlineColor.slice(0, 3) + ); + } + + material.setExtension(NAME, materialMToon); + } + ); + } + console.log("READ NODE", context.jsonDoc.json.nodes); + } + + console.log("READ LIST NODES", context.nodes.at(0)?.getTranslation()); + + return this; + } + + public write(context: WriterContext): this { + const jsonDoc = context.jsonDoc; + + const vrmProp = this.document.getRoot().getExtension(NAME); + + if (vrmProp) { + const vrmDef = {} as VRM0Type.VRM; + const rootDef = jsonDoc.json; + rootDef.extensions = rootDef.extensions || {}; + + vrmDef.specVersion = "0.0"; + + if (vrmProp.getExporterVersion()) { + vrmDef.exporterVersion = "GLTF Transformer"; + } + + const vrmMetaProp = vrmProp.getMetaProp(); + vrmDef.meta = vrmDef.meta || {}; + + if (vrmMetaProp) { + const metaDef = vrmDef.meta; + + if (vrmMetaProp.getName() !== undefined) { + metaDef.title = vrmMetaProp.getName(); + } + if (vrmMetaProp.getVersion() !== undefined) { + metaDef.version = vrmMetaProp.getVersion(); + } + if (vrmMetaProp.getAuthors() !== undefined) { + metaDef.author = vrmMetaProp.getAuthors().join(","); + } + if (vrmMetaProp.getContactInformation() !== undefined) { + metaDef.contactInformation = vrmMetaProp.getContactInformation(); + } + if (vrmMetaProp.getReferences() !== undefined) { + metaDef.reference = vrmMetaProp.getReferences().join(","); + } + + if (vrmMetaProp.getThumbnailImageTexture()) { + metaDef.texture = context.createTextureInfoDef( + vrmMetaProp.getThumbnailImageTexture()!, + vrmMetaProp.getThumbnailImageTextureInfo()! + ).index; + } + + if (vrmMetaProp.getAvatarPermission() !== undefined) { + if ( + vrmMetaProp.getAvatarPermission() === "onlySeparatelyLicensedPerson" + ) { + metaDef.allowedUserName = "ExplicitlyLicensedPerson"; + } else if (vrmMetaProp.getAvatarPermission() === "onlyAuthor") { + metaDef.allowedUserName = "OnlyAuthor"; + } else if (vrmMetaProp.getAvatarPermission() === "everyone") { + metaDef.allowedUserName = "Everyone"; + } + } + + if (vrmMetaProp.getAllowExcessivelyViolentUsage() !== undefined) { + metaDef.violentUssageName = + vrmMetaProp.getAllowExcessivelyViolentUsage() === true + ? "Allow" + : "Disallow"; + } + + if (vrmMetaProp.getAllowExcessivelySexualUsage() !== undefined) { + metaDef.sexualUssageName = + vrmMetaProp.getAllowExcessivelySexualUsage() === true + ? "Allow" + : "Disallow"; + } + + if (vrmMetaProp.getCommercialUsage() !== undefined) { + metaDef.commercialUssageName = + vrmMetaProp.getCommercialUsage() !== "personalNonProfit" + ? "Allow" + : "Disallow"; + } + + if (vrmMetaProp.getAllowRedistribution() !== undefined) { + if (vrmMetaProp.getAllowRedistribution() === false) { + metaDef.licenseName = "Redistribution_Prohibited"; + } else { + metaDef.licenseName = + VRMConstants.URL_TO_LICENSE_MAP.get( + vrmMetaProp.getLicenseUrl() + ) || "Other"; + } + } + + if (vrmMetaProp.getOtherLicenseUrl() !== undefined) { + metaDef.otherLicenseUrl = vrmMetaProp.getOtherLicenseUrl(); + } + console.log("WRITE META:", vrmDef.meta); + } + + console.log("PRE WRITE:", vrmDef.humanoid); + const vrmHumanoidProp = vrmProp.getHumanoidProp(); + vrmDef.humanoid = vrmDef.humanoid || {}; + + if (vrmHumanoidProp) { + const humanoidDef = vrmDef.humanoid; + + // WARNING - potential data loss when converted from VRM1 + const humanBonesDef = [] as VRM0Type.HumanoidBone[]; + VRMConstants.VRM1_BONE_ORDER.forEach( + (vrm1Bone: VRM1Type.HumanoidHumanBoneName) => { + const humanoidBoneProp = + vrmHumanoidProp.getHumanoidHumanBoneProp(vrm1Bone); + const vrm0Bone = VRMConstants.VRM1_BONE_TO_VRM0_BONE.get(vrm1Bone); + const node = humanoidBoneProp?.getNode(); + if (node) { + const nodeIndex = context.nodeIndexMap.get(node); + humanBonesDef.push({ + bone: vrm0Bone, + node: nodeIndex, + useDefaultValues: true, + }); + } + } + ); + humanoidDef.humanBones = humanBonesDef; + // vrmDef.humanoid = vrmProp.getHumanoid(); + } + + console.log("WRITE HUMANOID:", vrmDef.humanoid); + + if (vrmProp.getFirstPerson()) { + vrmDef.firstPerson = vrmProp.getFirstPerson(); + } + + if (vrmProp.getBlendShapeMaster()) { + vrmDef.blendShapeMaster = vrmProp.getBlendShapeMaster(); + } + + if (vrmProp.getSecondaryAnimation()) { + vrmDef.secondaryAnimation = vrmProp.getSecondaryAnimation(); + } + + if (vrmProp.getMaterialProperties()) { + vrmDef.materialProperties = vrmProp.getMaterialProperties() || []; + + this.document + .getRoot() + .listMaterials() + .forEach((material, materialIndex) => { + const materialMToon = + material.getExtension(NAME); + const materialPropertiesDef = + vrmDef.materialProperties![materialIndex]; + + materialPropertiesDef.name = material.getName(); + + if (materialMToon && materialPropertiesDef) { + // PBR Textures + materialPropertiesDef.textureProperties = + materialPropertiesDef.textureProperties || {}; + + if (material.getBaseColorTexture()) { + const texture = material.getBaseColorTexture()!; + const textureInfo = material.getBaseColorTextureInfo()!; + materialPropertiesDef.textureProperties._MainTex = + context.createTextureInfoDef(texture, textureInfo).index; + } + + if (material.getNormalTexture()) { + const texture = material.getNormalTexture()!; + const textureInfo = material.getNormalTextureInfo()!; + materialPropertiesDef.textureProperties._BumpMap = + context.createTextureInfoDef(texture, textureInfo).index; + } + + if (material.getEmissiveTexture()) { + const texture = material.getEmissiveTexture()!; + const textureInfo = material.getEmissiveTextureInfo()!; + materialPropertiesDef.textureProperties._EmissionMap = + context.createTextureInfoDef(texture, textureInfo).index; + } + + // Textures + if (materialMToon.getShadeMultiplyTexture()) { + const texture = materialMToon.getShadeMultiplyTexture()!; + const textureInfo = + materialMToon.getShadeMultiplyTextureInfo()!; + materialPropertiesDef.textureProperties._ShadeTexture = + context.createTextureInfoDef(texture, textureInfo).index; + } + + if (materialMToon.getMatcapTexture()) { + const texture = materialMToon.getMatcapTexture()!; + const textureInfo = materialMToon.getMatcapTextureInfo()!; + materialPropertiesDef.textureProperties._SphereAdd = + context.createTextureInfoDef(texture, textureInfo).index; + } + + if (materialMToon.getRimMultiplyTexture()) { + const texture = materialMToon.getRimMultiplyTexture()!; + const textureInfo = materialMToon.getRimMultiplyTextureInfo()!; + materialPropertiesDef.textureProperties._RimTexture = + context.createTextureInfoDef(texture, textureInfo).index; + } + + if (materialMToon.getOutlineWidthMultiplyTexture()) { + const texture = materialMToon.getOutlineWidthMultiplyTexture()!; + const textureInfo = + materialMToon.getOutlineWidthMultiplyTextureInfo()!; + materialPropertiesDef.textureProperties._OutlineWidthTexture = + context.createTextureInfoDef(texture, textureInfo).index; + } + + // Vectors + materialPropertiesDef.vectorProperties = + materialPropertiesDef.vectorProperties || {}; + + if (material.getBaseColorFactor()) { + materialPropertiesDef.vectorProperties._Color = + material.getBaseColorFactor(); + } + + if (material.getEmissiveFactor()) { + materialPropertiesDef.vectorProperties._EmissionColor = [ + ...material.getEmissiveFactor(), + 1, + ]; + } + + if (materialMToon.getShadeColorFactor()) { + materialPropertiesDef.vectorProperties._ShadeColor = [ + ...materialMToon.getShadeColorFactor(), + 1, + ]; + } + + if (materialMToon.getParametricRimColorFactor()) { + materialPropertiesDef.vectorProperties._RimColor = [ + ...materialMToon.getParametricRimColorFactor(), + 1, + ]; + } + + if (materialMToon.getOutlineColorFactor()) { + materialPropertiesDef.vectorProperties._OutlineColor = [ + ...materialMToon.getOutlineColorFactor(), + 1, + ]; + } + } + }); + } + + console.log("WRITE NODE", rootDef.nodes); + + rootDef.extensions[NAME] = vrmDef; + console.log("setting VRMDEF", rootDef.extensions); + + const nodesDef = rootDef.nodes; + if (nodesDef) { + context.nodeIndexMap.forEach((index, node) => { + const nodeDef = rootDef.nodes?.at(index); + + if (nodeDef) { + nodeDef.translation = node.getTranslation(); + nodeDef.rotation = node.getRotation(); + nodeDef.scale = node.getScale(); + } + }); + } + } + + return this; + } +} diff --git a/packages/extensions/src/vrm/VRM1/constants.ts b/packages/extensions/src/vrm/VRM1/constants.ts new file mode 100644 index 000000000..4bec19dff --- /dev/null +++ b/packages/extensions/src/vrm/VRM1/constants.ts @@ -0,0 +1,3 @@ +export const VRMC_VRM = "VRMC_vrm"; +export const VRMC_MATERIALS_MTOON = "VRMC_materials_mtoon"; +export const VRMC_SPRINGBONE = "VRMC_springBone"; diff --git a/packages/extensions/src/vrm/VRM1/properties/vrm1-material-mtoon-prop.ts b/packages/extensions/src/vrm/VRM1/properties/vrm1-material-mtoon-prop.ts new file mode 100644 index 000000000..76c869046 --- /dev/null +++ b/packages/extensions/src/vrm/VRM1/properties/vrm1-material-mtoon-prop.ts @@ -0,0 +1,16 @@ +import { PropertyType } from "@gltf-transform/core"; +import MaterialMToon from "../../material-mtoon-prop.ts"; +import { VRMC_MATERIALS_MTOON as NAME } from "../constants.ts"; + +export default class VRM1MaterialMToon extends MaterialMToon { + public static EXTENSION_NAME = NAME; + public declare extensionName: typeof NAME; + public declare propertyType: "VRMC_materialsMToon"; + public declare parentTypes: [PropertyType.MATERIAL]; + + protected init(): void { + this.extensionName = NAME; + this.propertyType = "VRMC_materialsMToon"; + this.parentTypes = [PropertyType.MATERIAL]; + } +} diff --git a/packages/extensions/src/vrm/VRM1/vrm1-materials-mtoon.ts b/packages/extensions/src/vrm/VRM1/vrm1-materials-mtoon.ts new file mode 100644 index 000000000..1fba4150f --- /dev/null +++ b/packages/extensions/src/vrm/VRM1/vrm1-materials-mtoon.ts @@ -0,0 +1,50 @@ +import { Extension, ReaderContext, WriterContext } from "@gltf-transform/core"; +import { VRMC_MATERIALS_MTOON } from "./constants.ts"; +import VRM1MaterialMToonProp from "./properties/vrm1-material-mtoon-prop.ts"; + +const NAME = VRMC_MATERIALS_MTOON; + +export default class VRM1MaterialsMToon extends Extension { + public readonly extensionName = NAME; + public static readonly EXTENSION_NAME = NAME; + + public createVRM1MaterialMToonProp(): VRM1MaterialMToonProp { + return new VRM1MaterialMToonProp(this.document.getGraph()); + } + + public read(context: ReaderContext): this { + const materialDefs = context.jsonDoc.json.materials || []; + materialDefs.forEach((materialDef, materialIndex) => { + if (materialDef.extensions && materialDef.extensions[NAME]) { + context.materials[materialIndex].setExtension( + NAME, + this.createVRM1MaterialMToonProp() + ); + } + }); + + return this; + } + + public write(context: WriterContext): this { + const jsonDoc = context.jsonDoc; + + this.document + .getRoot() + .listMaterials() + .forEach((material) => { + const materialMToonExtension = + material.getExtension(NAME); + + if (materialMToonExtension) { + const materialIndex = context.materialIndexMap.get(material)!; + const materialDef = jsonDoc.json.materials![materialIndex]; + materialDef.extensions = materialDef.extensions || {}; + // materialDef.extensions[NAME] = + // materialMToonExtension.getVRMCMaterialsMToon(); + } + }); + + return this; + } +} diff --git a/packages/extensions/src/vrm/VRM1/vrm1-springbone.ts b/packages/extensions/src/vrm/VRM1/vrm1-springbone.ts new file mode 100644 index 000000000..5a6f57174 --- /dev/null +++ b/packages/extensions/src/vrm/VRM1/vrm1-springbone.ts @@ -0,0 +1,17 @@ +import { Extension } from "@gltf-transform/core"; +import { VRMC_SPRINGBONE } from "./constants.ts"; + +const NAME = VRMC_SPRINGBONE; + +export default class VRM1SpringBone extends Extension { + public readonly extensionName = NAME; + public static readonly EXTENSION_NAME = NAME; + + public read(): this { + return this; + } + + public write(): this { + return this; + } +} diff --git a/packages/extensions/src/vrm/VRM1/vrm1-vrm.ts b/packages/extensions/src/vrm/VRM1/vrm1-vrm.ts new file mode 100644 index 000000000..a2d01d19f --- /dev/null +++ b/packages/extensions/src/vrm/VRM1/vrm1-vrm.ts @@ -0,0 +1,18 @@ +import { Extension } from "@gltf-transform/core"; +// import * as VRM1Def from "@pixiv/types-vrmc-vrm-1.0"; +import { VRMC_VRM } from "./constants.ts"; + +const NAME = VRMC_VRM; + +export default class VRM1VRM extends Extension { + public readonly extensionName = NAME; + public static readonly EXTENSION_NAME = NAME; + + public read(): this { + return this; + } + + public write(): this { + return this; + } +} diff --git a/packages/extensions/src/vrm/constants.ts b/packages/extensions/src/vrm/constants.ts new file mode 100644 index 000000000..2ed8fe82d --- /dev/null +++ b/packages/extensions/src/vrm/constants.ts @@ -0,0 +1,280 @@ +import * as VRM0Type from "@pixiv/types-vrm-0.0"; +import * as VRM1Type from "@pixiv/types-vrmc-vrm-1.0"; + +export enum PropertyType { + HUMANOID = "VRMC_vrm.humanoid", + HUMANOID_HUMAN_BONE = "VRMC_vrm.humanoid.humanBone", +} + +export type LicenseName = + | "Redistribution_Prohibited" + | "CC0" + | "CC_BY" + | "CC_BY_NC" + | "CC_BY_SA" + | "CC_BY_NC_SA" + | "CC_BY_ND" + | "CC_BY_NC_ND" + | "Other"; + +export const LICENSE_TO_URL_MAP = new Map([ + ["CC0", "https://creativecommons.org/public-domain/cc0/"], + ["CC_BY", "https://creativecommons.org/licenses/by/2.0/deed"], + ["CC_BY_NC", "https://creativecommons.org/licenses/by-nc/2.0/deed"], + ["CC_BY_SA", "https://creativecommons.org/licenses/by-sa/2.0/deed"], + ["CC_BY_NC_SA", "https://creativecommons.org/licenses/by-nc-sa/2.0/deed"], + ["CC_BY_ND", "https://creativecommons.org/licenses/by-nd/2.0/deed"], + ["CC_BY_NC_ND", "https://creativecommons.org/licenses/by-nc-nd/2.0/deed"], +]); + +export const URL_TO_LICENSE_MAP = new Map([ + ["https://creativecommons.org/public-domain/cc0/", "CC0"], + ["https://creativecommons.org/licenses/by/2.0/deed", "CC_BY"], + ["https://creativecommons.org/licenses/by-nc/2.0/deed", "CC_BY_NC"], + ["https://creativecommons.org/licenses/by-sa/2.0/deed", "CC_BY_SA"], + ["https://creativecommons.org/licenses/by-nc-sa/2.0/deed", "CC_BY_NC_SA"], + ["https://creativecommons.org/licenses/by-nd/2.0/deed", "CC_BY_ND"], + ["https://creativecommons.org/licenses/by-nc-nd/2.0/deed", "CC_BY_NC_ND"], +]); + +export const VRM0_BONE_ORDER: VRM0Type.HumanoidBoneName[] = [ + "hips", + "spine", + "chest", + "upperChest", + "neck", + "head", + "leftEye", + "rightEye", + "jaw", + "leftUpperLeg", + "leftLowerLeg", + "leftFoot", + "leftToes", + "rightUpperLeg", + "rightLowerLeg", + "rightFoot", + "rightToes", + "leftShoulder", + "leftUpperArm", + "leftLowerArm", + "leftHand", + "rightShoulder", + "rightUpperArm", + "rightLowerArm", + "rightHand", + "leftThumbIntermediate", + "leftThumbProximal", + "leftThumbDistal", + "leftIndexProximal", + "leftIndexIntermediate", + "leftIndexDistal", + "leftMiddleProximal", + "leftMiddleIntermediate", + "leftMiddleDistal", + "leftRingProximal", + "leftRingIntermediate", + "leftRingDistal", + "leftLittleProximal", + "leftLittleIntermediate", + "leftLittleDistal", + "rightThumbIntermediate", + "rightThumbProximal", + "rightThumbDistal", + "rightIndexProximal", + "rightIndexIntermediate", + "rightIndexDistal", + "rightMiddleProximal", + "rightMiddleIntermediate", + "rightMiddleDistal", + "rightRingProximal", + "rightRingIntermediate", + "rightRingDistal", + "rightLittleProximal", + "rightLittleIntermediate", + "rightLittleDistal", +]; + +export const VRM1_BONE_ORDER: VRM1Type.HumanoidHumanBoneName[] = [ + "hips", + "spine", + "chest", + "upperChest", + "neck", + "head", + "leftEye", + "rightEye", + "jaw", + "leftUpperLeg", + "leftLowerLeg", + "leftFoot", + "leftToes", + "rightUpperLeg", + "rightLowerLeg", + "rightFoot", + "rightToes", + "leftShoulder", + "leftUpperArm", + "leftLowerArm", + "leftHand", + "rightShoulder", + "rightUpperArm", + "rightLowerArm", + "rightHand", + "leftThumbProximal", + "leftThumbMetacarpal", + "leftThumbDistal", + "leftIndexProximal", + "leftIndexIntermediate", + "leftIndexDistal", + "leftMiddleProximal", + "leftMiddleIntermediate", + "leftMiddleDistal", + "leftRingProximal", + "leftRingIntermediate", + "leftRingDistal", + "leftLittleProximal", + "leftLittleIntermediate", + "leftLittleDistal", + "rightThumbProximal", + "rightThumbMetacarpal", + "rightThumbDistal", + "rightIndexProximal", + "rightIndexIntermediate", + "rightIndexDistal", + "rightMiddleProximal", + "rightMiddleIntermediate", + "rightMiddleDistal", + "rightRingProximal", + "rightRingIntermediate", + "rightRingDistal", + "rightLittleProximal", + "rightLittleIntermediate", + "rightLittleDistal", +]; + +export const VRM1_BONE_TO_VRM0_BONE = new Map< + VRM1Type.HumanoidHumanBoneName, + VRM0Type.HumanoidBoneName +>([ + ["hips", "hips"], + ["spine", "spine"], + ["chest", "chest"], + ["upperChest", "upperChest"], + ["neck", "neck"], + ["head", "head"], + ["leftEye", "leftEye"], + ["rightEye", "rightEye"], + ["jaw", "jaw"], + ["leftUpperLeg", "leftUpperLeg"], + ["leftLowerLeg", "leftLowerLeg"], + ["leftFoot", "leftFoot"], + ["leftToes", "leftToes"], + ["rightUpperLeg", "rightUpperLeg"], + ["rightLowerLeg", "rightLowerLeg"], + ["rightFoot", "rightFoot"], + ["rightToes", "rightToes"], + ["leftShoulder", "leftShoulder"], + ["leftUpperArm", "leftUpperArm"], + ["leftLowerArm", "leftLowerArm"], + ["leftHand", "leftHand"], + ["rightShoulder", "rightShoulder"], + ["rightUpperArm", "rightUpperArm"], + ["rightLowerArm", "rightLowerArm"], + ["rightHand", "rightHand"], + + ["leftThumbProximal", "leftThumbProximal"], + ["leftThumbMetacarpal", "leftThumbIntermediate"], + ["leftThumbDistal", "leftThumbDistal"], + ["leftIndexProximal", "leftIndexProximal"], + ["leftIndexIntermediate", "leftIndexIntermediate"], + ["leftIndexDistal", "leftIndexDistal"], + ["leftMiddleProximal", "leftMiddleProximal"], + ["leftMiddleIntermediate", "leftMiddleIntermediate"], + ["leftMiddleDistal", "leftMiddleDistal"], + ["leftRingProximal", "leftRingProximal"], + ["leftRingIntermediate", "leftRingIntermediate"], + ["leftRingDistal", "leftRingDistal"], + ["leftLittleProximal", "leftLittleProximal"], + ["leftLittleIntermediate", "leftLittleIntermediate"], + ["leftLittleDistal", "leftLittleDistal"], + + ["rightThumbProximal", "rightThumbProximal"], + ["rightThumbMetacarpal", "rightThumbIntermediate"], + ["rightThumbDistal", "rightThumbDistal"], + ["rightIndexProximal", "rightIndexProximal"], + ["rightIndexIntermediate", "rightIndexIntermediate"], + ["rightIndexDistal", "rightIndexDistal"], + ["rightMiddleProximal", "rightMiddleProximal"], + ["rightMiddleIntermediate", "rightMiddleIntermediate"], + ["rightMiddleDistal", "rightMiddleDistal"], + ["rightRingProximal", "rightRingProximal"], + ["rightRingIntermediate", "rightRingIntermediate"], + ["rightRingDistal", "rightRingDistal"], + ["rightLittleProximal", "rightLittleProximal"], + ["rightLittleIntermediate", "rightLittleIntermediate"], + ["rightLittleDistal", "rightLittleDistal"], +]); + +export const VRM0_BONE_TO_VRM1_BONE = new Map< + VRM0Type.HumanoidBoneName, + VRM1Type.HumanoidHumanBoneName +>([ + ["hips", "hips"], + ["spine", "spine"], + ["chest", "chest"], + ["upperChest", "upperChest"], + ["neck", "neck"], + ["head", "head"], + ["leftEye", "leftEye"], + ["rightEye", "rightEye"], + ["jaw", "jaw"], + ["leftUpperLeg", "leftUpperLeg"], + ["leftLowerLeg", "leftLowerLeg"], + ["leftFoot", "leftFoot"], + ["leftToes", "leftToes"], + ["rightUpperLeg", "rightUpperLeg"], + ["rightLowerLeg", "rightLowerLeg"], + ["rightFoot", "rightFoot"], + ["rightToes", "rightToes"], + ["leftShoulder", "leftShoulder"], + ["leftUpperArm", "leftUpperArm"], + ["leftLowerArm", "leftLowerArm"], + ["leftHand", "leftHand"], + ["rightShoulder", "rightShoulder"], + ["rightUpperArm", "rightUpperArm"], + ["rightLowerArm", "rightLowerArm"], + ["rightHand", "rightHand"], + + ["leftThumbProximal", "leftThumbProximal"], + ["leftThumbIntermediate", "leftThumbMetacarpal"], + ["leftThumbDistal", "leftThumbDistal"], + ["leftIndexProximal", "leftIndexProximal"], + ["leftIndexIntermediate", "leftIndexIntermediate"], + ["leftIndexDistal", "leftIndexDistal"], + ["leftMiddleProximal", "leftMiddleProximal"], + ["leftMiddleIntermediate", "leftMiddleIntermediate"], + ["leftMiddleDistal", "leftMiddleDistal"], + ["leftRingProximal", "leftRingProximal"], + ["leftRingIntermediate", "leftRingIntermediate"], + ["leftRingDistal", "leftRingDistal"], + ["leftLittleProximal", "leftLittleProximal"], + ["leftLittleIntermediate", "leftLittleIntermediate"], + ["leftLittleDistal", "leftLittleDistal"], + + ["rightThumbProximal", "rightThumbProximal"], + ["rightThumbIntermediate", "rightThumbMetacarpal"], + ["rightThumbDistal", "rightThumbDistal"], + ["rightIndexProximal", "rightIndexProximal"], + ["rightIndexIntermediate", "rightIndexIntermediate"], + ["rightIndexDistal", "rightIndexDistal"], + ["rightMiddleProximal", "rightMiddleProximal"], + ["rightMiddleIntermediate", "rightMiddleIntermediate"], + ["rightMiddleDistal", "rightMiddleDistal"], + ["rightRingProximal", "rightRingProximal"], + ["rightRingIntermediate", "rightRingIntermediate"], + ["rightRingDistal", "rightRingDistal"], + ["rightLittleProximal", "rightLittleProximal"], + ["rightLittleIntermediate", "rightLittleIntermediate"], + ["rightLittleDistal", "rightLittleDistal"], +]); diff --git a/packages/extensions/src/vrm/humanoid-human-bone-prop.ts b/packages/extensions/src/vrm/humanoid-human-bone-prop.ts new file mode 100644 index 000000000..07d4c36da --- /dev/null +++ b/packages/extensions/src/vrm/humanoid-human-bone-prop.ts @@ -0,0 +1,27 @@ +import { IProperty, Nullable, Property, Node } from "@gltf-transform/core"; +import { PropertyType as VRMPropertyType } from "./constants.ts"; + +export interface IHumanoidHumanBoneProp extends IProperty { + node: Node; +} + +export class HumanoidHumanBoneProp extends Property { + public declare propertyType: VRMPropertyType.HUMANOID_HUMAN_BONE; + + protected init(): void { + this.propertyType = VRMPropertyType.HUMANOID_HUMAN_BONE; + } + + protected getDefaults(): Nullable { + return Object.assign(super.getDefaults() as IProperty, { + node: null, + }); + } + + public getNode(): Node | null { + return this.getRef("node"); + } + public setNode(node: Node | null): this { + return this.setRef("node", node); + } +} diff --git a/packages/extensions/src/vrm/humanoid-prop.ts b/packages/extensions/src/vrm/humanoid-prop.ts new file mode 100644 index 000000000..9b8c491f3 --- /dev/null +++ b/packages/extensions/src/vrm/humanoid-prop.ts @@ -0,0 +1,153 @@ +import { + IProperty, + Nullable, + ExtensionProperty, + PropertyType, +} from "@gltf-transform/core"; +import * as VRM1Def from "@pixiv/types-vrmc-vrm-1.0"; +import { VRM0 as VRM0NAME } from "./VRM0/constants.ts"; +import { VRMC_VRM as VRM1NAME } from "./VRM1/constants.ts"; +import { HumanoidHumanBoneProp } from "./humanoid-human-bone-prop.ts"; + +export interface IHumanoidProp extends IProperty { + hips: HumanoidHumanBoneProp; + spine: HumanoidHumanBoneProp; + chest: HumanoidHumanBoneProp; + upperChest: HumanoidHumanBoneProp; + neck: HumanoidHumanBoneProp; + head: HumanoidHumanBoneProp; + leftEye: HumanoidHumanBoneProp; + rightEye: HumanoidHumanBoneProp; + jaw: HumanoidHumanBoneProp; + leftUpperLeg: HumanoidHumanBoneProp; + leftLowerLeg: HumanoidHumanBoneProp; + leftFoot: HumanoidHumanBoneProp; + leftToes: HumanoidHumanBoneProp; + rightUpperLeg: HumanoidHumanBoneProp; + rightLowerLeg: HumanoidHumanBoneProp; + rightFoot: HumanoidHumanBoneProp; + rightToes: HumanoidHumanBoneProp; + leftShoulder: HumanoidHumanBoneProp; + leftUpperArm: HumanoidHumanBoneProp; + leftLowerArm: HumanoidHumanBoneProp; + leftHand: HumanoidHumanBoneProp; + rightShoulder: HumanoidHumanBoneProp; + rightUpperArm: HumanoidHumanBoneProp; + rightLowerArm: HumanoidHumanBoneProp; + rightHand: HumanoidHumanBoneProp; + leftThumbMetacarpal: HumanoidHumanBoneProp; + leftThumbProximal: HumanoidHumanBoneProp; + leftThumbDistal: HumanoidHumanBoneProp; + leftIndexProximal: HumanoidHumanBoneProp; + leftIndexIntermediate: HumanoidHumanBoneProp; + leftIndexDistal: HumanoidHumanBoneProp; + leftMiddleProximal: HumanoidHumanBoneProp; + leftMiddleIntermediate: HumanoidHumanBoneProp; + leftMiddleDistal: HumanoidHumanBoneProp; + leftRingProximal: HumanoidHumanBoneProp; + leftRingIntermediate: HumanoidHumanBoneProp; + leftRingDistal: HumanoidHumanBoneProp; + leftLittleProximal: HumanoidHumanBoneProp; + leftLittleIntermediate: HumanoidHumanBoneProp; + leftLittleDistal: HumanoidHumanBoneProp; + rightThumbMetacarpal: HumanoidHumanBoneProp; + rightThumbProximal: HumanoidHumanBoneProp; + rightThumbDistal: HumanoidHumanBoneProp; + rightIndexProximal: HumanoidHumanBoneProp; + rightIndexIntermediate: HumanoidHumanBoneProp; + rightIndexDistal: HumanoidHumanBoneProp; + rightMiddleProximal: HumanoidHumanBoneProp; + rightMiddleIntermediate: HumanoidHumanBoneProp; + rightMiddleDistal: HumanoidHumanBoneProp; + rightRingProximal: HumanoidHumanBoneProp; + rightRingIntermediate: HumanoidHumanBoneProp; + rightRingDistal: HumanoidHumanBoneProp; + rightLittleProximal: HumanoidHumanBoneProp; + rightLittleIntermediate: HumanoidHumanBoneProp; + rightLittleDistal: HumanoidHumanBoneProp; +} + +export class HumanoidProp extends ExtensionProperty { + public declare extensionName: typeof VRM0NAME | typeof VRM1NAME; + public declare propertyType: "VRMC_vrm.humanoid"; + public declare parentTypes: [PropertyType.ROOT]; + + protected init(): void { + this.extensionName = VRM1NAME; + this.propertyType = "VRMC_vrm.humanoid"; + this.parentTypes = [PropertyType.ROOT]; + } + + protected getDefaults(): Nullable { + return Object.assign(super.getDefaults() as IProperty, { + hips: null, + spine: null, + chest: null, + upperChest: null, + neck: null, + head: null, + leftEye: null, + rightEye: null, + jaw: null, + leftUpperLeg: null, + leftLowerLeg: null, + leftFoot: null, + leftToes: null, + rightUpperLeg: null, + rightLowerLeg: null, + rightFoot: null, + rightToes: null, + leftShoulder: null, + leftUpperArm: null, + leftLowerArm: null, + leftHand: null, + rightShoulder: null, + rightUpperArm: null, + rightLowerArm: null, + rightHand: null, + leftThumbMetacarpal: null, + leftThumbProximal: null, + leftThumbDistal: null, + leftIndexProximal: null, + leftIndexIntermediate: null, + leftIndexDistal: null, + leftMiddleProximal: null, + leftMiddleIntermediate: null, + leftMiddleDistal: null, + leftRingProximal: null, + leftRingIntermediate: null, + leftRingDistal: null, + leftLittleProximal: null, + leftLittleIntermediate: null, + leftLittleDistal: null, + rightThumbMetacarpal: null, + rightThumbProximal: null, + rightThumbDistal: null, + rightIndexProximal: null, + rightIndexIntermediate: null, + rightIndexDistal: null, + rightMiddleProximal: null, + rightMiddleIntermediate: null, + rightMiddleDistal: null, + rightRingProximal: null, + rightRingIntermediate: null, + rightRingDistal: null, + rightLittleProximal: null, + rightLittleIntermediate: null, + rightLittleDistal: null, + }); + } + + public getHumanoidHumanBoneProp( + humanoidHumanBoneName: VRM1Def.HumanoidHumanBoneName + ): HumanoidHumanBoneProp | null { + return this.getRef(humanoidHumanBoneName); + } + + public setHumanoidHumanBoneProp( + humanoidHumanBoneName: VRM1Def.HumanoidHumanBoneName, + humanoidHumanBoneProp: HumanoidHumanBoneProp + ): this { + return this.setRef(humanoidHumanBoneName, humanoidHumanBoneProp); + } +} diff --git a/packages/extensions/src/vrm/material-mtoon-prop.ts b/packages/extensions/src/vrm/material-mtoon-prop.ts new file mode 100644 index 000000000..2bb0b1d2c --- /dev/null +++ b/packages/extensions/src/vrm/material-mtoon-prop.ts @@ -0,0 +1,429 @@ +import { + ExtensionProperty, + IProperty, + Nullable, + PropertyType, + Texture, + TextureInfo, + TextureChannel, + vec3, + ColorUtils, +} from "@gltf-transform/core"; +import { VRM0 as VRM0NAME } from "./VRM0/constants.ts"; +import { VRMC_MATERIALS_MTOON as VRM1NAME } from "./VRM1/constants.ts"; + +const { R, G, B } = TextureChannel; + +/** + * @see https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_materials_mtoon-1.0/README.md + */ +export interface IMaterialMToonProp extends IProperty { + specVersion: string; + + transparentWithZWrite: boolean; + renderQueueOffsetNumber: number; + + /** + * Lighting + */ + shadeColorFactor: vec3; + shadeMultiplyTexture: Texture; + shadeMultiplyTextureInfo: TextureInfo; + shadingShiftFactor: number; + shadingShiftTexture: Texture; + shadingShiftTextureInfo: TextureInfo; + shadingToonyFactor: number; + giEqualizationFactor: number; + + /** + * Rim + */ + matcapFactor: vec3; + matcapTexture: Texture; + matcapTextureInfo: TextureInfo; + parametricRimColorFactor: vec3; + rimMultiplyTexture: Texture; + rimMultiplyTextureInfo: TextureInfo; + rimLightingMixFactor: number; + parametricRimFresnelPowerFactor: number; + parametricRimLiftFactor: number; + + /** + * Outline + */ + outlineWidthMode: string; + outlineWidthFactor: number; + outlineWidthMultiplyTexture: Texture; + outlineWidthMultiplyTextureInfo: TextureInfo; + outlineColorFactor: vec3; + outlineLightingMixFactor: number; + + /** + * UV Animation + */ + uvAnimationMaskTexture: Texture; + uvAnimationMaskTextureInfo: TextureInfo; + uvAnimationScrollXSpeedFactor: number; + uvAnimationScrollYSpeedFactor: number; + uvAnimationRotationSpeedFactor: number; +} + +export default class MaterialMToonProp extends ExtensionProperty { + public declare extensionName: typeof VRM0NAME | typeof VRM1NAME; + public declare propertyType: "VRMC_materialsMToon"; + public declare parentTypes: [PropertyType.MATERIAL]; + + protected init(): void { + this.extensionName = VRM1NAME; + this.propertyType = "VRMC_materialsMToon"; + this.parentTypes = [PropertyType.MATERIAL]; + } + + protected getDefaults(): Nullable { + return Object.assign(super.getDefaults() as IProperty, { + specVersion: "1.0", + + transparentWithZWrite: false, + renderQueueOffsetNumber: 0, + + /** + * Lighting + */ + shadeColorFactor: [0, 0, 0] as vec3, + shadeMultiplyTexture: null, + shadeMultiplyTextureInfo: new TextureInfo( + this.graph, + "shadeMultiplyTextureInfo" + ), + shadingShiftFactor: 0.0, + shadingShiftTexture: null, + shadingShiftTextureInfo: new TextureInfo( + this.graph, + "shadingShiftTextureInfo" + ), + shadingToonyFactor: 0.9, + giEqualizationFactor: 0.9, + + /** + * Rim + */ + matcapFactor: [1, 1, 1] as vec3, + matcapTexture: null, + matcapTextureInfo: new TextureInfo(this.graph, "matcapTextureInfo"), + parametricRimColorFactor: [0, 0, 0] as vec3, + rimMultiplyTexture: null, + rimMultiplyTextureInfo: new TextureInfo( + this.graph, + "rimMultiplyTextureInfo" + ), + rimLightingMixFactor: 1.0, + parametricRimFresnelPowerFactor: 5.0, + parametricRimLiftFactor: 0.0, + + /** + * Outline + */ + outlineWidthMode: "none", + outlineWidthFactor: 0.0, + outlineWidthMultiplyTexture: null, + outlineWidthMultiplyTextureInfo: new TextureInfo( + this.graph, + "outlineWidthMultiplyTextureInfo" + ), + outlineColorFactor: [0, 0, 0] as vec3, + outlineLightingMixFactor: 1.0, + + /** + * UV Animation + */ + uvAnimationMaskTexture: null, + uvAnimationMaskTextureInfo: new TextureInfo( + this.graph, + "uvAnimationMaskTextureInfo" + ), + uvAnimationScrollXSpeedFactor: 0.0, + uvAnimationScrollYSpeedFactor: 0.0, + uvAnimationRotationSpeedFactor: 0.0, + }); + } + + public getSpecVersion(): string { + return this.get("specVersion"); + } + public setSpecVersion(specVersion: string): this { + return this.set("specVersion", specVersion); + } + + public getTransparentWithZWrite(): boolean { + return this.get("transparentWithZWrite"); + } + public setTransparentWithZWrite(transparentWithZWrite: boolean): this { + return this.set("transparentWithZWrite", transparentWithZWrite); + } + + public getRenderQueueOffsetNumber(): number { + return this.get("renderQueueOffsetNumber"); + } + public setRenderQueueOffsetNumber(renderQueueOffsetNumber: number): this { + return this.set("renderQueueOffsetNumber", renderQueueOffsetNumber); + } + + /********************************************************************************************** + * Lighting + */ + public getShadeColorFactor(): vec3 { + return this.get("shadeColorFactor"); + } + public setShadeColorFactor(shadeColorFactor: vec3): this { + return this.set("shadeColorFactor", shadeColorFactor); + } + public getShadeColorHex(): number { + return ColorUtils.factorToHex(this.get("shadeColorFactor")); + } + public setShadeColorHex(hex: number): this { + const factor = this.get("shadeColorFactor").slice() as vec3; + return this.set("shadeColorFactor", ColorUtils.hexToFactor(hex, factor)); + } + + public getShadeMultiplyTexture(): Texture | null { + return this.getRef("shadeMultiplyTexture"); + } + public setShadeMultiplyTexture(texture: Texture | null): this { + return this.setRef("shadeMultiplyTexture", texture, { + channels: R | G | B, + }); + } + public getShadeMultiplyTextureInfo(): TextureInfo | null { + return this.getRef("shadeMultiplyTexture") + ? this.getRef("shadeMultiplyTextureInfo") + : null; + } + + public getShadingShiftFactor(): number { + return this.get("shadingShiftFactor"); + } + public setShadingShiftFactor(shadingShiftFactor: number): this { + return this.set("shadingShiftFactor", shadingShiftFactor); + } + + public getShadingShiftTexture(): Texture | null { + return this.getRef("shadingShiftTexture"); + } + public setShadingShiftTexture(texture: Texture | null): this { + return this.setRef("shadingShiftTexture", texture, { + channels: R | G | B, + }); + } + public getShadingShiftTextureInfo(): TextureInfo | null { + return this.getRef("shadingShiftTexture") + ? this.getRef("shadingShiftTextureInfo") + : null; + } + + public getShadingToonyFactor(): number { + return this.get("shadingToonyFactor"); + } + public setShadingToonyFactor(shadingToonyFactor: number): this { + return this.set("shadingToonyFactor", shadingToonyFactor); + } + + public getGIEqualizationFactor(): number { + return this.get("giEqualizationFactor"); + } + public setGIEqualizationFactor(giEqualizationFactor: number): this { + return this.set("giEqualizationFactor", giEqualizationFactor); + } + + /********************************************************************************************** + * Rim + */ + public getMatcapFactor(): vec3 { + return this.get("matcapFactor"); + } + public setMatcapFactor(matcapFactor: vec3): this { + return this.set("matcapFactor", matcapFactor); + } + public getMatcapHex(): number { + return ColorUtils.factorToHex(this.get("matcapFactor")); + } + public setMatcapHex(hex: number): this { + const factor = this.get("matcapFactor").slice() as vec3; + return this.set("matcapFactor", ColorUtils.hexToFactor(hex, factor)); + } + + public getMatcapTexture(): Texture | null { + return this.getRef("matcapTexture"); + } + public setMatcapTexture(texture: Texture | null): this { + return this.setRef("matcapTexture", texture, { + channels: R | G | B, + }); + } + public getMatcapTextureInfo(): TextureInfo | null { + return this.getRef("matcapTexture") + ? this.getRef("matcapTextureInfo") + : null; + } + + public getParametricRimColorFactor(): vec3 { + return this.get("parametricRimColorFactor"); + } + public setParametricRimColorFactor(parametricRimColorFactor: vec3): this { + return this.set("parametricRimColorFactor", parametricRimColorFactor); + } + public getParametricRimColorHex(): number { + return ColorUtils.factorToHex(this.get("parametricRimColorFactor")); + } + public setParametricRimColorHex(hex: number): this { + const factor = this.get("parametricRimColorFactor").slice() as vec3; + return this.set( + "parametricRimColorFactor", + ColorUtils.hexToFactor(hex, factor) + ); + } + + public getRimMultiplyTexture(): Texture | null { + return this.getRef("rimMultiplyTexture"); + } + public setRimMultiplyTexture(texture: Texture | null): this { + return this.setRef("rimMultiplyTexture", texture, { + channels: R | G | B, + }); + } + public getRimMultiplyTextureInfo(): TextureInfo | null { + return this.getRef("rimMultiplyTexture") + ? this.getRef("rimMultiplyTextureInfo") + : null; + } + + public getRimLightningMixFactor(): number { + return this.get("rimLightingMixFactor"); + } + public setRimLightningMixFactor(rimLightningMixFactor: number): this { + return this.set("rimLightingMixFactor", rimLightningMixFactor); + } + + public getParametricRimFresnelPowerFactor(): number { + return this.get("parametricRimFresnelPowerFactor"); + } + public setParametricRimFresnelPowerFactor( + parametricRimFresnelPowerFactor: number + ): this { + return this.set( + "parametricRimFresnelPowerFactor", + parametricRimFresnelPowerFactor + ); + } + + public getParametricRimLiftFactor(): number { + return this.get("parametricRimLiftFactor"); + } + public setParametricRimLiftFactor(parametricRimLiftFactor: number): this { + return this.set("parametricRimLiftFactor", parametricRimLiftFactor); + } + + /********************************************************************************************** + * Outline + */ + public getOutlineWidthMode(): string { + return this.get("outlineWidthMode"); + } + public setOutlineWidthMode(outlineWidthMode: string) { + return this.set("outlineWidthMode", outlineWidthMode); + } + + public getOutlineWidthFactor(): number { + return this.get("outlineWidthFactor"); + } + public setOutlineWidthFactor(outlineWidthFactor: number): this { + return this.set("outlineWidthFactor", outlineWidthFactor); + } + + public getOutlineWidthMultiplyTexture(): Texture | null { + return this.getRef("outlineWidthMultiplyTexture"); + } + public setOutlineWidthMultiplyTexture(texture: Texture | null): this { + return this.setRef("outlineWidthMultiplyTexture", texture, { + channels: R | G | B, + }); + } + public getOutlineWidthMultiplyTextureInfo(): TextureInfo | null { + return this.getRef("outlineWidthMultiplyTexture") + ? this.getRef("outlineWidthMultiplyTextureInfo") + : null; + } + + public getOutlineColorFactor(): vec3 { + return this.get("outlineColorFactor"); + } + public setOutlineColorFactor(outlineColorFactor: vec3): this { + return this.set("outlineColorFactor", outlineColorFactor); + } + public getOutlineColorHex(): number { + return ColorUtils.factorToHex(this.get("outlineColorFactor")); + } + public setOutlineColorHex(hex: number): this { + const factor = this.get("outlineColorFactor").slice() as vec3; + return this.set("outlineColorFactor", ColorUtils.hexToFactor(hex, factor)); + } + + public getOutlineLightningMixFactor(): number { + return this.get("outlineLightingMixFactor"); + } + public setOutlineLightningMixFactor(outlineLightningMixFactor: number): this { + return this.set("outlineLightingMixFactor", outlineLightningMixFactor); + } + + /********************************************************************************************** + * UV Animation + */ + public getUVAnimationMaskTexture(): Texture | null { + return this.getRef("uvAnimationMaskTexture"); + } + public setUVAnimationMaskTexture(texture: Texture | null): this { + return this.setRef("uvAnimationMaskTexture", texture, { + channels: R | G | B, + }); + } + public getUVAnimationMaskTextureInfo(): TextureInfo | null { + return this.getRef("uvAnimationMaskTexture") + ? this.getRef("uvAnimationMaskTextureInfo") + : null; + } + + public getUVAnimationScrollXSpeedFactor(): number { + return this.get("uvAnimationScrollXSpeedFactor"); + } + public setUVAnimationScrollXSpeedFactor( + uvAnimationScrollXSpeedFactor: number + ): this { + return this.set( + "uvAnimationScrollXSpeedFactor", + uvAnimationScrollXSpeedFactor + ); + } + + public getUVAnimationScrollYSpeedFactor(): number { + return this.get("uvAnimationScrollYSpeedFactor"); + } + public setUVAnimationScrollYSpeedFactor( + uvAnimationScrollYSpeedFactor: number + ): this { + return this.set( + "uvAnimationScrollYSpeedFactor", + uvAnimationScrollYSpeedFactor + ); + } + + public getUVAnimationRotationSpeedFactor(): number { + return this.get("uvAnimationRotationSpeedFactor"); + } + public setUVAnimationSRotationpeedFactor( + uvAnimationRotationSpeedFactor: number + ): this { + return this.set( + "uvAnimationRotationSpeedFactor", + uvAnimationRotationSpeedFactor + ); + } +} diff --git a/packages/extensions/src/vrm/meta-prop.ts b/packages/extensions/src/vrm/meta-prop.ts new file mode 100644 index 000000000..7cf888ab0 --- /dev/null +++ b/packages/extensions/src/vrm/meta-prop.ts @@ -0,0 +1,253 @@ +import { + ExtensionProperty, + IProperty, + Nullable, + PropertyType, + Texture, + TextureChannel, + TextureInfo, +} from "@gltf-transform/core"; +import { VRM0 } from "./VRM0/constants.ts"; +import { VRMC_VRM } from "./VRM1/constants.ts"; + +const { R, G, B } = TextureChannel; + +export type AvatarPermission = + | "onlyAuthor" + | "onlySeparatelyLicensedPerson" + | "everyone"; + +export type CommercialUsage = + | "personalNonProfit" + | "personalProfit" + | "corporation"; + +export type CreditNotation = "required" | "unnecessary"; + +export type Modification = + | "prohibited" + | "allowModification" + | "allowModificationRedistribution"; + +/** + * @see https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_vrm-1.0/meta.md + */ +interface IMetaProp extends IProperty { + name: string; + version: string; + authors: string[]; + copyrightInformation: string; + contactInformation: string; + references: string[]; + thirdPartyLicenses: string; + thumbnailImageTexture: Texture; + thumbnailImageTextureInfo: TextureInfo; + licenseUrl: string; + avatarPermission: AvatarPermission; + allowExcessivelyViolentUsage: boolean; + allowExcessivelySexualUsage: boolean; + commercialUsage: CommercialUsage; + allowPoliticalOrReligiousUsage: boolean; + allowAntisocialOrHateUsage: boolean; + creditNotation: CreditNotation; + allowRedistribution: boolean; + modification: Modification; + otherLicenseUrl: string; +} + +const VRM0NAME = VRM0; +const VRM1NAME = VRMC_VRM; + +export class MetaProp extends ExtensionProperty { + public declare extensionName: typeof VRM0NAME | typeof VRM1NAME; + public declare propertyType: "VRMC_vrm"; + public declare parentTypes: [PropertyType.ROOT]; + + protected init(): void { + this.extensionName = VRM1NAME; + this.propertyType = "VRMC_vrm"; + this.parentTypes = [PropertyType.ROOT]; + } + + protected getDefaults(): Nullable { + return Object.assign(super.getDefaults() as IProperty, { + name: "", + version: "", + authors: [], + copyrightInformation: "", + contactInformation: "", + references: [], + thirdPartyLicenses: "", + thumbnailImageTexture: null, + thumbnailImageTextureInfo: new TextureInfo( + this.graph, + "thumbnailImageTextureInfo" + ), + licenseUrl: "", + avatarPermission: "onlyAuthor" as AvatarPermission, + allowExcessivelyViolentUsage: false, + allowExcessivelySexualUsage: false, + commercialUsage: "personalNonProfit" as CommercialUsage, + allowPoliticalOrReligiousUsage: false, + allowAntisocialOrHateUsage: false, + creditNotation: "required" as CreditNotation, + allowRedistribution: false, + modification: "prohibited" as Modification, + otherLicenseUrl: "", + }); + } + + public getName(): string { + return this.get("name"); + } + public setName(name: string): this { + return this.set("name", name); + } + + public getVersion(): string { + return this.get("version"); + } + public setVersion(version: string): this { + return this.set("version", version); + } + + public getAuthors(): string[] { + return this.get("authors"); + } + public setAuthors(authors: string[]): this { + return this.set("authors", authors); + } + + public getCopyrightInformation(): string { + return this.get("copyrightInformation"); + } + public setCopyrightInformation(copyrightInformation: string): this { + return this.set("copyrightInformation", copyrightInformation); + } + + public getContactInformation(): string { + return this.get("contactInformation"); + } + public setContactInformation(contactInformation: string): this { + return this.set("contactInformation", contactInformation); + } + + public getReferences(): string[] { + return this.get("references"); + } + public setReferences(references: string[]): this { + return this.set("references", references); + } + + public getThirdPartyLicenses(): string { + return this.get("thirdPartyLicenses"); + } + public setThirdPartyLicenses(thirdPartyLicenses: string): this { + return this.set("thirdPartyLicenses", thirdPartyLicenses); + } + + public getThumbnailImageTexture(): Texture | null { + return this.getRef("thumbnailImageTexture"); + } + public setThumbnailImageTexture(texture: Texture | null): this { + return this.setRef("thumbnailImageTexture", texture, { + channels: R | G | B, + }); + } + public getThumbnailImageTextureInfo(): TextureInfo | null { + return this.getRef("thumbnailImageTexture") + ? this.getRef("thumbnailImageTextureInfo") + : null; + } + + public getLicenseUrl(): string { + return this.get("licenseUrl"); + } + public setLicenseUrl(licenseUrl: string): this { + return this.set("licenseUrl", licenseUrl); + } + + public getAvatarPermission(): AvatarPermission { + return this.get("avatarPermission"); + } + public setAvatarPermission(avatarPermission: AvatarPermission): this { + return this.set("avatarPermission", avatarPermission); + } + + public getAllowExcessivelyViolentUsage(): boolean { + return this.get("allowExcessivelyViolentUsage"); + } + public setAllowExcessivelyViolentUsage( + allowExcessivelyViolentUsage: boolean + ): this { + return this.set( + "allowExcessivelyViolentUsage", + allowExcessivelyViolentUsage + ); + } + + public getAllowExcessivelySexualUsage(): boolean { + return this.get("allowExcessivelySexualUsage"); + } + public setAllowExcessivelySexualUsage( + allowExcessivelySexualUsage: boolean + ): this { + return this.set("allowExcessivelySexualUsage", allowExcessivelySexualUsage); + } + + public getCommercialUsage(): CommercialUsage { + return this.get("commercialUsage"); + } + public setCommercialUsage(commercialUsage: CommercialUsage): this { + return this.set("commercialUsage", commercialUsage); + } + + public getAllowPoliticalOrReligiousUsage(): boolean { + return this.get("allowPoliticalOrReligiousUsage"); + } + public setAllowPoliticalOrReligiousUsage( + allowPoliticalOrReligiousUsage: boolean + ): this { + return this.set( + "allowPoliticalOrReligiousUsage", + allowPoliticalOrReligiousUsage + ); + } + + public getAllowAntisocialOrHateUsage(): boolean { + return this.get("allowAntisocialOrHateUsage"); + } + public setAllowAntisocialOrHateUsage( + allowAntisocialOrHateUsage: boolean + ): this { + return this.set("allowAntisocialOrHateUsage", allowAntisocialOrHateUsage); + } + + public getCreditNotation(): CreditNotation { + return this.get("creditNotation"); + } + public setCreditNotation(creditNotation: CreditNotation): this { + return this.set("creditNotation", creditNotation); + } + + public getAllowRedistribution(): boolean { + return this.get("allowRedistribution"); + } + public setAllowRedistribution(allowRedistribution: boolean): this { + return this.set("allowRedistribution", allowRedistribution); + } + + public getModification(): Modification { + return this.get("modification"); + } + public setModification(modification: Modification): this { + return this.set("modification", modification); + } + + public getOtherLicenseUrl(): string { + return this.get("otherLicenseUrl"); + } + public setOtherLicenseUrl(otherLicenseUrl: string): this { + return this.set("otherLicenseUrl", otherLicenseUrl); + } +} From 9ce06105b71beca05584ade0f7543f651159543f Mon Sep 17 00:00:00 2001 From: miramocha <96218694+miramocha@users.noreply.github.com> Date: Sun, 26 Nov 2023 19:11:19 -0500 Subject: [PATCH 2/3] initial code --- .../properties/vrm0-humanoid-human-bone-prop.ts | 4 ++-- .../src/vrm/VRM0/properties/vrm0-humanoid-prop.ts | 4 ++-- .../VRM0/properties/vrm0-material-mtoon-prop.ts | 4 ++-- .../src/vrm/VRM0/properties/vrm0-meta-prop.ts | 4 ++-- .../src/vrm/VRM0/properties/vrm0-vrm-prop.ts | 6 +++--- packages/extensions/src/vrm/VRM0/vrm0-vrm.ts | 14 +++++++------- .../VRM1/properties/vrm1-material-mtoon-prop.ts | 4 ++-- .../src/vrm/VRM1/vrm1-materials-mtoon.ts | 4 ++-- .../extensions/src/vrm/VRM1/vrm1-springbone.ts | 2 +- packages/extensions/src/vrm/VRM1/vrm1-vrm.ts | 2 +- .../extensions/src/vrm/humanoid-human-bone-prop.ts | 2 +- packages/extensions/src/vrm/humanoid-prop.ts | 6 +++--- packages/extensions/src/vrm/material-mtoon-prop.ts | 4 ++-- packages/extensions/src/vrm/meta-prop.ts | 4 ++-- 14 files changed, 32 insertions(+), 32 deletions(-) diff --git a/packages/extensions/src/vrm/VRM0/properties/vrm0-humanoid-human-bone-prop.ts b/packages/extensions/src/vrm/VRM0/properties/vrm0-humanoid-human-bone-prop.ts index 7177cdaf4..e6957b7b0 100644 --- a/packages/extensions/src/vrm/VRM0/properties/vrm0-humanoid-human-bone-prop.ts +++ b/packages/extensions/src/vrm/VRM0/properties/vrm0-humanoid-human-bone-prop.ts @@ -1,5 +1,5 @@ -import { PropertyType as VRMPropertyType } from "../../constants.ts"; -import { HumanoidHumanBoneProp } from "../../humanoid-human-bone-prop.ts"; +import { PropertyType as VRMPropertyType } from "../../constants.js"; +import { HumanoidHumanBoneProp } from "../../humanoid-human-bone-prop.js"; export default class VRM0HumanoidHumanBoneProp extends HumanoidHumanBoneProp { protected init(): void { diff --git a/packages/extensions/src/vrm/VRM0/properties/vrm0-humanoid-prop.ts b/packages/extensions/src/vrm/VRM0/properties/vrm0-humanoid-prop.ts index 3acfc8523..4d49bae30 100644 --- a/packages/extensions/src/vrm/VRM0/properties/vrm0-humanoid-prop.ts +++ b/packages/extensions/src/vrm/VRM0/properties/vrm0-humanoid-prop.ts @@ -1,6 +1,6 @@ import { PropertyType } from "@gltf-transform/core"; -import { VRM0 as NAME } from "../constants.ts"; -import { HumanoidProp } from "../../humanoid-prop.ts"; +import { VRM0 as NAME } from "../constants.js"; +import { HumanoidProp } from "../../humanoid-prop.js"; export default class VRM0HumanoidProp extends HumanoidProp { protected init(): void { diff --git a/packages/extensions/src/vrm/VRM0/properties/vrm0-material-mtoon-prop.ts b/packages/extensions/src/vrm/VRM0/properties/vrm0-material-mtoon-prop.ts index 411fc7640..9d2d270f9 100644 --- a/packages/extensions/src/vrm/VRM0/properties/vrm0-material-mtoon-prop.ts +++ b/packages/extensions/src/vrm/VRM0/properties/vrm0-material-mtoon-prop.ts @@ -1,6 +1,6 @@ import { PropertyType } from "@gltf-transform/core"; -import MaterialMToonProp from "../../material-mtoon-prop.ts"; -import { VRM0 as NAME } from "../constants.ts"; +import MaterialMToonProp from "../../material-mtoon-prop.js"; +import { VRM0 as NAME } from "../constants.js"; export default class VRM0MaterialMToonProp extends MaterialMToonProp { protected init(): void { diff --git a/packages/extensions/src/vrm/VRM0/properties/vrm0-meta-prop.ts b/packages/extensions/src/vrm/VRM0/properties/vrm0-meta-prop.ts index 6871f18cc..07940ffda 100644 --- a/packages/extensions/src/vrm/VRM0/properties/vrm0-meta-prop.ts +++ b/packages/extensions/src/vrm/VRM0/properties/vrm0-meta-prop.ts @@ -1,6 +1,6 @@ import { PropertyType } from "@gltf-transform/core"; -import { MetaProp } from "../../meta-prop.ts"; -import { VRM0 as NAME } from "../constants.ts"; +import { MetaProp } from "../../meta-prop.js"; +import { VRM0 as NAME } from "../constants.js"; export default class VRM0MetaProp extends MetaProp { protected init(): void { diff --git a/packages/extensions/src/vrm/VRM0/properties/vrm0-vrm-prop.ts b/packages/extensions/src/vrm/VRM0/properties/vrm0-vrm-prop.ts index 700da3afd..521a2cdac 100644 --- a/packages/extensions/src/vrm/VRM0/properties/vrm0-vrm-prop.ts +++ b/packages/extensions/src/vrm/VRM0/properties/vrm0-vrm-prop.ts @@ -5,9 +5,9 @@ import { PropertyType, } from "@gltf-transform/core"; import * as VRM0Type from "@pixiv/types-vrm-0.0"; -import { VRM0 as NAME } from "../constants.ts"; -import VRM0MetaProp from "./vrm0-meta-prop.ts"; -import VRM0HumanoidProp from "./vrm0-humanoid-prop.ts"; +import { VRM0 as NAME } from "../constants.js"; +import VRM0MetaProp from "./vrm0-meta-prop.js"; +import VRM0HumanoidProp from "./vrm0-humanoid-prop.js"; interface IVRM0Prop extends IProperty { metaProp: VRM0MetaProp; diff --git a/packages/extensions/src/vrm/VRM0/vrm0-vrm.ts b/packages/extensions/src/vrm/VRM0/vrm0-vrm.ts index c84035808..9e8182a8f 100644 --- a/packages/extensions/src/vrm/VRM0/vrm0-vrm.ts +++ b/packages/extensions/src/vrm/VRM0/vrm0-vrm.ts @@ -6,13 +6,13 @@ import { } from "@gltf-transform/core"; import * as VRM0Type from "@pixiv/types-vrm-0.0"; import * as VRM1Type from "@pixiv/types-vrmc-vrm-1.0"; -import VRM0Prop from "./properties/vrm0-vrm-prop.ts"; -import { VRM0 as NAME } from "./constants.ts"; -import * as VRMConstants from "../constants.ts"; -import VRM0MaterialMToonProp from "./properties/vrm0-material-mtoon-prop.ts"; -import VRM0MetaProp from "./properties/vrm0-meta-prop.ts"; -import VRM0HumanoidProp from "./properties/vrm0-humanoid-prop.ts"; -import VRM0HumanoidHumanBoneProp from "./properties/vrm0-humanoid-human-bone-prop.ts"; +import VRM0Prop from "./properties/vrm0-vrm-prop.js"; +import { VRM0 as NAME } from "./constants.js"; +import * as VRMConstants from "../constants.js"; +import VRM0MaterialMToonProp from "./properties/vrm0-material-mtoon-prop.js"; +import VRM0MetaProp from "./properties/vrm0-meta-prop.js"; +import VRM0HumanoidProp from "./properties/vrm0-humanoid-prop.js"; +import VRM0HumanoidHumanBoneProp from "./properties/vrm0-humanoid-human-bone-prop.js"; export default class VRM0VRM extends Extension { public readonly extensionName = NAME; diff --git a/packages/extensions/src/vrm/VRM1/properties/vrm1-material-mtoon-prop.ts b/packages/extensions/src/vrm/VRM1/properties/vrm1-material-mtoon-prop.ts index 76c869046..39ddd4b9a 100644 --- a/packages/extensions/src/vrm/VRM1/properties/vrm1-material-mtoon-prop.ts +++ b/packages/extensions/src/vrm/VRM1/properties/vrm1-material-mtoon-prop.ts @@ -1,6 +1,6 @@ import { PropertyType } from "@gltf-transform/core"; -import MaterialMToon from "../../material-mtoon-prop.ts"; -import { VRMC_MATERIALS_MTOON as NAME } from "../constants.ts"; +import MaterialMToon from "../../material-mtoon-prop.js"; +import { VRMC_MATERIALS_MTOON as NAME } from "../constants.js"; export default class VRM1MaterialMToon extends MaterialMToon { public static EXTENSION_NAME = NAME; diff --git a/packages/extensions/src/vrm/VRM1/vrm1-materials-mtoon.ts b/packages/extensions/src/vrm/VRM1/vrm1-materials-mtoon.ts index 1fba4150f..816a633e0 100644 --- a/packages/extensions/src/vrm/VRM1/vrm1-materials-mtoon.ts +++ b/packages/extensions/src/vrm/VRM1/vrm1-materials-mtoon.ts @@ -1,6 +1,6 @@ import { Extension, ReaderContext, WriterContext } from "@gltf-transform/core"; -import { VRMC_MATERIALS_MTOON } from "./constants.ts"; -import VRM1MaterialMToonProp from "./properties/vrm1-material-mtoon-prop.ts"; +import { VRMC_MATERIALS_MTOON } from "./constants.js"; +import VRM1MaterialMToonProp from "./properties/vrm1-material-mtoon-prop.js"; const NAME = VRMC_MATERIALS_MTOON; diff --git a/packages/extensions/src/vrm/VRM1/vrm1-springbone.ts b/packages/extensions/src/vrm/VRM1/vrm1-springbone.ts index 5a6f57174..1b44c9cba 100644 --- a/packages/extensions/src/vrm/VRM1/vrm1-springbone.ts +++ b/packages/extensions/src/vrm/VRM1/vrm1-springbone.ts @@ -1,5 +1,5 @@ import { Extension } from "@gltf-transform/core"; -import { VRMC_SPRINGBONE } from "./constants.ts"; +import { VRMC_SPRINGBONE } from "./constants.js"; const NAME = VRMC_SPRINGBONE; diff --git a/packages/extensions/src/vrm/VRM1/vrm1-vrm.ts b/packages/extensions/src/vrm/VRM1/vrm1-vrm.ts index a2d01d19f..0227ae6a3 100644 --- a/packages/extensions/src/vrm/VRM1/vrm1-vrm.ts +++ b/packages/extensions/src/vrm/VRM1/vrm1-vrm.ts @@ -1,6 +1,6 @@ import { Extension } from "@gltf-transform/core"; // import * as VRM1Def from "@pixiv/types-vrmc-vrm-1.0"; -import { VRMC_VRM } from "./constants.ts"; +import { VRMC_VRM } from "./constants.js"; const NAME = VRMC_VRM; diff --git a/packages/extensions/src/vrm/humanoid-human-bone-prop.ts b/packages/extensions/src/vrm/humanoid-human-bone-prop.ts index 07d4c36da..1f817f1cd 100644 --- a/packages/extensions/src/vrm/humanoid-human-bone-prop.ts +++ b/packages/extensions/src/vrm/humanoid-human-bone-prop.ts @@ -1,5 +1,5 @@ import { IProperty, Nullable, Property, Node } from "@gltf-transform/core"; -import { PropertyType as VRMPropertyType } from "./constants.ts"; +import { PropertyType as VRMPropertyType } from "./constants.js"; export interface IHumanoidHumanBoneProp extends IProperty { node: Node; diff --git a/packages/extensions/src/vrm/humanoid-prop.ts b/packages/extensions/src/vrm/humanoid-prop.ts index 9b8c491f3..80b7de50d 100644 --- a/packages/extensions/src/vrm/humanoid-prop.ts +++ b/packages/extensions/src/vrm/humanoid-prop.ts @@ -5,9 +5,9 @@ import { PropertyType, } from "@gltf-transform/core"; import * as VRM1Def from "@pixiv/types-vrmc-vrm-1.0"; -import { VRM0 as VRM0NAME } from "./VRM0/constants.ts"; -import { VRMC_VRM as VRM1NAME } from "./VRM1/constants.ts"; -import { HumanoidHumanBoneProp } from "./humanoid-human-bone-prop.ts"; +import { VRM0 as VRM0NAME } from "./VRM0/constants.js"; +import { VRMC_VRM as VRM1NAME } from "./VRM1/constants.js"; +import { HumanoidHumanBoneProp } from "./humanoid-human-bone-prop.js"; export interface IHumanoidProp extends IProperty { hips: HumanoidHumanBoneProp; diff --git a/packages/extensions/src/vrm/material-mtoon-prop.ts b/packages/extensions/src/vrm/material-mtoon-prop.ts index 2bb0b1d2c..6e3dbcad4 100644 --- a/packages/extensions/src/vrm/material-mtoon-prop.ts +++ b/packages/extensions/src/vrm/material-mtoon-prop.ts @@ -9,8 +9,8 @@ import { vec3, ColorUtils, } from "@gltf-transform/core"; -import { VRM0 as VRM0NAME } from "./VRM0/constants.ts"; -import { VRMC_MATERIALS_MTOON as VRM1NAME } from "./VRM1/constants.ts"; +import { VRM0 as VRM0NAME } from "./VRM0/constants.js"; +import { VRMC_MATERIALS_MTOON as VRM1NAME } from "./VRM1/constants.js"; const { R, G, B } = TextureChannel; diff --git a/packages/extensions/src/vrm/meta-prop.ts b/packages/extensions/src/vrm/meta-prop.ts index 7cf888ab0..00517b9d9 100644 --- a/packages/extensions/src/vrm/meta-prop.ts +++ b/packages/extensions/src/vrm/meta-prop.ts @@ -7,8 +7,8 @@ import { TextureChannel, TextureInfo, } from "@gltf-transform/core"; -import { VRM0 } from "./VRM0/constants.ts"; -import { VRMC_VRM } from "./VRM1/constants.ts"; +import { VRM0 } from "./VRM0/constants.js"; +import { VRMC_VRM } from "./VRM1/constants.js"; const { R, G, B } = TextureChannel; From b9062ff8fbb027307300f9b777e1397bb87e0f4d Mon Sep 17 00:00:00 2001 From: miramocha <96218694+miramocha@users.noreply.github.com> Date: Sun, 26 Nov 2023 19:25:27 -0500 Subject: [PATCH 3/3] add dependency --- packages/extensions/package.json | 7 +++++-- .../extensions/src/vrm/VRM0/properties/vrm0-vrm-prop.ts | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/extensions/package.json b/packages/extensions/package.json index 2d67305f1..036908821 100644 --- a/packages/extensions/package.json +++ b/packages/extensions/package.json @@ -37,7 +37,10 @@ ], "dependencies": { "@gltf-transform/core": "^3.9.0", - "ktx-parse": "^0.6.0" + "ktx-parse": "^0.6.0", + "@pixiv/types-vrm-0.0": "2.0.6", + "@pixiv/types-vrmc-materials-mtoon-1.0": "2.0.6", + "@pixiv/types-vrmc-vrm-1.0": "2.0.6" }, "files": [ "dist/", @@ -46,4 +49,4 @@ "package.json" ], "gitHead": "405359aa647acc95d47f1da9ac11cb83060ab482" -} +} \ No newline at end of file diff --git a/packages/extensions/src/vrm/VRM0/properties/vrm0-vrm-prop.ts b/packages/extensions/src/vrm/VRM0/properties/vrm0-vrm-prop.ts index 521a2cdac..ea7d9a4b2 100644 --- a/packages/extensions/src/vrm/VRM0/properties/vrm0-vrm-prop.ts +++ b/packages/extensions/src/vrm/VRM0/properties/vrm0-vrm-prop.ts @@ -36,7 +36,7 @@ export default class VRM0Prop extends ExtensionProperty { protected getDefaults(): Nullable { return Object.assign(super.getDefaults() as IProperty, { metaProp: null, - exporterVersion: "VRM Sparks 0.0", + exporterVersion: "GLTF Transform", humanoidProp: null, serializedHumanoid: "{}", serializedFirstPerson: "{}",