Commit 1ef9f132 authored by Matthias Betz's avatar Matthias Betz
Browse files

Refine selection: no polygon tint, bigger markers, accurate picking



- Drop the selected-polygon colour tint; selection is shown only by the
  highlight points and edges (scene shader outputs vertex colour directly).
- Larger highlight points (glPointSize) and thicker edges (glLineWidth);
  markers use a constant on-screen pixel size independent of zoom.
- Fix click picking on HiDPI: scale logical click coords to physical
  framebuffer pixels so the sampled pixel is the one under the cursor.

Co-Authored-By: default avatarClaude Opus 4.8 <noreply@anthropic.com>
parent ac4cb04c
......@@ -61,11 +61,8 @@ public class HighlightController {
}
public void changeScaling(double translateZ) {
double scale = Math.abs(translateZ);
scale = Math.min(150, scale);
scale = Math.max(10, scale);
scale = scale * 0.01;
viewport.setPointScale((float) (scale * 8));
// GL points/lines are sized in screen pixels, so highlight markers keep a constant on-screen
// size regardless of zoom distance; nothing to recompute here.
}
// ---- point/line accumulation ----
......
......@@ -33,10 +33,10 @@ public class GLViewport {
// last index set seen; retained so it can be (re)applied after the scene is uploaded or the GL
// context is recreated (the index buffer only exists once the scene's buffers have been generated)
private volatile int[] lastIndices;
private volatile int selectedId = 0;
private volatile boolean wireframe = false;
private volatile boolean cull = false;
private volatile float pointScale = 5f;
private volatile float pointScale = 14f;
private volatile float lineScale = 4f;
// highlight marker data, uploaded on the GL thread when dirty
private volatile float[] hlPoints = new float[0];
......@@ -45,8 +45,8 @@ public class GLViewport {
private volatile float[] hlLineColors = new float[0];
private volatile boolean highlightsDirty = false;
// pick request: screen coords + callback (invoked on FX thread with resolved Object or null)
private volatile int[] pickRequest;
// pick request: logical (JavaFX) screen coords + callback (invoked on FX thread with resolved Object)
private volatile double[] pickRequest;
private volatile Consumer<Object> pickCallback;
private SceneData currentScene;
......@@ -78,8 +78,6 @@ public class GLViewport {
public void setIndexSet(int[] indices) { pendingIndexSet.set(indices); canvas.repaint(); }
public void setSelectedId(int id) { selectedId = id; canvas.repaint(); }
public void setWireframe(boolean on) { wireframe = on; canvas.repaint(); }
public void setCulling(boolean on) { cull = on; canvas.repaint(); }
......@@ -99,7 +97,7 @@ public class GLViewport {
public OrbitCamera camera() { return camera; }
public void requestPick(double x, double y, Consumer<Object> callback) {
pickRequest = new int[]{(int) Math.round(x), (int) Math.round(y)};
pickRequest = new double[]{x, y};
pickCallback = callback;
canvas.repaint();
}
......@@ -159,11 +157,10 @@ public class GLViewport {
sceneProgram.use(gl);
gl.glUniformMatrix4fv(sceneProgram.uniform(gl, "uMVP"), 1, false, mvp, 0);
gl.glUniform1i(sceneProgram.uniform(gl, "uSelectedId"), selectedId);
scene.draw(gl);
overlay.draw(gl, pointScale);
overlay.draw(gl, pointScale, lineScale);
int[] req = pickRequest;
double[] req = pickRequest;
if (req != null && currentScene != null) {
picking.resize(gl, w, h);
picking.bind(gl);
......@@ -173,9 +170,16 @@ public class GLViewport {
pickProgram.use(gl);
gl.glUniformMatrix4fv(pickProgram.uniform(gl, "uMVP"), 1, false, mvp, 0);
scene.draw(gl);
int id = picking.readId(gl, req[0], req[1]);
// click coords are logical (JavaFX) px; the picking buffer is physical px. Scale by the
// framebuffer/canvas ratio so HiDPI displays read the pixel actually under the cursor.
double cw = canvas.getWidth();
double ch = canvas.getHeight();
float sx = cw > 0 ? (float) (w / cw) : 1f;
float sy = ch > 0 ? (float) (h / ch) : 1f;
int px = Math.round((float) req[0] * sx);
int py = Math.round((float) req[1] * sy);
int id = picking.readId(gl, px, py);
Object target = currentScene.pickRegistry().resolve(id);
selectedId = (target != null) ? id : 0;
Consumer<Object> cb = pickCallback;
pickRequest = null;
pickCallback = null;
......
......@@ -74,11 +74,12 @@ public class HighlightOverlay {
gl.glVertexAttribPointer(loc, comp, GL.GL_FLOAT, false, 0, 0L);
}
public void draw(GL3 gl, float pointSize) {
public void draw(GL3 gl, float pointSize, float lineWidth) {
if (!created) {
return;
}
if (lineVertexCount > 0) {
gl.glLineWidth(lineWidth);
gl.glBindVertexArray(lineVao);
gl.glDrawArrays(GL.GL_LINES, 0, lineVertexCount);
}
......
#version 330 core
in vec3 vColor;
flat in int vSelected;
out vec4 fragColor;
void main() {
vec3 c = vColor;
if (vSelected == 1) {
c = mix(c, vec3(1.0, 0.0, 0.0), 0.6);
}
fragColor = vec4(c, 1.0);
fragColor = vec4(vColor, 1.0);
}
#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aColor;
layout(location = 2) in int aId;
uniform mat4 uMVP;
uniform int uSelectedId;
out vec3 vColor;
flat out int vSelected;
void main() {
gl_Position = uMVP * vec4(aPos, 1.0);
vColor = aColor;
vSelected = (aId == uSelectedId) ? 1 : 0;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment