› Foros › Multiplataforma › Desarrollo
saulotmalo escribió:hola, estoy haciendo un juego tipo arkanoid, es en 3d y el motor que gasta usa las colisiones con aabb y para calcular una colision se usa una recta, creo la recta de la posicion actual a la posicion anterior de la esfera y calculo la interseccion y gracias a la normal de la aabb se la direccion de rebote. Casi funciona, algunas veces no rebota y continua bien... alguna idea?
testeb escribió:hola, soy saulotmalo, tengo dos cosas pensadas, la primera sería o bien crear una recta paralela y desplazar la que tengo y entonces envolvería la bola, o bien usar una perpendicular a la que creo en primera instancia y con un tamaño determinado, cual de los dos métodos creeis que será mejor?
saulotmalo escribió:hola, he estado probando un par de cosas y uff que lio! xD si quereis os pongo un ejecutable para que veais lo que pasa ya que el caso esque es muy raro :S sé que el algoritmo falla en algún lado pero no sé donde..
saulotmalo escribió:esta noche te envio al privado una copia del codigo ( quiero privacidad hasta que lo releasee y me fio de ti ;) ) te ordenaré un poco el código que ahora mismo solo lo leo yo xD.
ah si por cierto aabb aligned axis bounding box. toma nombre... por cierto en teoría las colisiones ya lo verás pero las debería detectar el propio motor pero pasa de mi... :( en fin ya te lo enseñaré creo que lo que me dijiste de la precision puede tener que ver, ya que siempre pasa en los límites, intentaré habilitar algún tipo de traza para que te sea más fácil... pero no te prometo nada :(
y muchas gracias por la ayuda!!!!! :)
// TestBoxes: compara si dos cajas colisionan
// x1,y1,z1 -> posicion espacial de box 1
// dx1,dy1,dz1-> ancho,alto,fondo de box 1
// x2,y2,z2 -> posicion espacial de box 2
// dx2,dy2,dz2-> ancho,alto,fondo de box 2
// retorno: 1 si hay colision y 0 si no la hay
int TestBoxes(float x1,float y1,float z1,float dx1,float dy1,float dz1,float x2,float y2,float z2,float dx2,float dy2,float dz2)
{
int f;
float ax1,ay1,az1,ax2,ay2,az2;
float bx1,by1,bz1,bx2,by2,bz2;
// obtiene coordenadas de comparacion de las cajas
ax1=x1-(dx1/2.0f);
ax2=ax1+dx1;
ay1=y1-(dy1/2.0f);
ay2=ay1+dy1;
az1=z1-(dz1/2.0f);
az2=az1+dz1;
bx1=x2-(dx2/2.0f);
bx2=bx1+dx2;
by1=y2-(dy2/2.0f);
by2=by1+dy2;
bz1=z2-(dz2/2.0f);
bz2=bz1+dz2;
f=0;
if((ax1>=bx1 && ax1<=bx2) || (ax2>=bx1 && ax2<=bx2) ||
(bx1>=ax1 && bx1<=ax2) || (bx2>=ax1 && bx2<=ax2)) f=1; // las x se cruzan
if(f==1)
{
if((ay1>=by1 && ay1<=by2) || (ay2>=by1 && ay2<=by2) ||
(by1>=ay1 && by1<=ay2) || (by2>=ay1 && by2<=ay2)) f=2; // las y se cruzan
}
if(f==2)
{
if((az1>=bz1 && az1<=bz2) || (az2>=bz1 && az2<=bz2) ||
(bz1>=az1 && bz1<=az2) || (bz2>=az1 && bz2<=az2)) f=3; // las z se cruzan
}
if(f==3) return 1; // hay colision
return 0; // no hay colision
}
// TestPointInBox: compara si un punto esta dentro de la caja
// x1,y1,z1 -> posicion espacial del punto a comprobar
// x2,y2,z2 -> posicion espacial del box
// dx2,dy2,dz2-> ancho,alto,fondo del box
// retorno: 1 si elpunto esta dentro del box y 0 si no lo está
int TestPointInBox(float x1,float y1,float z1,float x2,float y2,float z2,float dx2,float dy2,float dz2)
{
float bx1,by1,bz1,bx2,by2,bz2;
// obtiene coordenadas de comparacion de la caja
bx1=x2-(dx2/2.0f);
bx2=bx1+dx2;
by1=y2-(dy2/2.0f);
by2=by1+dy2;
bz1=z2-(dz2/2.0f);
bz2=bz1+dz2;
if((x1>=bx1 && x1<=bx2) && (y1>=by1 && y1<=by2) && (z1>=bz1 && z1<=bz2)) return 1; // el punto esta dentro de la caja
return 0;// el punto no esta dentro de la caja
}
Santo99 escribió:Madre dios, menudo lio estais montando para hacer una mierda de Arkanoid.
Estoy leyendo cada burrada ,¿sistemas de colisiones? ¿interpolacion? ¿angulos?. No hace falta nada de eso para hace un arkanoid clonico por muy 3d ke sea, simplemente teniendo la posicion y velocidad de la pelota, posicion de la raketa y una matriz con la posicion de los ladrillos y con unos cuantos IFes para calcular las diferencias de posicion para saber si chocan y si chocan las formulas del rebote son facilisimas no hace falta angulos ni nada.
Y Hermes por lo que estas comentando sobre tu "sistema de colision de cajas no alineadas con los ejes" vas por mal camino, calculando segmentos (aristas), cuando tengas 10 cajas tu sistema reventara cualquier ordenador, eso en la vida ira a una velocidad decente.
Simplemente con la diferencia de angulos de las 2 cajas, la distancia de sus centros y sus tamaños sobra.
Perdonad si suena como si os hechase la bronca, pero calcular si hay lineas que se cruzan es lo ultimo de lo ultimisimo ke hay ke hacer. Poco futuro en la programacion de juegos os veo asi .
Saludos y tomaroslo a bien.
Santo99 escribió:
Como yo te digo por cada iteracion haces 2 operaciones trigonometricas, 2 multiplicaciones y una resta. Osea ya seguro que es bastante mas rapido
asi que el render y la colision se me quedarán con un orden n+n= n... y como todos sabemos O(n) no está mal.
saulotmalo escribió:mmm lo he estado pensando, primero quiero responder a lo de usar un sistema tan complejo para un arkanoid... si... tiene su lógica no es por el arkanoid en si, es por aprender!! una vez lo sepa hacer para esto podré aplicar mejor colisiones en otro tipo de juegos.
A ver sobre lo de que las funciones de hermes son costosas... lo he pensado algorimicamente y no, no lo son. Suponiendo que quiero calcular colisiones para n ladrillos la funcion tendrá un coste fijo A(alfa) por calcular la colisión y un coste dependiente de la talla del problema n-> A*n como el n será mallor que A se puede despreciar n. Por lo tanto el coste de la función será lineal, al igual que todas las funciones del renderizado, ya que estas requieren n pasadas ya que se han de mirar n objetos. asi que el render y la colision se me quedarán con un orden n+n= n... y como todos sabemos O(n) no está mal.
Hermes escribió:blah ... pero el problema, mi querido saulot, es el de siempre: que hay mucha gente que habla mucho, pero ayuda muy poco.
$ gcc algo.c -o algo -W -Wall
$ ./algo
Test div: 0.391174
Test mul: 0.186806
$ gcc algo.c -o algo -W -Wall -O3
$ ./algo
Test div: 0.338365
Test mul: 0.168882
NeoRave escribió:
Espero que no te refieras a mi porque no veo el motivo, la verdad.
--
Respecto a mejorar algo, pues si no se me escapa nada (lo cuál tampoco me extrañaría), en la función TestPointInBox quizá podrías usar el producto flotante en lugar de la división flotante. (* 0.5f en lugar de / 2.0f).
No sé si el compilador hará algo al respecto ni cómo es la arquitectura en la que estáis trabajando (NDS quizá?). Pero al menos en todas las arquitecturas que he visto yo, la división flotante es bastante más lenta que el producto, más del doble quizá. He hecho una cutre prueba rápida en mi PC y si no me dejo nada en el tintero:
Donde Test div es la prueba con "/ 2.0f" y Test mul con "* 0.5"
Saludos y espero no haber dicho muchas mentiras xD
core::vector3df vertices[4]; // aqui almaceno la posicion de la caja de la bola escalada ( luego se ha de trasladar )
vertices[0].set(core::vector3df(-1.25,1.25,0));
vertices[1].set(core::vector3df(1.25,1.25,0));
vertices[2].set(core::vector3df(1.25,-1.25,0));
vertices[3].set(core::vector3df(-1.25,-1.25,0));
bool f=false;
for(int h=0;h<3;h++){
line.start=vertices[h]+node->getPosition();
line.end=vertices[h+1]+node->getPosition();
for (int i=0;i<selectoresBlokes.size();i++){
if(smgr->getSceneCollisionManager()->getCollisionPoint(line,selectoresBlokes[i], colision,triangulo)){
ITriangleSelector * tsAux;
f=true;
tsAux=selectoresBlokes[selectoresBlokes.size()-1];
selectoresBlokes[i]=tsAux;
selectoresBlokes.pop_back();
blokes[i]->remove();
blokes[i]=blokes[blokes.size()-1];
blokes.pop_back();
var=triangulo.getNormal();
if (var.X > 10){
modo=0;break;
}
if (var.X < -10){
modo=1;break;
}
if (var.Y > 10){
modo=2;break;
}
if (var.Y < -10){
modo=3;break;
}
}
}
if(f)break;
}
Hermes escribió:Lo que tu dices, es cierto, pero si te fijas arriba, he puesto una solucion que no necesita ni de division, ni de multiplicacion, ya que al fin y al cabo, las dimensiones de las cajas que albergaran la bola y los ladrillos, no van a variar y son conocidas.
saulotmalo escribió:ufff no puedo.. en serio... esto es imposible... he probado con lo tuyo hermes y tampoco me va, luego he portado tu idea y lo he mezclado con lo del motor, así las colisiones las hacía caja contra caja en vez de línea contra caja... y nada. Ya estoy desesperado posteo el código de esta parte por si alguien quiere hecharle un vistazo que igual soy yo que no lo veo o algo ufff pero increible...
saulotmalo escribió:Hermes a ver... creo que esto te va ha hacer mucha gracia... creo que es un arcanoid como tu lo llamas de toda la vida, mira os subo un ejecutable y lo probais a ver que os parece y tal... mirad el fallo solo sale contadas ocasiones y en realidad no sé a que se debe.
http://www.megaupload.com/?d=3J520CG3
yo casi me he dado por vencido...
pd: si me decís como os va de velocidad y tal tambien sería un detalle, ya que a mi me va a 60 fps guay... pero sé que con menos de un p IV y una gráfica de nueva generación o de la anterior le costará xD
saulotmalo escribió:Voy a ver si me aclaro porque no se si se podrá hacer menor la caja en el motor sino vuelvo a instalar tus funciones y listo, crees que haciendo menor la caja de la bola bastaría?? o no sería un buen método?
saulotmalo escribió:mira los ladrillos hazte cuenta de que están totalmente juntos, ya que la caja que envuelve al modelo se tocan entre si, eso lo habías hacertado, he pensado en estrechar la caja en el eje Y ( de arriba a abajo)