Algoritmo para la selección de triangularjs?

Entonces descubrí que necesito un algorithm de selección de triangularjs, necesito ver si mi mouse está sobre el triángulo. He oído lo que es elegir el color, pero simplemente dejaría caer el performance dos veces (que no es lo que quiero).

Uso LWJGL java y OpenGL 3.3;

Si alguien puede indicarme un algorithm de selección de triangularjs, ¡sería increíble!

Mi mejor bash fue hacer algunas transformaciones en los vértices y luego comprobar si está dentro del centro, es limitado y no exactamente lo que quiero.

¡Gracias!

Lo que hago es una testing conocida como Ray-Picking . Es una testing para ver si un "rayo" intersecta un triángulo. Para usarlo, debes aprender cómo convertir las coorderadas de tu mouse en coorderadas mundiales (donde están tus triangularjs). Luego, necesita crear una matriz que sea inversa a la forma en que representa sus triangularjs, por lo que debe ser igual a la matriz de vista inversa ** multiplicada por la ** matriz de proyección inversa .

QVector3D screenToSpace(int x, int y, int z) { makeCurrent(); GLint viewport[4]; GLfloat winX, winY; glGetIntegerv(GL_VIEWPORT, viewport); winX = ((float)x/viewport[2]*2)-1; winY = ((float)(viewport[3]-y)/viewport[3]*2)-1; QMatrix4x4 mat = ViewMatrix().inverted() * Projection().inverted(); QVector4D wSC = (mat) * QVector4D(winX,winY,z,1); wSC /= wSC[3]; // Divide xyz by w (the fourth component in a 4D vector) return wSC.toVector3D(); } 

El método anterior se llama para generar un rayo a una determinada z distancia. Si solo hace clic en la pantalla, el primer punto del rayo debería usar una z de -1, y un punto de rayo lejano debería ser +1.

Con los puntos de rayos, ahora puede usar el siguiente alogoritmo para verificar si las coorderadas de su mouse (ahora convertidas en una línea en el espacio 3D, y en el código = NearPoint && FarPoint) se cruzan con un triángulo:

 bool intersect(QVector3D nearP, QVector3D farP) { for (int aA = 0; aA < triangles.size(); aA+=3) { QVector3D u, v, n; // triangle vectors QVector3D dir, w0, w; // ray vectors float r, a, b; // params to calc ray-plane intersect // get triangle edge vectors and plane normal u = Point1 - Point0; v = Point2 - Point0; n = QVector3D::crossProduct(u,v); // cross product if (n == (QVector3D(0,0,0))) // triangle is degenerate return false; // do not deal with this case dir = farP - nearP; // ray direction vector w0 = nearP - temp0; a = -dot(n,w0); b = dot(n,dir); if (fabs(b) < 0.00000001) { // ray is parallel to triangle plane if (a == 0) // ray lies in triangle plane continue; else continue; // ray disjoint from plane } // get intersect point of ray with triangle plane r = a / b; if (r < 0.0) // ray goes away from triangle continue; // => no intersect // for a segment, also test if (r > 1.0) => no intersect QVector3D I; I = (nearP + r * dir); // intersect point of ray and plane // is I inside T? float uu, uv, vv, wu, wv, D; uu = dot(u,u); uv = dot(u,v); vv = dot(v,v); w = I - temp0; wu = dot(w,u); wv = dot(w,v); D = uv * uv - uu * vv; // get and test parametric coords float s, t; s = (uv * wv - vv * wu) / D; if (s < 0.0 || s > 1.0) // I is outside T continue; t = (uv * wu - uu * wv) / D; if (t < 0.0 || (s + t) > 1.0) // I is outside T continue; return true; // I is in T } return false; } 

En la práctica, las 2 funciones anteriores se pueden usar así:

 bool createRay(int MouseX, int MouseY) { QVector3D nearP = screenToSpace(MouseX,MouseY,-1); QVector3D farP = screenToSpace(MouseX,MouseY,1); bool rayIntersect = intersect(nearP, farP); return rayIntersect; } 

Donde "createRay () devuelve verdadero si el mouse se cruza con un triángulo, y falso si no.

Solo necesita representar los ID de triángulo cuando necesita seleccionar y si la escena procesada cambió (object movido, camera girada, …) desde la última vez que tuvo que elegir.

También puede mejorar la selección al solo representar lo que se puede recoger. No es necesario procesar el background en el búfer de selección de color si no se puede interactuar con él. También puede simplificar la geometry de los objects seleccionables.

A menudo puede usar una textura objective más pequeña que la pantalla de 4kp ya ​​que solo necesita un área pequeña alnetworkingedor del mouse. La aplicación de una matriz de compensación de escala en la parte inferior (después de la proyección) de la stack de transformación le permitirá representar solo el área necesaria.

Si se niega por completo a elegir el color, puede usar un raycast en su lugar. Esto lanzará un rayo y devolverá el primer object que golpeó. Esto funciona más rápidamente con una partición espacial, por lo que no es necesario iterar sobre todos los objects para encontrar el que impacta.