[SOLVED] Are segments in a side selectable?

So I have a 6 sided cube thats 30x30x30 each side with 30x30x30 segments
originally i used

let shape = new THREE.Shape();
shape.lineTo(0, 0, 1, 0);
shape.lineTo(1, 0, 1, 1);
shape.lineTo(1, 1, 0, 1);
shape.lineTo(0, 1, 0, 0);

and ran it through a for loop to make a 30x30 plane with selectable planes as each shape was another mesh added to the scene.

And of course building 6 sides with each side consisting of 900 pieces which makes a total of 5400 pieces for just 1 cube would hurt the FPS
Of course being a lazy programmer decide to skip it for a few days… then decided that no shortcuts i needed to do it better…
So now im at a regular
new THREE.BoxGeometry(30,30,30,30,30,30)
I already know how to select an side of a cube
and wondering how to select individual segments
theres 2 ways i COULD do this…

  1. Find the cursor’s position and the cube’s position, rotation and zoom and do the math of whats being selected
  2. use raycaster somehow to select segments

so after some googling i havent found out if i even can select segments…
is it possible?
If not is there another/better way of finding out where on the 30x30 cube my mouse is selecting?

Thanks for bearing w/ me i just started on ThreeJS a couple weeks ago and am a noob :yum:

Each square (or “segment”) consists of two faces.
Using THREE.Raycaster() you can get the index of a face. Having that index, you can find its neighbour.
The rest is just to change colours of faces. There are many options, actually, of how you can change faces’ colours. The main thing is to find those faces :slight_smile:

Select_Segment

https://jsfiddle.net/prisoner849/hakf26hL/

var box = new THREE.Mesh(new THREE.BoxGeometry(30, 30, 30, 30, 30, 30), new THREE.MeshBasicMaterial({
  vertexColors: THREE.VertexColors
}));
scene.add(box);

var wireBox = new THREE.Mesh(new THREE.BoxGeometry(30, 30, 30, 30, 30, 30), new THREE.MeshBasicMaterial({
  color: "black",
  wireframe: true
}));
box.add(wireBox);

var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var intersects = [];
var faceIdx1 = -1, faceIdx2 = -1;
var baseColor = new THREE.Color("white");
var selectionColor = new THREE.Color("red");

window.addEventListener("mousemove", function(event) {
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}, false);

window.addEventListener("mousedown", function(event){
  raycaster.setFromCamera(mouse, camera);
  intersects = raycaster.intersectObject(box);
  if (intersects.length === 0) return;
  
  // set previously selected faces to white
  setFaceColor(faceIdx1, baseColor);
  setFaceColor(faceIdx2, baseColor);
  
  // find the new indices of faces
  faceIdx1 = intersects[0].faceIndex;
  faceIdx2 = faceIdx1 % 2 === 0 ? faceIdx1 + 1: faceIdx1 - 1;
  
  // set newly selected faces to red
  setFaceColor(faceIdx1, selectionColor);
  setFaceColor(faceIdx2, selectionColor);
}, false)

function setFaceColor(idx, color){
  if (idx === -1) return;
  box.geometry.faces[idx].color.copy(color);
  box.geometry.colorsNeedUpdate = true;
}
2 Likes

Thank you so much :smiley:

To reduce the frustration of programming, :relaxed: it can be useful to know the systematics of the arrangement. For a box and other objects.

A little helper for this: http://threejs.hofk.de/helperExample/

20180306-0925-45917

The helper is from THREEf. js from me.
You can add other geometries.

1 Like

Thank you :smiley:

Rather than selecting a segment (2 faces) is it possible to select multiple faces that are adjacent to the selected face. Like selecting 3 faces since a face has 3 edge. Because when I increment faceIndex by one last faces occurs on meaningless parts of the model. Guess an algorithm is required for that. Do u have any suggestion for that?

Something very inefficient :sweat_smile:

2 Likes

As long as it gives what desired it works for me actually. This is a great example!!. However I noticed that it uses BufferGeometry but I converted my model to Geometry to use faces and faceIndexes to paint my faces. Does this approach works on my code or should i convert it to buffergeometry?

You would just look for triangles that use the same vertex index numbers on one of the 3 edges with the 3 edges of the selected face. 1 edge, so 2 index numbers must match 2 index numbers of the triangle you test with, but regardless which in order as the test edge of the test triangle might share the same 2 vertex numbers (edge) but not in the same order.

By using a tiny radius you can also use Paul’s suggestion which will basically give the adjacent faces as well, but comparing just the vertex id’s would be quite faster.

1 Like