refactoring meshUtils, added sceneScale, #74
This commit is contained in:
@@ -22,7 +22,6 @@
|
||||
|
||||
<script>
|
||||
import { GameEngine } from '@/lib/GameEngine.js';
|
||||
import { autoScale } from '@/lib/MeshUtils';
|
||||
let engine = null;
|
||||
|
||||
export default{
|
||||
@@ -81,7 +80,7 @@ export default{
|
||||
this.animations = gltf.animations.map(a => ({
|
||||
name: a.name, id: a.uuid
|
||||
}));
|
||||
autoScale(gltf.scene);
|
||||
engine.meshUtils.autoScale(gltf.scene);
|
||||
let bb = new engine.$.Box3().setFromObject(gltf.scene);
|
||||
engine.camera.position.set(bb.max.x, bb.max.y, bb.max.z*3);
|
||||
engine.orbitControls.target.set((bb.max.x + bb.min.x) / 2, (bb.max.y + bb.min.y) / 2, (bb.max.z + bb.min.z) / 2)
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { bottomOrigin } from "@/lib/MeshUtils";
|
||||
class CharacterObject{
|
||||
constructor(engine, data){
|
||||
return new Promise(async(resolve, reject)=>{
|
||||
this.source = await engine.load(data.$go.asset.name);
|
||||
this.object = bottomOrigin(this.source.scene);
|
||||
this.object = engine.meshUtils.bottomOrigin(this.source.scene);
|
||||
resolve(this);
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Color, Group, DoubleSide, RepeatWrapping, MeshStandardMaterial, VideoTexture } from "three"
|
||||
import { EventManager } from '@/lib/EventManager';
|
||||
import { centerOrigin, clearMaterial, clearObject } from "@/lib/MeshUtils";
|
||||
import Utils from "#/app/Utils";
|
||||
|
||||
class ClassicPuzzle extends EventManager {
|
||||
@@ -100,11 +99,11 @@ class ClassicPuzzle extends EventManager {
|
||||
done0.position.set(0,0,0);
|
||||
engine.draggable.remove(done0)
|
||||
container.add(dragZone);
|
||||
this.object = centerOrigin(container);
|
||||
this.object = engine.meshUtils.centerOrigin(container);
|
||||
this.dispose = () => {
|
||||
//console.log('disposing!!!!!!!')
|
||||
clearMaterial(defaultMaterial);
|
||||
clearObject(gltf.scene);
|
||||
engine.meshUtils.clearMaterial(defaultMaterial);
|
||||
engine.meshUtils.clearObject(gltf.scene);
|
||||
super.dispose();
|
||||
}
|
||||
resolve(this);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { getBoundingBox, getBoundingBoxCenterPoint, getBoundingBoxMaxLength, centerOrigin } from "@/lib/MeshUtils";
|
||||
import { EventManager } from '@/lib/EventManager';
|
||||
|
||||
class GenericObject extends EventManager{
|
||||
@@ -7,7 +6,7 @@ class GenericObject extends EventManager{
|
||||
super();
|
||||
return new Promise(async(resolve, reject)=>{
|
||||
this.source = await engine.load(data.$go.asset.name);
|
||||
this.object = centerOrigin(this.source.scene)
|
||||
this.object = engine.meshUtils.bottomOrigin(this.source.scene)
|
||||
|
||||
if (!data.exclude){
|
||||
engine.clickable.add(this.object, async e=>{
|
||||
@@ -17,9 +16,9 @@ class GenericObject extends EventManager{
|
||||
if (this.object._hud ){
|
||||
engine.dashboard.detach(this.object);
|
||||
}else{
|
||||
let bb = getBoundingBox(this.object);
|
||||
let scale = 0.5 * engine.dashboard.height/getBoundingBoxMaxLength(bb);
|
||||
let position = getBoundingBoxCenterPoint(bb, this.object.position).multiplyScalar(scale).negate()
|
||||
let bb = engine.meshUtils.getBoundingBox(this.object);
|
||||
let scale = 0.5 * engine.dashboard.height/engine.meshUtils.getBoundingBoxMaxLength(bb);
|
||||
let position = engine.meshUtils.getBoundingBoxCenterPoint(bb, this.object.position).multiplyScalar(scale).negate()
|
||||
|
||||
let placement = {
|
||||
quaternion: { x:0, y:0, z:0, w:0 },
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Vector3, AnimationMixer } from "three";
|
||||
import { assignMaterial } from "@/lib/MeshUtils";
|
||||
import { AnimationMixer } from "three";
|
||||
|
||||
class GltfObject {
|
||||
constructor(engine, obj) {
|
||||
@@ -13,7 +12,7 @@ class GltfObject {
|
||||
}
|
||||
});
|
||||
|
||||
assignMaterial(gltfObj, obj);
|
||||
engine.meshUtils.assignMaterial(gltfObj, obj);
|
||||
if (gltf.animations && gltf.animations.length) {
|
||||
let mixer = new AnimationMixer(gltfObj);
|
||||
engine.mixers.push(mixer);
|
||||
|
||||
@@ -19,7 +19,6 @@ import { SingleQuestion } from "./SingleQuestion";
|
||||
import { MazeQuizGame } from "./MazeQuizGame/MazeQuizGame";
|
||||
import { Particles } from "./Particles";
|
||||
import { SceneSwitcher } from "./SceneSwitcher";
|
||||
import { assignParams, wrapInGroup, getBoundingBoxMaxLength } from "@/lib/MeshUtils";
|
||||
import { GameEngine } from "@/lib/GameEngine";
|
||||
|
||||
const InteractiveObjectsImports = {
|
||||
@@ -79,11 +78,11 @@ class InteractiveObject extends EventManager{
|
||||
break;
|
||||
}
|
||||
if (obj.shouldBeLocked){
|
||||
this.object = wrapInGroup(this.object)
|
||||
this.object = engine.meshUtils.wrapInGroup(this.object)
|
||||
this.activator = new (obj.activationType == 'unlock' ? LockActivator : VisibilityActivator)(engine, this.object);
|
||||
this.activator.deactivate();
|
||||
}
|
||||
assignParams(this.object, obj);
|
||||
engine.meshUtils.assignParams(this.object, obj);
|
||||
if (obj.motion){
|
||||
engine.motionQueue.add({
|
||||
o: this.object, ...obj.motion
|
||||
@@ -124,7 +123,7 @@ class LockActivator{
|
||||
transparent: true, opacity:1, color: 0xaaaaaa
|
||||
})
|
||||
constructor(engine, group){
|
||||
const bckGeometry = new SphereGeometry(getBoundingBoxMaxLength(group.userData.bbox)/2,8,8)
|
||||
const bckGeometry = new SphereGeometry(engine.meshUtils.getBoundingBoxMaxLength(group.userData.bbox)/2,8,8)
|
||||
const bckMesh = new Mesh(bckGeometry, LockActivator.materialLocked);
|
||||
bckMesh.visible = false;
|
||||
group.add(bckMesh)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Group, Vector3, Matrix4, Quaternion, RepeatWrapping, Vector2} from 'three';
|
||||
import { InteractiveObject } from '../InteractiveObject';
|
||||
import { getBoundingBox, getBoundingBoxSize } from '@/lib/MeshUtils';
|
||||
|
||||
class MazeObject {
|
||||
constructor(engine, def, params){
|
||||
@@ -157,8 +156,8 @@ class MazeObject {
|
||||
o[e] = mazeAsset.scene.getObjectByName(e);
|
||||
if (o[e]){
|
||||
o[e].scale.setScalar(scale);
|
||||
let bb = getBoundingBox(o[e]);
|
||||
o[e].userData.size = getBoundingBoxSize(bb);
|
||||
let bb = engine.meshUtils.getBoundingBox(o[e]);
|
||||
o[e].userData.size = engine.meshUtils.getBoundingBoxSize(bb);
|
||||
}
|
||||
});
|
||||
this.mazeObject(def, room);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { BoxGeometry, Mesh, MeshStandardMaterial, Group, Vector3, CatmullRomCurve3, Color } from 'three';
|
||||
import { BoxGeometry, Mesh, MeshStandardMaterial, Group, Vector3, CatmullRomCurve3} from 'three';
|
||||
import { LineMaterial, LineGeometry, Line2 } from 'three/examples/jsm/Addons.js';
|
||||
import { centerOrigin, clearMaterial } from '@/lib/MeshUtils';
|
||||
import { EventManager } from '@/lib/EventManager';
|
||||
import Utils from '#/app/Utils';
|
||||
|
||||
@@ -109,10 +108,10 @@ class PairMatchingGame extends EventManager {
|
||||
|
||||
};
|
||||
|
||||
this.object = centerOrigin(container);
|
||||
this.object = engine.meshUtils.centerOrigin(container);
|
||||
|
||||
this.dispose = () => {
|
||||
clearMaterial(material);
|
||||
engine.meshUtils.clearMaterial(material);
|
||||
bm.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { BoxGeometry, Mesh, MeshBasicMaterial, Group, VideoTexture } from 'three';
|
||||
import { centerOrigin, clearMaterial } from '@/lib/MeshUtils';
|
||||
import { EventManager } from '@/lib/EventManager';
|
||||
|
||||
class PuzzleGame1 extends EventManager {
|
||||
@@ -123,11 +122,11 @@ class PuzzleGame1 extends EventManager {
|
||||
|
||||
engine.addEventListener('beforeRender', this.update)
|
||||
|
||||
this.object = centerOrigin(container);
|
||||
this.object = engine.meshUtils.centerOrigin(container);
|
||||
|
||||
this.dispose = () => {
|
||||
//console.log('disposing PG1')
|
||||
clearMaterial(material);
|
||||
engine.meshUtils.clearMaterial(material);
|
||||
bm.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { BoxGeometry, Mesh, MeshBasicMaterial, Group, VideoTexture } from 'three';
|
||||
import { centerOrigin } from '@/lib/MeshUtils';
|
||||
import { EventManager } from '@/lib/EventManager';
|
||||
|
||||
class PuzzleGame2 extends EventManager {
|
||||
@@ -166,7 +165,7 @@ class PuzzleGame2 extends EventManager {
|
||||
};
|
||||
engine.addEventListener('beforeRender', this.update)
|
||||
|
||||
this.object = centerOrigin(container)
|
||||
this.object = engine.meshUtils.centerOrigin(container)
|
||||
resolve(this)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Group, Color } from 'three';
|
||||
import { centerOrigin } from '@/lib/MeshUtils';
|
||||
import { EventManager } from '@/lib/EventManager';
|
||||
import { TextObject } from './TextObject';
|
||||
import Utils from '#/app/Utils';
|
||||
@@ -38,7 +37,7 @@ class SingleQuestion extends EventManager {
|
||||
}
|
||||
container.add(question.object);
|
||||
container.add(answers);
|
||||
this.object = centerOrigin(container);
|
||||
this.object = engine.meshUtils.centerOrigin(container);
|
||||
resolve(this);
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { MeshBasicMaterial, Color, DoubleSide } from "three";
|
||||
import { Text } from "troika-three-text";
|
||||
import { assignParams } from "@/lib/MeshUtils";
|
||||
|
||||
class TextObject {
|
||||
constructor(engine, obj) {
|
||||
@@ -21,7 +20,7 @@ class TextObject {
|
||||
txt.depthOffset = 0.1;
|
||||
//txt.outlineBlur = '50%';
|
||||
txt.color = new Color(0x0);
|
||||
assignParams(txt, obj)
|
||||
engine.meshUtils.assignParams(txt, obj)
|
||||
let m = new MeshBasicMaterial({
|
||||
// roughness: .73,
|
||||
// metalness: .37,
|
||||
|
||||
@@ -4,7 +4,7 @@ class Clickable {
|
||||
constructor(engine, defaultDistance) {
|
||||
const objects = [];
|
||||
const raycaster = new Raycaster();
|
||||
let v = new Vector3;
|
||||
let v = new Vector3(), cv = new Vector3();
|
||||
|
||||
this.add = function (object, fn, distance) {
|
||||
objects.push(object);
|
||||
@@ -33,6 +33,7 @@ class Clickable {
|
||||
|
||||
this.handle = function(){
|
||||
let forExecute = [];
|
||||
engine.cameraWorld.getWorldPosition(cv);
|
||||
objects.filter(o=>{
|
||||
do {
|
||||
if (o.__active === false || o.visible === false) return false;
|
||||
@@ -41,7 +42,7 @@ class Clickable {
|
||||
return true;
|
||||
}).forEach(o => {
|
||||
o.getWorldPosition(v);
|
||||
if (engine.cameraWorld.position.distanceTo(v) <= o._clickable.distance) {
|
||||
if (cv.distanceTo(v) <= o._clickable.distance / engine.scale) {
|
||||
const intersects = raycaster.intersectObject(o);
|
||||
if (intersects[0]) {
|
||||
forExecute.push({ o, i: intersects[0] });
|
||||
|
||||
@@ -18,7 +18,6 @@ class DashBoard extends EventManager {
|
||||
this.object = dash;
|
||||
hud.visible = false;
|
||||
let hudAnimation, hudPlane, textPlane, sceneHeader;
|
||||
this.group = dash;
|
||||
dash.add(hud);
|
||||
hud.add(hudTarget)
|
||||
hudTarget.position.set(0,0,0.52);
|
||||
@@ -285,11 +284,11 @@ class DashBoard extends EventManager {
|
||||
}
|
||||
|
||||
get active(){
|
||||
return this.group.visible;
|
||||
return this.object.visible;
|
||||
}
|
||||
|
||||
set active(v){
|
||||
this.group.visible = v;
|
||||
this.object.visible = v;
|
||||
}
|
||||
|
||||
get points(){
|
||||
|
||||
+10
-3
@@ -4,7 +4,7 @@ class Draggable{
|
||||
constructor(engine, defaultDistance){
|
||||
const objects = [];
|
||||
const raycaster = new Raycaster();
|
||||
let v = new Vector3;
|
||||
let v = new Vector3(), cv = new Vector3();
|
||||
let dragging = null;
|
||||
this.add = function(object, dragZone, fn, distance){
|
||||
objects.push(object);
|
||||
@@ -29,9 +29,16 @@ class Draggable{
|
||||
this.handle = function(action){
|
||||
if (['start', 'selectstart'].includes(action)){
|
||||
let forExecute = [];
|
||||
objects.forEach(o=>{
|
||||
engine.cameraWorld.getWorldPosition(cv);
|
||||
objects.filter(o=>{
|
||||
do {
|
||||
if (o.__active === false || o.visible === false) return false;
|
||||
o = o.parent;
|
||||
} while (o);
|
||||
return true;
|
||||
}).forEach(o=>{
|
||||
o.getWorldPosition(v);
|
||||
if (engine.cameraWorld.position.distanceTo(v) <= o._draggable.distance && o.visible){
|
||||
if (cv.distanceTo(v) <= o._draggable.distance / engine.scale){
|
||||
const intersects = raycaster.intersectObject(o);
|
||||
if (intersects[0]) forExecute.push({o, i:intersects[0]})
|
||||
}
|
||||
|
||||
+19
-8
@@ -20,12 +20,13 @@ import { MotionEngine } from './MotionEngine.js';
|
||||
import { Draggable } from './Draggable.js';
|
||||
import { EventManager } from "./EventManager";
|
||||
import { Telemetry } from './Telemetry.js';
|
||||
import { clearObject } from './MeshUtils.js';
|
||||
import { MeshUtils } from './MeshUtils.js';
|
||||
|
||||
THREE.Cache.enabled = true
|
||||
|
||||
const assetPath = '/asset/default/';
|
||||
const defaultLightIntensity = 11;
|
||||
const sceneScale = 1//.33;
|
||||
|
||||
class GameEngine extends EventManager{
|
||||
|
||||
@@ -45,6 +46,11 @@ class GameEngine extends EventManager{
|
||||
);
|
||||
|
||||
const scene = new THREE.Scene();
|
||||
|
||||
this.sceneWrapper = new THREE.Group();
|
||||
this.sceneWrapper.scale.setScalar(this.scale);
|
||||
scene.add(this.sceneWrapper);
|
||||
|
||||
this.scene = scene;
|
||||
|
||||
this.initCameraPivot()
|
||||
@@ -84,7 +90,7 @@ class GameEngine extends EventManager{
|
||||
this.ambientSound = new THREE.Audio(this.listener);
|
||||
|
||||
this.activeObjects = new THREE.Group();
|
||||
scene.add(this.activeObjects);
|
||||
this.sceneWrapper.add(this.activeObjects);
|
||||
|
||||
if (this.opts.gizmo) {
|
||||
this.orbitControls = new OrbitControls(this.camera, this.renderer.domElement);
|
||||
@@ -99,6 +105,7 @@ class GameEngine extends EventManager{
|
||||
this.orthographicCamera.position.set(0, 0, 100);
|
||||
this.cameraRig.rotation.y = 0;
|
||||
}
|
||||
//this.scene.scale.setScalar(1.25);
|
||||
|
||||
//const controls = new MapControls( camera, renderer.domElement );
|
||||
|
||||
@@ -145,11 +152,12 @@ class GameEngine extends EventManager{
|
||||
}
|
||||
|
||||
async init(domNode, opts = {}) {
|
||||
this.scale = sceneScale;
|
||||
this.w = domNode.clientWidth || 1200, this.h = domNode.clientHeight || 800;
|
||||
this.aspect = this.w / this.h
|
||||
this.opts = opts;
|
||||
const gameEngine = this;
|
||||
this.raycaster = new THREE.Raycaster();
|
||||
this.meshUtils = new MeshUtils(this);
|
||||
|
||||
const renderer = new THREE.WebGLRenderer({
|
||||
antialias: true,
|
||||
@@ -378,7 +386,7 @@ class GameEngine extends EventManager{
|
||||
this.cameraRig.add(this.orthographicCamera);
|
||||
this.cameraRig.rotation.y = Math.PI;
|
||||
this.cameraWorld.add(this.cameraRig);
|
||||
this.scene.add(this.cameraWorld);
|
||||
this.sceneWrapper.add(this.cameraWorld);
|
||||
}
|
||||
|
||||
async initPhysics() {
|
||||
@@ -626,10 +634,11 @@ class GameEngine extends EventManager{
|
||||
}
|
||||
|
||||
processHideIfFar(){
|
||||
let v = new THREE.Vector3();
|
||||
let v = new THREE.Vector3(), cv = new THREE.Vector3();
|
||||
this.cameraWorld.getWorldPosition(cv);
|
||||
this.farArray.forEach(e=>{
|
||||
e.object.getWorldPosition(v);
|
||||
let dst = this.cameraWorld.position.distanceTo(v);
|
||||
let dst = v.distanceTo(cv) / this.scale;
|
||||
if (dst <= e.distance && !e.object.visible) {
|
||||
e.object.visible = true;
|
||||
}else if (dst > e.distance && e.object.visible){
|
||||
@@ -672,14 +681,14 @@ class GameEngine extends EventManager{
|
||||
this.gizmo?.dispose();
|
||||
this.motionQueue.clearAll();
|
||||
this.ambientSound.stop();
|
||||
this.loadedObjects.forEach(o=>clearObject(o.scene))
|
||||
this.loadedObjects.forEach(o=>this.meshUtils.clearObject(o.scene))
|
||||
GameEngine.loadedTextures.forEach(t=>{
|
||||
t.dispose();
|
||||
});
|
||||
GameEngine.loadedTextures.splice(0, GameEngine.loadedTextures.length);
|
||||
this.scene.background?.dispose?.();
|
||||
this.scene.environment?.dispose?.();
|
||||
clearObject(this.scene);
|
||||
this.meshUtils.clearObject(this.scene);
|
||||
this.scene = null;
|
||||
this.tm?.setScene(null);
|
||||
this.removeAllListenersOfType('beforeRender');
|
||||
@@ -739,6 +748,8 @@ class GameEngine extends EventManager{
|
||||
})
|
||||
}
|
||||
|
||||
static scale = 1.33;
|
||||
|
||||
loadTexture = GameEngine.loadTexture
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { InteractiveObject } from "@/components/InteractiveObjects/InteractiveObject";
|
||||
import { VideoPlayer } from '@/components/InteractiveObjects/VideoPlayer';
|
||||
import { Hero } from "./Hero";
|
||||
import { getBoundingBox, getBoundingBoxSize, autoScale } from "./MeshUtils";
|
||||
import { api } from "./Api";
|
||||
|
||||
class GameManager{
|
||||
constructor(engine, gameData, scenarioData, opts = {}){
|
||||
this.engine = engine
|
||||
return new Promise(async (resolve, reject)=>{
|
||||
if (typeof gameData != 'object'){
|
||||
gameData = (await api.game.load(gameData)).data;
|
||||
@@ -85,8 +85,8 @@ class GameManager{
|
||||
}
|
||||
|
||||
if (!i.data.noPhysics){
|
||||
let bb = getBoundingBox(io.object);
|
||||
let bbs = getBoundingBoxSize(bb);
|
||||
let bb = engine.meshUtils.getBoundingBox(io.object);
|
||||
let bbs = engine.meshUtils.getBoundingBoxSize(bb);
|
||||
engine.physics.add(io.object, 'fixed', false, undefined, 'capsule', {
|
||||
radius: Math.max(bbs.x, bbs.z)/2, halfHeight: bbs.y/2
|
||||
})
|
||||
@@ -145,7 +145,7 @@ class GameManager{
|
||||
|
||||
engine.dashboard?.loading(1)
|
||||
engine.physics.start();
|
||||
//this.debug('Scene loaded', engine.renderer.info.memory)
|
||||
//console.log('Scene loaded', engine.renderer.info.memory)
|
||||
}
|
||||
resolve(this);
|
||||
})
|
||||
@@ -173,7 +173,8 @@ class GameManager{
|
||||
object3d[p].copy(sceneObjects[data.id][p])
|
||||
})
|
||||
}else if (!data.type || data.type == 'GenericObject'){
|
||||
autoScale(object3d, autoScaleFactor);
|
||||
console.log('autoscaling', data.id, autoScaleFactor);
|
||||
this.engine.meshUtils.autoScale(object3d, autoScaleFactor);
|
||||
}
|
||||
sceneObjects[data.id] = sceneObjects[data.id] || {};
|
||||
if (this.opts.onObjectLoad){
|
||||
|
||||
+6
-6
@@ -1,5 +1,4 @@
|
||||
import { AnimationMixer, Vector3, Vector2 } from 'three';
|
||||
import { getBoundingBox, getBoundingBoxSize } from './MeshUtils';
|
||||
import { QueryFilterFlags } from '@dimforge/rapier3d';
|
||||
|
||||
const zero2 = new Vector2(0,0);
|
||||
@@ -66,8 +65,9 @@ class Hero{
|
||||
// let bb = this.model.userData.bbox;
|
||||
// let size = getBoundingBoxSize(bb);
|
||||
// let center = getBoundingBoxCenterPoint(bb, this.model.userData.object.position)
|
||||
let bb = getBoundingBox(io.object);
|
||||
this.size = getBoundingBoxSize(bb);
|
||||
let bb = engine.meshUtils.getBoundingBox(io.object);
|
||||
this.size = engine.meshUtils.getBoundingBoxSize(bb);
|
||||
console.log('Hero size is', this.size);
|
||||
// let center = getBoundingBoxCenterPoint(bb, io.object.position)
|
||||
|
||||
// console.log('hero', size, center, size.y - 2*this.characterGapOffset)
|
||||
@@ -307,9 +307,9 @@ class Hero{
|
||||
this.camera.position.copy(cameraPosition)
|
||||
if (!this.fpv){
|
||||
this.camera.lookAt(
|
||||
this.model.position.x,
|
||||
this.cameraY -this.size.y * 0.5 + this.model.position.y,
|
||||
this.model.position.z
|
||||
this.engine.scale * this.model.position.x,
|
||||
this.engine.scale * (this.cameraY -this.size.y * 0.5 + this.model.position.y),
|
||||
this.engine.scale * this.model.position.z
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+127
-124
@@ -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);
|
||||
}
|
||||
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 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);
|
||||
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