【发布时间】:2019-12-09 20:57:10
【问题描述】:
我是 Three.js 的新手。我试图使用示例中的STLLoader 加载 STL 模型。我要加载的model 是埃菲尔铁塔模型。我下载了 ASCII 格式的 STL 文件,大小接近 33 MB。我有以下设置来显示模型:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body { margin: 5% auto; }
canvas { width: 80%; height: 80% }
#progress {
margin-bottom: 2%;
min-width: 50%;
}
</style>
<script src="js/three.js"></script>
<script src="js/STLLoader.js"></script>
</head>
<body>
<div id="progress"></div>
<script>
// window properties
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
// camera properties
const FOV = 35;
const ASPECT_RATIO = windowWidth / windowHeight;
const NEAR = 0.1;
const FAR = 1000;
// scene settings
const SCENE_BKG = new THREE.Color("rgb(220,220,220)");
const scene = new THREE.Scene();
scene.background = SCENE_BKG;
const camera = new THREE.PerspectiveCamera( FOV, ASPECT_RATIO, NEAR, FAR );
const STLLoader = new THREE.STLLoader();
STLLoader.load('./sample_stl/Eiffel_tower_sample.STL', function(geometry) {
console.dir(geometry);
const materials = [];
const nGeometryGroups = geometry.groups.length;
let colorMap = []; // Some logic to index colors.
let material;
// create a random colorMap
let startColor = 0x010101;
let clr = startColor;
let count = 0;
while (count++ < nGeometryGroups) {
colorMap.push(clr);
clr = ( parseInt(clr, 16) + startColor ).toString();
}
console.log(colorMap);
for (let i = 0; i < nGeometryGroups; i++) {
material = new THREE.MeshPhongMaterial({
color: colorMap[i],
wireframe: false
});
}
materials.push(material);
const mesh = new THREE.Mesh(geometry, materials);
console.dir(mesh);
scene.add(mesh);
// should i call animate here?
}, function (xhr) {
// show progress here
progressBar.innerHTML = `<span style="color: green;">${(xhr.loaded/xhr.total) * 100}%</span> have been loaded`;
}, function(err) {
console.error('[!] Fatal Error: Could not load model');
console.error(err);
});
const renderer = new THREE.WebGLRenderer();
renderer.setSize( windowWidth, windowHeight );
const progressBar = document.querySelector('#progress');
document.body.appendChild( renderer.domElement );
const animate = () => {
requestAnimationFrame(animate);
renderer.render(scene, camera);
};
camera.position.set(0, 0, 10);
animate();
</script>
</body>
</html>
有两件事我不确定。首先,colorMap 数组是什么?我查看了MeshPhongMaterial 类文档,发现它是一个十六进制颜色值。我直接从 STLLoader 示例文件夹 here 复制了这段代码。我找到了一个快速的技巧来生成一些十六进制颜色并填充 colorMap 数组(一个空数组抛出错误)。其次,我应该在哪里调用animate() 函数?我尝试在modelLoaded 处理程序内部和外部调用它,唯一的区别是在处理程序内部,它抛出Violation: handler took 500ms。我检查了 Firefox 和 Chromium 上的网络选项卡,以查看 STL 文件是否已正确加载。我还在控制台中打印了Mesh 对象,如下所示:
Mesh
castShadow: false
children: []
drawMode: 0
frustumCulled: true
geometry: BufferGeometry
attributes: {position: Float32BufferAttribute, normal: Float32BufferAttribute}
boundingBox: null
boundingSphere: Sphere {center: Vector3, radius: 71.76963889659893}
drawRange: {start: 0, count: Infinity}
groups: [{…}]
index: null
morphAttributes: {}
morphTargetsRelative: false
name: ""
type: "BufferGeometry"
userData: {}
uuid: "28A4B269-2828-477D-9C6D-5C9A30E95A7F"
_listeners: {dispose: Array(1)}
drawcalls: (...)
id: 7
offsets: (...)
__proto__: EventDispatcher
layers: Layers
mask: 1
__proto__: Object
material: Array(1)
0: MeshPhongMaterial {uuid: "1E33986A-A979-49C0-ADF5-823CACC6F3AA", name: "", type: "MeshPhongMaterial", fog: true, blending: 1, …}
length: 1
__proto__: Array(0)
matrix: Matrix4
elements: Array(16)
0: 1
1: 0
2: 0
3: 0
4: 0
5: 1
6: 0
7: 0
8: 0
9: 0
10: 1
11: 0
12: 0
13: 0
14: 0
15: 1
length: 16
__proto__: Array(0)
__proto__: Object
matrixAutoUpdate: true
matrixWorld: Matrix4
elements: Array(16)
0: 1
1: 0
2: 0
3: 0
4: 0
5: 1
6: 0
7: 0
8: 0
9: 0
10: 1
11: 0
12: 0
13: 0
14: 0
15: 1
length: 16
__proto__: Array(0)
__proto__: Object
matrixWorldNeedsUpdate: false
name: ""
parent: Scene
autoUpdate: true
background: Color {r: 0.8627450980392157, g: 0.8627450980392157, b: 0.8627450980392157}
castShadow: false
children: [Mesh]
fog: null
frustumCulled: true
layers: Layers {mask: 1}
matrix: Matrix4 {elements: Array(16)}
matrixAutoUpdate: true
matrixWorld: Matrix4 {elements: Array(16)}
matrixWorldNeedsUpdate: false
name: ""
overrideMaterial: null
parent: null
position: Vector3 {x: 0, y: 0, z: 0}
quaternion: Quaternion {_x: 0, _y: 0, _z: 0, _w: 1, _onChangeCallback: ƒ}
receiveShadow: false
renderOrder: 0
rotation: Euler {_x: 0, _y: 0, _z: 0, _order: "XYZ", _onChangeCallback: ƒ}
scale: Vector3 {x: 1, y: 1, z: 1}
type: "Scene"
up: Vector3 {x: 0, y: 1, z: 0}
userData: {}
uuid: "3F9C4993-4CB4-4541-9C64-34FCBB12B1E3"
visible: true
_listeners: {dispose: Array(2)}
eulerOrder: (...)
id: 4
modelViewMatrix: Matrix4 {elements: Array(16)}
normalMatrix: Matrix3 {elements: Array(9)}
useQuaternion: (...)
__proto__: Object3D
position: Vector3 {x: 0, y: 0, z: 0}
quaternion: Quaternion {_x: 0, _y: 0, _z: 0, _w: 1, _onChangeCallback: ƒ}
receiveShadow: false
renderOrder: 0
rotation: Euler {_x: 0, _y: 0, _z: 0, _order: "XYZ", _onChangeCallback: ƒ}
scale: Vector3 {x: 1, y: 1, z: 1}
type: "Mesh"
up: Vector3 {x: 0, y: 1, z: 0}
userData: {}
uuid: "72BA29AF-F939-45F8-869A-D074E6696D7F"
visible: true
eulerOrder: (...)
id: 10
modelViewMatrix: Matrix4 {elements: Array(16)}
normalMatrix: Matrix3 {elements: Array(9)}
useQuaternion: (...)
__proto__: Object3D
这是打印出来的 Mesh 对象。我不确定出了什么问题,如果有人能解释我如何使用colorMap 属性并在animate 函数调用范围上给我一个明确的答案,我会很高兴。
编辑 添加了一个小提琴here。
【问题讨论】:
标签: three.js