add morph to head

This commit is contained in:
lo-th
2024-12-01 11:41:13 +01:00
parent 0ef4fef730
commit b0cab1925b
4 changed files with 159 additions and 8 deletions
+15 -8
View File
@@ -14,6 +14,7 @@ import { BrightnessContrastShader } from './lib/jsm/shaders/BrightnessContrastSh
import { Outline, Inline, BlackAll, sobelShader, thresholdShader } from "./lib/Toon.js";
import { Hub } from "./lib/Hub.js";
import { Files } from "./lib/Files.js";
import { Tools } from "./lib/Tools.js";
// Class ThreeCanvas
export class ThreeCanvas {
@@ -274,6 +275,8 @@ export class ThreeCanvas {
clear(b){
Tools.reset();
if( this.model ) this.scene.remove(this.model);
this.helper.children = [];
if(b) this.render();
@@ -378,6 +381,15 @@ export class ThreeCanvas {
const model = glb.scene || glb.scenes[0];
const clips = glb.animations || [];
// Apply automorph to model //!
// Convention model name is ModelNale__M__TypeOfMorph
Tools.autoMorph( model );
// active shadow
Tools.autoShadow( model );
model.updateMatrixWorld();
let b0 = new THREE.BoxHelper( model, 0x201924 );
@@ -389,7 +401,9 @@ export class ThreeCanvas {
const radius = b0.geometry.boundingSphere.radius;
const center = box.getCenter(new THREE.Vector3());
//console.log( radius)
// test morph
//console.log( Tools.MorphModel )
//Tools.setMorph(Tools.MorphModel.face,'Smile_Open', 1)
let lightpos = center.clone().add( new THREE.Vector3(-radius*0.3,radius*2, radius) )
@@ -397,13 +411,6 @@ export class ThreeCanvas {
let near = radius*0.5;
let far = radius * 4;
model.traverse( ( child ) => {
if ( child.isMesh ){
child.receiveShadow = true;
child.castShadow = true;
}
})
this.scene.add(model);
this.model = model;
Binary file not shown.
+138
View File
@@ -0,0 +1,138 @@
import {
Float32BufferAttribute
} from './three.module.js';
export const Tools = {
MorphModel:{},
reset:() => {
Tools.MorphModel = {}
},
getMesh:( scene ) => {
let meshs = {};
scene.traverse( ( child ) => {
if ( child.isMesh ) meshs[ child.name ] = child;
})
return meshs;
},
autoShadow:( scene ) => {
scene.traverse( ( child ) => {
if ( child.isMesh ){
child.receiveShadow = true;
child.castShadow = true;
}
})
},
setMorph:( obj, name, value )=>{
if(!obj.morphTargetInfluences) return
if(obj.morphTargetDictionary[name] === undefined ) return
obj.morphTargetInfluences[ obj.morphTargetDictionary[name] ] = value;
},
autoMorph: ( model, normal = true, relative = false ) => {
const meshs = Tools.getMesh( model );
let morph = {};
let tmpMesh = [];
model.traverse( ( node ) => {
if ( node.isMesh && node.name.search('__M__') !== -1){
morph[ node.name ] = node.geometry;
tmpMesh.push(node);
}
})
let oName, tName, target, id, g, gm, j, dp, dn, ar, m;
for ( let name in morph ){
oName = name.substring( 0, name.indexOf('__') )
tName = name.substring( name.lastIndexOf('__') + 2 );
target = meshs[ oName ];
if(!Tools.MorphModel[oName]){
Tools.MorphModel[oName] = target;
/*target.prototype.setMorph = function(name, value){
if(!this.morphTargetInfluences) return
if(this.morphTargetDictionary[name] === undefined ) return
this.morphTargetInfluences[ this.morphTargetDictionary[name] ] = value;
}*/
}
if( target ){
if(!target.userData.morph) target.userData.morph = []
g = target.geometry;
gm = morph[name];
g.morphTargetsRelative = relative;
if( g.attributes.position.count === gm.attributes.position.count ){
if( !g.morphAttributes.position ){
g.morphAttributes.position = [];
if( normal ) g.morphAttributes.normal = [];
target.morphTargetInfluences = [];
target.morphTargetDictionary = {};
}
id = g.morphAttributes.position.length;
// position
if( relative ){
j = gm.attributes.position.array.length;
ar = [];
while(j--) ar[j] = gm.attributes.position.array[j] - g.attributes.position.array[j]
dp = new Float32BufferAttribute( ar, 3 );
} else {
dp = new Float32BufferAttribute( gm.attributes.position.array, 3 );
}
g.morphAttributes.position.push( dp );
// normal
if( normal ){
dn = new Float32BufferAttribute( gm.attributes.normal.array, 3 );
g.morphAttributes.normal.push( dn );
}
target.morphTargetInfluences.push(0)
target.morphTargetDictionary[ tName ] = id;
target.userData.morph.push(tName);
} else {
console.warn( 'Morph '+ tName + ' target is no good on ' + target.name )
}
}
}
morph = {}
// claer garbege
j = tmpMesh.length
while(j--){
m = tmpMesh[j]
if( m.parent ) m.parent.remove( m );
if( m.geometry ) m.geometry.dispose()
//if( m.material ) m.material.dispose()
}
},
}
File diff suppressed because one or more lines are too long