问题描述
这可能是菜鸟的错误,但是我坚持了好几个小时,所以我想我会在这里问。我是three.js的新手,但在论坛上浏览时发现some good examples of mesh editing and managing a imported model,但是在改写我的代码to this example之后,我现在卡住了。
我想拖动模型的顶点,但是当我尝试单击顶点时,我有<a class='gotoLine' href='#140:42'>140:42</a> Uncaught ReferenceError: points is not defined"
我似乎无法在var points
之外获得function object
,否则我会出现黑屏。
下一个挑战将是exporting it to GLTF并成为3D打印机。
编辑:我设法更改了顶点,但是我的模型不会相应地转换为网格。经过测试,我发现即使我有
,彼此之间也有很多顶点 geometry.mergeVertices(); geometry.computeFacenormals(); geometry.computeVertexnormals();
已启用。
这是我现在的代码: https://jsfiddle.net/felipefsalazar/j9c1L6yr/6/
//SETUP DA TELA
var points,geometry;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000);
camera.position.set(0,5,10);
var renderer = new THREE.Webglrenderer();
renderer.setClearColor(0x404040);
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);
//CONTROLE com o MOUSE
var controls = new THREE.OrbitControls(camera,renderer.domElement);
//LUZ
var light = new THREE.DirectionalLight(0xffffff,0.5);
light.position.setScalar(100);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff,0.5));
//GRID CINZA NA TELA
scene.add(new THREE.GridHelper(100,100));
//LOAD DO OBJeto
var objLoader = new THREE.OBJLoader();
objLoader.load('https://raw.githubusercontent.com/felipefsalazar/venus/master/venuspeq.obj',function(object) {
child = object.children[0];
geometry = new THREE.Geometry().fromBufferGeometry(child.geometry);
geometry.computeFacenormals();
geometry.mergeVertices(geometry);
geometry.computeVertexnormals();
geometry = new THREE.BufferGeometry().fromGeometry(geometry);
scene.add(object);
//MALHA DA ESTATUA
var plane = new THREE.Mesh(geometry,new THREE.MeshBasicMaterial({
wireframe: true,color: "blue"
}));
scene.add(plane);
//PONTOS NA ESTÁTUA Para MEXER
points = new THREE.Points(geometry,new THREE.PointsMaterial({
size: 0.25,color: "yellow"
}));
scene.add(points);
//MALHA DA ESTATUA (wireframe)
venuspeq = new THREE.Mesh(geometry,mesh);
//ROTAÇÃO DO OBJeto
//object.rotation.x = -Math.PI * 0.5;
//Box DE AJUDA DO OBJeto
//var Box = new THREE.Box3().setFromObject(object);
//var Box3Helper = new THREE.Box3Helper(Box);
//scene.add(Box3Helper);
});
var raycaster = new THREE.Raycaster();
raycaster.params.Points.threshold = 0.25;
var mouse = new THREE.Vector2();
var intersects = null;
var plane = new THREE.Plane();
var planenormal = new THREE.Vector3();
var currentIndex = null;
var planePoint = new THREE.Vector3();
var dragging = false;
window.addEventListener("mousedown",mouseDown,false);
window.addEventListener("mousemove",mouseMove,false);
window.addEventListener("mouseup",mouseUp,false);
function mouseDown(event) {
setRaycaster(event);
getIndex();
dragging = true;
if (currentIndex != null){
controls.enabled = false;
}
}
function mouseMove(event) {
if (dragging && currentIndex !== null) {
setRaycaster(event);
raycaster.ray.intersectPlane(plane,planePoint);
geometry.attributes.position.setXYZ(currentIndex,planePoint.x,planePoint.y,planePoint.z);
geometry.attributes.position.needsUpdate = true;
}
}
function mouseUp(event) {
dragging = false;
currentIndex = null;
controls.enabled = true;
}
function getIndex() {
intersects = raycaster.intersectObject(points);
if (intersects.length === 0) {
currentIndex = null;
return;
}
currentIndex = intersects[0].index;
setPlane(intersects[0].point);
}
function setPlane(point) {
planenormal.subVectors(camera.position,point).normalize();
plane.setFromnormalAndcoplanarPoint(planenormal,point);
}
function setRaycaster(event) {
getMouse(event);
raycaster.setFromCamera(mouse,camera);
}
function getMouse(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
//RENDER
function render() {
requestAnimationFrame(render);
renderer.render(scene,camera);
}
render();
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/loaders/OBJLoader.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
解决方法
您的问题在于JavaScript范围。您必须确保points
在整个代码中可用,而不仅仅是在单个函数中可用。例如:
function init() {
var points = 1;
}
// This will not work because points is only available
// inside the init function
init();
console.log(points);
要解决此问题,请在函数外声明变量,以将其作用域提高一级:
var points;
function init() {
points = 1;
}
// Now you'll get the desired output of 1
init();
console.log(points);
有关固定版本,请参见此处。注意,我必须在代码的开头声明两个var points,geometry;
,以便它们在所有函数中都可用:
//SETUP DA TELA
var points,geometry;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000);
camera.position.set(0,5,10);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x404040);
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);
//CONTROLE com o MOUSE
var controls = new THREE.OrbitControls(camera,renderer.domElement);
//LUZ
var light = new THREE.DirectionalLight(0xffffff,0.5);
light.position.setScalar(100);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff,0.5));
//GRID CINZA NA TELA
scene.add(new THREE.GridHelper(100,100));
//LOAD DO OBJETO
var objLoader = new THREE.OBJLoader();
objLoader.load('https://raw.githubusercontent.com/felipefsalazar/venus/master/venuspeq.obj',function(object) {
child = object.children[0];
geometry = new THREE.Geometry().fromBufferGeometry(child.geometry);
geometry.computeFaceNormals();
//geometry.mergeVertices();
geometry.computeVertexNormals();
geometry = new THREE.BufferGeometry().fromGeometry(geometry);
scene.add(object);
//MALHA DA ESTATUA
var plane = new THREE.Mesh(geometry,new THREE.MeshBasicMaterial({
wireframe: true,color: "blue"
}));
scene.add(plane);
//PONTOS NA ESTÁTUA PARA MEXER
points = new THREE.Points(geometry,new THREE.PointsMaterial({
size: 0.15,color: "red"
}));
scene.add(points);
//MALHA DA ESTATUA (wireframe)
//venuspeq = new THREE.Mesh(geometry,mesh);
//ROTAÇÃO DO OBJETO
//object.rotation.x = -Math.PI * 0.5;
//BOX DE AJUDA DO OBJETO
//var box = new THREE.Box3().setFromObject(object);
//var box3Helper = new THREE.Box3Helper(box);
//scene.add(box3Helper);
});
var raycaster = new THREE.Raycaster();
raycaster.params.Points.threshold = 0.15;
var mouse = new THREE.Vector2();
var intersects = null;
var plane = new THREE.Plane();
var planeNormal = new THREE.Vector3();
var currentIndex = null;
var planePoint = new THREE.Vector3();
var dragging = false;
window.addEventListener("mousedown",mouseDown,false);
window.addEventListener("mousemove",mouseMove,false);
window.addEventListener("mouseup",mouseUp,false);
function mouseDown(event) {
setRaycaster(event);
getIndex();
dragging = true;
}
function mouseMove(event) {
if (dragging && currentIndex !== null) {
setRaycaster(event);
raycaster.ray.intersectPlane(plane,planePoint);
geometry.attributes.position.setXYZ(currentIndex,planePoint.x,planePoint.y,planePoint.z);
geometry.attributes.position.needsUpdate = true;
}
}
function mouseUp(event) {
dragging = false;
currentIndex = null;
}
function getIndex() {
intersects = raycaster.intersectObject(points);
if (intersects.length === 0) {
currentIndex = null;
return;
}
currentIndex = intersects[0].index;
setPlane(intersects[0].point);
}
function setPlane(point) {
planeNormal.subVectors(camera.position,point).normalize();
plane.setFromNormalAndCoplanarPoint(planeNormal,point);
}
function setRaycaster(event) {
getMouse(event);
raycaster.setFromCamera(mouse,camera);
}
function getMouse(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
//RENDER
function render() {
requestAnimationFrame(render);
renderer.render(scene,camera);
}
render();
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/loaders/OBJLoader.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>