- /**
- A **QuadraticBezierCurve** is a {{#crossLink "Curve"}}{{/crossLink}} along which a 3D position can be animated.
-
- ## Overview
-
- <ul>
- <li>As shown in the diagram below, a QuadraticBezierCurve is defined by three control points.</li>
- <li>You can sample a {{#crossLink "QuadraticBezierCurve/point:property"}}{{/crossLink}} and a {{#crossLink "Curve/tangent:property"}}{{/crossLink}}
- vector on a QuadraticBezierCurve for any given value of {{#crossLink "QuadraticBezierCurve/t:property"}}{{/crossLink}} in the range [0..1].</li>
- <li>When you set {{#crossLink "QuadraticBezierCurve/t:property"}}{{/crossLink}} on a QuadraticBezierCurve, its
- {{#crossLink "QuadraticBezierCurve/point:property"}}{{/crossLink}} and {{#crossLink "Curve/tangent:property"}}{{/crossLink}} properties
- will update accordingly.</li>
- <li>To build a complex path, you can combine an unlimited combination of QuadraticBezierCurves,
- {{#crossLink "CubicBezierCurve"}}CubicBezierCurves{{/crossLink}} and {{#crossLink "SplineCurve"}}SplineCurves{{/crossLink}}
- into a {{#crossLink "Path"}}{{/crossLink}}.</li>
- </ul>
-
- <img style="border:1px solid;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/3/3d/B%C3%A9zier_2_big.gif/240px-B%C3%A9zier_2_big.gif"/><br>
- *[Quadratic Bezier Curve from WikiPedia](https://en.wikipedia.org/wiki/B%C3%A9zier_curve)*
-
- ## Examples
-
- <ul>
- <li>[Tweening position along a QuadraticBezierCurve](../../examples/#animation_curves_quadraticBezier)</li>
- <li>[Tweening color along a QuadraticBezierCurve](../../examples/#animation_curves_quadraticBezier_color)</li>
- <li>[Path example](../../examples/#curves_Path)</li>
- </ul>
-
- ## Usage
-
- #### Animation along a QuadraticBezierCurve
-
- Let's create a QuadraticBezierCurve, subscribe to updates on its {{#crossLink "QuadraticBezierCurve/point:property"}}{{/crossLink}},
- {{#crossLink "Curve/tangent:property"}}{{/crossLink}} and {{#crossLink "Curve/t:property"}}{{/crossLink}} properties,
- then vary its {{#crossLink "QuadraticBezierCurve/t:property"}}{{/crossLink}}
- property over time:
-
- ````javascript
- var curve = new xeogl.QuadraticBezierCurve({
- v0: [10, 0, 0],
- v1: [20, 15, 0],
- v2: [10, 0, 0]
- });
-
- curve.on("point", function(point) {
- this.log("curve.point=" + JSON.stringify(point));
- });
-
- curve.on("tangent", function(tangent) {
- this.log("curve.tangent=" + JSON.stringify(tangent));
- });
-
- curve.on("t", function(t) {
- this.log("curve.t=" + t);
- });
-
- curve.scene.on("tick", function(e) {
- curve.t = (e.time - e.startTime) * 0.01;
- });
- ````
-
- #### Randomly sampling points
-
- Use QuadraticBezierCurve's {{#crossLink "QuadraticBezierCurve/getPoint:method"}}{{/crossLink}} and
- {{#crossLink "Curve/getTangent:method"}}{{/crossLink}} methods to sample the point and vector
- at a given **t**:
-
- ````javascript
- curve.scene.on("tick", function(e) {
-
- var t = (e.time - e.startTime) * 0.01;
-
- var point = curve.getPoint(t);
- var tangent = curve.getTangent(t);
-
- this.log("t=" + t + ", point=" + JSON.stringify(point) + ", tangent=" + JSON.stringify(tangent));
- });
- ````
-
- #### Sampling multiple points
-
- Use QuadraticBezierCurve's {{#crossLink "Curve/getPoints:method"}}{{/crossLink}} method to sample a list of equidistant points
- along it. In the snippet below, we'll build a {{#crossLink "Geometry"}}{{/crossLink}} that renders a line along the
- curve. Note that we need to flatten the points array for consumption by the {{#crossLink "Geometry"}}{{/crossLink}}.
-
- ````javascript
- var geometry = new xeogl.Geometry({
- positions: xeogl.math.flatten(curve.getPoints(50))
- });
- ````
-
- @class QuadraticBezierCurve
- @module xeogl
- @submodule curves
- @constructor
- @param [scene] {Scene} Parent {{#crossLink "Scene"}}Scene{{/crossLink}}.
- @param [cfg] {*} Configuration
- @param [cfg.id] {String} Optional ID, unique among all components in the parent {{#crossLink "Scene"}}Scene{{/crossLink}}, generated automatically when omitted.
- @param [cfg.meta] {String:Object} Optional map of user-defined metadata to attach to this QuadraticBezierCurve.
- @param [cfg.v0=[0,0,0]] The starting point.
- @param [cfg.v1=[0,0,0]] The middle control point.
- @param [cfg.v2=[0,0,0]] The end point.
- @param [cfg.t=0] Current position on this QuadraticBezierCurve, in range between 0..1.
- @extends Curve
- */
- xeogl.QuadraticBezierCurve = class xeoglQuadraticBezierCurve extends xeogl.Curve {
-
- init(cfg) {
- super.init(cfg);
- this.v0 = cfg.v0;
- this.v1 = cfg.v1;
- this.v2 = cfg.v2;
- this.t = cfg.t;
- }
-
- /**
- Starting point on this QuadraticBezierCurve.
-
- Fires a {{#crossLink "QuadraticBezierCurve/v0:event"}}{{/crossLink}} event on change.
-
- @property v0
- @default [0.0, 0.0, 0.0]
- @type Float32Array
- */
- set v0(value) {
-
- /**
- * Fired whenever this QuadraticBezierCurve's
- * {{#crossLink "QuadraticBezierCurve/v0:property"}}{{/crossLink}} property changes.
- * @event v0
- * @param value The property's new value
- */
- this.fire("v0", this._v0 = value || xeogl.math.vec3([0, 0, 0]));
- }
-
- get v0() {
- return this._v0;
- }
-
- /**
- Middle control point on this QuadraticBezierCurve.
-
- Fires a {{#crossLink "QuadraticBezierCurve/v1:event"}}{{/crossLink}} event on change.
-
- @property v1
- @default [0.0, 0.0, 0.0]
- @type Float32Array
- */
- set v1(value) {
-
- /**
- * Fired whenever this QuadraticBezierCurve's
- * {{#crossLink "QuadraticBezierCurve/v1:property"}}{{/crossLink}} property changes.
- * @event v1
- * @param value The property's new value
- */
- this.fire("v1", this._v1 = value || xeogl.math.vec3([0, 0, 0]));
- }
-
- get v1() {
- return this._v1;
- }
-
- /**
- End point on this QuadraticBezierCurve.
-
- Fires a {{#crossLink "QuadraticBezierCurve/v2:event"}}{{/crossLink}} event on change.
-
- @property v2
- @default [0.0, 0.0, 0.0]
- @type Float32Array
- */
- set v2(value) {
- /**
- * Fired whenever this QuadraticBezierCurve's
- * {{#crossLink "QuadraticBezierCurve/v2:property"}}{{/crossLink}} property changes.
- * @event v2
- * @param value The property's new value
- */
- this.fire("v2", this._v2 = value || xeogl.math.vec3([0, 0, 0]));
- }
-
- get v2() {
- return this._v2;
- }
-
- /**
- Progress along this QuadraticBezierCurve.
-
- Automatically clamps to range [0..1].
-
- Fires a {{#crossLink "QuadraticBezierCurve/t:event"}}{{/crossLink}} event on change.
-
- @property t
- @default 0
- @type Number
- */
- set t(value) {
- value = value || 0;
- this._t = value < 0.0 ? 0.0 : (value > 1.0 ? 1.0 : value);
- /**
- * Fired whenever this QuadraticBezierCurve's
- * {{#crossLink "QuadraticBezierCurve/t:property"}}{{/crossLink}} property changes.
- * @event t
- * @param value The property's new value
- */
- this.fire("t", this._t);
- }
-
- get t() {
- return this._t;
- }
-
- /**
- Point on this QuadraticBezierCurve at position {{#crossLink "QuadraticBezierCurve/t:property"}}{{/crossLink}}.
-
- @property point
- @type {{Array of Number}}
- */
- get point() {
- return this.getPoint(this._t);
- }
-
- /**
- * Returns point on this QuadraticBezierCurve at the given position.
- * @method getPoint
- * @param {Number} t Position to get point at.
- * @returns {{Array of Number}}
- */
- getPoint(t) {
- var math = xeogl.math;
- var vector = math.vec3();
- vector[0] = math.b2(t, this._v0[0], this._v1[0], this._v2[0]);
- vector[1] = math.b2(t, this._v0[1], this._v1[1], this._v2[1]);
- vector[2] = math.b2(t, this._v0[2], this._v1[2], this._v2[2]);
- return vector;
- }
-
- getJSON() {
- return {
- v0: this._v0,
- v1: this._v1,
- v2: this._v2,
- t: this._t
- };
- }
- };
-
-