(Brand new to venturing into Three.js)
Overview
Currently, I am immersed in the development of a 3D Viewer that can showcase multiple stl models simultaneously. Each model is supposed to be rendered within its own separate div element, resulting in a grid layout displaying diverse models. These model filenames are conveniently stored in a JSON file. By utilizing a for loop, I iterate through the JSON data and save each filename as "var filename", which is then used to construct the complete path to the respective model.
Insights
var filename = data[i].Filename;
The above snippet illustrates how all filenames are extracted from the JSON file via a well-structured for loop.
loader.load('model/' + filename, function(geometry) {...
After obtaining the filename, it gets appended to finalize the model path.
modelContainer = document.createElement('div');
modelContainer.className = modelClass;
document.getElementById(modelID).appendChild(modelContainer);
Consequently, a div element with a designated classname is dynamically generated inside the div specified by the given ID. The objective is to render the model content within a canvas housed within this particular div element.
Dilemma Encountered
Check out this image. The current issue at hand pertains to the fact that despite having three distinct models, they all end up being placed within the last div element. Consequently, the first two div elements, which were intended for the initial two models, remain blank.
Despite numerous trials and analytical investigations, the solution to this problem remains elusive. Perhaps storing all the scenes in an array and subsequently iterating through these scenes within the render function might lead to a breakthrough?
Complete CSS and JavaScript Source Code
You can access the entire project's source code (excluding the .stl models) here: https://codepen.io/indoguy/project/editor/XqNKGQ
<div class="container">
<div class="row" id="modelGrid">
<!-- Models will be inserted into this grid -->
</div>
</div>
<script src="js/three.js"></script>
<script src="js/STLLoader.js"></script>
<script src="js/WebGL.js"></script>
<script>
var modelDiv = document.getElementById('modelGrid');
var ourRequest = new XMLHttpRequest();
// Extracting model names from JSON
// Include URL where JSON is stored
ourRequest.open('GET', 'http://localhost:8888/3D%20Modeling/3D%20Previewer/3D%20Previewer%20Library/models.json');
ourRequest.onload = function() {
var queueData = JSON.parse(ourRequest.responseText);
renderHTML(queueData);
};
ourRequest.send();
function renderHTML(data) {
// Processing 3D Models
if (WEBGL.isWebGLAvailable() === false) {
document.body.appendChild(WEBGL.getWebGLErrorMessage());
}
// Editable Parameters
var divWidth = 300;
var divHeight = 300;
var modelID = 'modelGrid';
var modelClass = 'col-sm';
// Constants
var modelContainer;
var camera, cameraTarget, scene, renderer;
var cameraFOV = 45;
init(data);
animate();
// Initialization
function init(data) {
// Loop through each model in the JSON file
for (i = 0; i < data.length; i++) {
var filename = data[i].Filename;
// Scene Setup
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffe5e5);
// Camera Configuration
camera = new THREE.PerspectiveCamera(cameraFOV, divWidth / divHeight, 1, 15);
cameraTarget = new THREE.Vector3(0, -0.25, 0);
// Create a div element based on the value of className within the modelGrid ID
modelContainer = document.createElement('div');
modelContainer.className = modelClass; // Add class to the div
document.getElementById(modelID).appendChild(modelContainer);
// STL Model Loader
var loader = new THREE.STLLoader();
loader.load('model/' + filename, function(geometry) {
var material = new THREE.MeshStandardMaterial({
color: 0xff1919,
roughness: 0.5,
metalness: 0
});
var mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, -0.5, 0); // Set Y-axis position
mesh.rotation.set(0, -Math.PI / 2, 0);
mesh.scale.set(0.15, 0.15, 0.15);
scene.add(mesh); // Add model to the scene
});
// Lighting Effects
scene.add(new THREE.HemisphereLight(0xaaaaaa, 0x444444));
var light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.set(1, 1, 1);
scene.add(light);
// Renderer Configuration
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setClearColor(0xffffff, 1);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(divWidth, divHeight);
// renderer.setSize(window.innerWidth, window.innerHeight);
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.shadowMap.enabled = true;
modelContainer.appendChild(renderer.domElement);
// window.addEventListener('resize', onWindowResize, false);
}
}
// Animation Play
function animate() {
render();
requestAnimationFrame(animate);
}
// Render Function
function render() {
renderer.setClearColor(0xffffff);
var timer = Date.now() * 0.0005;
camera.position.x = Math.cos(timer) * 3;
camera.position.z = Math.sin(timer) * 3;
camera.lookAt(cameraTarget);
renderer.render(scene, camera);
}
};
</script>