Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

  • Video in Android Mode

    Really good comments @hudson_m4000

    Please don't forget to cross link your posts.

    I haven't had the time to check your code @flashbacker. I have had some issues myself with accessing Android res from processing. However, I know it is possible as it has been done before. I think we just need better documentation.

    Related to the wrapper for MediaPlayer, I believe @codeanticode has suggested something like that before. There are no enough hands on deck to do this type of work. Nevertheless, I agree it is important thing to do as it would make things much easier to implement, at least for the demonstration stage.

    These two links are relevant for anybody else reading this post:

    https://github.com/processing/processing-library-template
    https://github.com/processing/processing-android-library-template

    Kf

  • Video in Android Mode

    thanks

    @kfrajer isn't it what is already in use in the second code here ? afd = context.getAssets().openFd("machine_compr.mp4");

    @hudson_m4000 I would be curious to see if it works for you and what you changed

    Over all, thanks for your help and feedbacks, I wanted to make a simple video player controlled by OSC for a project, and run it on several tablets. I choose to use processing because I'm used to make simple projects with it, I think I didn't realized there was such a step when working for android... Maybe it's out of reach for my level now and I should find some work arounds...

  • Video in Android Mode

    @hudson_m4000 Thanks a lot for your feed back! I've finally found out about your code for the file's path and thanks for explaining me for the second code where I was calling the file from the data folder, I was a bit confused about this method compared to the previous one...

    However, I tried to replace with
    "/storage/emulated/0/machine_compr.mp4"
    in my both devices and
    "storage/3E07-120C/machine_compr.mp4"
    in my device which has an external SD card (the video file is always placed in the root folder of the storage).
    I even tried to put the video in the data folder, just for the sake of it... I always end up with the same error that I described above.

    I've allowed the 3 access location permissions types in the sketch permissions, but nothing will do

    Is there anything else I could try?

  • Video in Android Mode

    @kfrajer

    I've actually managed to use hudson_m4000 code to confirm what the path of my video file should be. Problem even with this info, my processing sketch won't find my file. The following code (even if I know it can't show the video image) compile on my device, but return to the console "error loading transit.mp4":

    import android.media.MediaPlayer;
    import android.os.Environment;
    import android.app.Activity;
    import android.content.Context;
    MediaPlayer mp ;
    Context context ;
    Activity activity ;
    String statusText = "VIDEO INITIALIZING";
    String SDCard = new String(Environment.getExternalStorageDirectory().getAbsolutePath());
    //String SDCard = "/storage/3E07-120C/";
    
    void setup() {
      size(400,400);
      activity = this.getActivity();
      context = activity.getApplicationContext();
      mp = new MediaPlayer();
      println( SDCard);
      try {
        mp.setDataSource(SDCard + "machine.mp4");
        mp.prepare();
        mp.start();
        statusText = "VIDEO PLAYING";
      }
      catch (IOException e) {
        println("error loading transit.mp4");
      }
      fill(255); 
      textAlign(CENTER, CENTER);
    }
    

    This code can't compile:

    import android.media.MediaMetadataRetriever;
    import android.os.Handler;
    import android.os.HandlerThread;
    import android.os.Looper;
    import android.app.Activity;
    import android.view.ViewGroup;
    import android.view.View;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.media.MediaMetadataRetriever;
    import android.media.MediaPlayer;
    import android.content.res.Resources;
    import android.content.res.AssetFileDescriptor;
    import android.content.res.AssetManager;
    import android.content.Context;
    
    AssetFileDescriptor afd;
    Context context;
    Activity act;
    SurfaceView mySurface;
    SurfaceHolder mSurfaceHolder;
    MediaMetadataRetriever metaRetriever;
    MediaPlayer mMediaPlayer;
    
    void setup() {
      size(400, 400, P2D);
      act = this.getActivity();
      context = act.getApplicationContext();
      Looper.prepare();
      mMediaPlayer = new MediaPlayer();
      try {
        afd = context.getAssets().openFd("machine_compr.mp4");
        MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever();
        metaRetriever.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
        String height = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT); 
        if (int(height) < 2) {
          throw new IOException();
        }
      }
      catch (IllegalArgumentException e) {
        e.printStackTrace();
      }
      catch (IllegalStateException e) {
        e.printStackTrace();
      } 
      catch (IOException e) {
        e.printStackTrace();
      }
    
      mySurface = new SurfaceView(act);
      mSurfaceHolder = mySurface.getHolder();
      mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
      mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
        @Override
          public void surfaceCreated(SurfaceHolder surfaceHolder) {
          mMediaPlayer.setDisplay(surfaceHolder);
        }
    
        @Override
          public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
          mMediaPlayer.setDisplay(surfaceHolder);
        }
    
        @Override
          public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        }
      }
      );
      startVideo();
    }
    
    void startVideo() {
      act.runOnUiThread(new Runnable() {
        public void run() {
          try {
            mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
            mSurfaceHolder = mySurface.getHolder();
            mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            mMediaPlayer.prepare();
    //        act.addContentView(mySurface, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT));
            act.addContentView(mySurface, new ViewGroup.LayoutParams(400,400));
            if (mMediaPlayer.isPlaying() == false) {
              mMediaPlayer.start();
            }
          }
          catch (IllegalArgumentException e) {
            e.printStackTrace();
          }
          catch (IllegalStateException e) {
            e.printStackTrace();
          } 
          catch (IOException e) {
            e.printStackTrace();
          }
        }
      }
      );
    };
    
    void draw() {
    }
    
    void onPause() {
      if (mMediaPlayer!=null) {
        mMediaPlayer.release();
        mMediaPlayer = null;
      }
      super.onPause() ;
    }
    
    void onStop() {
      if (mMediaPlayer!=null) {
        mMediaPlayer.release();
        mMediaPlayer = null;
      }
      super.onStop() ;
    }
    
    void onDestroy() {
      if (mMediaPlayer!=null) {
        mMediaPlayer.release();
        mMediaPlayer = null;
      }
      super.onDestroy() ;
    }
    
    void onResume() {
      super.onResume() ;
    }
    

    and the console says it's because file couldn't be loaded

    OpenGL error 1280 at bot beginDraw(): invalid enum
    java.io.FileNotFoundException: machine_compr.mp4
        at android.content.res.AssetManager.openAssetFd(Native Method)
        at android.content.res.AssetManager.openFd(AssetManager.java:334)
        at processing.test.android_nativeplayer.android_nativeplayer.setup(android_nativeplayer.java:66)
        at processing.core.PApplet.handleDraw(PApplet.java:1801)
        at processing.opengl.PSurfaceGLES$RendererGLES.onDrawFrame(PSurfaceGLES.java:264)
        at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1590)
        at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1286)
    FATAL EXCEPTION: main
    Process: processing.test.android_nativeplayer, PID: 12773
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.FileDescriptor android.content.res.AssetFileDescriptor.getFileDescriptor()' on a null object reference
        at processing.test.android_nativeplayer.android_nativeplayer$2.run(android_nativeplayer.java:110)
        at android.os.Handler.handleCallback(Handler.java:815)
        at android.os.Handler.dispatchMessage(Handler.java:104)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main(ActivityThread.java:5765)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
    OpenGL error 1285 at bot endDraw(): out of memory
    

    I'll maybe try a post on the new forum, but there's so much ressource here, it felt more accurate to post here rather than create a new post which would point towards here...

  • Video in Android Mode

    Thanks @hudson_m4000 that looks really promissing! But it seems i'm missing some android methods, and can't solve "Build" and "context" Are you importing anything which doesn't show in the code here?

    (thanks for the tip @Chrisir, this post just looked the closest to my problem I could find :) )

  • Send individual msj to a shader

    hey everybody. this time i've a problem sending invididual mensajes to a fragment shader. I've an array of spheres, and i want that every sphere have a different size of blur, witch is a uniform of the fragment. The main code is from an example, a post-processing effects.

    How can i do?

    import controlP5.*;
    
    ControlP5 cp5;
    import peasy.*;
    
    ArrayList<Sphere>s;
    
    PGraphics canvas;
    
    PGraphics brightPass;
    PGraphics horizontalBlurPass;
    PGraphics verticalBlurPass;
    
    PShader bloomFilter;
    PShader blurFilter;
    PeasyCam cam;
    float angle = 0;
    
    final int surfaceWidth = 250;
    final int surfaceHeight = 250;
    
    float luminanceFilter = 0.02;
    float blurSize = 100;
    float sigma = 200;
    
    void setup()
    {
      cam = new PeasyCam(this, 1400);
      size(1000, 1000, P3D);
    
      s = new ArrayList<Sphere>();
    
      canvas = createGraphics(width, height, P3D);
    
      brightPass = createGraphics(width, height, P2D);
      brightPass.noSmooth();
    
      horizontalBlurPass = createGraphics(width, height, P2D);
      horizontalBlurPass.noSmooth(); 
    
      verticalBlurPass = createGraphics(width, height, P2D);
      verticalBlurPass.noSmooth(); 
    
      bloomFilter = loadShader("bloomFrag.glsl");
      blurFilter = loadShader("blurFrag.glsl");
    }
    
    void draw()
    {
      background(0);
      bloomFilter.set("brightPassThreshold", luminanceFilter);
      angle += 0.05;
    
      for(Sphere s: s){
      blurFilter.set("blurSize", s.p);
      }
    
      blurFilter.set("sigma", sigma); 
    
      canvas.beginDraw();
      render(canvas);
      canvas.endDraw();
    
      // bright pass
      brightPass.beginDraw();
      brightPass.shader(bloomFilter);
      brightPass.image(canvas, 0, 0);
      brightPass.endDraw();
    
      // blur horizontal pass
      horizontalBlurPass.beginDraw();
      blurFilter.set("horizontalPass", 1);
      horizontalBlurPass.shader(blurFilter);
      horizontalBlurPass.image(brightPass, 0, 0);
      horizontalBlurPass.endDraw();
    
      // blur vertical pass
      verticalBlurPass.beginDraw();
      blurFilter.set("horizontalPass", 0);
      verticalBlurPass.shader(blurFilter);
      verticalBlurPass.image(horizontalBlurPass, 0, 0);
      verticalBlurPass.endDraw();
    
    
      cam.beginHUD();
      blendMode(BLEND);
      blendMode(SCREEN);
      image(brightPass, 0, 0);
      image(verticalBlurPass, 0, 0);
    
      cam.endHUD();
    
    println(frameRate);
    }
    
    void render(PGraphics pg)
    {
      cam.getState().apply(pg);
    
      pg.background(0, 50);
    
      canvas.pushMatrix();
      canvas.translate(width/2, height/2);
      for(Sphere s: s){
      s.display();
    
      }
      canvas.popMatrix();
    
    
    }
    
    void mousePressed() {
      s.add(new Sphere(random(-width/2, width/2), random(-height/2, height/2), random(1000)));
    }
    
    
    class Sphere {
    
      float p;
      float w;
      float h;
    
      Sphere(float _w, float _h, float _p) {
      p = _p;
      w = _w;
      h = _h;
      }
    
      void display() {
        canvas.pushMatrix();
        canvas.translate(w, h);
        noFill();
        canvas.sphere(100);
    
        canvas.popMatrix();
      }
    }
    
  • Depth of Field effect with a shader

    Posting the question back here since it seems I won't get any help on the new forum (?).

    As some of you may already know I'm trying to make a Depth of Field effect in Python mode. I've recently stumbled onto this thread where I could get hold of a Proscene DOF demo sketch based on the following shaders:

    depth.glsl

    uniform float maxDepth;
    
    void main() {
      float depth = gl_FragCoord.z / gl_FragCoord.w;
      gl_FragColor = vec4(vec3(1.0 - depth/maxDepth), 1.0);
    }
    

    dof.glsl

    uniform sampler2D texture;
    
    varying vec4 vertexture;
    varying vec4 vertTexCoord;
    
    uniform sampler2D tDepth;
    
    uniform float maxBlur; // max blur amount
    uniform float aperture; // aperture - bigger values for shallower depth of field
    
    uniform float focus;
    uniform float aspect;
    
    void main() {
        vec2 vUv = vertTexCoord.st;
    
        vec2 aspectcorrect = vec2( 1.0, aspect );
    
        vec4 depth1 = texture2D( tDepth, vUv );
    
        float factor = depth1.x - focus;
    
        vec2 dofblur = vec2 ( clamp( factor * aperture, -maxBlur, maxBlur ) );
    
        vec2 dofblur9 = dofblur * 0.9;
        vec2 dofblur7 = dofblur * 0.7;
        vec2 dofblur4 = dofblur * 0.4;
    
        vec4 col = vec4( 0.0 );
    
        col += texture2D( texture, vUv.xy );
        col += texture2D( texture, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur );
        col += texture2D( texture, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur );
        col += texture2D( texture, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur );
        col += texture2D( texture, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur );
        col += texture2D( texture, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur );
        col += texture2D( texture, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur );
        col += texture2D( texture, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur );
        col += texture2D( texture, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur );
        col += texture2D( texture, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur );
        col += texture2D( texture, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur );
        col += texture2D( texture, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur );
        col += texture2D( texture, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur );
        col += texture2D( texture, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur );
        col += texture2D( texture, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur );
        col += texture2D( texture, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur );
        col += texture2D( texture, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur );
    
        col += texture2D( texture, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur9 );
        col += texture2D( texture, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur9 );
        col += texture2D( texture, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur9 );
        col += texture2D( texture, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur9 );
        col += texture2D( texture, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur9 );
        col += texture2D( texture, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur9 );
        col += texture2D( texture, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur9 );
        col += texture2D( texture, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur9 );
    
        col += texture2D( texture, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur7 );
        col += texture2D( texture, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur7 );
        col += texture2D( texture, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur7 );
        col += texture2D( texture, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur7 );
        col += texture2D( texture, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur7 );
        col += texture2D( texture, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur7 );
        col += texture2D( texture, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur7 );
        col += texture2D( texture, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur7 );
    
        col += texture2D( texture, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur4 );
        col += texture2D( texture, vUv.xy + ( vec2( 0.4, 0.0 ) * aspectcorrect ) * dofblur4 );
        col += texture2D( texture, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur4 );
        col += texture2D( texture, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur4 );
        col += texture2D( texture, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur4 );
        col += texture2D( texture, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur4 );
        col += texture2D( texture, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur4 );
        col += texture2D( texture, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur4 );
    
        gl_FragColor = col / 41.0;
        gl_FragColor.a = 1.0;
    }
    

    What I'd like is to be able to use those shaders using the PeasyCam library instead of the Proscene dependency.

    In the sketch below I'm testing the shaders on a point cloud. I’m drawing the points on the scene PGraphics and then passing it through 2 other PGraphics (canvas and buf). In theory it should work but I’m still stuck with the PeasyCam part at the very end of the script.

    If I write:

    • cam.getState().apply(canvas): I get a DoF effect BUT on a 2D canvas
    • cam.getState().apply(scene) : I get a 3D canvas BUT without a DoF effect

    Any help would be really appreciated.

    add_library('peasycam')
    liste = []
    
    def setup():
        global depthShader, dofShader, cam, canvas, buf, scene
        size(900, 900, P3D)
    
        cam = PeasyCam(this, 900)
        cam.setMaximumDistance(width)
    
        for e in range(100):
            liste.append(PVector(random(width), random(height), random(width)))
    
        depthShader = loadShader("depth.glsl")
        dofShader = loadShader("dof.glsl")
    
        depthShader.set("maxDepth", cam.getDistance())
        dofShader.set("aspect", width / float(height))
        dofShader.set("maxBlur", 0.015)
        dofShader.set("aperture", 0.02)
    
        canvas = createGraphics(width, height, P3D)
        canvas.shader(depthShader)
        buf = createGraphics(width, height, P3D)
        buf.shader(dofShader)
    
        scene = createGraphics(width, height, P3D)
    
        frameRate(1000)
    
    def draw():
    
        scene.beginDraw()
        scene.background(255)
        scene.stroke(0)
        scene.strokeWeight(10)
        for e in liste:
            scene.point(e.x-width/2, e.y-height/2, e.z-height/2)
        scene.endDraw()
    
        canvas.beginDraw()
        canvas.image(scene, 0, 0)
        canvas.endDraw()
    
        buf.beginDraw()
        dofShader.set("focus", map(mouseX, 0, width, -0.5, 1.5))
        dofShader.set("tDepth", canvas)
        buf.image(scene, 0, 0)
        buf.endDraw()
    
        cam.beginHUD()
        image(buf, 0, 0)
        cam.endHUD()
    
        cam.getState().apply(scene)
    
  • Converting Java code to Python

    Here's my Python Mode attempt. However, it's not working yet, it's just pitch black! :-&

    This statement crashes the sketch: geombuffer.update(pg_render) within resizeScreen(). Even when following exactly what it does, it doesn't seem to render anything. :o3

    https://GitHub.com/diwi/PixelFlow/blob/master/src/com/thomasdiewald/pixelflow/java/render/skylight/DwScreenSpaceGeometryBuffer.java#L67-L79

    public void update(PGraphics3D pg_src){
      
      resize(pg_src.width, pg_src.height);
      
      pg_geom.beginDraw();
      updateMatrices(pg_src);
      pg_geom.blendMode(PConstants.REPLACE);
      pg_geom.clear();
      pg_geom.shader(shader);
      pg_geom.noStroke();
      scene_display.display(pg_geom);
      pg_geom.endDraw();
    }
    

    So I'm at loss about it! Sorry. X_X Try finding help on diwi or jdf. ^#(^

    """
     * Depth of Field (DoF) (1.20)
     * Thomas Diewald (diwi) (2017-Oct-07)
     
     * GitHub.com/diwi/PixelFlow/blob/master/examples/Miscellaneous/
     * DepthOfField_Demo/DepthOfField_Demo.java
     
     * Refactor by GoToLoop (v1.4.2) (2018-May-18) (PDE v3.3.5)
     * Forum.Processing.org/two/discussion/27905/
     * converting-java-code-to-python#Item_20
    """
    
    add_library('PixelFlow')
    add_library('peasycam')
    
    from com.jogamp.opengl import GL2
    from processing.opengl import PGL
    
    from java.util import Formatter, Locale
    from jarray import zeros
    
    formatter = Formatter(Locale.ENGLISH)
    
    POSITION = 'position: (%8.2f, %8.2f, %8.2f)\n'
    ROTATION = 'rotation: (%8.2f, %8.2f, %8.2f)\n'
    LOOK__AT = 'look-at:  (%8.2f, %8.2f, %8.2f)\n'
    DISTANCE = 'distance: (%8.2f)\n'
    
    TITLE = __file__[:-5] + '   [fps %6.2f]'
    
    BB_SIZE = 800
    BB_OFFSET = BB_SIZE >> 2
    BB_TOTAL = BB_SIZE + BB_OFFSET
    BB_COORD, BB_DIAM = -BB_TOTAL, BB_TOTAL << 1
    
    XMIN, XMAX = -BB_SIZE, BB_SIZE
    YMIN, YMAX = -BB_SIZE, BB_SIZE
    ZMIN, ZMAX = 0, BB_SIZE
    
    BOX_DIAM = BB_OFFSET + BB_OFFSET/20
    SPH_MIN_D, SPH_MAX_D = BB_OFFSET >> 2, BB_OFFSET >> 1
    
    BOXES, SPHERES = 50, 50
    BOX_RANGE, SPH_RANGE = tuple(range(BOXES)), tuple(range(SPHERES))
    
    CROSS_S, ZFAR = 10, 6000
    MULT_BLUR, FPS = 30, 60
    BLUR_POW, RAD60 = pow(MULT_BLUR, 1/3.0), 60*DEG_TO_RAD
    
    BASE_COL, CROSS_COL = 0x80FFFFFF, 0xd0FFFFFF
    
    SEED, FIXED_SEED = 0, False
    FULLSCREEN, RESIZABLE = False, False
    apply_dof, alt_render = False, False
    
    resized = zeros(1, 'z')
    cube_smooth, cube_facets = DwCube(4), DwCube(2)
    shp_scene = pg_render = pg_dof = pg_tmp = None
    
    def settings():
        if FULLSCREEN: fullScreen(P3D) 
        else: size(this.displayWidth*9/10, this.displayHeight*9/10, P3D)
        noSmooth()
    
    
    def setup():
        frameRate(FPS); cursor(CROSS)
    
        global surf, canv
        surf, canv = this.surface, this.graphics
    
        if RESIZABLE: surf.resizable = True
        surf.setLocation(this.displayWidth - width >> 1, 8)
    
        global peasy
        peasy = PeasyCam(this, -4.083, -6.096, 7, 2000)
        peasy.setRotations(1.085, -.477, 2.91)
    
        global context, dw_filter, dof, param, geombuffer, magnifier
    
        context = DwPixelFlow(this)
        dw_filter = DwFilter.get(context)
        context.print(); context.printGL()
    
        dof = DepthOfField(context)
        param = dof.param
        param.mult_blur = MULT_BLUR
    
        class SceneDisplay(DwSceneDisplay):
            def display(_, canvas): displayScene(canvas)
    
    
        geombuffer = DwScreenSpaceGeometryBuffer(context, SceneDisplay())
    
        mag_h = height/3
        magnifier = DwMagnifier(this, 4, 0, height - mag_h, mag_h, mag_h)
    
    
    def draw():
        setTitle(); resizeScreen(); displaySceneWrap(pg_render)
        dw_filter.gamma.apply(pg_render, pg_render)
    
        apply_dof and applyDoF()
        renderScene()
    
    
    def keyPressed():
        global apply_dof, alt_render, shp_scene
        k = chr(keyCode) if key != CODED else keyCode
    
        if k == 'P' or k == BACKSPACE: noLoop() if this.looping else loop()
        elif k == 'C' or k == CONTROL: printCam()
        elif k == ' ': apply_dof ^= True
        elif k == SHIFT: alt_render ^= True
        elif k == ENTER or k == RETURN: shp_scene = None
    
    
    def applyDoF():
        geom = geombuffer.pg_geom
        dw_filter.gaussblur.apply(geom, geom, pg_tmp, BLUR_POW)
    
        param.focus_pos[0] = map(mouseX + .5, 0, width, 00, 1)
        param.focus_pos[1] = map(mouseY + .5, 0, height, 1, 0)
        dof.apply(pg_render, pg_dof, geombuffer)
    
        dw_filter.copy.apply(pg_dof, pg_render)
    
    
    def renderScene():
        pg = geombuffer.pg_geom if alt_render else pg_render
    
        magnifier.apply(pg, mouseX, mouseY)
        magnifier.displayTool()
    
        DwUtils.beginScreen2D(canv)
        # peasy.beginHUD()
    
        blendMode(REPLACE); image(pg, 0, 0)
        magnifier.display(pg, 0, height - magnifier.h)
    
        fpx = param.focus_pos[0] * width
        fpy = (1 - param.focus_pos[1]) * height
    
        blendMode(EXCLUSION); strokeCap(PROJECT); stroke(CROSS_COL)
        line(fpx - CROSS_S, fpy, fpx + CROSS_S, fpy)
        line(fpx, fpy - CROSS_S, fpx, fpy + CROSS_S)
        blendMode(BLEND)
    
        # peasy.endHUD()
        DwUtils.endScreen2D(canv)
    
    
    def resizeScreen():
        global pg_render, pg_dof, pg_tmp
        w = width; h = height
    
        perspective(RAD60, float(w)/h, 2, ZFAR)
        peasy.feed()
    
        happened = resized[0] = False
        pg_render = DwUtils.changeTextureSize(this, pg_render, w, h, 8, resized)
        happened |= resized[0]
    
        resized[0] = False
        pg_dof = DwUtils.changeTextureSize(this, pg_dof, w, h, 0, resized)
        happened |= resized[0]
    
        resized[0] = False
        pg_tmp = DwUtils.changeTextureSize(this, pg_tmp, w, h, 0, resized,
        GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT)
    
        # geombuffer.update(pg_render)
    
        happened |= geombuffer.resize(pg_render.width, pg_render.height)
        geombuffer.pg_geom.beginDraw()
    
        # geombuffer.updateMatrices(pg_render)
        DwUtils.copyMatrices(pg_render, geombuffer.pg_geom)
    
        geombuffer.pg_geom.blendMode(REPLACE)
        geombuffer.pg_geom.clear()
        geombuffer.pg_geom.shader(geombuffer.shader)
        geombuffer.pg_geom.noStroke()
        geombuffer.scene_display.display(geombuffer.pg_geom)
        geombuffer.pg_geom.endDraw()
    
        return happened | resized[0]
    
    
    def displaySceneWrap(canvas):
        DwUtils.copyMatrices(canv, canvas)
        canvas.beginDraw()
        canvas.background(2)
        displayScene(canvas)
        canvas.endDraw()
    
    
    def displayScene(canvas):
        canvas.directionalLight(255, 255, 255, 200, 600, 400)
        canvas.directionalLight(255, 255, 255, -200, -600, -400)
        canvas.ambientLight(64, 64, 64)
    
        if canvas is geombuffer.pg_geom:
            canvas.background(-1)
            canvas.pgl.clearColor(1, 1, 1, ZFAR)
            canvas.pgl.clear(PGL.COLOR_BUFFER_BIT)
    
        global shp_scene
        if not shp_scene: shp_scene = makeShape()
        canvas.shape(shp_scene)
    
    
    def makeShape():
        scene = createShape(GROUP)
        FIXED_SEED and randomSeed(SEED)
    
        with pushStyle():
            colorMode(HSB, 360, 1, 1); noStroke()
    
            for i in BOX_RANGE:
                px = random(XMIN, XMAX); py = random(YMIN, YMAX)
                sx = random(BOX_DIAM, BOX_DIAM); sy = random(BOX_DIAM, BOX_DIAM)
                sz = random(ZMIN, ZMAX)
    
                fill(random(-45, 45), 1, random(.1, 1))
                shp_box = createShape(BOX, sx, sy, sz)
                shp_box.translate(px, py, sz*.5)
                scene.addChild(shp_box)
    
            for i in SPH_RANGE:
                px = random(XMIN, XMAX); py = random(YMIN, YMAX)
                pz = random(ZMIN, ZMAX); rr = random(SPH_MIN_D, SPH_MAX_D)
    
                fill(random(205, 245), 1, random(.1, 1))
                shp_sphere = createShape(PShape.GEOMETRY)
                shp_sphere.scale(rr); shp_sphere.translate(px, py, pz)
                scene.addChild(shp_sphere)
    
                DwMeshUtils.createPolyhedronShape(shp_sphere, cube_smooth, 1, 4, True)\
                if i&1 else\
                DwMeshUtils.createPolyhedronShape(shp_sphere, cube_facets, 1, 4, False)
    
            fill(BASE_COL)
            scene.addChild(createShape(RECT, BB_COORD, BB_COORD, BB_DIAM, BB_DIAM))
    
        return scene
    
    
    def clearFormatter(f): f.out().setLength(0)
    
    
    def setTitle():
        clearFormatter(formatter)
        surf.title = formatter.format(TITLE, frameRate).toString()
    
    
    def printCam():
        pos = peasy.position; rot = peasy.rotations
        lat = peasy.getLookAt(); dis = peasy.distance
    
        clearFormatter(formatter)
    
        print formatter.\
        format(POSITION, *pos).format(ROTATION, *rot).\
        format(LOOK__AT, *lat).format(DISTANCE, dis)
    
  • Converting Java code to Python

    Hi @solub! It took a long time, but I've just finished refactoring "Depth_of_Field.pde". #:-S

    Now that I've reorganized this sketch, I'm ready to convert it to a ".pyde" file. :)>-

    Just w8 a lil' more. Stay w/ the latest ".pde" file for now: :-\"

    /**
     * Depth of Field (DoF) (1.20)
     * Thomas Diewald (diwi) (2017-Oct-07)
    
     * GitHub.com/diwi/PixelFlow/blob/master/examples/Miscellaneous/
     * DepthOfField_Demo/DepthOfField_Demo.java
    
     * Refactor by GoToLoop (v1.4.2) (2018-May-18) (PDE v3.3.5)
     * Forum.Processing.org/two/discussion/27905/converting-java-code-to-python#Item_18
     */
    
    import com.thomasdiewald.pixelflow.java.DwPixelFlow;
    import com.thomasdiewald.pixelflow.java.geometry.DwIndexedFaceSetAble;
    import com.thomasdiewald.pixelflow.java.geometry.DwCube;
    import com.thomasdiewald.pixelflow.java.geometry.DwMeshUtils;
    import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DepthOfField;
    import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DwFilter;
    import com.thomasdiewald.pixelflow.java.render.skylight.DwSceneDisplay;
    import com.thomasdiewald.pixelflow.java.render.skylight.DwScreenSpaceGeometryBuffer;
    import com.thomasdiewald.pixelflow.java.utils.DwMagnifier;
    import com.thomasdiewald.pixelflow.java.utils.DwUtils;
    
    import peasy.PeasyCam;
    
    import com.jogamp.opengl.GL2;
    
    import static java.util.Locale.ENGLISH;
    import java.util.Formatter;
    
    final Formatter formatter = new Formatter(ENGLISH);
    
    static final String POSITION = "position: (%8.2f, %8.2f, %8.2f)\n";
    static final String ROTATION = "rotation: (%8.2f, %8.2f, %8.2f)\n";
    static final String LOOK__AT = "look-at:  (%8.2f, %8.2f, %8.2f)\n";
    static final String DISTANCE = "distance: (%8.2f)\n";
    
    final String TITLE = getClass().getName() + "   [fps %6.2f]";
    
    static final int BB_SIZE = 800, BB_OFFSET = BB_SIZE >> 2;
    static final int BB_TOTAL = BB_SIZE + BB_OFFSET;
    static final int BB_COORD = -BB_TOTAL, BB_DIAM = BB_TOTAL << 1;
    
    static final int XMIN = -BB_SIZE, XMAX = BB_SIZE;
    static final int YMIN = -BB_SIZE, YMAX = BB_SIZE;
    static final int ZMIN = 0, ZMAX = BB_SIZE;
    
    static final int BOX_DIAM = BB_OFFSET + BB_OFFSET/20;
    static final int SPH_MIN_D = BB_OFFSET >> 2, SPH_MAX_D = BB_OFFSET >> 1;
    
    static final int BOXES = 50, SPHERES = 50;
    
    static final int CROSS_S = 10, ZFAR = 6000;
    static final int MULT_BLUR = 30, BLUR_POW = (int) pow(MULT_BLUR, 1/3.0);
    static final float RAD60 = 60*DEG_TO_RAD, FPS = 60;
    
    static final color BASE_COL = 0x80FFFFFF, CROSS_COL = 0xd0FFFFFF;
    
    static final long SEED = 0;
    static final boolean FIXED_SEED = false;
    
    static final boolean FULLSCREEN = false, RESIZABLE = false;
    boolean apply_dof = false, alt_render = false;
    
    final boolean[] resized = new boolean[1];
    
    final DwIndexedFaceSetAble cube_smooth = new DwCube(4), cube_facets = new DwCube(2);
    
    PGraphics3D pg_render, pg_dof, pg_tmp;
    PShape shp_scene;
    
    PeasyCam peasy;
    
    DwPixelFlow context;
    DwFilter dw_filter;
    DepthOfField dof;
    DwScreenSpaceGeometryBuffer geombuffer;
    DwMagnifier magnifier;
    
    void settings() {
      if (FULLSCREEN) fullScreen(P3D);
      else size(displayWidth*9/10, displayHeight*9/10, P3D);
      noSmooth();
    }
    
    void setup() {
      frameRate(FPS);
      cursor(CROSS);
    
      if (RESIZABLE)  getSurface().setResizable(true);
      getSurface().setLocation(displayWidth - width >> 1, 8);
    
      peasy = new PeasyCam(this, -4.083, -6.096, 7, 2000);
      peasy.setRotations(1.085, -.477, 2.91);
    
      dw_filter = DwFilter.get(context = new DwPixelFlow(this));
      context.print();
      context.printGL();
    
      dof = new DepthOfField(context);
      dof.param.mult_blur = MULT_BLUR;
    
      final DwSceneDisplay scene_display = new DwSceneDisplay() {  
        @ Override final public void display(final PGraphics3D canvas) {
          displayScene(canvas);
        }
      };
    
      geombuffer = new DwScreenSpaceGeometryBuffer(context, scene_display);
    
      final int mag_h = height/3;
      magnifier = new DwMagnifier(this, 4, 0, height - mag_h, mag_h, mag_h);
    }
    
    void draw() {
      final PGraphics canv = getGraphics();
      final DepthOfField.Param param = dof.param;
    
      setTitle();
      resizeScreen();
      displaySceneWrap(pg_render, canv);
      dw_filter.gamma.apply(pg_render, pg_render);
    
      if (apply_dof)  applyDoF(param);
      renderScene(param, canv);
    }
    
    void keyPressed() {
      final int k = keyCode;
    
      if (k == ENTER | k == RETURN)  shp_scene = null;
      else if (k == 'C' | k == CONTROL)  printCam();
      else if (k == 'P' | k == BACKSPACE)  looping ^= true;
      else if (k == ' ')  apply_dof ^= true;
      else if (k == SHIFT)  alt_render ^= true;
    }
    
    void applyDoF(final DepthOfField.Param param) {
      final PGraphicsOpenGL geom = geombuffer.pg_geom;
      dw_filter.gaussblur.apply(geom, geom, pg_tmp, BLUR_POW);
    
      param.focus_pos[0] = map(mouseX + .5, 0, width, 00, 1);
      param.focus_pos[1] = map(mouseY + .5, 0, height, 1, 0);
      dof.apply(pg_render, pg_dof, geombuffer);
    
      dw_filter.copy.apply(pg_dof, pg_render);
    }
    
    void renderScene(final DepthOfField.Param param, final PGraphics canv) {
      final PGraphics pg = alt_render? geombuffer.pg_geom : pg_render;
    
      magnifier.apply(pg, mouseX, mouseY);
      magnifier.displayTool();
    
      DwUtils.beginScreen2D(canv);
      //peasy.beginHUD();
    
      blendMode(REPLACE);
      image(pg, 0, 0);
      magnifier.display(pg, 0, height - magnifier.h);
    
      final float fpx = param.focus_pos[0] * width;
      final float fpy = (1 - param.focus_pos[1]) * height;
    
      blendMode(EXCLUSION);
      strokeCap(PROJECT);
      stroke(CROSS_COL);
      line(fpx - CROSS_S, fpy, fpx + CROSS_S, fpy);
      line(fpx, fpy - CROSS_S, fpx, fpy + CROSS_S);
      blendMode(BLEND);
    
      //peasy.endHUD();
      DwUtils.endScreen2D(canv);
    }
    
    boolean resizeScreen() { // dynamically resize render-targets
      final int w = width, h = height;
    
      perspective(RAD60, (float) w/h, 2, ZFAR);
      peasy.feed();
    
      boolean happened = resized[0] = false;
      pg_render = DwUtils.changeTextureSize(this, pg_render, w, h, 8, resized);
      happened |= resized[0];
    
      resized[0] = false;
      pg_dof = DwUtils.changeTextureSize(this, pg_dof, w, h, 0, resized);
      happened |= resized[0];
    
      resized[0] = false;
      pg_tmp = DwUtils.changeTextureSize(this, pg_tmp, w, h, 0, resized, 
        GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT);
    
      geombuffer.update(pg_render);
      return happened | resized[0];
    }
    
    void displaySceneWrap(final PGraphics3D canvas, final PGraphics canv) {
      DwUtils.copyMatrices((PGraphicsOpenGL) canv, canvas);
      canvas.beginDraw();
      canvas.background(2);
      displayScene(canvas);
      canvas.endDraw();
    }
    
    void displayScene(final PGraphics3D canvas) {
      canvas.directionalLight(255, 255, 255, 200, 600, 400);
      canvas.directionalLight(255, 255, 255, -200, -600, -400);
      canvas.ambientLight(64, 64, 64);
    
      if (canvas == geombuffer.pg_geom) {
        canvas.background(-1);
        canvas.pgl.clearColor(1, 1, 1, ZFAR);
        canvas.pgl.clear(PGL.COLOR_BUFFER_BIT);
      }
    
      if (shp_scene == null)  shp_scene = makeShape();
      canvas.shape(shp_scene);
    }
    
    PShape makeShape() {
      final PShape scene = createShape(GROUP);
    
      pushStyle();
      colorMode(HSB, 360, 1, 1);
      noStroke();
    
      if (FIXED_SEED)  randomSeed(SEED);
    
      for (int i = 0; i < BOXES; ++i) {
        final float px = random(XMIN, XMAX), py = random(YMIN, YMAX);
        final float sx = random(BOX_DIAM, BOX_DIAM), sy = random(BOX_DIAM, BOX_DIAM);
        final float sz = random(ZMIN, ZMAX);
    
        fill(random(-45, 45), 1, random(.1, 1));
        final PShape shp_box = createShape(BOX, sx, sy, sz);
        shp_box.translate(px, py, sz*.5);
        scene.addChild(shp_box);
      }
    
      for (int i = 0; i < SPHERES; ++i) {
        final float px = random(XMIN, XMAX), py = random(YMIN, YMAX);
        final float pz = random(ZMIN, ZMAX), rr = random(SPH_MIN_D, SPH_MAX_D);
    
        fill(random(205, 245), 1, random(.1, 1));
        final PShape shp_sphere = createShape(PShape.GEOMETRY);
        shp_sphere.scale(rr);
        shp_sphere.translate(px, py, pz);
        scene.addChild(shp_sphere);
    
        if ((i&1) == 0)
          DwMeshUtils.createPolyhedronShape(shp_sphere, cube_facets, 1, 4, false);
        else
          DwMeshUtils.createPolyhedronShape(shp_sphere, cube_smooth, 1, 4, true);
      }
    
      fill(BASE_COL);
      scene.addChild(createShape(RECT, BB_COORD, BB_COORD, BB_DIAM, BB_DIAM));
    
      popStyle();
      return scene;
    }
    
    static final void clearFormatter(final Formatter f) {
      ((StringBuilder) f.out()).setLength(0);
    }
    
    void setTitle() {
      clearFormatter(formatter);
      getSurface().setTitle(formatter.format(TITLE, frameRate).toString());
    }
    
    void printCam() {
      final float[] pos = peasy.getPosition();
      final float[] rot = peasy.getRotations();
      final float[] lat = peasy.getLookAt();
      final double  dis = peasy.getDistance();
    
      clearFormatter(formatter);
    
      println(formatter.
        format(POSITION, pos[0], pos[1], pos[2]).
        format(ROTATION, rot[0], rot[1], rot[2]).
        format(LOOK__AT, lat[0], lat[1], lat[2]).
        format(DISTANCE, dis));
    }
    
  • Converting Java code to Python

    I wonder if you 1st was able to transpile back the ".java" sketch as a ".pde" in order to run it under Java Mode? :-?

    • Like removing the statement w/ the package keyword.
    • The public class DepthOfField_Demo extends PApplet { statement & its corresponding closing curly brace.
    • And of course, the whole public static void main(String args[]) { code block. #:-S

    That whole code is æsthetically messy. But here's what I've come w/ as a ".pde" file w/o changing the original ".java" 1 much: :P

    "Depth_of_Field.pde":

    // Depth of Field (DoF) (1.20)
    // Thomas Diewald (diwi) (2017-Oct-07)
    
    // GitHub.com/diwi/PixelFlow/blob/master/examples/Miscellaneous/
    // DepthOfField_Demo/DepthOfField_Demo.java
    
    import static java.util.Locale.ENGLISH;
    
    import com.jogamp.opengl.GL2;
    
    import peasy.PeasyCam;
    
    import com.thomasdiewald.pixelflow.java.DwPixelFlow;
    import com.thomasdiewald.pixelflow.java.geometry.DwCube;
    import com.thomasdiewald.pixelflow.java.geometry.DwMeshUtils;
    import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DepthOfField;
    import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DwFilter;
    import com.thomasdiewald.pixelflow.java.render.skylight.DwSceneDisplay;
    import com.thomasdiewald.pixelflow.java.render.skylight.DwScreenSpaceGeometryBuffer;
    import com.thomasdiewald.pixelflow.java.utils.DwMagnifier;
    import com.thomasdiewald.pixelflow.java.utils.DwUtils;
    
    static final String POSITION = "position: (%7.3f, %7.3f, %7.3f)\n";
    static final String ROTATION = "rotation: (%7.3f, %7.3f, %7.3f)\n";
    static final String LOOK_AT  = "look-at:  (%7.3f, %7.3f, %7.3f)\n";
    static final String DISTANCE = "distance: (%7.3f)\n";
    
    static final String FPS = "   [fps %6.2f]";
    
    boolean start_fullscreen = false;
    
    int viewport_w = 1000;
    int viewport_h = 600;
    int viewport_x = 200;
    int viewport_y = 0;
    
    // camera control
    PeasyCam peasycam;
    
    // library context
    DwPixelFlow context;
    
    PShape shp_scene;
    
    PGraphics3D pg_render;
    PGraphics3D pg_dof;
    PGraphics3D pg_tmp;
    
    DepthOfField dof;
    DwScreenSpaceGeometryBuffer geombuffer;
    
    DwMagnifier magnifier;
    
    boolean apply_dof = true;
    
    void settings() {
      if (!start_fullscreen)  size(viewport_w, viewport_h, P3D);
      else {
        fullScreen(P3D);
        viewport_w = displayWidth;
        viewport_h = displayHeight;
        viewport_x = 0;
        viewport_y = 0;
      }
    
      noSmooth();
    }
    
    void setup() {
      surface.setResizable(true);
      surface.setLocation(viewport_x, viewport_y);
    
      // camera
      peasycam = new PeasyCam(this, -4.083, -6.096, 7.000, 1300);
      peasycam.setRotations(1.085, -0.477, 2.910);
    
      // main library context
      context = new DwPixelFlow(this);
      context.print();
      context.printGL();
    
      // callback for scene display (used in GBAA)
      DwSceneDisplay scene_display = new DwSceneDisplay() {  
        @ Override public void display(PGraphics3D canvas) {
          displayScene(canvas);
        }
      };
    
      geombuffer = new DwScreenSpaceGeometryBuffer(context, scene_display);
    
      dof = new DepthOfField(context);
    
      int mag_h = height/3;
      magnifier = new DwMagnifier(this, 4, 0, height - mag_h, mag_h, mag_h);
    
      frameRate(1000);
    }
    
    void draw() {
      resizeScreen();
      displaySceneWrap(pg_render);
      DwFilter.get(context).gamma.apply(pg_render, pg_render);
    
      int mult_blur = 30;
    
      if (apply_dof) {
        geombuffer.update(pg_render);
    
        DwFilter.get(context).gaussblur.apply(geombuffer.pg_geom, geombuffer.pg_geom, 
          pg_tmp, (int) Math.pow(mult_blur, 0.33));
    
        //      dof.param.focus     = map(mouseX, 0, width, 0, 1);
        dof.param.focus_pos = new float[]{0.5, 0.5};
        dof.param.focus_pos[0] = map(mouseX+0.5, 0, width, 0, 1);
        dof.param.focus_pos[1] = map(mouseY+0.5, 0, height, 1, 0);
        dof.param.mult_blur = mult_blur;
        dof.apply(pg_render, pg_dof, geombuffer);
    
        DwFilter.get(context).copy.apply(pg_dof, pg_render);
      }
    
      magnifier.apply(pg_render, mouseX, mouseY);
      magnifier.displayTool();
    
      DwUtils.beginScreen2D(g);
      //    peasycam.beginHUD();
      {
        blendMode(REPLACE);
        clear();
        image(pg_render, 0, 0);
        //      image(geombuffer.pg_geom, 0, 0);
    
        magnifier.display(g, 0, height-magnifier.h);
    
        blendMode(BLEND);
    
        pushMatrix();
        float cursor_s = 10;
    
        float fpx = dof.param.focus_pos[0] * width;
        float fpy = (1.0 - dof.param.focus_pos[1]) * height;
    
        blendMode(EXCLUSION);
        translate(fpx, fpy);
        strokeWeight(1);
        stroke(255, 200);
        line(-cursor_s, 0, +cursor_s, 0);
        line(0, -cursor_s, 0, +cursor_s);
        blendMode(BLEND);
        popMatrix();
      }
      //    peasycam.endHUD();
      DwUtils.endScreen2D(g);
    
      String txt_fps = String.format(getClass().getName() + FPS, frameRate);
      surface.setTitle(txt_fps);
    }
    
    void keyReleased() {
      if (keyCode == 'C') printCam();
      else if (key == ' ') apply_dof = !apply_dof;
    }
    
    boolean resizeScreen() { // dynamically resize render-targets
      final boolean[] resized = { false };
    
      pg_render = DwUtils.changeTextureSize(this, pg_render, width, height, 8, resized);
      pg_dof    = DwUtils.changeTextureSize(this, pg_dof, width, height, 0, resized);
      pg_tmp    = DwUtils.changeTextureSize(this, pg_tmp, width, height, 0, resized, 
        GL2.GL_RGBA16F, GL2.GL_RGBA, GL2.GL_FLOAT);
    
      //    geombuffer.resize(width, height)
    
      if (resized[0]) {
        // nothing here
      }
    
      peasycam.feed();
      perspective(60 * DEG_TO_RAD, width/(float)height, 2, 6000);
    
      return resized[0];
    }
    
    void displaySceneWrap(PGraphics3D canvas) {
      canvas.beginDraw();
      DwUtils.copyMatrices((PGraphics3D) this.g, canvas);
    
      canvas.blendMode(PConstants.BLEND);
      canvas.background(2);
      displayScene(canvas);
      canvas.endDraw();
    }
    
    void displayScene(PGraphics3D canvas) {
      canvas.directionalLight(255, 255, 255, 200, 600, 400);
      canvas.directionalLight(255, 255, 255, -200, -600, -400);
      canvas.ambientLight(64, 64, 64);
    
      if (canvas == geombuffer.pg_geom) {
        canvas.background(255, 255);
        canvas.pgl.clearColor(1, 1, 1, 6000);
        canvas.pgl.clear(PGL.COLOR_BUFFER_BIT);
      }
    
      sceneShape(canvas);
    }
    
    void sceneShape(PGraphics3D canvas) {
      if (shp_scene != null) {
        canvas.shape(shp_scene);
        return;
      }
    
      shp_scene = createShape(GROUP);
    
      int num_boxes = 50;
      int num_spheres = 50;
      float bb_size = 800;
      float xmin = -bb_size;
      float xmax = +bb_size;
      float ymin = -bb_size;
      float ymax = +bb_size;
      float zmin =  0;
      float zmax = +bb_size;
    
      colorMode(HSB, 360, 1, 1);
      randomSeed(0);
    
      for (int i = 0; i < num_boxes; i++) {
        float px = random(xmin, xmax);
        float py = random(ymin, ymax);
        float sx = random(200) + 10;
        float sy = random(200) + 10;
        float sz = random(zmin, zmax);
    
        float off = 45;
        float base = 0;
        float hsb_h = base + random(-off, off);
        float hsb_s = 1;
        float hsb_b = random(0.1, 1.0);
        int shading = color(hsb_h, hsb_s, hsb_b);
    
        PShape shp_box = createShape(BOX, sx, sy, sz);
        shp_box.setFill(true);
        shp_box.setStroke(false);
        shp_box.setFill(shading);
        shp_box.translate(px, py, sz*.5);
        shp_scene.addChild(shp_box);
      }
    
      DwCube cube_smooth = new DwCube(4);
      DwCube cube_facets = new DwCube(2);
    
      for (int i = 0; i < num_spheres; i++) {
        float px = random(xmin, xmax);
        float py = random(ymin, ymax);
        float pz = random(zmin, zmax);
        float rr = random(50) + 50;
        boolean facets = true;//(i%2 == 0);
    
        float off = 20;
        float base = 225;
        float hsb_h = base + random(-off, off);
        float hsb_s = 1;
        float hsb_b = random(0.1, 1.0);
        int shading = color(hsb_h, hsb_s, hsb_b);
    
        PShape shp_sphere = createShape(PShape.GEOMETRY);
        if (facets) {
          DwMeshUtils.createPolyhedronShape(shp_sphere, cube_facets, 1, 4, false);
        } else {
          DwMeshUtils.createPolyhedronShape(shp_sphere, cube_smooth, 1, 4, true);
        }
    
        shp_sphere.setStroke(!true);
        shp_sphere.setStroke(color(0));
        shp_sphere.setStrokeWeight(0.01 / rr);
        shp_sphere.setFill(true);
        shp_sphere.setFill(shading);
        shp_sphere.resetMatrix();
        shp_sphere.scale(rr);
        shp_sphere.translate(px, py, pz);
        shp_scene.addChild(shp_sphere);
      }
    
      colorMode(RGB, 255, 255, 255);
    
      PShape shp_rect = createShape(RECT, -1000, -1000, 2000, 2000);
      shp_rect.setStroke(false);
      shp_rect.setFill(true);
      shp_rect.setFill(color(255));
    
      shp_scene.addChild(shp_rect);
    }
    
    PShape createGridXY(int lines, float s) {
      PShape shp_gridxy = createShape();
      shp_gridxy.beginShape(LINES);
      shp_gridxy.stroke(0);
      shp_gridxy.strokeWeight(1);
      float d = lines*s;
    
      for (int i = 0; i <= lines; i++) {
        shp_gridxy.vertex(-d, -i*s, 0); 
        shp_gridxy.vertex(d, -i*s, 0);
        shp_gridxy.vertex(-d, +i*s, 0); 
        shp_gridxy.vertex(d, +i*s, 0);
    
        shp_gridxy.vertex(-i*s, -d, 0); 
        shp_gridxy.vertex(-i*s, d, 0);
        shp_gridxy.vertex(+i*s, -d, 0); 
        shp_gridxy.vertex(+i*s, d, 0);
      }
    
      shp_gridxy.endShape();
      return shp_gridxy;
    }
    
    void printCam() {
      float[] pos = peasycam.getPosition();
      float[] rot = peasycam.getRotations();
      float[] lat = peasycam.getLookAt();
      float   dis = (float) peasycam.getDistance();
    
      System.out.printf(ENGLISH, POSITION, pos[0], pos[1], pos[2]);
      System.out.printf(ENGLISH, ROTATION, rot[0], rot[1], rot[2]);
      System.out.printf(ENGLISH, LOOK_AT, lat[0], lat[1], lat[2]);
      System.out.printf(ENGLISH, DISTANCE, dis);
    }
    
  • How to compute 3D Delaunay Triangulation ? (with or without library)

    Please show me the code, where you applied the bloom effect, with push and pop of the matrix stack.

    I'm not sure to understand, the code is right above your comment. Maybe you're refering to the first script (which is basically the same but without an off-screen graphics buffer)

    And by the way, if you are using peasycam, you have to do the post processing in the HUD state (beginHUD, endHUD).

    It did solve the problem, thank you very much cansik. Also let me thank you once again for all the work you've put in the PostFX library.

  • How to compute 3D Delaunay Triangulation ? (with or without library)

    @solub Please show me the code, where you applied the bloom effect, with push and pop of the matrix stack.

    And by the way, if you are using peasycam, you have to do the post processing in the HUD state (beginHUD, endHUD).

    It maybe makes sense to look at the examples of the libraries first. There is an example with the peasycam in the postfx library, and there is an offscreen rendering example in the peasycam library.

    Looking at them should solve all your problems.

  • How to create a screen with both P2D and P3D ?

    @Rajashekhar_V_S:

    Here are three methods to create a mixed 2D / 3D surface in Processing:

    1. Create a P3D sketch and use peasyCam + beginHUD()
    2. Create a P2D sketch and layer a P3D PGraphics on it
    3. Create a P3D sketch and use hint(DISABLE_DEPTH_TEST)

    You probably want approach 2 or 3.

    Discussions and example sketches of all three approaches here:

    https://forum.processing.org/two/discussion/22365/how-do-i-display-shapes-in-p3d-like-on-a-hud

  • How to create a screen with both P2D and P3D ?

    yes library peasyCam with beginHUD ... picture with buttons ... endHUD

    you'll see the model always a bit from the side though; maybe PGraphics would be a work around

  • How to create a screen with both P2D and P3D ?

    I don't think you can do that in the way you describe. But look up peasycam and it's HUD method for an example of this kind of thing.

  • Remove left-click requirement to move camera in PeasyCam

    I am working on a Minecraft clone developed using Processing and PeasyCam. I will code the rest myself, with help from this forum. I need to know how to track mouse movement without having to left-click. That will be used for a first-person look-around feature. Here is the code right now:

    import peasy.PeasyCam;
    
    PeasyCam cam;
    
    final float gravity = 1; //Inaccurate gravity simulation (impulse rather than force)
    
    // ArrayLists for the class
    //ArrayList<Box3D> boxes = new ArrayList(); 
    //Box3D box;
    
    // this is a very important size: size boxes
    float sizeBox = 70.0;
    float sizeLimit = 180;
    
    float rotationX;
    float rotationY;
    float rotationZ;
    
    float translatex=-sizeBox;
    float translatey=-sizeBox;
    float translatez=0;
    
    float z = 1.0;
    
    int objectNumber = 0;
    
    // folded triangle 
    PShape s; 
    
    float offsetZ=400;
    
    color colCurrent=color(0, 0, 255);
    
    boolean showHelpText=true; 
    
    void setup() {
    
      size(500, 500, P3D);
      background(0);
      sphereDetail(32);
    
      cam = new PeasyCam(this, 400); // new
      //box = new Box3D(0, 0, 0, 0, 0, color(255));
    
      s = createShape();
      s.beginShape();
      s.fill(255, 0, 0);
      s.stroke(177);
      s.vertex(100, 0, -100);
      s.vertex(-60, 0, 200);
      s.vertex(-50, 60, -30);
      s.vertex(110, 160, 40);
      s.scale(0.4);
      s.endShape(CLOSE);
    }
    
    void draw() {
      background(0);
      lights();
    
      //for (Box3D b : boxes ) {
       // box.display();
      //}
    
      noFill();
      box(sizeLimit*2+sizeBox); // ?
    
      showObject();
    
      cam.beginHUD(); 
      /**if (showHelpText) {
        fill(255); // white 
        text ("Use PeasyCam. Use wasd and pl; r/g/b for colors, space bar to toggle object, RETURN to enter object to list.\n\n"
          +"Use x to switch this text on and off. \n"
          +"Use Mousewheel to zoom, double click to reset view. The box you move has a white outline. An item that has been added to the list is marked with a gray box.\n"
          +"On adding to the list the placing box moves two units left. \n"
          +"Current: "
          +translatex
          +", "
          +translatey
          +", "
          +translatez, 
          19, 19);
      }*/ //HUD disabled
    
      if (keyPressed)
        keyPressed_ForContinuusKeyinput();
    
      cam.endHUD();
    }
    
    // -----------------------------------------------------------
    
    void showObject() {
    
      // show object 
    
      pushMatrix();
    
      translatey+=gravity;
    
      translatex=constrain(translatex,-sizeLimit,sizeLimit);
      translatey=constrain(translatey,-sizeLimit,sizeLimit);
      translatez=constrain(translatez,-sizeLimit,sizeLimit);
    
      fill(colCurrent); // color
      //translate(width/3, height/2, 0);
      translate(translatex, translatey, translatez);
      //rotateZ(rotationZ);
      //rotateY(rotationY);
      //rotateX(rotationX);
    
      stroke(255); 
    
      if (objectNumber==0) {
        //stroke(111);
        box(sizeBox);
      } else if (objectNumber==1) {
        s.setFill(colCurrent);
        shape(s, 0, 0);
      } else if (objectNumber==2) {
        //noStroke();
        sphere(sizeBox);
      }//else 
    
      popMatrix();
    }
    
    // -----------------------------------------------------------
    
    void keyPressed_ForContinuusKeyinput() {
      // keyPressed for registering a key throughout  
    
      float speed = 3.9; 
    
      //speed += gravity; //More accurate gravity simulation, may be removed
    
      switch(key) {
    
      case 'a':
        translatex-=speed;
        break; 
    
      case 'd':
        translatex+=speed;
        break;
    
      case 'w':
      case ' ':
        translatey-=speed; //Conflicting keypress info: change object
        break;
    
      case SHIFT:
      case 's':
        translatey+=speed;
        break;
    
        // --
    
      case 'p':
        translatez-=speed;
        break; //Unnecessary in 2D version, but useful
    
      case 'l':
        translatez+=speed;
        break; //Unnecessary in 2D version, but useful
    
        // -----
    
        //
      }//switch
      //
    }//func
    
    // ----------------------------
    
    void keyPressed() {
    
      // keyPressed for registering a single key only 
    
      switch(key) {
        /**
      case ' ':
        objectNumber++;
        if (objectNumber>2)
          objectNumber=0;
        key=0;
        break;
        */ //Object switch disabled in favor of jumping
    
     /**
      case RETURN:
      case ENTER:
        Box3D newBox = new Box3D (
          translatex, 
          translatey, 
          translatez, 
          rotationY, 
          objectNumber, 
          colCurrent
          ); 
        boxes.add(newBox); 
        translatex-=sizeBox*2;
        break;
        */ //New object function disabled
    
        // ---
        //colors
    
      case 'r':
        colCurrent=color(255, 0, 0);
        break;
    
      case 'b':
        colCurrent=color(0, 0, 255);
        break;
    
      case 'g':
        colCurrent=color(0, 255, 0);
        break;
    
        // --
    
      case 'x':
        showHelpText = !showHelpText; 
        break;
      }//switch
      //
    } //func
    
    //=============================================================
    
    class Box3D {
    
      float x=mouseX, y=410, z=mouseY;
    
      float offsetX=0; 
      float offsetZ2=0; 
    
      float rotateY=0;
      color colBox = color(255, 0, 0);
    
      // type
      final int boxTypeUndefined = -1;
      final int boxType0   = 0;
      final int boxType1   = 1; 
      final int boxType2   = 2; 
      // more needed !!!!! ???? 
      int type = boxTypeUndefined; 
    
      // constr - full
      Box3D(float x_, 
        float y_, 
        float z_, 
        float rotateY_, 
        int type_, 
        color col1_) {
        //
    
        x=x_;
        y=y_;
        z=z_;
    
        rotateY= rotateY_;
        type=type_;
    
        colBox=col1_;
      } // constr 2 
    
      void display() {
        pushMatrix();
    
        translate(x, y, z);
        //  rotateY(radians(rotateY)); 
    
        fill(colBox);
        noStroke(); 
    
        // depending on the current buttons tag 
        // 
        switch (type) {
    
        case boxTypeUndefined:
          // undefined 
          break; 
    
        case boxType0: 
          stroke(111);
          box(sizeBox);
          break; 
    
        case boxType1: 
          s.setFill(colBox);
          shape(s, 0, 0);
          break;
    
        case boxType2: 
          noStroke();
          sphere(sizeBox);
          break;
    
        default:
          // error 
          break;
        }//switch 
    
        if (showHelpText) {
          translate(sizeBox/2, -sizeBox/2, sizeBox/2);
    
          fill(111);
          stroke(0);
          box(sizeBox/6);
        }
    
        popMatrix();
      } // method 
    
      String toString() {
        return
          str(x) +","+ 
          str(y) +","+ 
          str(z) +","+ 
          str(rotateY) +","+ 
          str(type) +","+ 
          str(red(colBox)) +","+ 
          str(green(colBox)) +","+ 
          str(blue(colBox)) ;
      }
      //
    } // class 
    //
    

    I understand there is a redundant class "Box3D", but I will handle that before implementing whatever solution you give me.

  • Use arrow keys to "pull" object, translate keypresses to changes in X, Y, and Z rotation

    Thank you! This has solved my problem. Also, here is the code, modified to suit my needs:

    import peasy.PeasyCam;
    
    PeasyCam cam;
    
    final float gravity = 1; //Inaccurate gravity simulation (impulse rather than force)
    
    // ArrayLists for the class
    ArrayList<Box3D> boxes = new ArrayList(); 
    
    // this is a very important size: size boxes
    float sizeBox = 70.0;
    float sizeLimit = 180;
    
    float rotationX;
    float rotationY;
    float rotationZ;
    
    float translatex=-sizeBox;
    float translatey=-sizeBox;
    float translatez=0;
    
    float z = 1.0;
    
    int objectNumber = 0;
    
    // folded triangle 
    PShape s; 
    
    float offsetZ=400;
    
    color colCurrent=color(0, 0, 255);
    
    boolean showHelpText=true; 
    
    void setup() {
    
      size(500, 500, P3D);
      background(0);
      sphereDetail(32);
    
      cam = new PeasyCam(this, 400); // new 
    
      s = createShape();
      s.beginShape();
      s.fill(255, 0, 0);
      s.stroke(177);
      s.vertex(100, 0, -100);
      s.vertex(-60, 0, 200);
      s.vertex(-50, 60, -30);
      s.vertex(110, 160, 40);
      s.scale(0.4);
      s.endShape(CLOSE);
    }
    
    void draw() {
      background(0);
      lights();
    
      for (Box3D b : boxes ) {
        b.display();
      }
    
      showObject();
    
      cam.beginHUD(); 
      if (showHelpText) {
        fill(255); // white 
        text ("Use PeasyCam. Use wasd and pl; r/g/b for colors, space bar to toggle object, RETURN to enter object to list.\n\n"
          +"Use x to switch this text on and off. \n"
          +"Use Mousewheel to zoom, double click to reset view. The box you move has a white outline. An item that has been added to the list is marked with a gray box.\n"
          +"On adding to the list the placing box moves two units left. \n"
          +"Current: "
          +translatex
          +", "
          +translatey
          +", "
          +translatez, 
          19, 19);
      }
    
      if (keyPressed)
        keyPressed_ForContinuusKeyinput();
    
      cam.endHUD();
    }
    
    // -----------------------------------------------------------
    
    void showObject() {
    
      // show object 
    
      pushMatrix();
    
      translatey+=gravity;
    
      translatex=constrain(translatex,-sizeLimit,sizeLimit);
      translatey=constrain(translatey,-sizeLimit,sizeLimit);
      translatez=constrain(translatez,-sizeLimit,sizeLimit);
    
      fill(colCurrent); // color
      //translate(width/3, height/2, 0);
      translate(translatex, translatey, translatez);
      //rotateZ(rotationZ);
      //rotateY(rotationY);
      //rotateX(rotationX);
    
      stroke(255); 
    
      if (objectNumber==0) {
        //stroke(111);
        box(sizeBox);
      } else if (objectNumber==1) {
        s.setFill(colCurrent);
        shape(s, 0, 0);
      } else if (objectNumber==2) {
        //noStroke();
        sphere(sizeBox);
      }//else 
    
      popMatrix();
    }
    
    // -----------------------------------------------------------
    
    void keyPressed_ForContinuusKeyinput() {
      // keyPressed for registering a key throughout  
    
      float speed = 3.9; 
    
      switch(key) {
    
      case 'a':
        translatex-=speed;
        break; 
    
      case 'd':
        translatex+=speed;
        break;
    
      case 'w':
      case ' ':
        translatey-=speed; //Conflicting keypress info: change object
        break;
    
      case SHIFT:
      case 's':
        translatey+=speed;
        break;
    
        // --
    
      case 'p':
        translatez-=speed;
        break; 
    
      case 'l':
        translatez+=speed;
        break; //Unnecessary in 2D version, but useful
    
        // -----
    
        //
      }//switch
      //
    }//func
    
    // ----------------------------
    
    void keyPressed() {
    
      // keyPressed for registering a single key only 
    
      switch(key) {
        /*
      case ' ':
        objectNumber++;
        if (objectNumber>2)
          objectNumber=0;
        key=0;
        break;
        */ //Object switch disabled in favor of jumping
    
      case RETURN:
      case ENTER:
        Box3D newBox = new Box3D (
          translatex, 
          translatey, 
          translatez, 
          rotationY, 
          objectNumber, 
          colCurrent
          ); 
        boxes.add(newBox); 
        translatex-=sizeBox*2;
        break;
    
        // ---
        //colors
    
      case 'r':
        colCurrent=color(255, 0, 0);
        break;
    
      case 'b':
        colCurrent=color(0, 0, 255);
        break;
    
      case 'g':
        colCurrent=color(0, 255, 0);
        break;
    
        // --
    
      case 'x':
        showHelpText = !showHelpText; 
        break;
      }//switch
      //
    } //func
    
    //=============================================================
    
    class Box3D {
    
      float x=mouseX, y=410, z=mouseY;
    
      float offsetX=0; 
      float offsetZ2=0; 
    
      float rotateY=0;
      color colBox = color(255, 0, 0);
    
      // type
      final int boxTypeUndefined = -1;
      final int boxType0   = 0;
      final int boxType1   = 1; 
      final int boxType2   = 2; 
      // more needed !!!!! ???? 
      int type = boxTypeUndefined; 
    
      // constr - full
      Box3D(float x_, 
        float y_, 
        float z_, 
        float rotateY_, 
        int type_, 
        color col1_) {
        //
    
        x=x_;
        y=y_;
        z=z_;
    
        rotateY= rotateY_;
        type=type_;
    
        colBox=col1_;
      } // constr 2 
    
      void display() {
        pushMatrix();
    
        translate(x, y, z);
        //  rotateY(radians(rotateY)); 
    
        fill(colBox);
        noStroke(); 
    
        // depending on the current buttons tag 
        // 
        switch (type) {
    
        case boxTypeUndefined:
          // undefined 
          break; 
    
        case boxType0: 
          stroke(111);
          box(sizeBox);
          break; 
    
        case boxType1: 
          s.setFill(colBox);
          shape(s, 0, 0);
          break;
    
        case boxType2: 
          noStroke();
          sphere(sizeBox);
          break;
    
        default:
          // error 
          break;
        }//switch 
    
        if (showHelpText) {
          translate(sizeBox/2, -sizeBox/2, sizeBox/2);
    
          fill(111);
          stroke(0);
          box(sizeBox/6);
        }
    
        popMatrix();
      } // method 
    
      String toString() {
        return
          str(x) +","+ 
          str(y) +","+ 
          str(z) +","+ 
          str(rotateY) +","+ 
          str(type) +","+ 
          str(red(colBox)) +","+ 
          str(green(colBox)) +","+ 
          str(blue(colBox)) ;
      }
      //
    } // class 
    //
    
  • Rotate a camera around Z axis

    Quick demo

    plane doesn't really fly up and down but only forward left / right

    use wasd plus mouse

    // https : // forum.processing.org/two/discussion/24912/radar-view-of-infinite-3d-space#latest
    // https : // www.openprocessing.org/sketch/25255
    
    // all spheres 
    ArrayList<Sphere3D> Sphere3Ds = new ArrayList();
    
    // camera / where you are 
    float xpos, ypos, zpos, 
      xlookat, ylookat, zlookat, 
      xCamOwnAngle=0, yCamOwnAngle=1.0, zCamOwnAngle=0;
    
    float angle=0.0; // (angle left / right; 0..359)
    
    // "Floor" has y-value (the plane you fly in (y-direction)) 
    final float floorLevel = 500.0;
    
    // ---------------------------------------------------------------
    
    void setup() {
      size(1900, 990, P3D);
    
      for ( int i = 0; i < 112; i++ ) {
        Sphere3Ds.add( new Sphere3D() );
      }
    }//func 
    
    void draw() {
    
      background(0);
    
      // draw Main Scene in 3D
      drawMainSceneIn3D(); 
    
      // 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);
    }//func 
    
    //---------------------------------------------------------------
    
    void drawMainSceneIn3D() {
      // draw Main Scene in 3D (main screen)
    
      hint(ENABLE_DEPTH_TEST);
    
    
      pushMatrix();
      CheckCameraMouse();
      lights();
      noFill();
      stroke(255);
      gridOnFloor();
      for ( Sphere3D Sphere3D : Sphere3Ds ) { 
        Sphere3D.simulate(); 
        Sphere3D.draw3D();
      }
      popMatrix();
    }//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;
          }
        }        
        // ----------------------------        
        if (key == 'i' || key == 'I') {
          // Saves a TIFF file named "diagonal.tif"
          save("Runner1.tif");
        }
        //
      } // if(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 = map(rmy, 0, height, -270, 333); // look up / down // OR just 300 as fix value 
      zlookat = Radius*cos(radians(angle)) + zpos; 
    
      if (rmx<width/2) 
        yCamOwnAngle= map(rmx, 0, width, 0, 1); 
      yCamOwnAngle=.3;
      zCamOwnAngle=.3;
    
      camera (xpos, ypos, zpos, 
        xlookat, ylookat, zlookat, 
        xCamOwnAngle, yCamOwnAngle, zCamOwnAngle
        );
    }
    
    void gridOnFloor() {
    
      // pushMatrix();
    
      noFill();
    
      // add
      int d = int ( 24000 / 200);
    
      // diameter
      int d1 = d;
    
      float floorLevel1 = 2* floorLevel; 
    
      // color
      stroke(111);  // gridColor);
      // rectMode(CENTER);
      strokeWeight(1);
    
      for (int x = -12000; x <= 12000; x += d) {
        for (int y = -12000; y <= 12000; y += d) {
          //rect(x, y, d1, d1);
          line(x, floorLevel1, y, 
            x+d1, floorLevel1, y); 
          line(x, floorLevel1, y, 
            x, floorLevel1, y+d1); 
          line(x, floorLevel1, y+d1, 
            x+d1, floorLevel1, y+d1);
        }
      }
    
      // rectMode(CORNER);
      //popMatrix();
    }
    
    
    //=============================================================
    
    class Sphere3D {
    
      // class for a 3D sphere
    
      PVector p; //position 
      color c;   //color
    
      // pulsating effect (OFF)
      float size, 
        primSize, 
        add=0;       // 0 = no pulsating (OFF)
    
      // constr 
      Sphere3D() {
    
        //position 
        p = new PVector( random(-12180, 1180), random(-1180, 1180), random(-12180, 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();
      }
      //
    }//class 
    //
    
  • Rotate a camera around Z axis

    OK before we come to "Rotate a camera around Z axis":

    here is a standard version where the camera position rotates in the X/Z plane around a fixed center (a Lamp post). Camera Y position (its height) is fixed.

    The camera moves on a circle, calculated with cos and sin.

    It looks as if the bar (Lamp post) rotates, but in fact only the camera position rotates.

    The bar is fixed and the camera look at (Center) is fixed.

    The camera position itself moves. UP vector is also fixed.

    Forget the lamp post just look at function CheckCameraSinusLevel().

    https://www.processing.org/reference/camera_.html

    // Lamppost
    int lampPost_XValue = 250; // nach rechts
    int lampPost_YValue = 330; // nach unten
    int lampPost_ZValue = -150; // nach hinten
    
    String actualTextMessage = "Use 0,1,2,3 for Camera";
    String actualTextMessage2 = "Camera circles at constant height";
    
    // ==================================================
    // Kamerasteuerung:
    
    float Angle = 0.0; // Angle 
    float Height = 130;    // Height
    float Radius = 210.0;  // Radius
    
    // Camera
    int LookAtX;
    int LookAtY;
    int LookAtZ;
    
    // ==========================================================
    
    void setup() {
      size(600, 600, P3D);
    
      // LookAt
      LookAtX=lampPost_XValue;
      LookAtY= lampPost_YValue;
      LookAtZ= lampPost_ZValue;
    } // function
    
    void draw() {
      background(153);
      lights();
    
      // the scene 
      CheckCameraSinusLevel();
      fill(242);
      stroke(22);
      PaintLamppost();
      Angle=Angle+1.0;
    
      // HUD to display text 
      camera();
      noLights();
      hint(DISABLE_DEPTH_TEST); 
      text ("Fixed Look At", 30, 30);
    }
    
    // =====================================================================
    
    void PaintLamppost () {
    
      pushMatrix();
      int myHeight = 220;
      fill(190, 3, 3);
      translate(lampPost_XValue-0, 
        lampPost_YValue+(myHeight / 2), 
        lampPost_ZValue);
      box(11, myHeight, 11);
      popMatrix();
    }
    
    void CheckCameraSinusLevel () {
    
      // camera rotates in height "Height"
      // position of camera is on a circle calculated with cos and sin
      // look to scene (center/lampPost)
      camera (
        Radius*sin (radians(Angle)) + lampPost_XValue, Height, Radius* cos (radians(Angle)) + lampPost_ZValue, 
        lampPost_XValue, lampPost_YValue, lampPost_ZValue, 
        0.0, 1.0, 0.0);
    }
    //
    
  • Different sizes on different devices

    @hudson_m4000 Thanks for the comment! I was originally going to do that but my game is meant to be played in both portrait and landscape mode and when I tried that it messed up the proportions.