Question for PeasyCam: Auto positioning

Hello all,

I have a question to Peasycam

I‘d like to zoom and pan the cam during an animation to the area where something happens. Think of an animation of a game of chess where the board is so big that the camera wanders smoothly from move to move (with lerp/easing).

I have screenX, screenY and also 3D coordinates

All help appreciated

Warm regards

Chrisir

Hi @Chrisir

This doesn’t work, so I’m not sure how helpful it is.

There’s no available set position method (that I know), but the camera getState() and setState() methods can get and set its position, rotation etc (You probably know about this). Unfortunately, getting the position from this isn’t easy (at least I don’t know how). https://github.com/jdf/peasycam

My thought was to make a clone (ish) of this state object, and maybe use that to set position. But no luck so far. (It’s serializable. I wonder if it’s possible to save/load from disk, but that would be a bit stupid. Haven’t tried that. But maybe some other way?).

Basically copied this: https://github.com/jdf/peasycam/blob/master/src/peasy/CameraState.java
And added some other bits to get it to run. Very hacky.

Peasycam lookAt() also reacts a bit strange.

Here’s what I got so far. Maybe some others (that actually know what they are doing :stuck_out_tongue: ) have better ideas.

For testing. Left-click saves camera state, right-click restores it. There’s also WASD + RF (up/down). Panning (middle mouse button) seems to have disappeared.

/** PeasyCam get set position test 
*/

import peasy.*;
import peasy.org.apache.commons.math.geometry.Rotation;
//import peasy.org.apache.commons.math.geometry.RotationOrder;
import peasy.org.apache.commons.math.geometry.Vector3D;
import java.io.Serializable;


PShape shpSphere;
int moveFB, moveLR, moveUD; // used with WASD + R/F and cam.lookAt() method.

// Attempt at making a "clone" of PeasyCam's CameraState
// to set position via its Vector3D
Rotation rot   = new Rotation(new Vector3D(0,0,1), new Vector3D(0,1,0)); // dummy/temp rotation
Vector3D vec3D = new Vector3D(0,0,0); // temp Vector3D
clonedCameraState myCamState = new clonedCameraState(rot, vec3D, 100);

PeasyCam cam;
CameraState savedState;

float cx, cy, cz;



void setup()
{
  size(400,400,P3D);
  avoidClipping();
 
  sphereDetail(10);
  shpSphere = createShape(SPHERE, 20);
  shpSphere.setStroke(color(0,0,128));
  shpSphere.setFill(color(0));
  
  cam = new PeasyCam(this, 0, 0, 0, 200);
  savedState = cam.getState();
}



void draw()
{ 
  background(0);

  cam.lookAt(cx, cy, cz);
  
  shape(shpSphere);

  cam.beginHUD();
  float[] cpos = cam.getPosition();

  text("Cam pos     : " + cpos[0] + ", " + cpos[1] + ", " + cpos[2], 20,20);
  //text("Camera state: " + savedState, 20, 40);
  //text("myCamera state: " + myCamState, 20, 60);
  cam.endHUD();
}




void avoidClipping() {
  perspective(PI/3.0, (float) width/height, 1, 1000000);
}




void mouseClicked() {
  if (mouseButton == LEFT) {
    println();
    println("Left clicked");
    savedState = cam.getState(); 
    println(savedState);

    //myCamState = cam.getState();                // doesn't work
    //myCamState = (clonedCameraState) savedState;   // doesn't work
    println(myCamState);
  }
  
  if (mouseButton == RIGHT) {
    println();
    println("Right clicked");
    println(savedState);
    cam.setState(savedState);
  }
}



void keyPressed() {
    
  if (key == 'w') moveFB = -100;
  if (key == 's') moveFB =  100;
  if (key != 'w' && key != 's') moveFB = 0;
  if (key == 'a') moveLR = -100;
  if (key == 'd') moveLR =  100;
  if (key != 'a' && key != 'd') moveLR = 0;
  if (key == 'r') moveUD = -100;
  if (key == 'f') moveUD =  100;
  if (key != 'r' && key != 'f') moveUD = 0;

  cx += moveLR;
  cy += moveUD;
  cz += moveFB;
  
  println(key);
}



void keyReleased() {
  moveLR = 0;
  moveUD = 0;
  moveFB = 0;
}



public class clonedCameraState implements Serializable {
	private static final long serialVersionUID = 1L;  // Needs to be the same as PeasyCam's ID
	final Rotation rotation;
	final Vector3D center;
	final double distance;
  
  final Vector3D LOOK = Vector3D.plusK;
  final Vector3D UP = Vector3D.plusJ;

	public clonedCameraState(final Rotation rotation, final Vector3D center,
			final double distance) {
		this.rotation = rotation;
		this.center = center;
		this.distance = distance;
	}

	public void apply(final PApplet a) {
		if (a.recorder != null) {
			apply(a.recorder);
		}
		apply(a.g);
	}
	public void apply(final PGraphics g) {
		apply(g, center, rotation, distance);
	}

	void apply(final PGraphics g, final Vector3D center, final Rotation rotation,
			final double distance) {
		final Vector3D pos = rotation.applyTo(LOOK).scalarMultiply(distance).add(center);
		final Vector3D rup = rotation.applyTo(UP);
		g.camera((float)pos.getX(), (float)pos.getY(), (float)pos.getZ(), //
				(float)center.getX(), (float)center.getY(), (float)center.getZ(), //
				(float)rup.getX(), (float)rup.getY(), (float)rup.getZ());
	}

}
1 Like

Hi there…

Reading here found this other post that I think you should see, because of its relation to your post. I found it yesterday looking for a way to save the cam.setState so that I was able to return to that exact camera view while writing. I tried to print to the console
cam.setState and I got this output, changing between keystrokes.

state1 = peasy.CameraState@127eec75
state1 = peasy.CameraState@419b289a
state1 = peasy.CameraState@3a64d831
state1 = peasy.CameraState@4d23537d

Is this output what you refer to as “serialized” ? sort of like when you try to see the actual position / location? in an array… I was expecting some coordinates (x, y, z) of the position of the camera in that 3D space…
Have not used it yet. Will install manually as I do not see it in the Contribution Manager. The states get saved to a JSON file. Excited to try it
:slight_smile:

FPVCam by @LuisFerreira

1 Like