Files
2024-12-09 23:37:17 +01:00

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;
},
}