* Performs a spherical linear interpolation between two quat * * @param {quat} out the receiving quaternion * @param {quat} a the first operand * @param {quat} b the second operand * @param {Number} t interpolation amount between the two inputs * @returns {quat} out
(out, a, b, t)
| 19266 | * @returns {quat} out |
| 19267 | */ |
| 19268 | function slerp (out, a, b, t) { |
| 19269 | // benchmarks: |
| 19270 | // http://jsperf.com/quaternion-slerp-implementations |
| 19271 | |
| 19272 | var ax = a[0], ay = a[1], az = a[2], aw = a[3], |
| 19273 | bx = b[0], by = b[1], bz = b[2], bw = b[3] |
| 19274 | |
| 19275 | var omega, cosom, sinom, scale0, scale1 |
| 19276 | |
| 19277 | // calc cosine |
| 19278 | cosom = ax * bx + ay * by + az * bz + aw * bw |
| 19279 | // adjust signs (if necessary) |
| 19280 | if (cosom < 0.0) { |
| 19281 | cosom = -cosom |
| 19282 | bx = -bx |
| 19283 | by = -by |
| 19284 | bz = -bz |
| 19285 | bw = -bw |
| 19286 | } |
| 19287 | // calculate coefficients |
| 19288 | if ((1.0 - cosom) > 0.000001) { |
| 19289 | // standard case (slerp) |
| 19290 | omega = Math.acos(cosom) |
| 19291 | sinom = Math.sin(omega) |
| 19292 | scale0 = Math.sin((1.0 - t) * omega) / sinom |
| 19293 | scale1 = Math.sin(t * omega) / sinom |
| 19294 | } else { |
| 19295 | // "from" and "to" quaternions are very close |
| 19296 | // ... so we can do a linear interpolation |
| 19297 | scale0 = 1.0 - t |
| 19298 | scale1 = t |
| 19299 | } |
| 19300 | // calculate final values |
| 19301 | out[0] = scale0 * ax + scale1 * bx |
| 19302 | out[1] = scale0 * ay + scale1 * by |
| 19303 | out[2] = scale0 * az + scale1 * bz |
| 19304 | out[3] = scale0 * aw + scale1 * bw |
| 19305 | |
| 19306 | return out |
| 19307 | } |
| 19308 | |
| 19309 | |
| 19310 | /***/ }), |
no outgoing calls
no test coverage detected
searching dependent graphs…