Set up gltf loading, set up switching, fixed imports, fixed helpers, added model gui

This commit is contained in:
Paul Graffam 2020-07-06 17:29:08 -04:00
parent 548da33664
commit 6374273055
4 changed files with 159 additions and 55 deletions

View File

@ -1,6 +1,6 @@
// Global imports -
import * as THREE from 'three';
import TWEEN from 'tween.js';
import TWEEN from '@tweenjs/tween.js';
// Local imports -
// Components
@ -8,10 +8,11 @@ import Renderer from './components/renderer';
import Camera from './components/camera';
import Light from './components/light';
import Controls from './components/controls';
import Geometry from './components/geometry';
// Helpers
import Geometry from './helpers/geometry';
import Stats from './helpers/stats';
import MeshHelper from './helpers/meshHelper';
// Model
import Texture from './model/texture';
@ -66,6 +67,11 @@ export default class Main {
this.stats.setUp();
}
// Set up gui
if (Config.isDev) {
this.gui = new DatGUI(this)
}
// Instantiate texture class
this.texture = new Texture();
@ -75,7 +81,7 @@ export default class Main {
// Textures loaded, load model
this.model = new Model(this.scene, this.manager, this.texture.textures);
this.model.load();
this.model.load(Config.models[Config.model.selected].type);
// onProgress callback
this.manager.onProgress = (item, loaded, total) => {
@ -89,7 +95,10 @@ export default class Main {
// Add dat.GUI controls if dev
if(Config.isDev) {
new DatGUI(this, this.model.obj);
this.meshHelper = new MeshHelper(this.scene, this.model.obj);
if (Config.mesh.enableHelper) this.meshHelper.enable();
this.gui.load(this, this.model.obj);
}
// Everything is now fully loaded

View File

@ -2,18 +2,27 @@ import Config from '../../data/config';
// Manages all dat.GUI interactions
export default class DatGUI {
constructor(main, mesh) {
const gui = new dat.GUI();
constructor(main) {
this.gui = new dat.GUI();
this.camera = main.camera.threeCamera;
this.controls = main.controls.threeControls;
this.light = main.light;
this.scene = main.scene;
this.model = null;
this.meshHelper = null;
}
load(main, mesh) {
/* Global */
//gui.close();
//this.gui.close();
this.model = main.model;
this.meshHelper = main.meshHelper;
/* Camera */
const cameraFolder = gui.addFolder('Camera');
const cameraFolder = this.gui.addFolder('Camera');
const cameraFOVGui = cameraFolder.add(Config.camera, 'fov', 0, 180).name('Camera FOV');
cameraFOVGui.onChange((value) => {
this.controls.enableRotate = false;
@ -38,13 +47,13 @@ export default class DatGUI {
});
const cameraFogColorGui = cameraFolder.addColor(Config.fog, 'color').name('Fog Color');
cameraFogColorGui.onChange((value) => {
main.scene.fog.color.setHex(value);
this.scene.fog.color.setHex(value);
});
const cameraFogNearGui = cameraFolder.add(Config.fog, 'near', 0.000, 0.010).name('Fog Near');
cameraFogNearGui.onChange((value) => {
this.controls.enableRotate = false;
main.scene.fog.density = value;
this.scene.fog.density = value;
});
cameraFogNearGui.onFinishChange(() => {
this.controls.enableRotate = true;
@ -52,7 +61,7 @@ export default class DatGUI {
/* Controls */
const controlsFolder = gui.addFolder('Controls');
const controlsFolder = this.gui.addFolder('Controls');
controlsFolder.add(Config.controls, 'autoRotate').name('Auto Rotate').onChange((value) => {
this.controls.autoRotate = value;
});
@ -66,8 +75,29 @@ export default class DatGUI {
});
/* Model */
const modelFolder = this.gui.addFolder('Model');
modelFolder.add(Config.model, 'type', [...Config.model.initialTypes]).name('Select Model').onChange((value) => {
if (value) {
if (Config.mesh.enableHelper)
this.meshHelper.disable();
Config.model.selected = Config.model.initialTypes.indexOf(value);
this.unload();
this.model.unload();
this.model.load(value);
}
});
/* Mesh */
const meshFolder = gui.addFolder('Mesh');
const meshFolder = this.gui.addFolder('Mesh');
meshFolder.add(Config.mesh, 'enableHelper', true).name('Enable Helpers').onChange((value) => {
if(value) {
this.meshHelper.enable();
} else {
this.meshHelper.disable();
}
});
meshFolder.add(Config.mesh, 'translucent', true).name('Translucent').onChange((value) => {
if(value) {
mesh.material.transparent = true;
@ -83,7 +113,7 @@ export default class DatGUI {
/* Lights */
// Ambient Light
const ambientLightFolder = gui.addFolder('Ambient Light');
const ambientLightFolder = this.gui.addFolder('Ambient Light');
ambientLightFolder.add(Config.ambientLight, 'enabled').name('Enabled').onChange((value) => {
this.light.ambientLight.visible = value;
});
@ -93,7 +123,7 @@ export default class DatGUI {
// Directional Light
const directionalLightFolder = gui.addFolder('Directional Light');
const directionalLightFolder = this.gui.addFolder('Directional Light');
directionalLightFolder.add(Config.directionalLight, 'enabled').name('Enabled').onChange((value) => {
this.light.directionalLight.visible = value;
});
@ -138,7 +168,7 @@ export default class DatGUI {
});
// Shadow Map
const shadowFolder = gui.addFolder('Shadow Map');
const shadowFolder = this.gui.addFolder('Shadow Map');
shadowFolder.add(Config.shadow, 'enabled').name('Enabled').onChange((value) => {
this.light.directionalLight.castShadow = value;
});
@ -232,7 +262,7 @@ export default class DatGUI {
// Point Light
const pointLightFolder = gui.addFolder('Point Light');
const pointLightFolder = this.gui.addFolder('Point Light');
pointLightFolder.add(Config.pointLight, 'enabled').name('Enabled').onChange((value) => {
this.light.pointLight.visible = value;
});
@ -287,7 +317,7 @@ export default class DatGUI {
// Hemi Light
const hemiLightFolder = gui.addFolder('Hemi Light');
const hemiLightFolder = this.gui.addFolder('Hemi Light');
hemiLightFolder.add(Config.hemiLight, 'enabled').name('Enabled').onChange((value) => {
this.light.hemiLight.visible = value;
});
@ -334,4 +364,9 @@ export default class DatGUI {
this.controls.enableRotate = true;
});
}
unload() {
this.gui.destroy();
this.gui = new dat.GUI();
}
}

View File

@ -1,8 +1,9 @@
import * as THREE from 'three';
import Material from '../helpers/material';
import MeshHelper from '../helpers/meshHelper';
import Material from '../components/material';
import Helpers from '../../utils/helpers';
import { BufferGeometryUtils } from '../../utils/bufferGeometryUtils';
import { GLTFLoader } from '../loaders/GLTFLoader';
import Config from '../../data/config';
// Loads in a single object from the config file
@ -10,45 +11,91 @@ export default class Model {
constructor(scene, manager, textures) {
this.scene = scene;
this.textures = textures;
this.manager = manager;
// Manager is passed in to loader to determine when loading done in main
this.loader = new THREE.ObjectLoader(manager);
this.obj = null;
this.ref = null;
}
load() {
// Load model with ObjectLoader
this.loader.load(
Config.model.path,
obj => {
obj.traverse(child => {
if(child instanceof THREE.Mesh) {
// Create material for mesh and set its map to texture by name from preloaded textures
const material = new Material(0xffffff).standard;
material.map = this.textures.UV;
child.material = material;
load(type) {
// Manager is passed in to loader to determine when loading done in main
// Set to cast and receive shadow if enabled
if(Config.shadow.enabled) {
child.receiveShadow = true;
child.castShadow = true;
switch (type) {
case 'gltf':
// Load model with selected loader
new GLTFLoader(this.manager).load(
Config.models[Config.model.selected].path,
(gltf) => {
const scene = gltf.scene;
let mesh;
if (Config.shadow.enabled) {
scene.traverse(function(node) {
if (node.isMesh || node.isLight) node.castShadow = true;
if (node.isMesh) {
node.material.wireframe = Config.mesh.wireframe;
mesh = node;
}
});
}
}
});
// Add mesh helper if Dev
if(Config.isDev && Config.mesh.enableHelper) {
new MeshHelper(this.scene, obj);
}
this.obj = mesh;
// Set prop to obj so it can be accessed from outside the class
this.obj = obj;
BufferGeometryUtils.computeTangents(mesh.geometry);
obj.scale.multiplyScalar(Config.model.scale);
this.scene.add(obj);
},
Helpers.logProgress(),
Helpers.logError()
);
var group = new THREE.Group();
group.scale.multiplyScalar(0.25);
this.scene.add( group );
this.ref = group;
// To make sure that the matrixWorld is up to date for the boxhelpers
group.updateMatrixWorld(true);
group.add(mesh);
// Add to scene
this.scene.add(scene);
},
Helpers.logProgress(),
Helpers.logError()
);
break;
case 'object':
// Load model with ObjectLoader
new THREE.ObjectLoader(this.manager).load(
Config.models[Config.model.selected].path,
obj => {
obj.traverse(child => {
if(child instanceof THREE.Mesh) {
// Create material for mesh and set its map to texture by name from preloaded textures
const material = new Material(0xffffff).standard;
material.map = this.textures.UV;
child.material = material;
// Set to cast and receive shadow if enabled
if(Config.shadow.enabled) {
child.receiveShadow = true;
child.castShadow = true;
}
}
});
// Set prop to obj so it can be accessed from outside the class
this.obj = obj;
this.ref = obj;
obj.scale.multiplyScalar(Config.models[Config.model.selected].scale);
this.scene.add(obj);
},
Helpers.logProgress(),
Helpers.logError()
);
break;
}
}
unload() {
this.scene.remove(this.ref);
}
}

View File

@ -1,4 +1,4 @@
import TWEEN from 'tween.js';
import TWEEN from '@tweenjs/tween.js';
// This object contains the state of the app
export default {
@ -14,17 +14,30 @@ export default {
easing: TWEEN.Easing.Quadratic.InOut,
duration: 500,
model: {
path: './assets/models/Teapot.json',
scale: 20
selected: 0,
initialTypes: ['gltf', 'object'],
type: 'gltf'
},
models: [
{
path: './assets/models/duck.gltf',
scale: 20,
type: 'gltf'
},
{
path: './assets/models/Teapot.json',
scale: 20,
type: 'object'
}
],
texture: {
path: './assets/textures/',
imageFiles: [
{name: 'UV', image: 'UV_Grid_Sm.jpg'}
{ name: 'UV', image: 'UV_Grid_Sm.jpg' }
]
},
mesh: {
enableHelper: false,
enableHelper: true,
wireframe: false,
translucent: false,
material: {