Tutorial: Locked Rotation with p5.easycam

Hey guys, I just wanted to share my experience and my newfound knowledge of easycam.

This idea started when I wanted to smoothly move around a physics sim that I am working on. The freeness of the camera was slightly too chaotic for my liking and I wanted something that was less all over the place.

I originally created a overcomplicated function in mouseDragged() that got the gradient between each of the mouse drags and then check the gradient and then used the built in function cam.setRotationConstraint()

here is that code:

b = [];
function mouseDragged(){
  let gp;
  if(b.length != mouseArray){
    cam.setRotation(current_rotation,0);
    cam.setDistance(zoom);
  }
  
  if(b.length == mouseArray){
    gp = (b[0].y-b[b.length-1].y)/(b[0].x-b[b.length-1].x);
    //console.log(gp);
    if(gp>1 || gp == -Infinity) cam.setRotationConstraint(false,true,false);
    else cam.setRotationConstraint(true,false,false);
  }
}

function mouseReleased(){
  b=[];
}

This code, although functional (most of the time), wasn’t as pristine as I was hoping; and it had a few noticeable bugs.
.

As a bit of a perfectionist. I decided to go deeper into the library and find out how exactly everything ticked. And after delving into the controls, I realised that holding shift and dragging had the exact behaviour that I needed.

I searched for the snippet if code that contained the shift key and I eventually found the holy grail. On line 192-205 is everything one would need to change function of the shift key.

solveConstraint : function(){
        var dx = this.dist[0];
        var dy = this.dist[1];
        
        // YAW, PITCH
        if (this.shiftKey && !cam.SHIFT_CONSTRAINT && Math.abs(dx - dy) > 1) {
          cam.SHIFT_CONSTRAINT = Math.abs(dx) > Math.abs(dy) ? cam.AXIS.YAW : cam.AXIS.PITCH;
        }
        
        // define constraint by increasing priority
        cam.DRAG_CONSTRAINT = cam.AXIS.ALL;
        if(cam.FIXED_CONSTRAINT) cam.DRAG_CONSTRAINT = cam.FIXED_CONSTRAINT;
        if(cam.SHIFT_CONSTRAINT) cam.DRAG_CONSTRAINT = cam.SHIFT_CONSTRAINT;
      }

All you need to do is set this set the reverse of the shift key (allows free rotation). like this:
if (!this.shiftKey && !cam.SHIFT_CONSTRAINT && Math.abs(dx - dy) > 1)

or remove the requirement of the shift key press entirely and have it permanently set to single axis rotation mode. like this:
if (!cam.SHIFT_CONSTRAINT && Math.abs(dx - dy) > 1)

If you don’t wan’t to edit the library yourself, I have created a library which adds 2 functions
setLockedRotation(); and setLockedRotationShift();

setLockedRotation permanently sets the rotation and setLockedRotationShift allows you to hold shift to activate free rotation.

here is the GitHub repo with the file in it :))

here is an example sketch of the use of my functions: sketch

.

Thanks for reading guys.

-Sam

2 Likes