Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

blendshape restriction #188

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions src/library/characterManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ export class CharacterManager {
/**
* remove blendshape trait
* @param {string} traitGroupID
* @param {string} blendshapeGroupId
* @param {string|null} blendshapeGroupId
* @returns
*/
removeBlendShapeTrait(groupTraitID, blendShapeGroupId){
Expand Down Expand Up @@ -630,6 +630,20 @@ export class CharacterManager {
return isAllowAggregated.length? isAllowAggregated:[{allowed:true,blocking:{}}]
}

/**
* INTERNAL: Check Blendshape restrictions;
* @param {} groupTraitID
*/
_checkBlendshapeRestrictions(groupTraitID){
for( const trait in this.avatar){
const p = this.manifestData.manifestRestrictions.restrictionMaps[trait]?.isReverseBlendshapeTraitAllowed(groupTraitID)
if(!p.allowed && p.blockingTrait){
console.warn(`Trait with name: Blendshapes of ${trait} is not allowed to be loaded with ${groupTraitID}`)
this.removeBlendShapeTrait(trait,null)
}
}
}

/**
* INTERNAL: Checks and Remove blocking traits; Used when loading a new trait
* @param {string} groupTraitID
Expand All @@ -639,6 +653,8 @@ export class CharacterManager {
const isAllowed = this._getTraitAllowedRules(groupTraitID,traitID)

if(isAllowed[0].allowed){
// check if blendshape restrictions are met
this._checkBlendshapeRestrictions(groupTraitID)
return
}
for(const rule of isAllowed){
Expand Down Expand Up @@ -1045,7 +1061,7 @@ export class CharacterManager {
/**
*
* @param {string} traitGroupID
* @param {string} blendshapeGroupId
* @param {string|null} blendshapeGroupId
* @param {string|null} blendshapeTraitId
* @returns
*/
Expand All @@ -1058,6 +1074,15 @@ export class CharacterManager {
if(!currentTrait.blendShapeTraitsInfo){
currentTrait.blendShapeTraitsInfo = {};
}

if(!blendshapeGroupId){
for(const k in currentTrait.blendShapeTraitsInfo){
// Deactivate the current blendshape trait
this.toggleBinaryBlendShape(currentTrait.model, currentTrait.blendShapeTraitsInfo[k], false);
}
return
}

if(currentTrait.blendShapeTraitsInfo[blendshapeGroupId]){
// Deactivate the current blendshape trait
this.toggleBinaryBlendShape(currentTrait.model, currentTrait.blendShapeTraitsInfo[blendshapeGroupId], false);
Expand Down
49 changes: 45 additions & 4 deletions src/library/manifestRestrictions.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export class ManifestRestrictions {
* @type {Record<string, {
* restrictedTraits: string[];
* restrictedTypes: string[];
* restrictedBlendshapes: string[];
* }>;}
*/
traitRestrictions
Expand Down Expand Up @@ -50,8 +51,9 @@ export class ManifestRestrictions {
const log = []
for(const r in this.restrictionMaps){
const restriction = this.restrictionMaps[r]
restriction.restrictedTypes.size && log.push(`Trait: ${restriction.group.trait} is restrciting traits ${Array.from(restriction.restrictedTraits.values()).join(', ')}`)
restriction.restrictedTypes.size && log.push(`Trait: ${restriction.group.trait} also restricts types ${Array.from(restriction.restrictedTypes.values()).join(', ')}`)
restriction.restrictedTraits.size && console.log(`Trait: ${restriction.group.trait} is restrciting ${Array.from(restriction.restrictedTraits.values()).join(', ')}`)
restriction.restrictedTypes.size && console.log(`Trait: ${restriction.group.trait} also restricts types ${Array.from(restriction.restrictedTypes.values()).join(', ')}`)
restriction.restrictedBlendshapes.size && console.log(`Trait: ${restriction.group.trait} has blendshape restrictions on trait ${Array.from(restriction.restrictedBlendshapes.values()).join(', ')}`)
}
this.itemRestrictions.forEach((v,k)=>{
log.push(`Item ${k} is restricting item ${Array.from(v.values()).join(', ')}`)
Expand Down Expand Up @@ -176,16 +178,25 @@ export class ManifestRestrictions {
* @type {Record<string, {
* restrictedTraits: string[];
* restrictedTypes: string[];
* restrictedBlendshapes: string[];
*}>}
*/
const traitRes = {}
if (this.traitRestrictions) {
for (const prop in this.traitRestrictions) {
if (traitRes[prop] == null) {
traitRes[prop] = { restrictedTraits: [], restrictedTypes: [] }
traitRes[prop] = { restrictedTraits: [], restrictedTypes: [], restrictedBlendshapes: [] }
}
traitRes[prop].restrictedTraits = getAsArray(this.traitRestrictions[prop].restrictedTraits).filter((t) => !!t);
traitRes[prop].restrictedTraits = getAsArray(this.traitRestrictions[prop].restrictedTraits).map((t)=>{
if(!this.manifestData.requiredTraits.includes(t)){
console.warn(`A required trait cannot be a restricted trait. This is because trait A can remove required trait B when A is selected.`)
return t
}else{
return null
}
}).filter((t) => !!t)
traitRes[prop].restrictedTypes = getAsArray(this.traitRestrictions[prop].restrictedTypes).filter((t) => !!t);
traitRes[prop].restrictedBlendshapes = getAsArray(this.traitRestrictions[prop].restrictedBlendshapes).filter((t) => !!t);
}
}
this.traitRestrictions = traitRes
Expand Down Expand Up @@ -229,6 +240,11 @@ export class TraitRestriction {
*/
restrictedTypes

/**
* @type {Set}
*/
restrictedBlendshapes

/**
*
* @param {ManifestRestrictions} manifestRestrictions
Expand All @@ -240,6 +256,7 @@ export class TraitRestriction {

this.restrictedTraits = new Set(this.manifestRestrictions.traitRestrictions[group.trait]?.restrictedTraits || []);
this.restrictedTypes = new Set(this.manifestRestrictions.traitRestrictions[group.trait]?.restrictedTypes || []);
this.restrictedBlendshapes = new Set(this.manifestRestrictions.traitRestrictions[group.trait]?.restrictedBlendshapes || []);

/**
* Check if the current trait is restricting another trait, if so add the current trait to the restrictedTraits list of the other trait
Expand Down Expand Up @@ -377,4 +394,28 @@ export class TraitRestriction {
blockingItemId:isReverseItemAllowed.blockingItemId
}}
}

/**
*
* @param {string} traitId
* @returns
*/
isBlendshapeOfTraitAllowed = (traitId) => {
return !this.restrictedBlendshapes.has(traitId);
}

/**
* Check whether this trait restriction is allowed by target trait
* @param {string} targetTrait
* @returns {TraitRestrictionResult}
*/
isReverseBlendshapeTraitAllowed = (targetTrait) => {
const restriction = this.manifestRestrictions.restrictionMaps[targetTrait];
if (restriction) {
const isAllowed = restriction.isBlendshapeOfTraitAllowed(this.traitId)
return {allowed:isAllowed, blockingTrait: isAllowed?undefined:this.traitId};
}

return {allowed:true, blockingTrait: undefined};
}
}
4 changes: 2 additions & 2 deletions src/library/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { CullHiddenFaces, DisposeCullMesh } from './cull-mesh.js';
import { combine } from "./merge-geometry";
import { VRMLoaderPlugin, VRMUtils } from '@pixiv/three-vrm';
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"
import { VRMHumanBoneName, VRMHumanBoneParentMap } from "@pixiv/three-vrm";
import { VRMHumanBoneName } from "@pixiv/three-vrm";

export function getAsArray(target) {
if (target == null) return []
if (target == null || target == undefined) return []
return Array.isArray(target) ? target : [target]
}

Expand Down