Capa de abstracción para Chipmunk.

Started by Erkosone, January 16, 2013, 04:56:10 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Erkosone

Esta es la forma que está tomando la función.. no está testeada.. estoy montandola ahora mismo.. voy por un café que la neurona me pide azucar XD..
Os lo pego por si alguien tiene curiosidad.. es bastante sencillo de seguir.. y tengo que optimizarlo un montón cuando lo termine.. pero básicamente esta es la estructura de la función en si misma..





//.............................................................
//.............................................................
//..............VECTORIZAR UN GRAFICO EN LINEAS................
function Physics_entity_calculate_shape();
private
   // variables para el scanner de contorno..
   int ancho_;            // ancho de la imágen en pixels..
   int alto_;            // alto de la imágen en pixels..
   int x_inicial = -1;      // X del inicio del contorno..
   int y_inicial = -1;      // Y del inicio del contorno..
   int secure_steeps = -4;   // En el quinto paso por la tortuga será mayor que cero y entonces tendré la certeza de que no estoy
                     // En el punto inicial del contorno..
   
   // variables para el vectorizador de contorno..                  
   int _x_[4];            // buffer de 5 posiciones X para pixels con color..
   int _y_[4];            // buffer de 5 posiciones Y para pixels con color..
   int _steep_ = 0;      // indica los pasos de relleno del buffer..
   int vertices = 1;      // Empezamos a rellenar en el c_point número 1.. el cero lo dejamos para ubicar al gráfico en pantalla..
   int med_x_;            // indica la média aritmética del buffer de variables X..
   int med_y_;            // indica la média aritmética del buffer de variables Y..
   int back_x_;         // indica la posición en X del c_point anterior..
   int back_y_;         // indica la posición en Y del c_point anterior..
   int umbral_angulo_ = 10000;   // umbral en angulo que debe superar una comparación entre vectores para considerarse fuera de una recta el segundo de ellos..
begin
   // Heredar gráfico del proceso que realiza la llamada..
   file = father.file;
   graph = father.graph;
   
   // No pintar nada en pantalla desde esta función..
   alpha = 0;
   
   // Obtener las dimensiones del gráfico..
   ancho_ = map_info(file, graph, g_width);
   alto_  = map_info(file, graph, g_height);
   
   // Buscar un pixel con color diferente de cero para establecer el inicio del contorno...
   for(y=0; y<alto_; y++)      // Scanear filas de la imágen..
      for(x=0; x<ancho_; x++)   // Scanear columnas de la imágen..
         if( map_get_pixel( file, graph, x, y ) <> rgb(0,0,0) );
            // Guardo las coordenadas del punto que tomaré como inicio del contorno para la imágen..
            x_inicial = X;
            y_inicial = Y;
            break;
         end
      end
   end
   
   
   // Si la imágen no contenía ningún pixel con color entonces se termina esta función..
   // Valor de retorno -1 para este error..
   if(x_inicial == -1 or y_inicial == -1)
      Return(-1);
   end
   
   // ya que tenemos la posición inicial del contorno.. le creamos ya el primer vector..
   set_point(file, graph, vertices, x, y);
   // pasamos al siguiente punto de control..
   vertices ++;
   
   
   // Comienza el scan real de contorno..
   while(true)
      // Tortuga de Pappert, COLOR DETECTION, método excelente..
      if(map_get_pixel(file, graph, x, y) <> rgb(0, 0, 0) )
         
         // _vectorGraphic_ por _buffer_ de 5 pixels..
         if( _steep_ < 5)         // si quedan posiciones del buffer por rellenar..
            _x_[_steep_] = x;      // las relleno..
            _y_[_steep_] = y;      // las relleno..
             _steep_ ++;         // paso a la siguiente posición del buffer..
               else            // si el buffer está lleno.. entonces toca mirar si hay que crear un nuevo vector..
                  
                  if(vertices > 1)
                     
                     // calculo la posición real para el nuevo vector.. será la media aritmética de las 5 lecturas tomadas en el buffer..
                     med_x_ = (_x_[0] + _x_[1] +_x_[2] + _x_[3] + _x_[4]) / 5;
                     med_Y_ = (_y_[0] + _y_[1] +_y_[2] + _y_[3] + _y_[4]) / 5;
                     
                     // obtengo la posición del vector anterior..
                     get_point( file, graph, vertices-1, &back_x_, &back_y_ );
                     
                     // comparo el angulo entre los vectores que forman ambos puntos de control..
                     // si sobrepasan un umbral en angulo se considerará que es necesario crear un nuevo punto de control..
                     // si no se pasa el umbral se considerará que el punto actual está dentro de la trayectoria de una recta..
                     // y en consecuencia sería un desperdicio de performance crear mas puntos de control para definir una unica recta..
                     z = fget_angle( back_x_, back_y_, med_x_, med_y_);
                     if(abs(z) > umbral_angulo_)
                        set_point(file, graph, vertices, med_x_, med_y_ );
                        vertices ++;   // nos colocamos en el siguiente punto de control..
                        _steep_ = 0;   // y ahora volvemos a empezar a rellenarlo..
                        for(z=0; z<5; z++)   // pero primero pongo a cero el buffer..
                           _x_[z] = 0;      // pues eso.. lo pongo a cero..
                           _y_[z] = 0;      // pues eso.. lo pongo a cero..
                        end
                     end
                  end
         end
         
         angle+=90000;
         advance(1);
      end
      // Tortuga de Pappert, COLOR MISSING, método excelente..
      if(map_get_pixel(file, graph, x, y) == rgb(0, 0, 0) )
         angle-=90000;
         advance(1);
      end
      
      // Aumento este contador.. es el que pasados 5 pasos me dejará comprobar si la posición actual es la inicial..
      // y entonces asumiré que el contorno se ha recorrido al completo..
      secure_steeps ++;
      
      if(secure_steeps > 0 )
         if(x_inicial = X && y_inicial == Y)      // he vuelto al punto de partida del contorno??
            BREAK;                        // si es cierto se termina el scanner..
         end
      end
      
   end
end
//.............................................................

FreeYourMind

mañana lo pruebo y veremos si te llebas uno de jabugo o de cebo  ;D

Erkosone

Todavía no está terminada, esa es la forma que está tomando pero estoy todavía implementandolo en el api que tengo, cuando lo tenga listo lo cuelgo con vídeo tutorial extra.

Erkosone

Primera parte del tema solucionada!!


Ya tengo la función: Physics_entity_calculate_shape();

Al usarla desde cualquier proceso lo que sucederá es que se rellenará la tabla de c_point del gráfico del proceso que realiza la llamada con los puntos que definen el contorno del shape poligonal  ;D


El código es una copiada descarada de uno de los tutoriales de Prg XD.. pero adaptado a las necesidades de este caso concreto..


Ahora toca la parte que creo que será mas sencilla.. es la de crear el shape para el proceso a partir de esta información de puntitos ;)


Sigo con ello.. creo que en breve estará listo y será coser y cantar hacer shapes super complejas con un pedo de función.
Gracias PRG por tus códigos de ejemplo y por el algoritmo de vectorización de imagen, es un trabajo soberbio te lo digo de verdad, puede preguntarte si lo diseñaste tu solo?? te basaste en algún otro trabajo de alguien para poder hacerlo o es de tu propia cosecha? por que si me dices que es tuyo desde cero te puedo decir que OLE MACHOTE!

Erkosone

Estoooooo....


Vale... haber como lo digo XD...


Estoy flipando en colores...


Yo matandome a montar las funciones y bla bla bla aquí pasando las noches alimentandome a cacahuetes y café jajajaja... y oye.. me da por probar por eso de que la curiosidad mató al gato..


Pues eso.. que me ha dado por probar a meterle un TYPE_CONVEX_POLIGON así directamente ya por el cansancio a un objeto.. y COÑO!! la lib calcula el shape poligonal ella solita!


No se si ya es el sueño o que.. pero estoy flipando.. acto seguido "que se me ha caido el puñetero café encima XD.." he vuelto a poner TYPE_BOX y coño!! la cosa cambia y mucho!




No se si estoy ya loco o que.. pero me da que la librería ya coje el shape y hace todo esto solita, weno.. no es que me dé.. es que lo estoy probando y es así, funciona perfecto  :o

Erkosone

Verificado al 100%


No hace falta para nada especificar un shape complejo y un arreglo de vectores para crear una forma poligonal, no salgo de mi asombro.. hasta calcula el centro de gravedad todo automático en función del area del poligono.


Estoy usando una versión de mi API que todavía no he liberado, calcula varias cosas extra cuando hacemos un Physics_entity_build() y el resultado es soberamente bueno.


Voy a montar un ejemplo ahora mismo en vídeo y cuelgo la ultima versión que tengo que ya incluye un sistema ridiculamente simple para crear perros guardianes para los joint´s, osea, los watchdog´s de toda la vida en C.


Incomming.. ahora si que estoy contento jeje.. esto es la leche, funciona mas que perfecto.

Prg

Arriba comentabas que si me hice solito lo de la vectorización: La verdad es que uní partes mías y partes ajenas. Yo codifiqué todo, pero la idea del algoritmo de aproximación poligonal ya es vieja. Lo mío fue la parte del cálculo de bordes por morfología matemática + limpieza de bordes con morfología matemática y cálculo de chi (Se define como dos veces el número de conexiones potenciales del resto del objeto con el pixel que se analiza). El cálculo de bordes usa operaciones binarias de corto circuito para acelerarse... Esa es mi cocecha. A partir de estos bordes reviso elementos conexos y obtengo sus coordenadas; luego identifico si es un contorno cerrado o abierto para luego aproximarlo por partición sucesiva.

La partde convex_poly... síp, la librería las calcula sola. REvisa el test 16 para más información

La lista de text es esta:

Quotetest00        Pelota rebotando
                    addInanimateShape
                    lphysics.mass
                        lphysics.ELASTICITY
                        lphysics.friction
                        lphysics.ShapeType
                        forceCreateBody()
                        lphysics.inertia
                        GETOPTIMALINERTIA()
                        INTERSECTSBB(id2)       --> colisión
                        muerte de procesos con física


test01        Cuerpos sin gravedad estilo bomberman, Empujar objetos, Movimiento de personaje y Traspasar objetos.
                        gphysics.bias_coef
                        gphysics.damping
                        lphysics.static
                        lphysics.group
                        TYPE_CONVEX_POLYGON
                        cpMomentForCircle()
                        TYPE_CIRCLE
                        CP_NO_GROUP
                        TYPE_box

test02        Slew, cuerpos estáticos y Pirámide de dominós.
                        gphysics.iterations
                        gphysics.collision_slop
                        gphysics.sleepTimeThreshold
                        cpvadd()
                        Slew()

test03        Polígonos definidos por arreglo y lphysics.group
                  lphysics.params
                  TYPE_CONVEX_POLYGON

test04        Movimiento con el ratón, Joint, Colisión puntual, gphysics.interval, y uso de boundingbox (intersecciones y envoltura).
                  gphysics.SLEEPTIMETHRESHOLD
                  infinityf()
                  cpBBIntersects
                  cpBBmerge
                  DefConstraintF
                  CP_C_MAXFORCE
                  CP_C_BIASCOEF
                  RemoveConstraint
                  ShapeCacheBB
                  cpBB

test05        Varias pelotas que se pueden mover, piso formado por línea y función para obtener los shapes y constraints de un proceso, gphysics.bias_coef.
                  COLLISIONHANDLERNEW
                  SpaceSegmentQueryFirst
                  SegmentQueryHitPoint
                  SegmentQueryHitDist
                  GETCOLLISIONINFO
                  GETCONSTRAINTS
                  GETSHAPES

test06        phresolution, pin, joint, motor y resortes.
                  addPivotJoint
                  addSimpleMotor
                  addPinJoint
                  addDampedRotarySpring
                  infinityf

test07        Física de juego tipo plataformas, péndulos, objetos con centro distinto del (0,0), Movimiento por fuerzas
                  cpContactPointSet
                  cpvperp
                  cpvmult
                  cpvadd
                  DEFBODYP
                  CP_C_V
                  GETCOLLISIONINFO
                  cpfclamp

test08        Eliminar zona y eliminar todos los cuerpos físicos. Constraints
                  cleanSpace
                  WORLD2LOCAL
                  RemoveConstraint
                  cpMomentForPoly
                  addPinJoint
                  addSlideJoint
                  addPivotJoint
                  addGrooveJoint
                  addDampedSpring
                  addDampedRotarySpring
                  addRotaryLimitJoint
                  addRatchetJoint
                  addSimpleMotor
                  DefShapeI
                  CP_C_LAYERS
                  NOT_GRABABLE_MASK
                  addInanimateShape
                  COLLISIONHANDLERNEW
                 
test09        Uso de constraints, Modificación de propiedades de constraints, Procesos con más de un shape, Simulación de máquina TheoJansen.
                  cpMomentForSegment
                  ADDPIVOTJOINT2
                  ADDCIRCLESHAPE
                  defShapef
                  ADDPINJOINT
                  SETPINJOINTPROPERTIES
                  CP_C_DIST
                  DefShapeI
                  CP_C_LAYERS
                  NOT_GRABABLE_MASK
                  CP_C_E
                  CP_C_U
                  DefShapeF
                  cpvforangle
                  CM_PI
                  ADDSIMPLEMOTOR
                  SETSIMPLEMOTORPROPERTIES
                  DEFCONSTRAINTF
                  CP_C_MAXFORCE

test10        Generación de terrenos mediante .cpt
                  COLLISIONHANDLERNEW
                  addInanimateShape
                  cpMomentForCircle
                  cpvperp
                  cpvmult
                  cpvadd
                  GETCOLLISIONINFO
                  cpBodyActivate
                  cpContactPointSet

test11          Handlers de collision.  Omitir respuesta de cuerpos al colisionar (Útil para juegos de plataformas donde el personaje colisiona con el piso sólo cuando desciende y no cuando asciende (aquí revisaríamos la dirección de la normal de colisión para filtrar las colisiones)).
                  SPACEADDCOLLISIONHANDLER
                  SPACEREMOVECOLLISIONHANDLER
                  Ejemplo de handler presolve, postsolve, separate e inicia.

test12          Simulando objeto que cae en un líquido
                  addInanimateShape
                  SPACEADDCOLLISIONHANDLER
                  GETARBITERPOINT
                  MODARBITERPROCESSA
                  ResetForces
                  ApplyForce
                  DefBodyP
                  cpfclamp
                  lphysics.collisionType
                  updateVelocity

test13          Lista de cuerpos colgados y destrucción de constraints al superar un umbral en la fuerza aplicada (Destrucción de uniones y resortes)
                  ADDSLIDEJOINT
                  DEFCONSTRAINTF
                  CONSTRAINTSETPOSTSOLVEFUNC
                  RemoveConstraint
                  getConstraintFatherA
                  getConstraintFatherB
                  CP_C_MAXFORCE
                  GETCONSTRAINTF
                  SpaceGetCurrentTimeStep
                  constraintGetImpulse

test14          Mover un cuerpo y hacer que se vaya frenando con el tiempo
                  APPLYIMPULSE
                  gphysics.damping

test15        Simulando una soga
                  APPLYIMPULSE
                  addPivotJoint2
                  WORLD2LOCAL

test17         simulación de soga.

test16        Creación automática de cuerpos convexos
                         CALCULATECONVEXBODY
            ejemplo con uso de size

test18        Creación de cuerpos a partir de gráfico

test19        Simulación y pintado de agua...


El problema de mi algoritmo de convex es que genera un cuerpo convexo de toda la imagen, pero esto es para lo que normalmente se usa.

El algoritmo de aproximación poligonal por su parte genera un cuerpo poligonal para cada elemento conectado (Hace un etiquetado de componentes conexas al vuelo, si es que lo podría llamar así a lo que hace).
en humos puedes mover la camara con los cursores. es necesario para los niveles a partir del dos :)

Prg

Quote from: Erkosone on February 03, 2013, 02:28:08 AM
Verificado al 100%


No hace falta para nada especificar un shape complejo y un arreglo de vectores para crear una forma poligonal, no salgo de mi asombro.. hasta calcula el centro de gravedad todo automático en función del area del poligono.


Estoy usando una versión de mi API que todavía no he liberado, calcula varias cosas extra cuando hacemos un Physics_entity_build() y el resultado es soberamente bueno.


Voy a montar un ejemplo ahora mismo en vídeo y cuelgo la ultima versión que tengo que ya incluye un sistema ridiculamente simple para crear perros guardianes para los joint´s, osea, los watchdog´s de toda la vida en C.


Incomming.. ahora si que estoy contento jeje.. esto es la leche, funciona mas que perfecto.

El algoritmo calcula solo cuerpos convexos...

Splinter comentaba algo de una tabla.

Yo sólo ofrezco la librería y algunos test-examples... Lo que sí podría hacer es listar las nuevas características... je je... pero hacer una tabla, Erksone me ganaría ya que el ofrece lo de mi librería y lo que él está haciendo.

Erksone nos ha creado código para facilitar el uso de la librería mod_chipmunk. Gracias amigo.



en humos puedes mover la camara con los cursores. es necesario para los niveles a partir del dos :)

Erkosone

No se merecen Prg, yo solo comparto igual que compartís vosotros. ;)

Erkosone

Nuevo tutorial de camino jeje..
Contenido:
- Shapes poligonales.
- Funciones "perro guardián".
- Nueva función Physics_joint_get_impulse() que retorna el porcentaje de esfuerzo realizado por un joint.


Lo estoy compilando.. en cuanto esté listo lo cuelgo con la ultima versión del api.

SplinterGU

a que te referis con las funciones "Watch Dog"? un watch dog es un metodo por el cual se envian pulsos con una frecuencia preestablecida para confirmar que el sistema sigue vivo y no congelado y en caso de falla (no recibir una de estas señales) reinicia todo el sistema... pero como ayuda esto a esto al motor de fisica? podrias dar detalles?
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

SplinterGU

Quote from: Prg on February 03, 2013, 02:51:00 AM
Quote from: Erkosone on February 03, 2013, 02:28:08 AM
Verificado al 100%


No hace falta para nada especificar un shape complejo y un arreglo de vectores para crear una forma poligonal, no salgo de mi asombro.. hasta calcula el centro de gravedad todo automático en función del area del poligono.


Estoy usando una versión de mi API que todavía no he liberado, calcula varias cosas extra cuando hacemos un Physics_entity_build() y el resultado es soberamente bueno.


Voy a montar un ejemplo ahora mismo en vídeo y cuelgo la ultima versión que tengo que ya incluye un sistema ridiculamente simple para crear perros guardianes para los joint´s, osea, los watchdog´s de toda la vida en C.


Incomming.. ahora si que estoy contento jeje.. esto es la leche, funciona mas que perfecto.

El algoritmo calcula solo cuerpos convexos...

Splinter comentaba algo de una tabla.

Yo sólo ofrezco la librería y algunos test-examples... Lo que sí podría hacer es listar las nuevas características... je je... pero hacer una tabla, Erksone me ganaría ya que el ofrece lo de mi librería y lo que él está haciendo.

Erksone nos ha creado código para facilitar el uso de la librería mod_chipmunk. Gracias amigo.





no se trata de ganar o perder... la pregunta va mas en "por que deberia usar la libreria de Erkosone en lugar de la de Prg o a la inversa?" y no me vale que me digan, porque la de Erkosone esta mas completa o tiene mas features.

me interesa saber, diferencias de uso, funcionalidad que trae una y la otra, en que fallan, en que tienen soporte parciales (por ejemplo, entendi que dicen que el sistema detecta formas convexas... y que onda con las concavas? o quizas seguramente estoy entendiendo mal)... pregunto todo esto, desde la mas absoluta ignorancia del tema... pero seguramente asi como me lo pregunto yo, se lo preguntaran mucho.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Erkosone

#72
Si, Splinter, mira cuelgo ya el link del vídeo que he montado para enseñar las funciones estas watch dog y algunas cosas mas y supongo que viendolo se entiende a la primera el concepto, en esencia es el mismo que cuando se programa un watch dog para la integridad de un circuito electrónico basado en un microcontrolador, he sacado de ahí el nombre por que pienso que es lo que mas se asemeja a su uso en la lib.


Quiero aclarar que todo el trabajo que yo he añadido está profundamente ligado y se apoya en el trabajo de Prg, el api que muestro no es mas que una capa de abstracción de muchos aspectos que complican el diseño de un juego por que requieren un mayor manejo y control de la chipmunk, simplemente hacen mas sencillas operaciones que ya existen en la librería o agrupan un set de operaciones para realizar acciones que son necesarias de forma repetitiva en los vídeo juegos.


Originalmente la PhysicsMotion no era "API", era "LIB" y esa versión si que es un motor de física dinámica en si mismo, pero este para bennu está apoyado en los calculos de la chipmunk que son bastante mejores en todo  ;D


Iba a colgar el vídeo en la sección recursos pero no la veo accesible en el foro, no veo nada del foro en español, ande está ahora?

Erkosone

Bueno, lo he encontrado accediendo desde el finder, ya está disponible el nuevo vídeo tutorial sobre estos temas y el descargable para trastearlo ;)