Sketch with a GViewPeasyCam control

This control makes it easy to combine the power of PeasyCam with G4P. Each GViewPeasyCam control behaves independantly, each having its own camera.

This video shows a Processing sketch with 2 PeasyCam view controls embedded in the main sketch display. It will give you a flavour of what cn be done with this control but to find out more you need to read these guides.

The sketch shown in this video is also included as an example in the library download / installation.

How do I do that?

The first thing to to is create the two controls. First we decalre them globally.

GViewPeasyCam view1, view2;

Then in setup we create the actual controls.

void setup() {
  size(600, 340, P2D);
  surface.setTitle("G4P PeasyCam View");
  cursor(HAND);
  // Setup first GViewPeasyCam
  view1 = new GViewPeasyCam(this, 10, 30, 250, 250, 200);
  PeasyCam pcam = view1.getPeasyCam();
  pcam.setMinimumDistance(120);
  pcam.setMaximumDistance(400);
  // Setup second GViewPeasyCam
  view2 = new GViewPeasyCam(this, 290, 30, 300, 200, 400);
  pcam = view2.getPeasyCam();
  pcam.setMinimumDistance(220);
  pcam.setMaximumDistance(800);
  // Setup the main backdrop balls animation
  makeBalls();
  textSize(18);
}

The controls are created in lines 40 and 45. We are using the default GCtrlMode.CORNER mode (see Creating GUI controls) so the first parameter value (this) is the main sketch window, the next four numbers are the x/y position of top left corner, the width and the height of the view. The final parameter is the distance to the camera's lookat position, by default [0,0,0].

There is another constructor that lets the user specify the lookat position, this table details the two constructors available.

Constructors

Constructor Description
GViewPeasyCam (PApplet theApplet, 
     float p0, float p1, 
     float p2, float p3,
     PVector lookAt, 
     float distance)
In most sketches the first parameter will have the value this to represent the main sketch widow.
The 4 float parameters will be the [x, y, width, height] of the view area.
The 5th parameter is a vector indicating the camera's lookat position.
The final parameter is the distance from the lookat position.
GViewPeasyCam (PApplet theApplet, 
     float p0, float p1, 
     float p2, float p3,
     float distance)
Same os the first constrictor but the lookat position is set to [0,0,0]

Updating the view.

For each control the user must provide a method / function to update the display. Here is the code for the left view (view1).

void updateView1() {
  // ############################################################
  // Get the graphics context and camera
  PGraphics pg = view1.getGraphics();
  PeasyCam pcam = view1.getPeasyCam();
  // ############################################################
  // Initialise the canvas
  pg.beginDraw();
  pg.resetMatrix();
  // ############################################################
  // World view lighting here (optional)
  pg.ambientLight(100, 100, 100);
  pg.directionalLight(220, 220, 0, 0.8f, 1, -1.2f);

  // ############################################################
  // set model view - using camera state
  pcam.feed();

  // ############################################################
  // Model view lighting here (optional)

  // ############################################################
  // Code to draw canvas
  pg.background(120, 120, 0, 120);

  pg.fill(255, 200, 128);
  pg.stroke(255, 0, 0);
  pg.strokeWeight(4);
  pg.box(80);

  // ############################################################
  // Demonstrates use of the PeaseyCam HUD feature
  pcam.beginHUD();
  pg.rectMode(CORNER);
  pg.noStroke();
  pg.fill(0);
  pg.rect(0, 0, view1.width(), 30);
  pg.fill(255, 255, 0);
  pg.textSize(18);
  pg.textAlign(CENTER, CENTER);
  pg.text("Using Worldview lighting", 0, 0, view1.width(), 30);
  pcam.endHUD();

  // ############################################################
  // We are done!!!
  pg.endDraw();
}

This code is quite length but there are a lot of comments to help you organise your code. I will discuss the key features.

In line 65 we get the graphics conext (canvas) we want to draw to, you can see this is used a lot in this method. The next line (66) gets the PeasyCam used in this control, this is really useful because it gives the programmer full access to PeaseCam's API. These lines should always be at the beginning of the update methods because we will use these values inside this method.

The statement pcam.feed(); is essential because it sets the transformation matrix based on the camera's state. Before this instruction we are using world-view coordinates, after we are using model-view coordinates. The lightingof the shapes is different in the two views and is determined whether the lighting source code is before or after this statement.

Finally both views show how to use PeasyCam's HUD feature.

Listeners

You can add a GViewListener to a GViewPeasyCam in the same way we did for the GView control but these listeners will only report mouse ENTERED, EXITED and CLICK events since the PeasyCam is expected to handle the rest.

Limitations

Again there are some limitations which don't apply to the GView control, they are -

  1. they cannot be rotated
  2. must not be added to GPanel controls
  3. must not be used on GWindow controls

Despite these restrictions this ia a powerful and fun control to use.