|
@@ -3005,4 +3005,93 @@
|
|
|
return new Path2(x, y);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ export class Path3D {
|
|
|
+ private _curve: Vector3[] = [];
|
|
|
+ private _distances: number[] = [];
|
|
|
+ private _tangents: Vector3[] = [];
|
|
|
+ private _normals: Vector3[] = [];
|
|
|
+ private _binormals: Vector3[] = [];
|
|
|
+
|
|
|
+ constructor(public path: Vector3[]) {
|
|
|
+ this._curve = path.slice(); // copy array
|
|
|
+ var l: number = this._curve.length;
|
|
|
+ // first and last tangents
|
|
|
+ this._tangents[0] = this._curve[1].subtract(this._curve[0]);
|
|
|
+ this._tangents[0].normalize();
|
|
|
+ this._tangents[l-1] = this._curve[l-1].subtract(this._curve[l-2]);
|
|
|
+ this._tangents[l-1].normalize();
|
|
|
+ // normals and binormals at first point : arbitrary vector with _normalVector()
|
|
|
+ var tg0: Vector3 = this._tangents[0];
|
|
|
+ var pp0: Vector3 = this._normalVector(this._curve[0], tg0);
|
|
|
+ this._normals[0] = pp0;
|
|
|
+ this._normals[0].normalize();
|
|
|
+ this._binormals[0] = BABYLON.Vector3.Cross(tg0, this._normals[0]);
|
|
|
+ this._normals[0].normalize();
|
|
|
+ this._distances[0] = 0;
|
|
|
+ // normals and binormals : next points
|
|
|
+ var prev: Vector3; // previous vector (segment)
|
|
|
+ var cur: Vector3; // current vector (segment)
|
|
|
+ var curTang: Vector3; // current tangent
|
|
|
+ var prevNorm: Vector3; // previous normal
|
|
|
+ var prevBinor: Vector3; // previous binormal
|
|
|
+ for(var i: number = 1; i < l; i++) {
|
|
|
+ // tangents
|
|
|
+ prev = this._curve[i].subtract(this._curve[i-1]);
|
|
|
+ if (i < l-1) {
|
|
|
+ cur = this._curve[i+1].subtract(this._curve[i]);
|
|
|
+ this._tangents[i] = prev.add(cur);
|
|
|
+ this._tangents[i].normalize();
|
|
|
+ }
|
|
|
+ this._distances[i] = this._distances[i-1] + prev.length();
|
|
|
+ // normals and binormals
|
|
|
+ // http://www.cs.cmu.edu/afs/andrew/scs/cs/15-462/web/old/asst2camera.html
|
|
|
+ curTang = this._tangents[i];
|
|
|
+ prevNorm = this._normals[i-1];
|
|
|
+ prevBinor = this._binormals[i-1];
|
|
|
+ this._normals[i] = BABYLON.Vector3.Cross(prevBinor, curTang);
|
|
|
+ this._normals[i].normalize();
|
|
|
+ this._binormals[i] = BABYLON.Vector3.Cross(curTang, this._normals[i]);
|
|
|
+ this._binormals[i].normalize();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public getCurve(): Vector3[] {
|
|
|
+ return this._curve;
|
|
|
+ }
|
|
|
+
|
|
|
+ public getTangents(): Vector3[] {
|
|
|
+ return this._tangents;
|
|
|
+ }
|
|
|
+
|
|
|
+ public getNormals(): Vector3[] {
|
|
|
+ return this._normals;
|
|
|
+ }
|
|
|
+
|
|
|
+ public getBinormals(): Vector3[] {
|
|
|
+ return this._binormals;
|
|
|
+ }
|
|
|
+
|
|
|
+ public getDistances(): number[] {
|
|
|
+ return this._distances;
|
|
|
+ }
|
|
|
+
|
|
|
+ // private function normalVector(v0, vt) :
|
|
|
+ // returns an arbitrary point in the plane defined by the point v0 and the vector vt orthogonal to this plane
|
|
|
+ private _normalVector(v0: Vector3, vt: Vector3): Vector3 {
|
|
|
+ var point: Vector3;
|
|
|
+ if (vt.x != 1) { // search for a point in the plane
|
|
|
+ point = new BABYLON.Vector3(1, 0, 0);
|
|
|
+ }
|
|
|
+ else if (vt.y != 1) {
|
|
|
+ point = new BABYLON.Vector3(0, 1, 0);
|
|
|
+ }
|
|
|
+ else if (vt.z != 1) {
|
|
|
+ point = new BABYLON.Vector3(0, 0, 1);
|
|
|
+ }
|
|
|
+ var normal0: Vector3 = BABYLON.Vector3.Cross(vt, point);
|
|
|
+ normal0.normalize();
|
|
|
+ return normal0;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|