processing / p5.js

p5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Processing. http://twitter.com/p5xjs —
http://p5js.org/
GNU Lesser General Public License v2.1
21.08k stars 3.22k forks source link

Implemented roll function #7093

Closed rohanjulka19 closed 1 day ago

rohanjulka19 commented 1 week ago

Resolves #6760

Changes: Addressed the changes suggested by @SableRaf and @davepagurek mentioned in the issue #6819 for implementation of roll function highlighted below. Now quaternions are used to calculate the new up vector after rotation of camera on the z-axis.

https://github.com/processing/p5.js/pull/6819#issuecomment-1961624727

A good approach would be to compute the camera rotation using quaternions, then compute the up and forward vectors from the resulting rotation and apply them to the camera. This demo by scudly is a good example of how to do it: https://infinitefunspace.com/p5/fly/

I made a minimal example based on it here: https://editor.p5js.org/SableRaf/sketches/WPYb6PRMu

https://github.com/processing/p5.js/pull/6819#issuecomment-1960584109.

I think the correct output of roll() would leave the center and eye the same, but just rotate the up vector. @SableRaf does that make sense, given how much you've been looking into cameras recently?

Right now not really sure about the code structure and correctness (still don't completely understand quaternions and their working) that's why haven't added unit tests.

Screenshots of the change:

https://github.com/processing/p5.js/assets/19673968/4e7cce58-c37d-4c31-82fe-bf4c6c83f860

PR Checklist

rohanjulka19 commented 3 days ago

Hi @davepagurek , Apologies for the delay in response. Added unit tests for roll function and a new function which rotates a vector over a quaternion axis, the code I picked from @sableraf's sketch, the one you mentioned.

rotate( p ) {
    // ( w*w - dot( v, v )) * p + 2 * dot( p, v ) * v + 2 * w * cross( v, p )
    return p5.Vector.mult( p, this.w*this.w - this.v.dot(this.v) )
      .add( p5.Vector.mult( this.v, 2 * p.dot(this.v) ) )
      .add( p5.Vector.mult( this.v, 2 * this.w ).cross( p ) );
  }

Also as you highlighted have added the links to the stackexchange answer and the doc I referred to, in the comments.

Additionaly, I had to add a new function called clampToZero in p5.Vector class because the result of subtracting floating point numbers is often not exactly zero but very close to zero. I rounded them to zero following the guidelines from

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/EPSILON

rohanjulka19 commented 1 day ago

Ok have made quaternion class private for the time being. It won't show in docs now.

davepagurek commented 1 day ago

@all-contributors please add @rohanjulka19 for code

allcontributors[bot] commented 1 day ago

@davepagurek

I've put up a pull request to add @rohanjulka19! :tada:

davepagurek commented 1 day ago

@all-contributors please add @haroon10725 for code

allcontributors[bot] commented 1 day ago

@davepagurek

I've put up a pull request to add @haroon10725! :tada: