152 lines
4.6 KiB
JavaScript
152 lines
4.6 KiB
JavaScript
import * as THREE from 'three';
|
|
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
|
|
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
|
|
import { UltraHDRLoader } from 'three/addons/loaders/UltraHDRLoader.js';
|
|
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
|
|
|
|
|
|
const scene = new THREE.Scene();
|
|
|
|
const sizes = {
|
|
width: window.innerWidth,
|
|
height: window.innerHeight,
|
|
}
|
|
|
|
|
|
//RENDERER
|
|
const renderer = new THREE.WebGLRenderer({antialias:true});
|
|
renderer.setSize( sizes.width, sizes.height );
|
|
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
|
renderer.toneMapping = THREE.ACESFilmicToneMapping;
|
|
renderer.toneMappingExposure = 1.5;
|
|
renderer.outputColorSpace = THREE.SRGBColorSpace;
|
|
renderer.shadowMap.enabled = true;
|
|
renderer.shadowMap.type = THREE.PCFShadowMap;
|
|
document.body.appendChild( renderer.domElement );
|
|
|
|
|
|
//CAMERA
|
|
const camera = new THREE.PerspectiveCamera( 65, sizes.width / sizes.height, 0.1, 1000 );
|
|
camera.position.x = 0;
|
|
camera.position.y = 0;
|
|
camera.position.z = 2;
|
|
|
|
const controls = new OrbitControls( camera, renderer.domElement );
|
|
controls.enableDamping = true;
|
|
controls.dampingFactor = 0.05; // Friction
|
|
controls.screenSpacePanning = false; // Vertical panning along screen
|
|
controls.update();
|
|
|
|
|
|
//RESIZING
|
|
function handleResize(){
|
|
sizes.width = window.innerWidth;
|
|
sizes.height = window.innerHeight;
|
|
camera.aspect = sizes.width/sizes.height;
|
|
camera.updateProjectionMatrix();
|
|
renderer.setSize( sizes.width, sizes.height );
|
|
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
|
}
|
|
window.addEventListener("resize", handleResize);
|
|
|
|
|
|
//MODEL LOADER
|
|
const loader = new GLTFLoader();
|
|
let currentModel = null;
|
|
|
|
|
|
// MODEL PATHS
|
|
const modelPaths = {
|
|
'[MBS-2351] Ansonia muelleri': 'models/MBS-2351 Ansonia muelleri.glb',
|
|
'[MBS-2355] Platymantis corrugatus': 'models/MBS-2355 Platymantis corrugatus.glb',
|
|
'[MBS-2357] Hylarana grandocula': 'models/MBS-2357 Hylarana grandocula.glb',
|
|
'[MBS-2358] Sanguirana mearnsi': 'models/MBS-2358 Sanguirana mearnsi.glb',
|
|
'[MBS-2362] Hoplobatrachus rugulosus': 'models/MBS-2362 Hoplobatrachus rugulosus.glb',
|
|
'[MBS-2407] Staurois natator': 'models/MBS-2407 Staurois natator.glb',
|
|
'[MBS-2408] Oreophryne anulata': 'models/MBS-2408 Oreophryne anulata.glb',
|
|
'[MBS-2410] Platymantis guentheri': 'models/MBS-2410 Platymantis guentheri.glb',
|
|
'[MBS-2415] Kaloula pulchra': 'models/MBS-2415 Kaloula pulchra.glb',
|
|
'[MBS-2416] Rhinella marina': 'models/MBS-2416 Rhinella marina.glb',
|
|
'Frog Zoo': 'models/-------- Frog Zoo.glb'
|
|
};
|
|
const params = {
|
|
selectedModel: modelPaths['[MBS-2351] Ansonia muelleri'] // default selected option
|
|
};
|
|
|
|
function updateNameText(name) {
|
|
const recordtitleElement = document.getElementById('recordnumbertext');
|
|
const titleElement = document.getElementById('nametext');
|
|
|
|
//Record Number
|
|
const recnumberstart = name.slice(7);
|
|
const trimmedrecnumber = recnumberstart.slice(0,8);
|
|
recordtitleElement.textContent = trimmedrecnumber;
|
|
|
|
//Scientific Name
|
|
const trimmedstart = name.slice(16);
|
|
const trimmedsciname = trimmedstart.slice(0, -4);
|
|
titleElement.textContent = trimmedsciname;
|
|
}
|
|
|
|
|
|
// LOADING FUNCTION
|
|
function loadNewModel(url) {
|
|
if (currentModel) {
|
|
scene.remove(currentModel);
|
|
currentModel.traverse((child) => {
|
|
if (child.isMesh) {
|
|
child.geometry.dispose();
|
|
if (Array.isArray(child.material)) {
|
|
child.material.forEach(mat => mat.dispose());
|
|
} else {
|
|
child.material.dispose();
|
|
}
|
|
}
|
|
});
|
|
currentModel = null;
|
|
}
|
|
|
|
//Load the new model
|
|
loader.load(
|
|
url,
|
|
(glb) => {
|
|
currentModel = glb.scene;
|
|
scene.add(currentModel);
|
|
}
|
|
);
|
|
|
|
//Call function to update name text
|
|
updateNameText(params.selectedModel);
|
|
}
|
|
|
|
|
|
// GUI
|
|
const gui = new GUI({ width: 425 });
|
|
gui.add(params, 'selectedModel', modelPaths)
|
|
.name('Displayed Model:')
|
|
.onChange((newUrl) => {
|
|
loadNewModel(newUrl);
|
|
});
|
|
|
|
// Load the initial default model right away
|
|
loadNewModel(params.selectedModel);
|
|
|
|
gui.domElement.style.right = '0px';
|
|
|
|
|
|
//ENVIRONMENT
|
|
const env_loader = new UltraHDRLoader();
|
|
const env_texture = await env_loader.loadAsync( 'assets/studio_small_08_4k.jpg' );
|
|
env_texture.mapping = THREE.EquirectangularReflectionMapping;
|
|
scene.background = new THREE.Color(0xe6e6e6);
|
|
scene.environment = env_texture;
|
|
|
|
|
|
//UPDATE PER FRAME
|
|
renderer.setAnimationLoop( animate );
|
|
|
|
function animate( time ) {
|
|
|
|
controls.update();
|
|
renderer.render( scene, camera );
|
|
} |