Nota: Es necesario tener experiencia con realidad Aumentada. Si aún no lo has hecho entra al tutorial inicial. Aquí
Tambien es necesario saber como diseñar objetos md2. Entra aquí

 

Md2 es un tipo de formato que permite la animación interna de objetos 3d. Aunque lo usan muy pocos, processing puede asimilar muy bien sus funciones sin envidiar al entrañable DAE que por azares del destino no existe librería que la importe. Sí, efectivamente, no existe dicha librería que logre leer objetos collada, almenos por ahora no.

Debido a que la creatividad surge de la necesidad de expresarse. Meses atrás busqué la forma de proyectar animaciones  en realidad aumentada. Hoy les explicaré como desarrollarlo:

 

  • Primero necesitaremos una archivos: “GL_Vertex. java”, “MD2_Loader.java”, “MD2_Model.java”, “MD2_ModelState.java”, “Vector3.java” y finalmente el archivo pde. Cada uno de estos elemenos contiene una parte importante para la visualización del archivo md2. Si faltara alguno de ellos no se podría ejecutar el archivo.

Aquí les dejo los archivos correspondientes para que funcione el MD2 Loader. El autor es Peter Lager y liberó estos codigos hace algunos meses.  

No se preocupen si al descargarlo no se ve bien. Ahora les enseñaré como unirlo con realidad aumentada.

  • Una vez descargado el zip. Incorpora los elementos de Nyartoolkit y lo integraremos con los demas:

import processing.opengl.*;
import processing.video.*;
import jp.nyatla.nyar4psg.*;
import processing.opengl.*;
import javax.media.opengl.*;

  • Tambien llamaremos a las funciones

Capture cam;
NyARBoard marcador;
PMatrix3D dmat, dmatOrg;

float interpolate = 0;
boolean showWire = false;

PGraphics3D g3;

MD2_Loader loader;
MD2_Model model1;

  • Trabajaremos con el Void Setup.

void setup() {
size(600,420,OPENGL);
frameRate(60);
marcador=new NyARBoard(this,width,height,”camera_para.dat”,”patt.hiro”,80);
marcador.gsThreshold=100;
marcador.cfThreshold=0.4;

cam=new Capture(this,width,height);

loader = new MD2_Loader(this);

model1 = loader.loadModel(“models/ogro/iconoblender.md2”, “models/ogro/iconoblender.jpg”);

if(model1 != null){
MD2_ModelState[] mdlStates = model1.getModelStates();

for(int i = 0; i < mdlStates.length; i++){

}

}
if(model1 != null) model1.setState(9);

registerPre(this);
}

void pre(){
interpolate = PApplet.constrain(2.1/(frameRate + 0.01), 0.001, 0.8);
if(model1 != null)
model1.update(interpolate);

}

  • Trabajaremos con el Void Draw

void draw() {
if (cam.available() !=true) {
return;
}

cam.read();

hint(DISABLE_DEPTH_TEST);
image(cam,0,0);
hint(ENABLE_DEPTH_TEST);
if(marcador.detect(cam)) {

PGraphicsOpenGL pgl = (PGraphicsOpenGL) g;

marcador.beginTransform(pgl);

pushMatrix();

if(showWire){

}
else {
noStroke();
fill(128);
}
if(model1 != null) model1.render();

popMatrix();

G4P.draw();
marcador.endTransform();
}
}

<p

20 COMMENTS

  1. Anduvo de lujo.
    te dejo la versión para Mac:
    /////////////////////////////////////////
    import processing.opengl.*;
    import processing.video.*;
    import jp.nyatla.nyar4psg.*;
    import processing.opengl.*;
    import javax.media.opengl.*;

    Capture cam;
    NyARBoard marcador;
    PMatrix3D dmat;
    PMatrix3D dmatOrg;

    float interpolate = 0;
    boolean showWire = false;

    PGraphics3D g3;

    MD2_Loader loader;
    MD2_Model model1;

    void setup() {

    //START turning Camera state= on;
    try {
    quicktime.QTSession.open();
    }
    catch (quicktime.QTException qte) {
    qte.printStackTrace();
    }
    //END turned Camera state= on;

    size(600,400,OPENGL);
    frameRate(60);
    marcador=new NyARBoard(this,width,height,”camera_para.dat”,”patt.edcp”,80);
    //Reemplazar el 5to parametro (patt.edcp) por nuestro patron exportado desde ARToolKit Marker Generator.app
    marcador.gsThreshold=100;
    marcador.cfThreshold=0.4;

    cam=new Capture(this,width,height);

    loader = new MD2_Loader(this);

    model1 = loader.loadModel(“models/square.md2”, “models/CaraSidonia.jpg”);
    //Reemplazar el primer parametro por nuestro .MD2 y el segundo con la textura que cubre el MD2

    if(model1 != null){
    MD2_ModelState[] mdlStates = model1.getModelStates();

    for(int i = 0; i < mdlStates.length; i++){

    }
    }

    if(model1 != null) model1.setState(9);
    registerPre(this);
    }

    void pre(){
    interpolate = PApplet.constrain(2.1/(frameRate + 0.01), 0.001, 0.8);
    if(model1 != null) model1.update(interpolate);

    }

    void draw() {
    if (cam.available() !=true) {
    return;
    }

    cam.read();

    hint(DISABLE_DEPTH_TEST);
    image(cam,0,0);
    hint(ENABLE_DEPTH_TEST);
    if(marcador.detect(cam)) {

    PGraphicsOpenGL pgl = (PGraphicsOpenGL) g;

    marcador.beginTransform(pgl);

    pushMatrix();

    if(showWire == false){
    noStroke();
    fill(128);
    }

    scale(20);
    //scale lo uso para agrandar mi MD2 (se veia diminuto)

    if(model1 != null) model1.render();

    popMatrix();
    G4P.draw();
    marcador.endTransform();
    }
    }

  2. hi there!!

    when i try to run the code i get a error message saying:

    The file “models/ogro/iconoblender.jpg” is missing or inaccessible, make sure the URL is valid or that the file has been added to your sketch and is readable.
    java.io.IOException: Stream closed
    at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:134)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
    at processing.core.PApplet.loadBytes(Unknown Source)
    at MD2_Loader.createBuffer(MD2_Loader.java:111)
    at MD2_Loader.loadModel(MD2_Loader.java:83)
    at md2_clear.setup(md2_clear.java:99)
    at processing.core.PApplet.handleDraw(Unknown Source)
    at processing.core.PApplet.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:619)
    Failed to open buffer

    any ideas?!

    by the way great blog… very useful!!

    cheers

    • Hi, that’s because there’s no such a route on the example (no “models” folder)… try getting an md2 model, place it on your sketch folder and update the routes on the load model lines.

    • Hi!

      Maybe the url to the IMAGE is wrong “models/ogro/iconoblender.jpg”. Please change for the url of your computer.

    • Yo tengo la versión 2.49b y no he cambiado jejeje. Será eso? Pruebalo. La verdad no sabía que las nuevas versiones de Blender eliminaron la exportación de MD2. Eso sería un gran problema :S

  3. Emilio, en el ejemplo que has puesto y el zip, no hay el modelo ni la textura por ello que no funciona este codigo.

    Porfa los puedes poner???

    • Hola Jesus. El zip es el código de MD2 para que tu lo integres a tu código de realidad aumentada. Si contiene la textura que en este caso es una imagen que se direcciona a una carpeta. Mira la siguiente linea:
      model1 = loader.loadModel(“models/ogro/iconoblender.md2”, “models/ogro/iconoblender.jpg”);

      ICONOBLENDER.JPG es el skin de objeto.

  4. Me olvidaba, la idea es hacer esto que muestras en tu video:
    [youtube=http://www.youtube.com/watch?v=4qlaZHCmeio&w=640&h=390]

  5. Colabora me pues la ruta me sale error y ni idea de como hacerlo porfavor quiero aprender lo necesito urgente mi correo es smarquez1991@misena.edu.co si me puedes enviar tutoriales por favor es que he buscado pero nada solo encuentro ejemplos en su blog pero hasta el momento no me a dado nada , vi tu conferencia pero gastando ojo haber como era pero no no he podido si me puedes hacer el favor te lo agrade seria demasiado ; estoy loco por aprender pero no he encontrado buenos tutoriales o mejor dicho no los he sabido aplicar sos un teso .saludos desde COLOMBIA

    • Hola Sebas. Disculpa si te respondo tarde… He tenido una semana full y no te preocupes que no me he olvidado de tu email! Por fa sólo hazme recordar este sábado para poder hacer algo al respecto.

      Saludos!

  6. Hello!

    Soy francès, tengo un problema con tu codigo.
    Tiene una idea?

    Muchas gracias!!

    > Cannot find a class or type named “MD2_Loader”

    // Librairies

    import processing.opengl.*;
    import processing.video.*;
    import jp.nyatla.nyar4psg.*;
    import processing.opengl.*;
    import javax.media.opengl.*;

    // Fonctions

    Capture cam;
    NyARBoard marcador;
    PMatrix3D dmat, dmatOrg;

    float interpolate = 0;
    boolean showWire = false;

    PGraphics3D g3;

    MD2_Loader loader;
    MD2_Model model1;

    // Setup

    void setup() {
    size(600,420,OPENGL);
    frameRate(60);
    marcador=new NyARBoard(this,width,height,”camera_para.dat”,”patt.hiro”,80);
    marcador.gsThreshold=100;
    marcador.cfThreshold=0.4;

    cam=new Capture(this,width,height);

    loader = new MD2_Loader(this);

    model1 = loader.loadModel(“models/ogre.md2”, “models/ogre.jpg”);

    if(model1 != null){
    MD2_ModelState[] mdlStates = model1.getModelStates();

    for(int i = 0; i < mdlStates.length; i++){

    }

    }
    if(model1 != null) model1.setState(9);

    registerPre(this);
    }

    void pre(){
    interpolate = PApplet.constrain(2.1/(frameRate + 0.01), 0.001, 0.8);
    if(model1 != null)
    model1.update(interpolate);

    }

    // draw

    void draw() {
    if (cam.available() !=true) {
    return;
    }

    cam.read();

    hint(DISABLE_DEPTH_TEST);
    image(cam,0,0);
    hint(ENABLE_DEPTH_TEST);
    if(marcador.detect(cam)) {

    PGraphicsOpenGL pgl = (PGraphicsOpenGL) g;

    marcador.beginTransform(pgl);

    pushMatrix();

    if(showWire){

    }
    else {
    noStroke();
    fill(128);
    }
    if(model1 != null) model1.render();

    popMatrix();

    G4P.draw();
    marcador.endTransform();
    }
    }

  7. logre cargar el md2, pero no tiene animacion, supongo que es con la funcion void pre() que aparece alli pero no se donde ubicarla, podrias ayudarme?

    • Si, tiene que ser con versiones antiguas de blender. No sé por qué motivo sacaron el exportado de md2 pero lo encontraras en la versión que yo use.
      Saludos

      • que tal emilio, gracias por tomarte el tiempo de responder mis dudas, el problema era que al cargar el objeto me salia muy pequeño y lo escale desde processing, mi animacion lo que hacia era moverse 5 unidades a la izquierda y luego 5 a la derecha, como lo escalaba no se notaba el movimiento.

        otra pregunta, yo cargo la textura desde blender con el UVimage y en blender me sale bien el mapeo pero al cargarla en processing con el md2_loader el mapeo de la imagen no sale bien, que puede ser?

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.