jdf / peasycam

Dead-simple mouse-driven camera for Processing
http://MrFeinberg.com/peasycam/
Apache License 2.0
116 stars 35 forks source link

Apply peasyCam matrix onto PGraphics3D #25

Closed cansik closed 7 years ago

cansik commented 7 years ago

At the moment I am working on a multi-pass rendering in processing. There I have to use a new PGraphics3D canvas and I can not use the default g object. After the rendering and shading, I'm just going to "print" it on to the g object again as texture:

cam.beginHUD();
image(canvas, 0, 0);
cam.endHUD();

Now I have the problem that things like peasycam do not work anymore because they are attached to the original g and do not transform the camera matrix of my canvas.

So I tried to use the camera matrix of the original graphics and copy it to my canvas:

PGraphics3D p = (PGraphics3D)this.g;
canvas.camera = p.camera;

This did not work, maybe because peasycam is doing something special and it does not change the original camera matrix. So my next idea was to use the static apply method from peasy cam. I had to copy the function out of the original code and make it public:

import peasy.org.apache.commons.math.geometry.Rotation;
import peasy.org.apache.commons.math.geometry.Vector3D;

Vector3D positionVec = new Vector3D(cam.getPosition()[0], cam.getPosition()[1], cam.getPosition()[2]);
Vector3D rotationVec = new Vector3D(cam.getRotations()[0], cam.getRotations()[1], cam.getRotations()[2]);
apply(canvas, positionVec, new Rotation(rotationVec, 0), cam.getDistance());

Here the apply method:

void apply(final PGraphics g, final Vector3D center, final Rotation rotation, 
  final double distance) {
  final Vector3D pos = rotation.applyTo(Vector3D.plusK).scalarMultiply(distance).add(center);
  final Vector3D rup = rotation.applyTo(Vector3D.plusJ);
  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());
}

There I always have a zero norm for rotation (Arithmetic Exception). So my final idea was to just copy all the rotations and translation to my camera matrix:

canvas.beginCamera();
canvas.camera();

canvas.rotateX(cam.getRotations()[0]);
canvas.rotateY(cam.getRotations()[1]);
canvas.rotateZ(cam.getRotations()[2]);

canvas.translate(
  cam.getPosition()[0], 
  cam.getPosition()[1], 
  cam.getPosition()[2]);

canvas.endCamera();

So now I could rotate my cube, but it was not accurate and I think there is something wrong with some axis.

I would like to ask if someone has done this before and if there is a simple method to do this?

jdf commented 7 years ago

I'd guess that instead of canvas.camera = p.camera you'd have to copy the peasycam camera, as in canvas.camera = new PMatrix3D(p.camera).

But this is just a guess.

cansik commented 7 years ago

Found this as solution. Works great!

cam.getState().apply(canvas);
jdf commented 7 years ago

Oh, yeah. That's what that's for. :)