PDA

View Full Version : how to pick objects with ray cast ?

hambelo
07-10-2008, 05:39 AM
Hi people,

i want to pick objects in my 3d scene. i will do that with a raycast? Can somebody help me out? I cant use methods like gluunproject because im working with OpenglES. How can i easy implement a raycast in openglES?

-NiCo-
07-10-2008, 08:19 AM
Sure you can use gluUnproject.

static void __gluMakeIdentityd(GLdouble m[16])
{
m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;
m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;
m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;
m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;
}

static int __gluInvertMatrixd(const GLdouble src[16], GLdouble inverse[16])
{
int i, j, k, swap;
double t;
GLdouble temp[4][4];

for (i=0; i<4; i++) {
for (j=0; j<4; j++) {
temp[i][j] = src[i*4+j];
}
}
__gluMakeIdentityd(inverse);

for (i = 0; i < 4; i++) {
/*
** Look for largest element in column
*/
swap = i;
for (j = i + 1; j < 4; j++) {
if (fabs(temp[j][i]) > fabs(temp[i][i])) {
swap = j;
}
}

if (swap != i) {
/*
** Swap rows.
*/
for (k = 0; k < 4; k++) {
t = temp[i][k];
temp[i][k] = temp[swap][k];
temp[swap][k] = t;

t = inverse[i*4+k];
inverse[i*4+k] = inverse[swap*4+k];
inverse[swap*4+k] = t;
}
}

if (temp[i][i] == 0) {
/*
** No non-zero pivot. The matrix is singular, which shouldn't
** happen. This means the user gave us a bad matrix.
*/
return GL_FALSE;
}

t = temp[i][i];
for (k = 0; k < 4; k++) {
temp[i][k] /= t;
inverse[i*4+k] /= t;
}
for (j = 0; j < 4; j++) {
if (j != i) {
t = temp[j][i];
for (k = 0; k < 4; k++) {
temp[j][k] -= temp[i][k]*t;
inverse[j*4+k] -= inverse[i*4+k]*t;
}
}
}
}
return GL_TRUE;
}

static void __gluMultMatricesd(const GLdouble a[16], const GLdouble b[16],
GLdouble r[16])
{
int i, j;

for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
r[i*4+j] =
a[i*4+0]*b[0*4+j] +
a[i*4+1]*b[1*4+j] +
a[i*4+2]*b[2*4+j] +
a[i*4+3]*b[3*4+j];
}
}
}

static void __gluMultMatrixVecd(const GLdouble matrix[16], const GLdouble in[4],
GLdouble out[4])
{
int i;

for (i=0; i<4; i++) {
out[i] =
in[0] * matrix[0*4+i] +
in[1] * matrix[1*4+i] +
in[2] * matrix[2*4+i] +
in[3] * matrix[3*4+i];
}
}

GLint
gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz,
const GLdouble modelMatrix[16],
const GLdouble projMatrix[16],
const GLint viewport[4],
GLdouble *objx, GLdouble *objy, GLdouble *objz)
{
double finalMatrix[16];
double in[4];
double out[4];

__gluMultMatricesd(modelMatrix, projMatrix, finalMatrix);
if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE);

in[0]=winx;
in[1]=winy;
in[2]=winz;
in[3]=1.0;

/* Map x and y from window coordinates */
in[0] = (in[0] - viewport[0]) / viewport[2];
in[1] = (in[1] - viewport[1]) / viewport[3];

/* Map to range -1 to 1 */
in[0] = in[0] * 2 - 1;
in[1] = in[1] * 2 - 1;
in[2] = in[2] * 2 - 1;

__gluMultMatrixVecd(finalMatrix, in, out);
if (out[3] == 0.0) return(GL_FALSE);
out[0] /= out[3];
out[1] /= out[3];
out[2] /= out[3];
*objx = out[0];
*objy = out[1];
*objz = out[2];
return(GL_TRUE);
}