以下代码是使用自定义几何体绘制带有three.js
的四面体(相关的是mesh2
)的工作示例:
<!DOCTYPE html>
<html>
<header>
<script src="three.min.js"></script>
<style>
body {
overflow: hidden;
}
</style>
</header>
<body>
<script>
var camera, scene, renderer;
var geometry, material, mesh1, mesh2;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 100, window.innerWidth / window.innerHeight, 0.01, 300 );
camera.position.z = 50;
scene = new THREE.Scene();
material = new THREE.MeshNormalMaterial();
// 1
geometry = new THREE.BoxGeometry( 10, 10, 10 );
mesh1 = new THREE.Mesh( geometry, material );
scene.add( mesh1 );
// 2 begin
geometry = new THREE.Geometry( );
geometry.vertices.push( new THREE.Vector3( 6,6, 6), new THREE.Vector3( 10,6, 6), new THREE.Vector3( 6,10, 6), new THREE.Vector3( 6,6, 10) );
geometry.faces.push( new THREE.Face3( 0,2,1),new THREE.Face3( 1,2,3),new THREE.Face3( 1,3,0),new THREE.Face3( 0,3,2));
geometry.computeFaceNormals();
geometry.computeVertexNormals();
mesh2 = new THREE.Mesh( geometry, material );
scene.add( mesh2 );
// 2 end
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
mesh1.rotation.x += 0.01;
mesh1.rotation.y += 0.02;
mesh2.rotation.x += 0.01;
mesh2.rotation.y += 0.02;
renderer.render( scene, camera );
}
</script>
</body>
</html>
以下代码尝试绘制家具的组件:
<!DOCTYPE html>
<html>
<header>
<script src="three.min.js"></script>
<style>
body {
overflow: hidden;
}
</style>
</header>
<body>
<script>
var camera, scene, renderer;
var geometry, material, mesh;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 100, window.innerWidth / window.innerHeight, 0, 550 );
camera.position.z = 4000;
scene = new THREE.Scene();
scene.add(camera);
function cos(x) {
return Math.cos(Math.PI*x/180);
}
function sin(x) {
return Math.sin(Math.PI*x/180);
}
var geometry = new THREE.Geometry();
var step_deg = 10;
var count = -1;
for(deg=0 ;deg<=360;deg+=step_deg) {
var x1,y1,z1,x2,y2,z2;
if (deg>=0 && deg<=90) {
x1 = 400+100*cos(deg); y1 = 900+100*sin(deg); z1=0;
x2 = x1; y2 = y1; z2 = 27;
geometry.vertices.push( new THREE.Vector3( x1,y1, z1), new THREE.Vector3( x2,y2,z2) );
count++; console.log(""+count+": ["+x1+","+y1+","+z1+"]");
count++; console.log(""+count+": ["+x2+","+y2+","+z2+"]");
}
if (deg>=90 && deg<=180) {
x1 = 50+50*cos(deg); y1 = 950+50*sin(deg); z1 = 0;
x2 = x1; y2 = y1; z2 = 27;
geometry.vertices.push( new THREE.Vector3( x1,y1, z1), new THREE.Vector3( x2,y2,z2) );
count++; console.log(""+count+": ["+x1+","+y1+","+z1+"]");
count++; console.log(""+count+": ["+x2+","+y2+","+z2+"]");
}
if (deg>=180 && deg<=270) {
x1 = 50+50*cos(deg); y1 = -950+50*sin(deg); z1 = 0;
x2 = x1; y2 = y1; z2 = 27;
geometry.vertices.push( new THREE.Vector3( x1,y1, z1), new THREE.Vector3( x2,y2,z2) );
count++; console.log(""+count+": ["+x1+","+y1+","+z1+"]");
count++; console.log(""+count+": ["+x2+","+y2+","+z2+"]");
}
if (deg>=270 && deg<=360) {
x1 = 400+100*cos(deg); y1 = -900+100*sin(deg); z1 = 0;
x2 = x1; y2 = y1; z2 = 27;
geometry.vertices.push( new THREE.Vector3( x1,y1, z1), new THREE.Vector3( x2,y2,z2) );
count++; console.log(""+count+": ["+x1+","+y1+","+z1+"]");
count++; console.log(""+count+": ["+x2+","+y2+","+z2+"]");
}
}
geometry.vertices.push( new THREE.Vector3( 400,900, 0), new THREE.Vector3( 400,900, 27) ); // 80, 81
geometry.vertices.push( new THREE.Vector3( 50,950, 0), new THREE.Vector3( 50,950, 27) );
geometry.vertices.push( new THREE.Vector3( 50,-950, 0), new THREE.Vector3( 50,-950, 27) );
geometry.vertices.push( new THREE.Vector3( 400,-900, 0), new THREE.Vector3( 400,-900, 27) ); // 86, 87
for(i=0;i<40;i++) {
geometry.faces.push( new THREE.Face3( i*2, (i*2+2) % 80, i*2+1) );
console.log("["+i*2+","+ ((i*2+2) % 80)+","+ (i*2+1)+"]");
geometry.faces.push( new THREE.Face3( i*2+1, (i*2+2) % 80, (i*2+3) % 80) );
console.log("["+(i*2+1)+","+ ((i*2+2)%80)+","+ ((i*2+3) % 80)+"]");
}
geometry.faces.push( new THREE.Face3( 82,20,80), new THREE.Face3( 18,80,20),
new THREE.Face3( 84,38,82), new THREE.Face3( 84,40,38),
new THREE.Face3( 80,86,82), new THREE.Face3( 82,86,84),
new THREE.Face3( 0,78,80), new THREE.Face3( 80,78,86),
new THREE.Face3( 60,84,86), new THREE.Face3( 60,58,84)
);
geometry.faces.push( new THREE.Face3( 83,81,21), new THREE.Face3( 19,21,81),
new THREE.Face3( 85,83,39), new THREE.Face3( 85,39,41),
new THREE.Face3( 81,83,87), new THREE.Face3( 83,85,87),
new THREE.Face3( 1,81,79), new THREE.Face3( 81,87,79),
new THREE.Face3( 61,87,85), new THREE.Face3( 61,85,59)
);
for(i=0;i<10;i++) {
geometry.faces.push( new THREE.Face3( 80, 2*(i+1), 2*i),new THREE.Face3( 81, 2*i+1, 2*(i+1)+1),
new THREE.Face3( 82, 2*(i+1)+20,2*i+20),new THREE.Face3( 83, 2*i+21, 2*(i+1)+21),
new THREE.Face3( 84, 2*(i+1)+40,2*i+40),new THREE.Face3( 85, 2*i+41, 2*(i+1)+41),
new THREE.Face3( 86, (2*(i+1)+60)%80,2*i+60),new THREE.Face3( 87, 2*i+61, (2*(i+1)+61)%80)
);
}
geometry.computeFaceNormals();
geometry.computeVertexNormals();
var box = new THREE.Box3().setFromPoints( geometry.vertices );
console.log( box.min, box.max, box.getSize() );
material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.02;
renderer.render( scene, camera );
}
</script>
</body>
</html>
基本上它是相同的技术,但更复杂。第二个例子没有出现。
我的问题:
PerspectiveCamera
和camera.position.z
(或概括:给定x = -X..X,y = -Y..Y,z = -Z..Z)?修改 现在它有效!我做了以下更改
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 500, 0 );
camera.position.z = 3000;
如果我理解正确,我们在(0,0,3000)点(0,0,0)方向观察角度为60°,“近”是xy平面z = 500 resp。 “far”是xy平面,z = 0。网格是100%正确的(在第一次尝试!;-))。
编辑2 摆弄完整的家具:link
更新,现在动画制作更有意义。但重点是:我需要家具的中心位于图片的中心。我需要某种功能“lookAt”用于相机并将其设置为相机位置和家具中心之间的差异(pos_center.add(pos_camera.negate()).normalize()
)。
地板的花岗岩纹理不起作用,但这是另一个问题。