refactoring meshUtils, added sceneScale, #74

This commit is contained in:
2026-03-24 20:25:50 +02:00
parent 0928ef8999
commit 008cc428d4
19 changed files with 199 additions and 189 deletions
+129 -126
View File
@@ -1,134 +1,137 @@
import { Box3, Vector3, Group } from "three";
import { GameEngine } from "./GameEngine";
function assignParams(mesh, params){
['scale', 'rotation', 'position'].forEach(p=>params[p] && mesh[p].fromArray(params[p]));
[
'visible', 'name', 'fontSize', 'color', 'lineHeight',
'maxWidth', 'anchorX', 'anchorY', 'outlineColor', 'outlineWidth', 'textAlign'
].forEach(p=>{
if (params[p]!==undefined) mesh[p] = params[p];
});
}
function assignMaterial(mesh, params){
if (params.name && params.material){
//let mp = params.material.metalness ? new MeshStandardMaterial(params.material) : new MeshBasicMaterial(params.material)
Object.assign(mesh.material, params.material)
if (params.dm){
GameEngine.loadTexture(params.dm, params.path, undefined, [mesh.material, 'map'])
// var dm = new TextureLoader().setPath(params.path).load(params.dm);
// mesh.material.map = dm;
}
if (params.nm){
GameEngine.loadTexture(params.nm, params.path, undefined, [mesh.material, 'normalMap'])
//mesh.material.normalMap = new TextureLoader().setPath(params.path).load(params.nm);
}
if (params.em) {
GameEngine.loadTexture(params.em, params.path, undefined, [mesh.material, 'emissiveMap'])
//mesh.material.emissiveMap = new TextureLoader().setPath(params.path).load(params.em);
}
//mesh.material = mp;
mesh.material.needsUpdate = true;
class MeshUtils {
constructor(engine) {
this.engine = engine;
}
}
function getBoundingBox(object){
return new Box3().setFromObject(object);
}
function getBoundingBoxSize(bb){
return new Vector3(bb.max.x - bb.min.x, bb.max.y - bb.min.y, bb.max.z - bb.min.z);
}
function getBoundingBoxMaxLength(bb){
let size = getBoundingBoxSize(bb)
return Math.max(size.x, size.y, size.z)
}
function getBoundingBoxCenterPoint(bb, relativeTo){
relativeTo = relativeTo || new Vector3(0,0,0)
let size = getBoundingBoxSize(bb)
return new Vector3(
bb.min.x + (size.x)/2 - relativeTo.x,
bb.min.y + (size.y)/2 - relativeTo.y,
bb.min.z + (size.z)/2 - relativeTo.z
)
}
function autoScale(object, mk = 1) {
if (mk === null) return;
let bb = getBoundingBox(object);
let k = getBoundingBoxMaxLength(bb);
object.scale.multiplyScalar(mk / k);
}
function wrapInGroup(object){
if (object.isWrapper) return object;
let group = new Group();
group.userData.bbox = getBoundingBox(object);
group.add(object);
group.userData.object = object;
group.isWrapper = true;
return group;
}
function centerOrigin(object){
let group = wrapInGroup(object);
let position = getBoundingBoxCenterPoint(group.userData.bbox, object.position).negate();
object.position.copy(position)
return group;
}
function bottomOrigin(object){
let group = centerOrigin(object);
group.userData.object.position.y = -group.userData.bbox.min.y
return group;
}
function clearObject(o){
let disposables = []
o.traverse(object => {
if (object.isMesh) {
disposables.push(object);
assignParams(mesh, params){
['scale', 'rotation', 'position'].forEach(p=>params[p] && mesh[p].fromArray(params[p]));
[
'visible', 'name', 'fontSize', 'color', 'lineHeight',
'maxWidth', 'anchorX', 'anchorY', 'outlineColor', 'outlineWidth', 'textAlign'
].forEach(p=>{
if (params[p]!==undefined) mesh[p] = params[p];
});
}
assignMaterial(mesh, params){
if (params.name && params.material){
//let mp = params.material.metalness ? new MeshStandardMaterial(params.material) : new MeshBasicMaterial(params.material)
Object.assign(mesh.material, params.material)
if (params.dm){
this.engine.loadTexture(params.dm, params.path, undefined, [mesh.material, 'map'])
// var dm = new TextureLoader().setPath(params.path).load(params.dm);
// mesh.material.map = dm;
}
if (params.nm){
this.engine.loadTexture(params.nm, params.path, undefined, [mesh.material, 'normalMap'])
//mesh.material.normalMap = new TextureLoader().setPath(params.path).load(params.nm);
}
if (params.em) {
this.engine.loadTexture(params.em, params.path, undefined, [mesh.material, 'emissiveMap'])
//mesh.material.emissiveMap = new TextureLoader().setPath(params.path).load(params.em);
}
//mesh.material = mp;
mesh.material.needsUpdate = true;
}
if (object.isLight){
//console.log('Disposeing light', object)
object.dispose();
object.shadow?.dispose();
object.shadow?.map?.dispose();
}
if (object.userData?._io){
object.userData._io.dispose?.();
delete object.userData._io;
}
});
disposables.forEach(object=>{
object.removeFromParent();
object.geometry.dispose();
if (object.material.isMaterial) {
clearMaterial(object.material)
} else {
for (const material of object.material) clearMaterial(material)
}
})
o.clear();
}
function clearMaterial(material) {
material.dispose();
for (const key of Object.keys(material)) {
const value = material[key]
if (value && typeof value == 'object' && 'minFilter' in value) {
//console.log('Disposing', value.name, this.renderer.info.memory.textures );
value.dispose();
//console.log('Disposed', value.name, this.renderer.info.memory.textures );
}
getBoundingBox(object){
let bb = new Box3().setFromObject(object);
bb.min.multiplyScalar(1 / this.engine.scale);
bb.max.multiplyScalar(1 / this.engine.scale);
return bb;
}
getBoundingBoxSize(bb){
return new Vector3(bb.max.x - bb.min.x, bb.max.y - bb.min.y, bb.max.z - bb.min.z);
}
getBoundingBoxMaxLength(bb){
let size = this.getBoundingBoxSize(bb)
return Math.max(size.x, size.y, size.z)
}
getBoundingBoxCenterPoint(bb, relativeTo){
relativeTo = relativeTo || new Vector3(0,0,0)
let size = this.getBoundingBoxSize(bb)
return new Vector3(
bb.min.x + (size.x)/2 - relativeTo.x,
bb.min.y + (size.y)/2 - relativeTo.y,
bb.min.z + (size.z)/2 - relativeTo.z
)
}
autoScale(object, mk = 1) {
if (mk === null) return;
let bb = this.getBoundingBox(object);
let k = this.getBoundingBoxMaxLength(bb);
object.scale.multiplyScalar(mk / k);
}
wrapInGroup(object){
if (object.isWrapper) return object;
let group = new Group();
group.userData.bbox = this.getBoundingBox(object);
group.add(object);
group.userData.object = object;
group.isWrapper = true;
return group;
}
centerOrigin(object){
let group = this.wrapInGroup(object);
let position = this.getBoundingBoxCenterPoint(group.userData.bbox, object.position).negate();
object.position.copy(position)
return group;
}
bottomOrigin(object){
let group = this.centerOrigin(object);
group.userData.object.position.y = -group.userData.bbox.min.y
return group;
}
clearObject(o){
let disposables = []
o.traverse(object => {
if (object.isMesh) {
disposables.push(object);
}
if (object.isLight){
//console.log('Disposeing light', object)
object.dispose();
object.shadow?.dispose();
object.shadow?.map?.dispose();
}
if (object.userData?._io){
object.userData._io.dispose?.();
delete object.userData._io;
}
});
disposables.forEach(object=>{
object.removeFromParent();
object.geometry.dispose();
if (object.material.isMaterial) {
this.clearMaterial(object.material)
} else {
for (const material of object.material) this.clearMaterial(material)
}
})
o.clear();
}
clearMaterial(material) {
material.dispose();
for (const key of Object.keys(material)) {
const value = material[key]
if (value && typeof value == 'object' && 'minFilter' in value) {
//console.log('Disposing', value.name, this.renderer.info.memory.textures );
value.dispose();
//console.log('Disposed', value.name, this.renderer.info.memory.textures );
}
}
}
}
export {
assignParams, assignMaterial, autoScale, centerOrigin, wrapInGroup, bottomOrigin,
getBoundingBox, getBoundingBoxSize, getBoundingBoxMaxLength, getBoundingBoxCenterPoint,
clearObject, clearMaterial
}
export { MeshUtils }