(我对Three.js不熟悉)
描述
我正在为多个stl模型创建一个3D查看器。每个模型都应该在单独的div中呈现,因此您将获得具有不同模型的网格。 文件名存储在json文件中。使用for循环遍历json并将文件名存储在“var filename”中。我使用该变量来完成到模型的路径。
详细信息
var filename = data[i].Filename;
使用for循环,我能够从json文件中获取所有文件名。
loader.load('model/' + filename, function(geometry) {...
我接着加上文件名来完成模型路径。
modelContainer = document.createElement('div');
modelContainer.className = modelClass;
document.getElementById(modelId).appendChild(modelContainer);
在给定的ID的div内创建一个带有类名的div。并且模型应该被渲染到带有类的div内的画布中。
问题
查看图片现在发生的情况是,代码将所有模型(此示例中的3个模型)都放入最后一个div中。原本用于模型1和2的前两个div是黑色的。
经过大量实验和分析,我仍然找不到解决方案。也许我必须将所有场景存储在一个数组中,并在渲染函数中循环所有场景?
完整的HTML和JavaScript
您可以在此处找到完整的项目代码(不包括.stl模型): https://codepen.io/indoguy/project/editor/XqNKGQ
<div class="container">
<div class="row" id="modelGrid">
<!-- The models will be uploaded within 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();
// In this code snippit I will read the model filenames out of the json.
// Add URL where the 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) {
// 3D Model Process
if (WEBGL.isWebGLAvailable() === false) {
document.body.appendChild(WEBGL.getWebGLErrorMessage());
}
// Editable
var divWidth = 300;
var divHeight = 300;
var modelId = 'modelGrid';
var modelClass = 'col-sm';
// Don't change
var modelContainer;
var camera, cameraTarget, scene, renderer;
var cameraFov = 45;
init(data);
animate();
// init
function init(data) {
// For loop for every model in the json file
for (i = 0; i < data.length; i++) {
var filename = data[i].Filename;
// Scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffe5e5);
// Camera
camera = new THREE.PerspectiveCamera(cameraFov, divWidth / divHeight, 1, 15);
cameraTarget = new THREE.Vector3(0, -0.25, 0);
// Creates a div with the name of the value of var className, inside modelGrid id
modelContainer = document.createElement('div');
modelContainer.className = modelClass; // Add class to the div
document.getElementById(modelId).appendChild(modelContainer);
// STL 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); // Position with the Y value
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
});
// Lights
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
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);
}
}
// animate
function animate() {
render();
requestAnimationFrame(animate);
}
// render
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>
scene.background = new THREE.Color(0xffe5e5);
但是所有3个模型仍然被渲染在最后一个div中,重叠在一起,就像您在描述中看到的图片一样。 - tiesfascenes.push(scene);
然后他们在render()函数中使用foreach,在其中执行renderer.render(scene, camera);
此外,我注意到渲染器在for循环之外但在init()函数内。 - tiesfamodelContainer
、scene
、camera
、cameraTarget
、renderer
)移动到for循环内部。虽然场景等是在循环内实例化的,但变量是在作用域外声明的,这意味着它们将被覆盖。 - Garrett Johnsonrender
和animate
函数移动到init
函数内部。重要的是,它们与那些变量一起被移动到循环中,就像我在我的示例中所展示的那样。 - Garrett Johnson