Being new to three.js, I've been stuck on a rookie mistake for hours. After finding some useful examples of mesh editing and managing an imported model on the forum (link), I tried adapting my code based on this example but now I'm facing a problem.
The issue arises when trying to drag the vertices of the model; clicking on them results in an error:
<a class='gotoLine' href='#140:42'>140:42</a> Uncaught ReferenceError: points is not defined""
I can't seem to access the var points
outside of the function object
without encountering a black screen.
My next hurdle would be exporting this to GLTF format and possibly to a 3D printer.
EDIT: I've managed to change the vertices, but the model doesn't transform correctly with the mesh. Testing revealed many overlapping vertices despite having:
geometry.mergeVertices(); geometry.computeFaceNormals(); geometry.computeVertexNormals();
enabled.
Here's my current code: https://jsfiddle.net/felipefsalazar/j9c1L6yr/6/
//SCREEN SETUP
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);
//MOUSE CONTROLS
var controls = new THREE.OrbitControls(camera, renderer.domElement);
//LIGHTING
var light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.setScalar(100);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.5));
//GRAY GRID ON SCREEN
scene.add(new THREE.GridHelper(100, 100));
//LOAD OBJECT
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);
//STATUE MESH
var plane = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
wireframe: true,
color: "blue"
}));
scene.add(plane);
//DRAGGABLE POINTS ON STATUE
points = new THREE.Points(geometry, new THREE.PointsMaterial({
size: 0.25,
color: "yellow"
}));
scene.add(points);
//STATUE MESH (wireframe)
venuspeq = new THREE.Mesh(geometry, mesh);
});
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>