add morph to head
This commit is contained in:
+15
-8
@@ -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
@@ -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
Reference in New Issue
Block a user