Radar view of infinite 3D space.

edited December 2017 in How To...

Hi! im very interesting in the tarik barri software, Versum: https://Vimeo.com/20347210


i was wandering how to do that radar view of the 3D generative space. how to build something like that and which is the place to start thinking in a system like that. Thank you! PS: it works with shaders?

Answers

  • edited November 2017

    vimeo.com/20347210

  • I can’t see the image?

  • vimeo links are troublesome, they just disappear for some reason.

  • edited November 2017 Answer ✓

    The radar view is just a 2D representation of what is in the 3D space. Assuming you have all your objects stored in some data structure, iterate over it once to draw them in the 3D space and then again to draw them in the 2D space.

  • some example Tfguy44? what about the infinite space?

  • Answer ✓
    PGraphics pg;
    
    class Obj {
      PVector p;
      color c;
      Obj(){
        p = new PVector( random(20,180), random(20,180), random(20,180) );
        c = color( random(255),random(255),random(255) );
      }
      void simulate() {
        // move it or whatever?
      }
      void draw3D() {
        pg.pushMatrix();
        pg.translate(p.x, p.y, p.z);
        pg.scale(20);
        pg.noStroke();
        pg.fill(c);
        pg.sphere(1);
        pg.popMatrix();
      }
      void draw2D() {
        pushMatrix();
        stroke(c);
        noFill();
        translate(p.x, p.y);
        ellipse(0,0,20,20);
        popMatrix();
      }
    }
    
    ArrayList<Obj> objs = new ArrayList();
    
    void setup() {
      size(800, 400, P2D);
      pg = createGraphics(400, 400, P3D);
      for( int i = 0; i < 10; i++ ){
        objs.add( new Obj() );
      }
    }
    
    void draw() {
      background(0, 32, 0);
      pg.beginDraw();
      pg.background(0);
      pg.translate(200, 200, 0);
      pg.lights();
      pg.rotateX(map(mouseY, 0, height, -PI, PI));
      pg.rotateY(map(mouseX, 0, width, -PI, PI));
      pg.noFill();
      pg.stroke(255);
      pg.box(200);
      pg.translate(-100,-100,-100);
      for( Obj obj : objs ){ obj.simulate(); obj.draw3D(); }
      pg.endDraw();
      image(pg.get(), 0, 0);
      translate(400,0);
      for( Obj obj : objs ){ obj.draw2D(); }
    }
    
  • what about infinite space? some ideas? any kind of principle of generative 3D world?

  • Noise is good, but I thought it had issues over a certain value.

    Infinite is quite an ask, it's quite big. The video, I notice, definitely has a width and a length.

  • ArrayList<Obj> objs = new ArrayList();
    
    void setup() {
      size(800, 400, P3D);
    
      for ( int i = 0; i < 112; i++ ) {
        objs.add( new Obj() );
      }
    }
    
    void draw() {
    
      background(0);
    
      translate(width/2, 200, 0);
      lights();
      rotateX(map(mouseY, 0, height, -PI, PI));
      rotateY(map(mouseX, 0, width, -PI, PI));
      noFill();
      stroke(255);
      // box(200);
      //translate(-100, -100, -100);
      for ( Obj obj : objs ) { 
        obj.simulate(); 
        obj.draw3D();
      }
    
      //image(get(), 0, 0);
      //translate(400, 0);
      //for ( Obj obj : objs ) { 
      //  obj.draw2D();
      //}
    }
    
    //=============================================================
    
    class Obj {
    
      PVector p;
      color c;
      float size, primSize, 
        add=1;
    
      Obj() {
    
        p = new PVector( random(-1180, 1180), random(-1180, 1180), random(-1180, 1180) );
    
        c = color( random(255), random(255), random(255) );
    
        size=random(4, 21);
        primSize=size;
      }
    
      void simulate() {
        // move it or whatever?
        size+=add;
        if (size>primSize)
          add=-1; 
        else if (size<2)
          add=1;
      }
    
      void draw3D() {
        pushMatrix();
        translate(p.x, p.y, p.z);
        noStroke();
        fill(c);
        sphere(size);
        popMatrix();
      }
    }//class 
    //
    
  • maybe is not a infinite space, and i ask if is really necessary to define the size of a 3d World. i notice traveling with peasyCam that coordinates never end (or to big). i still can't resolve the radar thing. I imagine some kind of airplane traveling in the sky. the 2D radar grid also move in relation with the 3D coordinate. (2D grid generate according distance) in the Versum example the XZ grid is moving according the camera moving and it print in the coordinates in the top of each rows and cols of the grid. How can i do something like that?

  • the approach is very classic in games, like GTA for example

  • You’re talking about the map in the lower left corner. It’s a top down view, nothing to do with radar.

    You don’t provide any code or context. Are you going to do something like in the video or something like GTA? That’s a huge difference.

    Based on my sketch above for a map you would just drop the y-value of everything and use the x,z value. Also use a factor of 0.1 or so to make it small.

    For a bigger scene you would use a internal list of your landscape / data map.

    Use the camera position as player position.

    For a first person perspective look at library queasyCam iirc

    Best, Chrisir ;-)

  • edited February 2018

    did a little scetch, maybe it's helpfull

    /** 
     * Render To Texture - Viewport
     *
     * ^;.;^
     * nabr (2018/Feb/11)
     *
     * forum.processing.org/two/discussion/24912/radar-view-of-infinite-3d-space
     */
    
    // i don't write any notes to invite you for the experiment
    
    
    String[] vertSource={"#version 150"
      , "in vec2 position;"
      , "in vec2 texCoord;"
      , "uniform float time;"
      , "out vec2 vertTexCoord;"
      , "void main() {"
      , "gl_Position =vec4(position.xy*.5-.5*vec2(sin(time*3.),cos(time*3.)),-1.0, 1.0);"
      , "vertTexCoord.xy = position.xy;"
      , "}"
    };
    String[] fragSource={"#version 150"
      , "in vec2 vertTexCoord;"
      , "uniform sampler2D framebuffer,bckground;"
      , "out vec4 fragColor;"
      , "void main() {" 
      , "fragColor =mix( vec4(texture(bckground, vec2(vertTexCoord.x,1.-vertTexCoord.y)).rgb,.4), vec4(texture(framebuffer,vertTexCoord.xy).rgb, 1.) , .7 );"
      , "}"
    };
    PShader shdr;
    PImage img;
    void setup() {
      // size(960, 540, P3D);
      size(640, 360, P3D);
      hint(DISABLE_OPTIMIZED_STROKE);
      noStroke();
      shdr=new PShader(this, vertSource, fragSource);
      img =  loadImage("https://"+"processing.org/examples/moonwalk.jpg");
      shdr.set("bckground", img);
    
    }
    float rand = 0.;
    void draw() {
      float t = frameCount*.01f;
      shdr.set("time", millis()*.0001f);
    
    
      background(127);
    
      pushMatrix();
      translate(width/2, height/2, 0);
      rotateY(t);
      rotateX(t);
      box(200);
      popMatrix();
    
      shader(shdr);
      // get is the bottleneck here use pixels[] or native jogl
      shdr.set("framebuffer", get());
      rect(0, 0, 1f, 1f);
      // second bottleneck sheder gets recompiled with ~60fps use processings filter()
      resetShader();
    
    
      if (frameCount % 30 == 0) println(frameRate);
    }
    
  • edited February 2018

    I worked a little on it, you can steer the cam like in first person shooter fashion using mouse and wasd keys.

    It also shows some kind of map, but this doesn't work yet

    Best, Chrisir ;-)

    // https : // forum.processing.org/two/discussion/24912/radar-view-of-infinite-3d-space#latest
    // https : // www.openprocessing.org/sketch/25255
    
    // all spheres 
    ArrayList<Obj> objs = new ArrayList();
    
    // camera / where you are 
    float xpos, ypos, zpos, 
      xlookat, ylookat, zlookat; 
    float angle=0.0; // (angle left / right; 0..359)
    
    // player is crouching yes / no 
    boolean isCrouching = false; 
    
    // "Floor" has y-value (the plane you fly in (y-direction)) 
    final float floorLevel = 500.0;
    
    // this is the map (in 2D) 
    PGraphics pg; 
    
    // ---------------------------------------------------------------
    
    void setup() {
      size(800, 400, P3D);
    
      pg = createGraphics( width, height );
    
      for ( int i = 0; i < 112; i++ ) {
        objs.add( new Obj() );
      }
    }//func 
    
    void draw() {
    
      background(0);
    
      // draw Main Scene in 3D
      drawMainSceneIn3D(); 
    
      // make a 2D map of the entire scene
      make2DMap(); 
    
      // read key throughout 
      keyPressedIsCheckedContinuusly();
    
      // HUD https : // en.wikipedia.org/wiki/Head-up_display ------------- 
      camera();
      noLights();
      hint(DISABLE_DEPTH_TEST);  
      fill(255);
      text("wasd to move, mouse to look left/right (or combine mouse and keyboard)", 18, 18);
      image(pg, 
        18, height-18-120, 
        240, 120);
    }//func 
    
    //---------------------------------------------------------------
    
    void drawMainSceneIn3D() {
      // draw Main Scene in 3D (main screen)
    
      hint(ENABLE_DEPTH_TEST); 
      pushMatrix();
      CheckCameraMouse();
      lights();
      noFill();
      stroke(255);
      for ( Obj obj : objs ) { 
        obj.simulate(); 
        obj.draw3D();
      }
      popMatrix();
    }//func
    
    void make2DMap() {
    
      // make a 2D map of the entire scene (small map)
    
      pg.beginDraw();
      pg.background(111); // lightgray
    
      pg.pushMatrix(); // ----
    
      // cam pos  
      pg.translate(xpos+width/2, zpos+height/2); 
    
      // cam angle 
      pg.rotate(radians(angle)); 
    
      for ( Obj obj : objs ) { 
        obj.draw2D(pg);
      }
    
      pg.popMatrix(); // ----
    
      // draw cam (static at fixed position)
      pg.translate(width/2, height-120);
    
      pg.noFill();
      pg.strokeWeight(16); 
      pg.stroke(255, 2, 2);
      pg.ellipse(0, 0, 25, 25);
    
      pg.noStroke();
      pg.fill(255, 2, 2); 
      pg.ellipse(0, 0, 20, 20);
      pg.strokeWeight(4);
    
      pg.noFill();
      pg.stroke(0);
      pg.ellipse(0, 0, 10, 10);
      pg.strokeWeight(1);
    
      pg.endDraw();
    }//func 
    
    // --------------------------------------------------------------------------
    // Inputs 
    
    void keyPressedIsCheckedContinuusly() {
    
      float Radius = 13; 
    
      if (keyPressed) {
    
        // ----------------------------    
        // forward & backward
        if (key == 'w' || key == 'W') {
          // forward : should be running towards lookat 
          xpos =   Radius*sin(radians(angle)) + xpos;
          zpos =   Radius*cos(radians(angle)) + zpos;
        }
        if (key == 's' || key == 'S') {
          // backward
          xpos =  xpos- (Radius*sin(radians(angle))) ;
          zpos =  zpos- (Radius*cos(radians(angle))) ;
        }
        // ----------------------------    
        // left & right 
        if (key == 'a' || key == 'A') {
          // left
          xpos =   xpos- Radius*sin(radians(angle-90)) ;
          zpos =   zpos- Radius*cos(radians(angle-90)) ;
        }
        if (key == 'D' || key == 'd') {
          // right 
          xpos =   Radius*sin(radians(angle-90)) + xpos;
          zpos =   Radius*cos(radians(angle-90)) + zpos;
        } 
        // ----------------------------    
        // fly up & down 
        if (key == 'r' || key == 'R') {
          ypos-=4;  // fly up
        }
        if (key == 'f' || key == 'F') {
          ypos+=4;  // down 
          if (ypos > floorLevel-120) {  // check Floor
            ypos = floorLevel-120;
          }
        }     
        // ----------------------------    
        // fly up & down FAST 
        if (key == 'b' || key == 'B') {
          // Bird
          ypos-=400;
        }    
        if (key == 'n' || key == 'N') {
          // un-Bird: go deeper 
          ypos+=400; 
          if (ypos > floorLevel-120) { // check Floor
            ypos = floorLevel-120;
          }
        }        
        // ----------------------------        
        // crouch 
        if (key == 'c' || key == 'C') {
          // toggle 
          isCrouching=!isCrouching;
          if ( isCrouching ) {
            // crouch
            ypos = floorLevel - 40; //  height/2.0;
          } else
          {
            // stand 
            ypos = floorLevel - 120; //  height/2.0;
          }
        } // 'c'
        if (key == 'i' || key == 'I') {
          // Saves a TIFF file named "diagonal.tif"
          save("Runner1.tif");
        }
        // checkBoundaries ();
      } // keyPressed
    }
    
    // --------------------------------------------------------------------------------
    // Tools 
    
    void CheckCameraMouse () {
      // Mouse  
    
      float Radius = 450.0;  // radius 
    
      float rmx=mouseX; 
      float rmy=mouseY;
    
      // command map: See Help. 
      angle = map(rmx, width, 0, 0, 359); // left right 
    
      // look at 
      xlookat = Radius*sin(radians(angle)) + xpos;
      ylookat = 300; //  map(rmy, -300, floorLevel-120, -270, height); // look up / down 
      zlookat = Radius*cos(radians(angle)) + zpos; 
    
      camera (xpos, ypos, zpos, 
        xlookat, ylookat, zlookat, 
        0.0, 1.0, 0.0
        );
    }
    
    //=============================================================
    
    class Obj {
    
      // class for a 3D sphere
    
      PVector p; //position 
      color c;   //color
    
      // pulsating effect (OFF)
      float size, 
        primSize, 
        add=0;       // 0 = no pulsating (OFF)
    
      // constr 
      Obj() {
    
        //position 
        // p = new PVector( random(-1180, 1180), random(-1180, 1180), random(-1180, 1180) );
        p = new PVector( random(-1180, 1180), 208, random(-1180, 1180) );
    
        //color
        c = color( random(255), random(255), random(255) );
    
        size     = random(14, 21);
        primSize = size;
      }// constr 
    
      void simulate() {
        // move it or whatever?
        size+=add;
        if (size>primSize)
          add=-1; 
        else if (size<12)
          add=1;
      }
    
      void draw3D() {  
        // draw main scene in 3D
        pushMatrix();
        translate(p.x, p.y, p.z);
        noStroke();
        fill(c);
        sphere(size);
        popMatrix();
      }
    
      void draw2D(PGraphics pg) {
    
        // draw element on "pg" for map in 2D
    
        pg.noStroke();
        pg.fill(c);
    
        float f = 1.0; // 1.0 = no effect 
        pg.ellipse(p.x*f, p.z*f, max(12, size*f), max(12, size*f));
      }//method 
      //
    }//class 
    //
    
  • I improved the version above and edited the post but it's still not good

    I just lack the math for it....

  • edited February 2018

    hey guys. i was working in the radar/map/gps thing. here is the code i wrote. in general is the first approach,and i`ve a lot of questions to do:

    import peasy.*;
    import peasy.org.apache.commons.math.*;
    import peasy.org.apache.commons.math.geometry.*;
    
    ArrayList<Sphere>spheres;
    PGraphics off;
    PGraphics player;
    PWindow win;
    Radar r;
    PeasyCam cam;
    void settings(){
    size(500, 500, P3D);
    }
    
    void setup() {
      cam = new PeasyCam(this, 1500);
      win = new PWindow();
      spheres = new ArrayList<Sphere>();
      spheres.add(new Sphere(new PVector(100, 0, 0)));
    }
    
    
    void draw() {
      background(0);
    
      for(Sphere s: spheres){
      s.display();
      }
    }
    
    class Sphere {
      ArrayList<PVector>pos = new ArrayList<PVector>();
    
      Sphere(PVector o) {
        pos.add(o);
      }
      void display(){
      for(PVector o:pos){
      stroke(255);
      translate(o.x, o.y, o.z);
      sphere(150);
      }
      }
    }
    
    class PWindow extends PApplet {
    
      PWindow() {
        super();
        PApplet.runSketch(new String[] {this.getClass().getSimpleName()}, this);
      }
    
      float x;
      float y;
      Sphere s;
    
      void settings() {
        size(500, 500, P2D);
      }
    
      void setup() {
        x = 0;
        y = 0;
        r = new Radar(this);
    
        off = createGraphics(2000, 2000, P2D);
        player = createGraphics(250, 250, P2D);
      }
    
      void draw() {
        background(0);
        noFill();
        stroke(255);
        strokeWeight(5);
        //rect(0, 0, width, height);
        surface.setTitle("GPS"+ int(frameRate));
    
    
        off.beginDraw();
        render(off);
        off.endDraw();
    
        player.beginDraw();
        cam(player);
        player.endDraw();
    
        pushMatrix();
        translate(width/2, height/2);
        imageMode(CENTER);
        blendMode(ADD);
        image(off, x, y);
        image(player, 0, 0);
        popMatrix();
    
    
    
        if (keyPressed==true) {
          if (keyCode == RIGHT) {
            x+=5;
          } else if (keyCode == LEFT) {
            x+= -5;
          } else if (keyCode == DOWN) {
            y+= -5;
          } else if (keyCode == UP) {
            y+= 5;
          } else if (key == 'b') {
            x=0;
            y=0;
          }
        }
      }
    
      void render(PGraphics a) {
        a.background(0);
        a.ellipse(0, 0, 10, 10);
    
    
        for (Sphere s : spheres) {
          for(PVector e : s.pos){
           pushMatrix();
           translate(e.x, e.z);   
           r.displayObj(s.pos);
           popMatrix();
        }
    }
         r.displayGrid();
      }
    
      void mousePressed() {
    
        for (Sphere s : spheres) {
          r.mousePressed();
        }
      }
    
      void mouseReleased() {
        for (Sphere s : spheres) {
          r.mouseReleased();
        }
      }
    
      void mouseDragged() {
        for (Sphere s : spheres) {
          r.mouseDragged();
        }
      }
    }
    
    void cam(PGraphics a) {
      //a.background(25);
      r.displayCamera();
    }
    
    class Radar {
    
      PApplet parent;
      boolean overObj = false;
      boolean lock = false;
      float xOffset;
      float yOffset;
      int radio;
    
      int c;
      int r;
    
      float Cr;
    
      int zoom = 100;
      float zx;
      float zz;
    
      ArrayList<PVector>objPos;
    
      Radar(PApplet parent) {
        this.parent = parent;
        this.radio = 25;
    
        this.objPos = new ArrayList<PVector>();
        // c = cols.lenght;
        // r = rows.lenght;
      }
    
      void displayObj(ArrayList<PVector>rpos) {
        objPos = rpos;
        off.pushMatrix();
        off.translate(off.width/2, off.height/2); 
        off.ellipseMode(RADIUS);
    
        for (PVector p : objPos) {
    
          off.pushMatrix();
          off.translate(p.x*0.5, p.z*0.5);
    
          off.stroke(255);
          off.ellipse(0, 0, radio, radio);   
    
          if (parent.mouseX > 0 - radio && parent.mouseX < 0 + radio &&
            parent.mouseY > 0 - radio && parent.mouseY < 0 + radio) {
            overObj = true;
            if (!lock) {
              off.stroke(255);
              off.fill(153);
            }
          } else {
            off.noFill();
            overObj = false;
          }
          println(parent.mouseX);
    
          off.popMatrix();
        }
    
        println(overObj);
    
        off.popMatrix();
    
      }
    
      void mousePressed() {
        if (overObj) {
          lock = true;
          off.fill(200, 0, 200);
        } else {
          lock = false;
        }
        for (PVector p : objPos) {
          xOffset = parent.mouseX-p.x;
          yOffset = parent.mouseY-p.z;
        }
      }
    
      void mouseReleased() {
        lock = false;
      }
    
      void mouseDragged() {
        for (PVector p : objPos) {
          if (lock) {
            p.x = (parent.mouseX-xOffset);
            p.z = (parent.mouseY-yOffset);
          }
        }
      }
    
      void displayCamera() {
    
        parent.pushMatrix();
        parent.translate(player.width/2, player.height/2);
        parent.rectMode(CENTER);
        parent.fill(255);
        parent.rect(player.width/2, player.height/2, 10, 10);
        parent.noFill();
        parent.stroke(200, 200, 0, map(Cr, 0, 250, 255, 0));
        parent.strokeWeight(1);
        parent.ellipse(player.width/2, player.width/2, Cr, Cr);
        Cr+=1;
    
        if (Cr >= 250) {
          Cr=0;
        }
        parent.popMatrix();
      }
    
      void displayGrid() {
    
        float p = off.width*-1;
        float py = off.height*-1;
    
        off.pushMatrix();
        off.translate(off.width/2, off.height/2);
    
        off.beginShape(POINTS);
        off.strokeWeight(1);
    
        for (float xPos = p; xPos <= off.width; xPos+=zoom) {
          off.line(xPos, -py, xPos, py);
    
          for (float yPos = p; yPos <= off.height; yPos+=zoom) {
            //xPos = int(map(xPos, 0, cols.length, -width/2, width/2));
    
            off.line(-p, yPos, p, yPos);
            off.stroke(255, 255, 0);
    
            off.vertex(xPos, yPos);
          }
        }
        off.endShape();
    
    
        off.popMatrix();
      }
    }
    

    thisve a loot of problems yet. don't pay attention to displayCamera(). first, the big problem that ive is with transformations. i can't resolve how determine parent.mouseX and parent.mouseY is over the objPos (the 0,0 is still in the left corner). maybe the transformations are a little bit disorganized, i really appreciate some help.

    my logical is this: draw a big Image and later with the arrows move that image and display on the surface on a PApplet . What do you think about this logic? what about the scale factor? (i don't use anyone here). it is possible to map the off buffer into a rect? because i want to use the controller Applet to others things, maybe add some buttons). some many things, but im glad to move along. thanks

Sign In or Register to comment.