refactoring meshUtils, added sceneScale, #74
This commit is contained in:
+129
-126
@@ -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 }
|
||||
Reference in New Issue
Block a user