Implemented model-index.json, Separated individual variants, Italicized scientific name, updated Frog Zoo

This commit is contained in:
2026-05-28 16:53:21 +08:00
parent 5314f859b6
commit 386aa5958a
42 changed files with 196 additions and 71 deletions
+84 -53
View File
@@ -13,6 +13,16 @@ const sizes = {
}
let loadData = null;
fetch('model-index.json')
.then(response => response.json())
.then(data => {
loadData = data;
startApp();
});
//RENDERER
const renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize( sizes.width, sizes.height );
@@ -26,18 +36,14 @@ document.body.appendChild( renderer.domElement );
//CAMERA
const DEFAULT_CAMERA_POS = new THREE.Vector3(0, 0, 2); // Camera default position
const DEFAULT_CAMERA_POS = new THREE.Vector3(-0.4, 0.5, 1.5); // Camera default position
const DEFAULT_TARGET = new THREE.Vector3(0, 0, 0); // Camera default target
const camera = new THREE.PerspectiveCamera( 65, sizes.width / sizes.height, 0.1, 1000 );
const camera = new THREE.PerspectiveCamera( 65, sizes.width / sizes.height, 0.001, 1000 );
// Apply default position initially
camera.position.copy(DEFAULT_CAMERA_POS);
camera.lookAt(DEFAULT_TARGET);
// 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
@@ -63,44 +69,26 @@ 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
};
// UPDATE NAME FUNCTION
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;
const recnumber = name.slice(0,11);
recordtitleElement.textContent = recnumber;
//Scientific Name
const trimmedstart = name.slice(16);
const trimmedsciname = trimmedstart.slice(0, -4);
titleElement.textContent = trimmedsciname;
const trimmedstart = name.slice(11);
titleElement.textContent = trimmedstart;
titleElement.style.fontStyle = "italic"; //italicize scientific name
}
// LOAD MODEL FUNCTION
function loadNewModel(url) {
const gui = new GUI({ width: 425 }); //New UI
//Load Function
function loadModel(modelPath) {
if (currentModel) {
scene.remove(currentModel);
currentModel.traverse((child) => {
@@ -115,29 +103,75 @@ function loadNewModel(url) {
});
currentModel = null;
}
console.log(`Loaded: ${modelPath}`);
//Load the new model
loader.load(
url,
(glb) => {
loader.load(modelPath, (glb) => {
currentModel = glb.scene;
scene.add(currentModel);
}
);
//Call function to update name text
updateNameText(params.selectedModel);
scene.add(glb.scene);
});
}
function startApp() {
// 1. Create an object to hold the currently selected values
const modelsData = loadData;
const params = {
name: modelsData[0].name,
variant: Object.keys(modelsData[0].variants)[0]
};
// 2. Extract just the names for the first dropdown
const modelNames = modelsData.map(item => item.name);
// GUI
const gui = new GUI({ width: 425 });
gui.add(params, 'selectedModel', modelPaths)
.name('Displayed Model:')
.onChange((newUrl) => {
loadNewModel(newUrl);
// 3. Add the Controllers
const nameController = gui.add(params, 'name', modelNames).name('Model Name');
// Initialize the variants dropdown with the first model's options
let variantOptions = Object.keys(modelsData[0].variants);
let variantController = gui.add(params, 'variant', variantOptions).name('Variant');
// 4. Handle dynamic updates
nameController.onChange((selectedName) => {
const selectedModelData = modelsData.find(item => item.name === selectedName); // Find the data for the newly selected model
const newVariants = Object.keys(selectedModelData.variants);
params.variant = newVariants[0]; // Update the param state to the first available variant of the new model
// Destroy the old variant dropdown and create a new one with updated options
variantController.destroy();
variantController = gui.add(params, 'variant', newVariants).name('Variant');
// Re-attach the onChange listener to the new dropdown
attachVariantListener(variantController, selectedModelData);
//Load Model
loadModel(selectedModelData.variants[params.variant]);
// Reset camera position and target
resetcam();
//Call function to update name text
updateNameText(selectedName);
});
// Helper function to handle variant changes
function attachVariantListener(controller, modelData) {
controller.onChange((selectedVariant) => {
const modelPath = modelData.variants[selectedVariant];
// Load Model
loadModel(modelPath);
});
}
// Attach listener to the very first variant dropdown
attachVariantListener(variantController, modelsData[0]);
const initialModelPath = modelsData[0].variants[params.variant];
// Load default model right away
loadModel(initialModelPath);
updateNameText(modelsData[0].name);
// Reset camera transforms
function resetcam(){
camera.position.copy(DEFAULT_CAMERA_POS);
if (controls) {
controls.target.copy(DEFAULT_TARGET);
@@ -145,14 +179,11 @@ gui.add(params, 'selectedModel', modelPaths)
} else {
camera.lookAt(DEFAULT_TARGET);
}
});
// 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' );
+101 -7
View File
@@ -1,18 +1,112 @@
[
{
{
"name": "[MBS-2351] Ansonia muelleri",
"variants": {
"posed": "models/MBS-2351 Ansonia muelleri.glb",
"expanded dorsal": "models/MBS-2351 Ansonia muelleri.glb",
"expanded ventral": "models/MBS-2351 Ansonia muelleri.glb"
"posed": "models/new/MBS-2351 Ansonia muelleri.glb",
"dorsal": "models/new/MBS-2351 Ansonia muelleri_dorsal.glb",
"ventral": "models/new/MBS-2351 Ansonia muelleri_ventral.glb"
}
},
{
"name": "[MBS-2355] Platymantis corrugatus",
"variants": {
"posed": "models/MBS-2355 Platymantis corrugatus.glb",
"expanded dorsal": "models/MBS-2355 Platymantis corrugatus.glb",
"expanded ventral": "models/MBS-2355 Platymantis corrugatus.glb"
"posed": "models/new/MBS-2355 Platymantis corrugatus.glb",
"dorsal": "models/new/MBS-2355 Platymantis corrugatus_dorsal.glb",
"ventral": "models/new/MBS-2355 Platymantis corrugatus_ventral.glb"
}
},
{
"name": "[MBS-2357] Hylarana grandocula",
"variants": {
"posed": "models/new/MBS-2357 Hylarana grandocula.glb",
"dorsal": "models/new/MBS-2357 Hylarana grandocula_dorsal.glb",
"ventral": "models/new/MBS-2357 Hylarana grandocula_ventral.glb"
}
},
{
"name": "[MBS-2358] Sanguirana mearnsi",
"variants": {
"posed": "models/new/MBS-2358 Sanguirana mearnsi.glb",
"dorsal": "models/new/MBS-2358 Sanguirana mearnsi_dorsal.glb",
"ventral": "models/new/MBS-2358 Sanguirana mearnsi_ventral.glb"
}
},
{
"name": "[MBS-2361] Indosylvirana nicobariensis",
"variants": {
"posed": "models/new/MBS-2361 Indosylvirana nicobariensis.glb",
"dorsal": "models/new/MBS-2361 Indosylvirana nicobariensis_dorsal.glb",
"ventral": "models/new/MBS-2361 Indosylvirana nicobariensis_ventral.glb"
}
},
{
"name": "[MBS-2362] Hoplobatrachus rugulosus",
"variants": {
"posed": "models/new/MBS-2362 Hoplobatrachus rugulosus.glb",
"dorsal": "models/new/MBS-2362 Hoplobatrachus rugulosus_dorsal.glb",
"ventral": "models/new/MBS-2362 Hoplobatrachus rugulosus_ventral.glb"
}
},
{
"name": "[MBS-2407] Staurois natator",
"variants": {
"posed": "models/new/MBS-2407 Staurois natator.glb",
"dorsal": "models/new/MBS-2407 Staurois natator_dorsal.glb",
"ventral": "models/new/MBS-2407 Staurois natator_ventral.glb"
}
},
{
"name": "[MBS-2408] Oreophryne anulata",
"variants": {
"posed": "models/new/MBS-2408 Oreophryne anulata.glb",
"dorsal": "models/new/MBS-2408 Oreophryne anulata_dorsal.glb",
"ventral": "models/new/MBS-2408 Oreophryne anulata_ventral.glb"
}
},
{
"name": "[MBS-2410] Platymantis guentheri",
"variants": {
"posed": "models/new/MBS-2410 Platymantis guentheri.glb",
"dorsal": "models/new/MBS-2410 Platymantis guentheri_dorsal.glb",
"ventral": "models/new/MBS-2410 Platymantis guentheri_ventral.glb"
}
},
{
"name": "[MBS-2412] Philautus leitensis",
"variants": {
"posed": "models/new/MBS-2412 Philautus leitensis.glb",
"dorsal": "models/new/MBS-2412 Philautus leitensis_dorsal.glb",
"ventral": "models/new/MBS-2412 Philautus leitensis_ventral.glb"
}
},
{
"name": "[MBS-2413] Fejervarya vittigera",
"variants": {
"posed": "models/new/MBS-2413 Fejervarya vittigera.glb",
"dorsal": "models/new/MBS-2413 Fejervarya vittigera_dorsal.glb",
"ventral": "models/new/MBS-2413 Fejervarya vittigera_ventral.glb"
}
},
{
"name": "[MBS-2415] Kaloula pulchra",
"variants": {
"posed": "models/new/MBS-2415 Kaloula pulchra.glb",
"dorsal": "models/new/MBS-2415 Kaloula pulchra_dorsal.glb",
"ventral": "models/new/MBS-2415 Kaloula pulchra_ventral.glb"
}
},
{
"name": "[MBS-2416] Rhinella marina",
"variants": {
"posed": "models/new/MBS-2416 Rhinella marina.glb",
"dorsal": "models/new/MBS-2416 Rhinella marina_dorsal.glb",
"ventral": "models/new/MBS-2416 Rhinella marina_ventral.glb"
}
},
{
"name": "Frog Zoo",
"variants": {
"default": "models/---------- Frog Zoo.glb"
}
}
]
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.