此代码应在三个js中生成一个圆环的网格。我很确定数学是正确的。但是,如果我更改一些参数,它只会呈现出一片圆环,或者是更奇怪的东西。我对THREE.Mesh的练习有什么不好的地方吗?
// the vertices of the mesh and the vertex normals ----------------
var nx = 64;
var ny = 32;
var R = 10; var r = 3;
var Vertices = new Array(nx);
var Normals = new Array(nx);
for (var i = 0; i < nx; i++) {
Vertices[i] = new Array(ny);
Normals[i] = new Array(ny);
var u = i / nx * 2 * Math.PI;
var cos_u = Math.cos(u);
var sin_u = Math.sin(u);
var cx = R * cos_u;
var cy = R * sin_u;
for (var j = 0; j < ny; j++) {
var v = j / ny * 2 * Math.PI;
var rcos_v = r * Math.cos(v);
var rsin_v = r * Math.sin(v);
Vertices[i][j] = new THREE.Vector3(
cx + rcos_v * cos_u,
cy + rcos_v * sin_u,
rsin_v
);
Normals[i][j] = new THREE.Vector3(
rcos_v * cos_u,
rcos_v * sin_u,
rsin_v
);
}
}
// vertices as a dot cloud ----------------------------------------
var dotGeometry = new THREE.Geometry();
for (var i = 0; i < nx; i++) {
for (var j = 0; j < ny; j++) {
dotGeometry.vertices.push(Vertices[i][j]);
}
}
var dotMaterial =
new THREE.PointsMaterial({ size: 1, sizeAttenuation: false });
var cloud = new THREE.Points(dotGeometry, dotMaterial);
// mesh -----------------------------------------------------------
var geom = new THREE.Geometry();
for (var i = 0; i < nx; i++) {
var ip1 = (i == nx - 1 ? 0 : i + 1);
for (var j = 0; j < ny; j++) {
var jp1 = (j == ny - 1 ? 0 : j + 1);
geom.vertices.push(Vertices[i][j]);
geom.vertices.push(Vertices[i][jp1]);
geom.vertices.push(Vertices[ip1][j]);
var vnormals1 =
[Normals[i][j], Normals[i][jp1], Normals[ip1][j]];
geom.faces.push(new THREE.Face3(
i * ny + j,
i * ny + jp1,
ip1 * ny + j,
vnormals1
));
geom.vertices.push(Vertices[i][jp1]);
geom.vertices.push(Vertices[ip1][jp1]);
geom.vertices.push(Vertices[ip1][j]);
var vnormals2 =
[Normals[i][jp1], Normals[ip1][jp1], Normals[ip1][j]];
geom.faces.push(new THREE.Face3(
i * ny + jp1,
ip1 * ny + jp1,
ip1 * ny + j,
vnormals2
));
}
}
var torusMesh = new THREE.Mesh(
geom,
new THREE.MeshNormalMaterial({ wireframe: false }));
// three js scene -------------------------------------------------
var scene = new THREE.Scene();
var aspect = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(50, aspect, 1, 10000);
camera.position.z = 30;
scene.add(camera);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var object = new THREE.Object3D();
object.add(torusMesh);
object.add(cloud);
scene.add(object);
renderer.render(scene, camera);
// animation ---------------------------------------------------------
var isDragging = false;
var previousMousePosition = {
x: 0,
y: 0
};
$(renderer.domElement).on('mousedown', function (e) {
isDragging = true;
}).on('mousemove', function (e) {
var deltaMove = {
x: e.offsetX - previousMousePosition.x,
y: e.offsetY - previousMousePosition.y
};
if (isDragging) {
var deltaRotationQuaternion = new THREE.Quaternion()
.setFromEuler(new THREE.Euler(
Math.PI / 180 * (deltaMove.y * 1),
Math.PI / 180 * (deltaMove.x * 1),
0,
'XYZ'
));
object.quaternion.multiplyQuaternions(deltaRotationQuaternion,
object.quaternion);
}
previousMousePosition = {
x: e.offsetX,
y: e.offsetY
};
});
$(document).on('mouseup', function (e) {
isDragging = false;
});
window.requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
function render() {
renderer.render(scene, camera);
requestAnimFrame(render);
}
render();
canvas {
width: 100%;
height: 100%
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/98/three.js"></script>
答案 0 :(得分:2)
我认为您的代码有两个问题:
使用Geometry
时,只需将Face3
类型的对象添加到faces
数组中即可定义面。几何的顶点仅定义一次。就您而言,您可以这样做:
geom.vertices = dotGeometry.vertices;
此外,脸部的缠绕顺序不正确。您必须切换第一个索引和第三个索引。
// the vertices of the mesh and the vertex normals ----------------
var nx = 64;
var ny = 32;
var R = 10; var r = 3;
var Vertices = new Array(nx);
var Normals = new Array(nx);
for (var i = 0; i < nx; i++) {
Vertices[i] = new Array(ny);
Normals[i] = new Array(ny);
var u = i / nx * 2 * Math.PI;
var cos_u = Math.cos(u);
var sin_u = Math.sin(u);
var cx = R * cos_u;
var cy = R * sin_u;
for (var j = 0; j < ny; j++) {
var v = j / ny * 2 * Math.PI;
var rcos_v = r * Math.cos(v);
var rsin_v = r * Math.sin(v);
Vertices[i][j] = new THREE.Vector3(
cx + rcos_v * cos_u,
cy + rcos_v * sin_u,
rsin_v
);
Normals[i][j] = new THREE.Vector3(
rcos_v * cos_u,
rcos_v * sin_u,
rsin_v
);
}
}
// vertices as a dot cloud ----------------------------------------
var dotGeometry = new THREE.Geometry();
for (var i = 0; i < nx; i++) {
for (var j = 0; j < ny; j++) {
dotGeometry.vertices.push(Vertices[i][j]);
}
}
var dotMaterial =
new THREE.PointsMaterial({ size: 1, sizeAttenuation: false });
var cloud = new THREE.Points(dotGeometry, dotMaterial);
// mesh -----------------------------------------------------------
var geom = new THREE.Geometry();
geom.vertices = dotGeometry.vertices;
for (var i = 0; i < nx; i++) {
var ip1 = (i == nx - 1 ? 0 : i + 1);
for (var j = 0; j < ny; j++) {
var jp1 = (j == ny - 1 ? 0 : j + 1);
var vnormals1 =
[Normals[i][j], Normals[i][jp1], Normals[ip1][j]];
geom.faces.push(new THREE.Face3(
ip1 * ny + j,
i * ny + jp1,
i * ny + j,
vnormals1
));
var vnormals2 =
[Normals[i][jp1], Normals[ip1][jp1], Normals[ip1][j]];
geom.faces.push(new THREE.Face3(
ip1 * ny + j,
ip1 * ny + jp1,
i * ny + jp1,
vnormals2
));
}
}
var torusMesh = new THREE.Mesh(
geom,
new THREE.MeshNormalMaterial({ wireframe: false }));
// three js scene -------------------------------------------------
var scene = new THREE.Scene();
var aspect = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(50, aspect, 1, 10000);
camera.position.z = 30;
scene.add(camera);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var object = new THREE.Object3D();
object.add(torusMesh);
object.add(cloud);
scene.add(object);
renderer.render(scene, camera);
// animation ---------------------------------------------------------
var isDragging = false;
var previousMousePosition = {
x: 0,
y: 0
};
$(renderer.domElement).on('mousedown', function (e) {
isDragging = true;
}).on('mousemove', function (e) {
var deltaMove = {
x: e.offsetX - previousMousePosition.x,
y: e.offsetY - previousMousePosition.y
};
if (isDragging) {
var deltaRotationQuaternion = new THREE.Quaternion()
.setFromEuler(new THREE.Euler(
Math.PI / 180 * (deltaMove.y * 1),
Math.PI / 180 * (deltaMove.x * 1),
0,
'XYZ'
));
object.quaternion.multiplyQuaternions(deltaRotationQuaternion,
object.quaternion);
}
previousMousePosition = {
x: e.offsetX,
y: e.offsetY
};
});
$(document).on('mouseup', function (e) {
isDragging = false;
});
window.requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
function render() {
renderer.render(scene, camera);
requestAnimFrame(render);
}
render();
canvas {
width: 100%;
height: 100%
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/98/three.js"></script>
<script
src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha256-3edrmyuQ0w65f8gfBsqowzjJe2iM6n0nKciPUp8y+7E="
crossorigin="anonymous"></script>
此外,考虑使用TorusBufferGeometry
的方法。此外,使用BufferGeometry
生成几何比使用Geometry
生成几何要快得多。