167 lines
4.2 KiB
JavaScript
167 lines
4.2 KiB
JavaScript
import {
|
|
Float32BufferAttribute
|
|
} from './three.module.js';
|
|
|
|
|
|
export const Tools = {
|
|
|
|
MorphModel:{},
|
|
SkinModel:{},
|
|
|
|
reset:() => {
|
|
Tools.MorphModel = {};
|
|
Tools.SkinModel = {};
|
|
},
|
|
|
|
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;
|
|
}
|
|
})
|
|
|
|
},
|
|
|
|
// SKINNING
|
|
|
|
autoSkinning( model ){
|
|
|
|
let haveSkinning = false;
|
|
|
|
model.traverse( ( child ) => {
|
|
if ( child.isMesh ){
|
|
if(child.skeleton){
|
|
haveSkinning = true;
|
|
if(child.name!=='Head')Tools.SkinModel[child.name] = child;
|
|
|
|
}
|
|
}
|
|
})
|
|
|
|
return haveSkinning;
|
|
|
|
},
|
|
|
|
|
|
// MORPH
|
|
|
|
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 ) => {
|
|
|
|
let haveMorph = 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[tName] = 0;
|
|
haveMorph = true;
|
|
|
|
|
|
} 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()
|
|
|
|
}
|
|
|
|
return haveMorph;
|
|
|
|
},
|
|
|
|
} |