Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Colisiones, estoy jodido.

Iniciado por misscelan, 14 de Julio de 2006, 12:04:54 AM

« anterior - próximo »

misscelan

Bueno, sigo con la carga de los jodidos mapas del quake 3.

Ahora mismo estoy con la carga de objectos dinámicos: puertas, péndulos, plataformas, etc...

Esta es la información de la estructura de los objectos:

typedef struct
{
   tvector3f min;          //
   tvector3f max;          // mínimo y máximo para el bounding box
   int faceIndex;          // índice al vector de caras
   int numOfFaces;         // número de caras
   int brushIndex;         // índice al vector de planos de colisión
   int numOfBrushes;       // número de planos de colisión
}tBSPModel;

Esta es la estructura de los planos

typedef struct
{
   tvector3f vNormal;    
   float d;              
}tBSPPlane;

Mi modelo principal está contenido dentro de una BBox por lo que la colisión entre el personaje principal y los objectos dinámicos mediante BBoxes no es muy difícil.

El problema es que el BBox es sencillo para detectar la colisión, pero mi personaje se queda pegado al objecto. Para poder deslizarme (hacer sliding, o como se diga) con el objecto necesito el plano de colisión, no quiero ni pensar como extraer el plano de colisión con las BBox además si en la estructura viene información sobre los planos de colisión será para usarlos no?.

Ya tengo hecho el procedimiento de colisión usando los brushes(planos de colisión) el problema es que está hecho para objectos estáticos, para los dinámicos supongo que necesitaría recalcular la información de los planos (por si el objecto rota, se traslada, etc..)

Y ahí está mi duda, la normal es un simple vector, rotarlo y trasladarlo no debería ser muy difícil, lo que no sé es qué hacer con la componente d cuando mueva el objeto,  ¿calculo la distancia de la normal a 0,0,0?

Todo esto son suposiciones pero es la única manera que encuentro de solventar esto.

Alguien que me eche una manita.

Muchas gracias.

marcode

Si d es la distancia del plano de colisión al centro del objeto, ¿no deberá ser la misma aún después de rotarlo?
size=9]afortunadamente siempre ha habido alguien dispuesto a reinventar la rueda, de lo contrario seguiríamos usando un disco de piedra con un agujero.[/size]

Elvis Enmanuel

Creo que te refieres a esto:

/*
   Just think about what the plane equation really is:
   A * x + B * y + C * z + D = 0

   Every point that satisfies this -equation- is on the plane.
   Let's add a w component (equal to 1 for all points) to homogenize it:

   A * x + B * y + C * z + D * w = 0

   Now what we mean with transforming a plane is getting the A, B, C, D
   factors that make this equation true for all the points in the new space.
   And if we've got a matrix to transform points (x' y' z' w') from the new
   to the old space (x y z w):

   [m11 m12 m13 m14] [x']
   [m21 m22 m23 m24].[y'] = [x y z w]
   [m31 m32 m33 m34] [z']
   [m41 m42 m43 m44] [w']

   Or written out long:

   x = x' * m11 + y' * m12 + z' * m13 + w' * m14
   y = x' * m21 + y' * m22 + z' * m23 + w' * m24
   z = x' * m31 + y' * m32 + z' * m33 + w' * m34
   w = x' * m41 + y' * m42 + z' * m43 + w' * m44

   Now we can simply substitute these into the original plane equation and we
   get a new equation for points with coordinates (x' y' z' w'):

   A * (x' * m11 + y' * m12 + z' * m13 + w' * m14) +
   B * (x' * m21 + y' * m22 + z' * m23 + w' * m24) +
   C * (x' * m31 + y' * m32 + z' * m33 + w' * m34) +
   D * (x' * m41 + y' * m42 + z' * m43 + w' * m44) = 0

   This is a correct answer but obviously we'd like to simplify it so we get
   new A, B, C, D factors. All we have to do is group the coordinates together:

   (A * m11 + B * m21 + C * m31 + D * m41) * x' +
   (A * m12 + B * m22 + C * m32 + D * m42) * y' +
   (A * m13 + B * m23 + C * m33 + D * m43) * z' +
   (A * m14 + B * m24 + C * m34 + D * m44) * w' = 0

   So the new plane equation factors A', B', C', D' are:

   A' = A * m11 + B * m21 + C * m31 + D * m41
   B' = A * m12 + B * m22 + C * m32 + D * m42
   C' = A * m13 + B * m23 + C * m33 + D * m43
   D' = A * m14 + B * m24 + C * m34 + D * m44

   Now look, this is exactly the matrix transformation of (A B C D) into
   (A' B' C' D')! Note that this matrix transforms from 'new' to 'old'
   coordinates for points, so for transforming the plane equation you're
   actually using the inverse matrix of what you might have expected.

   This derivation can be 'simplified' by using matrix notation all the time,
   but I hope writing everything explicitely is clearer in this case...*/

SPlane const CMatrix::transform(SPlane p,SMatrix4x4 *m) {
   SPlane result;
   result.normal.x = (p.normal.x*m->M00 + p.normal.y*m->M10 + p.normal.z*m->M20 + p.d*m->M30);
   result.normal.y = (p.normal.x*m->M01 + p.normal.y*m->M11 + p.normal.z*m->M21 + p.d*m->M31);
   result.normal.z = (p.normal.x*m->M02 + p.normal.y*m->M12 + p.normal.z*m->M22 + p.d*m->M32);
   result.d = (p.normal.x*m->M03 + p.normal.y*m->M13 + p.normal.z*m->M23 + p.d*m->M33);
   return result;
}

Si tienes el índice de las caras y el número de ellas, tendrás una serie de planos para calcular (con el cross-product), despues hallar la colision con una o varias de ellas.

ains.

misscelan

Gracias por las respuestas.

Al final hice lo que no quería hacer, como tenía los puntos de los planos del BBox, resté un par e hice el producto vectorial para sacar la normal, luego la normalizé y la multiple por otro punto del plano para sacar la D.

Con unos pocos ifs compruebo si colisionan las bbox, si es así actualizo los planos para poder determinar con cual me cocho y hacer el deslizamiento.

Para el procedimiento de colisión con deslizamiento podía reutilizar el estático.

Miré un poco por el código de un visor de mapas del quake, pero me parecío entender que cada ciclo si el objecto se movía lo reorganizaba dentro del arbol bsp estático, se me abrieron las carnes y no seguí mirando.

Como tampoco voy a usar muchos objetos móviles pues bueno tampoco me preocupa una super optimización de este prodec. De todas maneras cualquier sugerencia es bienvenida.

Muchas gracias.

Un saludo.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.