jax 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +36 -0
- data/Rakefile +34 -0
- data/lib/jax/generators/app/templates/public/javascripts/jax.js +900 -164
- data/lib/jax/version.rb +2 -2
- metadata +4 -4
@@ -1,7 +1,7 @@
|
|
1
1
|
var Jax = {
|
2
2
|
PRODUCTION: 1,
|
3
3
|
|
4
|
-
VERSION: "1.1.
|
4
|
+
VERSION: "1.1.1.rc1",
|
5
5
|
|
6
6
|
webgl_not_supported_path: "/webgl_not_supported.html",
|
7
7
|
|
@@ -44,7 +44,6 @@ if (typeof(document) == "undefined") {
|
|
44
44
|
Jax.getGlobal().document = require("helpers/node_dom_emulator");
|
45
45
|
}
|
46
46
|
|
47
|
-
|
48
47
|
Jax.Compatibility = (function() {
|
49
48
|
var offsetTop = 1;
|
50
49
|
var offsetLeft = 1;
|
@@ -2070,6 +2069,62 @@ mat3.multiplyVec3 = function(matrix, vec, dest) {
|
|
2070
2069
|
};
|
2071
2070
|
mat4.IDENTITY = mat4.identity(mat4.create());
|
2072
2071
|
|
2072
|
+
quat4.fromAxes = function(view, right, up, dest) {
|
2073
|
+
var mat = quat4.fromAxes.mat = quat4.fromAxes.mat || mat3.create();
|
2074
|
+
|
2075
|
+
mat[0] = right[0];
|
2076
|
+
mat[3] = right[1];
|
2077
|
+
mat[6] = right[2];
|
2078
|
+
|
2079
|
+
mat[1] = up[0];
|
2080
|
+
mat[4] = up[1];
|
2081
|
+
mat[7] = up[2];
|
2082
|
+
|
2083
|
+
mat[2] = view[0];
|
2084
|
+
mat[5] = view[1];
|
2085
|
+
mat[8] = view[2];
|
2086
|
+
|
2087
|
+
quat4.fromRotationMatrix(mat, dest);
|
2088
|
+
};
|
2089
|
+
|
2090
|
+
quat4.fromRotationMatrix = function(mat, dest) {
|
2091
|
+
if (!dest) dest = quat4.create();
|
2092
|
+
|
2093
|
+
|
2094
|
+
var fTrace = mat[0] + mat[4] + mat[8];
|
2095
|
+
var fRoot;
|
2096
|
+
|
2097
|
+
if ( fTrace > 0.0 )
|
2098
|
+
{
|
2099
|
+
fRoot = Math.sqrt(fTrace + 1.0); // 2w
|
2100
|
+
dest[3] = 0.5 * fRoot;
|
2101
|
+
fRoot = 0.5/fRoot; // 1/(4w)
|
2102
|
+
dest[0] = (mat[7]-mat[5])*fRoot;
|
2103
|
+
dest[1] = (mat[2]-mat[6])*fRoot;
|
2104
|
+
dest[2] = (mat[3]-mat[1])*fRoot;
|
2105
|
+
}
|
2106
|
+
else
|
2107
|
+
{
|
2108
|
+
var s_iNext = quat4.fromRotationMatrix.s_iNext = quat4.fromRotationMatrix.s_iNext || [1,2,0];
|
2109
|
+
var i = 0;
|
2110
|
+
if ( mat[4] > mat[0] )
|
2111
|
+
i = 1;
|
2112
|
+
if ( mat[8] > mat[i*3+i] )
|
2113
|
+
i = 2;
|
2114
|
+
var j = s_iNext[i];
|
2115
|
+
var k = s_iNext[j];
|
2116
|
+
|
2117
|
+
fRoot = Math.sqrt(mat[i*3+i]-mat[j*3+j]-mat[k*3+k] + 1.0);
|
2118
|
+
dest[i] = 0.5 * fRoot;
|
2119
|
+
fRoot = 0.5 / fRoot;
|
2120
|
+
dest[3] = (mat[k*3+j] - mat[j*3+k]) * fRoot;
|
2121
|
+
dest[j] = (mat[j*3+i] + mat[i*3+j]) * fRoot;
|
2122
|
+
dest[k] = (mat[k*3+i] + mat[i*3+k]) * fRoot;
|
2123
|
+
}
|
2124
|
+
|
2125
|
+
return dest;
|
2126
|
+
};
|
2127
|
+
|
2073
2128
|
quat4.toAngleAxis = function(src, dest) {
|
2074
2129
|
if (!dest) dest = src;
|
2075
2130
|
|
@@ -3449,7 +3504,7 @@ Jax.Shader = (function() {
|
|
3449
3504
|
|
3450
3505
|
getRawSource: function(options, which) {
|
3451
3506
|
var source = this.options[which];
|
3452
|
-
options = Jax.Util.normalizeOptions(options, {shader_type:which});
|
3507
|
+
options = Jax.Util.normalizeOptions(options, {shader:this,shader_type:which});
|
3453
3508
|
if (source && (source = source.render(options))) {
|
3454
3509
|
var result = this.getPreamble(options);
|
3455
3510
|
if (!options || !options.skip_export_definitions)
|
@@ -3710,7 +3765,12 @@ Jax.Shader.Manifest = Jax.Class.create({
|
|
3710
3765
|
texture: function(name, tex, context) {
|
3711
3766
|
if (!context) throw new Error("Can't bind texture without a context");
|
3712
3767
|
if (this.texture_tracker == GL_MAX_ACTIVE_TEXTURES-1) {
|
3713
|
-
|
3768
|
+
/* FIXME add a callback for Materials to enter compatibility mode and recompile their shaders
|
3769
|
+
before throwing a hard error. Until this is implemented, the hard error itself is disabled
|
3770
|
+
because it causes unnecessary barfing on machines that are otherwise capable of running the
|
3771
|
+
scene. Using too many textures doesn't seem to have any catastrophic results on tested
|
3772
|
+
hardware, except some visual anomolies, so there's no reason to crash out catastrophically.
|
3773
|
+
*/
|
3714
3774
|
}
|
3715
3775
|
|
3716
3776
|
if (typeof(this.getValue(name)) != "number")
|
@@ -3880,6 +3940,7 @@ Jax.ShaderChain = (function() {
|
|
3880
3940
|
|
3881
3941
|
function preprocessorOptions(self) {
|
3882
3942
|
return {
|
3943
|
+
shader: self,
|
3883
3944
|
ignore_es_precision: true,
|
3884
3945
|
export_prefix: self.getName(),
|
3885
3946
|
exports: self.gatherExports(),
|
@@ -5350,7 +5411,7 @@ function calculateNormals(mesh) {
|
|
5350
5411
|
for (var i in options)
|
5351
5412
|
this[i] = options[i];
|
5352
5413
|
|
5353
|
-
if (
|
5414
|
+
if (this.draw_mode == undefined)
|
5354
5415
|
this.draw_mode = GL_TRIANGLES;
|
5355
5416
|
},
|
5356
5417
|
|
@@ -5398,7 +5459,7 @@ function calculateNormals(mesh) {
|
|
5398
5459
|
var result = Jax.Util.normalizeOptions(options, {
|
5399
5460
|
material: this.material,
|
5400
5461
|
default_material: this.default_material,
|
5401
|
-
draw_mode: this.draw_mode
|
5462
|
+
draw_mode: this.draw_mode == undefined ? GL_TRIANGLES : this.draw_mode
|
5402
5463
|
});
|
5403
5464
|
|
5404
5465
|
if (!result.material) result.material = result.default_material;
|
@@ -5560,15 +5621,260 @@ Jax.Scene.ILLUMINATION_PASS = 1;
|
|
5560
5621
|
Jax.Scene.AMBIENT_PASS = 2;
|
5561
5622
|
Jax.Scene.SHADOWMAP_PASS = 3;
|
5562
5623
|
|
5563
|
-
Jax.Geometry = {
|
5624
|
+
Jax.Geometry = {
|
5625
|
+
DISJOINT: 0,
|
5626
|
+
COINCIDE: 1,
|
5627
|
+
INTERSECT: 2,
|
5628
|
+
};
|
5629
|
+
|
5630
|
+
Jax.Geometry.Line = (function() {
|
5631
|
+
var Line = Jax.Class.create({
|
5632
|
+
initialize: function(a, b) {
|
5633
|
+
|
5634
|
+
this.a = vec3.create();
|
5635
|
+
|
5636
|
+
this.b = vec3.create();
|
5637
|
+
|
5638
|
+
this.normal = vec3.create();
|
5639
|
+
|
5640
|
+
this.length = 0;
|
5641
|
+
|
5642
|
+
if (arguments.length) this.set(a, b);
|
5643
|
+
},
|
5644
|
+
|
5645
|
+
set: function(a, b) {
|
5646
|
+
vec3.set(a, this.a);
|
5647
|
+
vec3.set(b, this.b);
|
5648
|
+
|
5649
|
+
vec3.subtract(b, a, this.normal);
|
5650
|
+
this.length = vec3.length(this.normal);
|
5651
|
+
vec3.normalize(this.normal);
|
5652
|
+
|
5653
|
+
return this;
|
5654
|
+
},
|
5655
|
+
|
5656
|
+
intersectLineSegment: function(line, dest) {
|
5657
|
+
var u = vec3.subtract(this.b, this.a, vec3.create());
|
5658
|
+
var v = vec3.subtract(line.b, line.a, vec3.create());
|
5659
|
+
var w = vec3.subtract(this.a, line.a, vec3.create());
|
5660
|
+
var D = (u[0] * v[1] - u[1] * v[0]);
|
5661
|
+
if (Math.abs(D) < Math.EPSILON) { // S1 and S2 are parallel
|
5662
|
+
if ((u[0] * w[1] - u[1] * w[0]) != 0 || (v[0] * w[1] - v[1] * w[0]) != 0) {
|
5663
|
+
return Jax.Geometry.DISJOINT; // they are NOT colinear
|
5664
|
+
}
|
5665
|
+
var du = vec3.dot(u, u);
|
5666
|
+
var dv = vec3.dot(v, v);
|
5667
|
+
if (du == 0 && dv == 0) { // both segments are points
|
5668
|
+
if (!Math.equalish(this.a, line.a)) // they are distinct points
|
5669
|
+
return Jax.Geometry.DISJOINT;
|
5670
|
+
if (dest) vec3.set(line.a, dest.a);
|
5671
|
+
return Jax.Geometry.INTERSECT;
|
5672
|
+
}
|
5673
|
+
if (du == 0) { // +this+ is a single point
|
5674
|
+
if (!line.contains(this.a)) // but is not in S2
|
5675
|
+
return Jax.Geometry.DISJOINT;
|
5676
|
+
if (dest) vec3.set(this.a, dest.a);
|
5677
|
+
return Jax.Geometry.INTERSECT;
|
5678
|
+
}
|
5679
|
+
if (dv == 0) { // +line+ is a single point
|
5680
|
+
if (!this.contains(line.a)) // but is not in this line
|
5681
|
+
return Jax.Geometry.DISJOINT;
|
5682
|
+
if (dest) vec3.set(line.a, dest.a);
|
5683
|
+
return Jax.Geometry.INTERSECT;
|
5684
|
+
}
|
5685
|
+
var t0, t1; // endpoints of +this+ in eqn for +line+
|
5686
|
+
var w2 = vec3.subtract(this.a, line.a, vec3.create());
|
5687
|
+
if (v[0] != 0) {
|
5688
|
+
t0 = w[0] / v[0];
|
5689
|
+
t1 = w2[0] / v[0];
|
5690
|
+
} else {
|
5691
|
+
t0 = w[1] / v[1];
|
5692
|
+
t1 = w2[1] / v[1];
|
5693
|
+
}
|
5694
|
+
if (t0 > t1) { // must have t0 smaller than t1
|
5695
|
+
var t = t0; t0 = t1; t1 = t;
|
5696
|
+
}
|
5697
|
+
if (t0 > 1 || t1 < 0) // NO overlap
|
5698
|
+
return Jax.Geometry.DISJOINT;
|
5699
|
+
t0 = t0 < 0 ? 0 : t0; // clamp to min 0
|
5700
|
+
t1 = t1 > 1 ? 1 : t1; // clamp to max 1
|
5701
|
+
if (t0 == t1) {
|
5702
|
+
if (line) {
|
5703
|
+
vec3.add(line.a, vec3.scale(v, t0, dest.a), dest.a);
|
5704
|
+
return Jax.Geometry.INTERSECT;
|
5705
|
+
}
|
5706
|
+
}
|
5707
|
+
|
5708
|
+
if (dest) {
|
5709
|
+
vec3.add(line.a, vec3.scale(v, t0, dest.a), dest);
|
5710
|
+
vec3.add(line.b, vec3.scale(v, t1, dest.b), dest);
|
5711
|
+
}
|
5712
|
+
return Jax.Geometry.COINCIDENT;
|
5713
|
+
}
|
5714
|
+
|
5715
|
+
var sI = (v[0] * w[1] - v[1] * w[0]) / D;
|
5716
|
+
if (sI < 0 || sI > 1) // no intersect with +this+
|
5717
|
+
return Jax.Geometry.DISJOINT;
|
5718
|
+
var tI = (u[0] * w[1] - u[1] * w[0]) / D;
|
5719
|
+
if (tI < 0 || tI > 1) // no intersect with +line+
|
5720
|
+
return Jax.Geometry.DISJOINT;
|
5721
|
+
|
5722
|
+
if (dest) vec3.add(this.a, vec3.scale(u, sI, dest), dest);
|
5723
|
+
return Jax.Geometry.INTERSECT;
|
5724
|
+
},
|
5725
|
+
|
5726
|
+
toString: function() {
|
5727
|
+
return "[Line a:"+this.a+", b:"+this.b+"]";
|
5728
|
+
}
|
5729
|
+
});
|
5730
|
+
|
5731
|
+
Object.defineProperty(Line.prototype, 0, {
|
5732
|
+
get: function() { return this.a; },
|
5733
|
+
set: function(v) { return this.a = v; },
|
5734
|
+
enumerable: false,
|
5735
|
+
configurable: false
|
5736
|
+
});
|
5737
|
+
|
5738
|
+
Object.defineProperty(Line.prototype, 1, {
|
5739
|
+
get: function() { return this.b; },
|
5740
|
+
set: function(v) { return this.b = v; },
|
5741
|
+
enumerable: false,
|
5742
|
+
configurable: false
|
5743
|
+
});
|
5564
5744
|
|
5745
|
+
return Line;
|
5746
|
+
})();
|
5565
5747
|
Jax.Geometry.Plane = (function() {
|
5748
|
+
var bufs = {};
|
5749
|
+
|
5566
5750
|
function innerProduct(a, x, y, z) {
|
5567
5751
|
return (a[0]*x + a[1]*y + a[2]*z);
|
5568
5752
|
}
|
5569
5753
|
|
5570
|
-
|
5754
|
+
var Plane = Jax.Class.create({
|
5755
|
+
toString: function() {
|
5756
|
+
return "[Plane normal:"+this.normal+"; D:"+this.d+"]";
|
5757
|
+
},
|
5758
|
+
|
5759
|
+
intersectTriangle: function(t, line) {
|
5760
|
+
var ad = this.classify(t.a), bd = this.classify(t.b), cd = this.classify(t.c);
|
5761
|
+
var sideAB = ad * bd, sideBC = bd * cd;
|
5762
|
+
if (sideAB > 0.0 && sideBC > 0.0) return false; // all points on same side of plane
|
5763
|
+
|
5764
|
+
if (!line) return true;
|
5765
|
+
|
5766
|
+
var otherSide, sameSide1, sameSide2;
|
5767
|
+
if (sideAB > 0) {
|
5768
|
+
sameSide1 = t.a;
|
5769
|
+
sameSide2 = t.b;
|
5770
|
+
otherSide = t.c;
|
5771
|
+
} else {
|
5772
|
+
if (sideBC > 0) {
|
5773
|
+
otherSide = t.a;
|
5774
|
+
sameSide1 = t.b;
|
5775
|
+
sameSide2 = t.c;
|
5776
|
+
} else {
|
5777
|
+
sameSide1 = t.a;
|
5778
|
+
otherSide = t.b;
|
5779
|
+
sameSide2 = t.c;
|
5780
|
+
}
|
5781
|
+
}
|
5782
|
+
|
5783
|
+
var seg1 = bufs.tri_seg1 = bufs.tri_seg1 || new Jax.Geometry.Line();
|
5784
|
+
var seg2 = bufs.tri_seg2 = bufs.tri_seg2 || new Jax.Geometry.Line();
|
5785
|
+
seg1.set(otherSide, sameSide1);
|
5786
|
+
seg2.set(otherSide, sameSide2);
|
5787
|
+
|
5788
|
+
var p1 = bufs.tri_p1 = bufs.tri_p1 || vec3.create(),
|
5789
|
+
p2 = bufs.tri_p2 = bufs.tri_p2 || vec3.create();
|
5790
|
+
this.intersectLineSegment(seg1, p1);
|
5791
|
+
this.intersectLineSegment(seg2, p2);
|
5792
|
+
return line.set(p1, p2);
|
5793
|
+
},
|
5794
|
+
|
5795
|
+
intersectLineSegment: function(line, point) {
|
5796
|
+
var u = vec3.subtract(line.b, line.a, (bufs.lineseg_u = bufs.lineseg_u || vec3.create()));
|
5797
|
+
var w = vec3.subtract(line.a, this.point, (bufs.lineseg_w = bufs.lineseg_w || vec3.create()));
|
5798
|
+
var D = vec3.dot(this.normal, u);
|
5799
|
+
var N = -vec3.dot(this.normal, w);
|
5800
|
+
|
5801
|
+
if (Math.abs(D) < Math.EPSILON) // segment is parallel to plane
|
5802
|
+
if (N == 0) return Jax.Geometry.COINCIDE; // segment lies in plane
|
5803
|
+
else return Jax.Geometry.DISJOINT;
|
5804
|
+
|
5805
|
+
var sI = N / D;
|
5806
|
+
if (sI < 0 || sI > 1)
|
5807
|
+
return Jax.Geometry.DISJOINT;
|
5808
|
+
|
5809
|
+
if (point)
|
5810
|
+
vec3.add(line.a, vec3.scale(u, sI, point), point);
|
5811
|
+
|
5812
|
+
return Jax.Geometry.INTERSECT;
|
5813
|
+
},
|
5814
|
+
|
5815
|
+
intersectRay: function(origin, direction) {
|
5816
|
+
var numer = vec3.dot(this.normal, origin) + this.d;
|
5817
|
+
var denom = vec3.dot(this.normal, direction);
|
5818
|
+
|
5819
|
+
if (denom == 0) // normal is orthogonal to vector, can't intersect
|
5820
|
+
return false;
|
5821
|
+
|
5822
|
+
var result = -(numer / denom);
|
5823
|
+
return -(numer / denom);
|
5824
|
+
},
|
5825
|
+
|
5826
|
+
intersectPlane: function(p, line) {
|
5827
|
+
var d1 = this.d, d2 = p.d;
|
5828
|
+
var p1n = this.normal, p2n = p.normal;
|
5829
|
+
var u = bufs.u = bufs.u || vec3.create();
|
5830
|
+
vec3.cross(p1n, p2n, u);
|
5831
|
+
var ax = (u[0] >= 0 ? u[0] : -u[0]);
|
5832
|
+
var ay = (u[1] >= 0 ? u[1] : -u[1]);
|
5833
|
+
var az = (u[2] >= 0 ? u[2] : -u[2]);
|
5834
|
+
|
5835
|
+
if ((ax+ay+az) < Math.EPSILON) { // planes are near parallel
|
5836
|
+
if (Math.equalish(d1, d2)) return Jax.Geometry.COINCIDE;
|
5837
|
+
else return Jax.Geometry.DISJOINT;
|
5838
|
+
}
|
5839
|
+
|
5840
|
+
if (line) {
|
5841
|
+
var maxc;
|
5842
|
+
if (ax > ay)
|
5843
|
+
if (ax > az) maxc = 0;
|
5844
|
+
else maxc = 2;
|
5845
|
+
else
|
5846
|
+
if (ay > az) maxc = 1;
|
5847
|
+
else maxc = 2;
|
5848
|
+
|
5849
|
+
var iP = bufs.iP = bufs.iP || vec3.create(); // intersection point
|
5850
|
+
switch(maxc) {
|
5851
|
+
case 0: // intersect with x = 0
|
5852
|
+
iP[0] = 0;
|
5853
|
+
iP[1] = (d2 * p1n[2] - d1 * p2n[2]) / u[0];
|
5854
|
+
iP[2] = (d1 * p2n[1] - d2 * p1n[1]) / u[0];
|
5855
|
+
break;
|
5856
|
+
case 1: // intersect with y = 0
|
5857
|
+
iP[0] = (d1 * p2n[2] - d2 * p1n[2]) / u[1];
|
5858
|
+
iP[1] = 0;
|
5859
|
+
iP[2] = (d2 * p1n[0] - d1 * p2n[0]) / u[1];
|
5860
|
+
break;
|
5861
|
+
case 2: // intersect with z = 0
|
5862
|
+
iP[0] = (d2 * p1n[1] - d1 * p2n[1]) / u[2];
|
5863
|
+
iP[1] = (d1 * p2n[0] - d2 * p1n[0]) / u[2];
|
5864
|
+
iP[2] = 0;
|
5865
|
+
break;
|
5866
|
+
}
|
5867
|
+
|
5868
|
+
vec3.set(iP, line[0]);
|
5869
|
+
vec3.add(iP, u, line[1]);
|
5870
|
+
}
|
5871
|
+
|
5872
|
+
return Jax.Geometry.INTERSECT;
|
5873
|
+
},
|
5874
|
+
|
5571
5875
|
initialize: function(points) {
|
5876
|
+
this.point = vec3.create();
|
5877
|
+
|
5572
5878
|
this.normal = vec3.create([0,1,0]);
|
5573
5879
|
|
5574
5880
|
this.d = 0.0;
|
@@ -5578,32 +5884,33 @@ Jax.Geometry.Plane = (function() {
|
|
5578
5884
|
},
|
5579
5885
|
|
5580
5886
|
classify: function(O) {
|
5581
|
-
return vec3.dot(this.normal, O) + this.d;
|
5887
|
+
if (O.array) return vec3.dot(this.normal, O.array) + this.d;
|
5888
|
+
else return vec3.dot(this.normal, O) + this.d;
|
5582
5889
|
},
|
5583
5890
|
|
5584
5891
|
set: function() {
|
5585
|
-
|
5586
|
-
|
5587
|
-
|
5588
|
-
var vec = vec3.create();
|
5589
|
-
vec3.subtract(points[1].array, points[0].array, this.normal);
|
5590
|
-
vec3.subtract(points[2].array, points[0].array, vec);
|
5591
|
-
vec3.cross(this.normal, vec, this.normal);
|
5592
|
-
vec3.normalize(this.normal);
|
5593
|
-
|
5594
|
-
this.point = points[1].array;
|
5595
|
-
this.d = -innerProduct(this.normal, this.point[0], this.point[1], this.point[2]);
|
5892
|
+
if (arguments.length == 2) {
|
5893
|
+
vec3.set(arguments[1], this.normal);
|
5894
|
+
this.d = -vec3.dot(arguments[1], arguments[0]);
|
5596
5895
|
} else {
|
5597
|
-
var
|
5598
|
-
|
5599
|
-
|
5600
|
-
|
5601
|
-
|
5602
|
-
|
5603
|
-
|
5604
|
-
|
5896
|
+
var tmp1 = this.normal, tmp2 = vec3.create();
|
5897
|
+
var points = arguments;
|
5898
|
+
|
5899
|
+
if (arguments.length != 3) points = arguments[0];
|
5900
|
+
if (typeof(points[0]) == 'object' && points[0].array) {
|
5901
|
+
vec3.subtract(points[1].array, points[0].array, tmp1);
|
5902
|
+
vec3.subtract(points[2].array, points[0].array, tmp2);
|
5903
|
+
vec3.normalize(vec3.cross(tmp1, tmp2, this.normal));
|
5904
|
+
this.d = -vec3.dot(this.normal, points[0].array);
|
5905
|
+
} else {
|
5906
|
+
vec3.subtract(points[1], points[0], tmp1);
|
5907
|
+
vec3.subtract(points[2], points[0], tmp2);
|
5908
|
+
vec3.normalize(vec3.cross(tmp1, tmp2, this.normal));
|
5909
|
+
this.d = -vec3.dot(this.normal, points[0]);
|
5910
|
+
}
|
5605
5911
|
}
|
5606
5912
|
|
5913
|
+
vec3.scale(this.normal, this.d, this.point);
|
5607
5914
|
return this;
|
5608
5915
|
},
|
5609
5916
|
|
@@ -5616,14 +5923,6 @@ Jax.Geometry.Plane = (function() {
|
|
5616
5923
|
return this;
|
5617
5924
|
},
|
5618
5925
|
|
5619
|
-
distance: function(point)
|
5620
|
-
{
|
5621
|
-
var x, y, z;
|
5622
|
-
if (arguments.length == 3) { x = arguments[0]; y = arguments[1]; z = arguments[2]; }
|
5623
|
-
else if (point.array) { x = point.array[0]; y = point.array[1]; z = point.array[2]; }
|
5624
|
-
else { x = point[0]; y = point[1]; z = point[2]; }
|
5625
|
-
return this.d + innerProduct(this.normal, x, y, z);
|
5626
|
-
},
|
5627
5926
|
|
5628
5927
|
whereis: function()
|
5629
5928
|
{
|
@@ -5638,68 +5937,244 @@ Jax.Geometry.Plane = (function() {
|
|
5638
5937
|
return Jax.Geometry.Plane.INTERSECT;
|
5639
5938
|
}
|
5640
5939
|
});
|
5940
|
+
|
5941
|
+
Plane.prototype.distance = Plane.prototype.classify;
|
5942
|
+
|
5943
|
+
return Plane;
|
5641
5944
|
})();
|
5642
5945
|
|
5643
5946
|
Jax.Geometry.Plane.FRONT = 1;
|
5644
5947
|
Jax.Geometry.Plane.BACK = 2;
|
5645
5948
|
Jax.Geometry.Plane.INTERSECT = 3;
|
5646
5949
|
Jax.Geometry.Triangle = (function() {
|
5647
|
-
|
5648
|
-
|
5950
|
+
/* for capturing point of intersection */
|
5951
|
+
var bufs;
|
5952
|
+
if (typeof(bufs) == 'undefined') // in case it was defined elsewhere
|
5953
|
+
bufs = {};
|
5954
|
+
|
5955
|
+
|
5956
|
+
function slow_tri_tri_intersect(t1, t2, dest)
|
5957
|
+
{
|
5958
|
+
var line1 = bufs.slowtri_line1 = bufs.slowtri_line1 || new Jax.Geometry.Line();
|
5959
|
+
var line2 = bufs.slowtri_line2 = bufs.slowtri_line2 || new Jax.Geometry.Line();
|
5960
|
+
if (t1.plane.intersectTriangle(t2, line1) && t2.plane.intersectTriangle(t1, line2)) {
|
5961
|
+
line1.intersectLineSegment(line2, dest);
|
5962
|
+
return true;
|
5963
|
+
}
|
5964
|
+
else return false;
|
5965
|
+
|
5966
|
+
/*
|
5967
|
+
var p1 = t1.plane;
|
5968
|
+
var f1, f2, f3, f12, f23;
|
5969
|
+
var other_side=0;
|
5970
|
+
|
5649
5971
|
{
|
5650
|
-
|
5651
|
-
|
5652
|
-
|
5972
|
+
f1=p1.classify(t2.a);
|
5973
|
+
f2=p1.classify(t2.b);
|
5974
|
+
f3=p1.classify(t2.c);
|
5975
|
+
f12=f1*f2;
|
5976
|
+
f23=f2*f3;
|
5977
|
+
if (f12>0.0 && f23>0.0)
|
5978
|
+
return false;
|
5979
|
+
other_side=(f12<0.0?(f23<0.0?1:0):2);
|
5653
5980
|
}
|
5654
|
-
}
|
5655
5981
|
|
5656
|
-
|
5657
|
-
|
5658
|
-
|
5659
|
-
|
5982
|
+
var p2 = t2.plane;
|
5983
|
+
var n12 = bufs.slowtritri_n12 = bufs.slowtritri_n12 || vec3.create();
|
5984
|
+
vec3.add(p1.normal, p2.normal, n12);
|
5985
|
+
var a2 = t2[(other_side+1) % 3];
|
5986
|
+
var b2 = t2[other_side];
|
5987
|
+
var c2 = t2[(other_side+2) % 3];
|
5988
|
+
|
5989
|
+
var t21 = -(p1.d + p2.d + vec3.dot(a2, n12)) / vec3.dot(vec3.subtract(b2, a2, dest), n12);
|
5990
|
+
vec3.add(a2, vec3.scale(dest, t21, dest), dest);
|
5991
|
+
if (t1.pointInTri(dest)) return dest;
|
5992
|
+
|
5993
|
+
var t22 = -(p1.d + p2.d + vec3.dot(c2, n12)) / vec3.dot(vec3.subtract(b2, c2, dest), n12);
|
5994
|
+
vec3.add(c2, vec3.scale(dest, t22, dest), dest);
|
5995
|
+
if (t1.pointInTri(dest)) return dest;
|
5660
5996
|
|
5661
|
-
function COMPUTE_INTERVALS(VV0,VV1,VV2,D0,D1,D2,D0D1,D0D2,isect) {
|
5662
|
-
if(D0D1 > 0)
|
5663
5997
|
{
|
5664
|
-
|
5665
|
-
|
5666
|
-
|
5998
|
+
f1=p2.classify(t1.a);
|
5999
|
+
f2=p2.classify(t1.b);
|
6000
|
+
f3=p2.classify(t1.c);
|
6001
|
+
f12=f1*f2;
|
6002
|
+
f23=f2*f3;
|
6003
|
+
if (f12>0.0 && f23>0.0)
|
6004
|
+
return false;
|
6005
|
+
other_side=(f12<0.0?(f23<0.0?1:0):2);
|
5667
6006
|
}
|
5668
|
-
|
6007
|
+
|
6008
|
+
var a1 = t1[(other_side+1)%3];
|
6009
|
+
var b1 = t1[other_side];
|
6010
|
+
var c1 = t1[(other_side+2)%3];
|
6011
|
+
|
6012
|
+
var t11 = -(p1.d + p2.d + vec3.dot(a1, n12)) / vec3.dot(vec3.subtract(b1, a1, dest), n12);
|
6013
|
+
vec3.add(a1, vec3.scale(dest, t11, dest), dest);
|
6014
|
+
if (t2.pointInTri(dest)) return dest;
|
6015
|
+
|
6016
|
+
var t12 = -(p1.d + p2.d + vec3.dot(c1, n12)) / vec3.dot(vec3.subtract(b1, c1, dest), n12);
|
6017
|
+
vec3.add(c1, vec3.scale(dest, t12, dest), dest);
|
6018
|
+
if (t2.pointInTri(dest)) return dest;
|
6019
|
+
|
6020
|
+
return false;
|
6021
|
+
*/
|
6022
|
+
}
|
6023
|
+
|
6024
|
+
/* faster than capturing intersection point when we don't care about it */
|
6025
|
+
var bufs;
|
6026
|
+
if (typeof(bufs) != 'undefined') // in case it was defined elsewhere
|
6027
|
+
bufs = {};
|
6028
|
+
|
6029
|
+
|
6030
|
+
|
6031
|
+
|
6032
|
+
|
6033
|
+
|
6034
|
+
|
6035
|
+
/* sort so that a<=b */
|
6036
|
+
|
6037
|
+
|
6038
|
+
|
6039
|
+
|
6040
|
+
|
6041
|
+
|
6042
|
+
|
6043
|
+
|
6044
|
+
/* this edge to edge test is based on Franlin Antonio's gem:
|
6045
|
+
"Faster Line Segment Intersection", in Graphics Gems III,
|
6046
|
+
pp. 199-202 */
|
6047
|
+
|
6048
|
+
|
6049
|
+
|
6050
|
+
|
6051
|
+
|
6052
|
+
|
6053
|
+
function coplanar_tri_tri(N, V0, V1, V2, U0, U1, U2) {
|
6054
|
+
var A = bufs.tritri_A = bufs.tritri_A || vec3.create();
|
6055
|
+
var i0, i1;
|
6056
|
+
|
6057
|
+
/* first project onto an axis-aligned plane, that maximizes the area */
|
6058
|
+
/* of the triangles, compute indices: i0,i1. */
|
6059
|
+
A[0] = Math.abs(N[0]);
|
6060
|
+
A[1] = Math.abs(N[1]);
|
6061
|
+
A[2] = Math.abs(N[2]);
|
6062
|
+
|
6063
|
+
if(A[0]>A[1])
|
5669
6064
|
{
|
5670
|
-
|
5671
|
-
|
6065
|
+
if(A[0]>A[2])
|
6066
|
+
{
|
6067
|
+
i0=1; /* A[0] is greatest */
|
6068
|
+
i1=2;
|
6069
|
+
}
|
6070
|
+
else
|
6071
|
+
{
|
6072
|
+
i0=0; /* A[2] is greatest */
|
6073
|
+
i1=1;
|
6074
|
+
}
|
5672
6075
|
}
|
5673
|
-
else
|
6076
|
+
else /* A[0]<=A[1] */
|
5674
6077
|
{
|
5675
|
-
|
5676
|
-
|
6078
|
+
if(A[2]>A[1])
|
6079
|
+
{
|
6080
|
+
i0=0; /* A[2] is greatest */
|
6081
|
+
i1=1;
|
6082
|
+
}
|
6083
|
+
else
|
6084
|
+
{
|
6085
|
+
i0=0; /* A[1] is greatest */
|
6086
|
+
i1=2;
|
6087
|
+
}
|
5677
6088
|
}
|
5678
|
-
|
6089
|
+
|
6090
|
+
/* test all edges of triangle 1 against the edges of triangle 2 */
|
6091
|
+
/* (inline function EDGE_AGAINST_TRI_EDGES) */
|
6092
|
+
|
6093
|
+
{
|
6094
|
+
var Ax,Ay,Bx,By,Cx,Cy,e,d,f;
|
6095
|
+
Ax=V1[i0]-V0[i0];
|
6096
|
+
Ay=V1[i1]-V0[i1];
|
6097
|
+
/* test edge U0,U1 against V0,V1 */
|
6098
|
+
/* (inline function EDGE_EDGE_TEST) */
|
6099
|
+
|
6100
|
+
Bx=U0[i0]-U1[i0];
|
6101
|
+
By=U0[i1]-U1[i1];
|
6102
|
+
Cx=V0[i0]-U0[i0];
|
6103
|
+
Cy=V0[i1]-U0[i1];
|
6104
|
+
f=Ay*Bx-Ax*By;
|
6105
|
+
d=By*Cx-Bx*Cy;
|
6106
|
+
if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f))
|
5679
6107
|
{
|
5680
|
-
|
6108
|
+
e=Ax*Cy-Ay*Cx;
|
6109
|
+
if(f>0)
|
6110
|
+
{
|
6111
|
+
if(e>=0 && e<=f) return true;
|
6112
|
+
}
|
6113
|
+
else
|
6114
|
+
{
|
6115
|
+
if(e<=0 && e>=f) return true;
|
6116
|
+
}
|
5681
6117
|
}
|
5682
|
-
|
6118
|
+
|
6119
|
+
/* test edge U1,U2 against V0,V1 */
|
6120
|
+
/* (inline function EDGE_EDGE_TEST) */
|
6121
|
+
|
6122
|
+
Bx=U1[i0]-U2[i0];
|
6123
|
+
By=U1[i1]-U2[i1];
|
6124
|
+
Cx=V0[i0]-U1[i0];
|
6125
|
+
Cy=V0[i1]-U1[i1];
|
6126
|
+
f=Ay*Bx-Ax*By;
|
6127
|
+
d=By*Cx-Bx*Cy;
|
6128
|
+
if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f))
|
5683
6129
|
{
|
5684
|
-
|
6130
|
+
e=Ax*Cy-Ay*Cx;
|
6131
|
+
if(f>0)
|
6132
|
+
{
|
6133
|
+
if(e>=0 && e<=f) return true;
|
6134
|
+
}
|
6135
|
+
else
|
6136
|
+
{
|
6137
|
+
if(e<=0 && e>=f) return true;
|
6138
|
+
}
|
5685
6139
|
}
|
5686
|
-
|
6140
|
+
|
6141
|
+
/* test edge U2,U1 against V0,V1 */
|
6142
|
+
/* (inline function EDGE_EDGE_TEST) */
|
6143
|
+
|
6144
|
+
Bx=U2[i0]-U0[i0];
|
6145
|
+
By=U2[i1]-U0[i1];
|
6146
|
+
Cx=V0[i0]-U2[i0];
|
6147
|
+
Cy=V0[i1]-U2[i1];
|
6148
|
+
f=Ay*Bx-Ax*By;
|
6149
|
+
d=By*Cx-Bx*Cy;
|
6150
|
+
if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f))
|
5687
6151
|
{
|
5688
|
-
|
5689
|
-
|
6152
|
+
e=Ax*Cy-Ay*Cx;
|
6153
|
+
if(f>0)
|
6154
|
+
{
|
6155
|
+
if(e>=0 && e<=f) return true;
|
6156
|
+
}
|
6157
|
+
else
|
6158
|
+
{
|
6159
|
+
if(e<=0 && e>=f) return true;
|
6160
|
+
}
|
5690
6161
|
}
|
5691
|
-
}
|
5692
6162
|
|
5693
|
-
|
5694
|
-
|
5695
|
-
|
5696
|
-
|
5697
|
-
|
6163
|
+
}
|
6164
|
+
|
6165
|
+
/* (inline function EDGE_AGAINST_TRI_EDGES) */
|
6166
|
+
|
6167
|
+
{
|
6168
|
+
var Ax,Ay,Bx,By,Cx,Cy,e,d,f;
|
6169
|
+
Ax=V2[i0]-V1[i0];
|
6170
|
+
Ay=V2[i1]-V1[i1];
|
6171
|
+
/* test edge U0,U1 against V1,V2 */
|
6172
|
+
/* (inline function EDGE_EDGE_TEST) */
|
5698
6173
|
|
5699
6174
|
Bx=U0[i0]-U1[i0];
|
5700
6175
|
By=U0[i1]-U1[i1];
|
5701
|
-
Cx=
|
5702
|
-
Cy=
|
6176
|
+
Cx=V1[i0]-U0[i0];
|
6177
|
+
Cy=V1[i1]-U0[i1];
|
5703
6178
|
f=Ay*Bx-Ax*By;
|
5704
6179
|
d=By*Cx-Bx*Cy;
|
5705
6180
|
if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f))
|
@@ -5714,108 +6189,190 @@ function EDGE_EDGE_TEST(Ax, Ay, V0,U0,U1, i0, i1) {
|
|
5714
6189
|
if(e<=0 && e>=f) return true;
|
5715
6190
|
}
|
5716
6191
|
}
|
5717
|
-
return false;
|
5718
|
-
}
|
5719
6192
|
|
5720
|
-
|
5721
|
-
|
5722
|
-
var Ax,Ay;
|
5723
|
-
Ax=V1[i0]-V0[i0];
|
5724
|
-
Ay=V1[i1]-V0[i1];
|
5725
|
-
|
5726
|
-
/* test edge U0,U1 against V0,V1 */
|
5727
|
-
return EDGE_EDGE_TEST(Ax,Ay, V0,U0,U1, i0,i1) ||
|
5728
|
-
/* test edge U1,U2 against V0,V1 */
|
5729
|
-
EDGE_EDGE_TEST(Ax,Ay, V0,U1,U2, i0,i1) ||
|
5730
|
-
/* test edge U2,U1 against V0,V1 */
|
5731
|
-
EDGE_EDGE_TEST(Ax,Ay, V0,U2,U0, i0,i1);
|
5732
|
-
}
|
6193
|
+
/* test edge U1,U2 against V1,V2 */
|
6194
|
+
/* (inline function EDGE_EDGE_TEST) */
|
5733
6195
|
|
5734
|
-
|
5735
|
-
|
5736
|
-
|
5737
|
-
|
5738
|
-
|
5739
|
-
|
5740
|
-
|
5741
|
-
c = -a*U0[i0]-b*U0[i1];
|
5742
|
-
d0 = a*V0[i0]+b*V0[i1]+c;
|
5743
|
-
|
5744
|
-
a = U2[i1]-U1[i1];
|
5745
|
-
b = -(U2[i0]-U1[i0]);
|
5746
|
-
c = -a*U1[i0]-b*U1[i1];
|
5747
|
-
d1 = a*V0[i0]+b*V0[i1]+c;
|
5748
|
-
|
5749
|
-
a = U0[i1] - U2[i1];
|
5750
|
-
b = - (U0[i0] - U2[i0]);
|
5751
|
-
c = -a * U2[i0] - b * U2[i1];
|
5752
|
-
d2 = a * V0[i0] + b * V0[i1] + c;
|
5753
|
-
|
5754
|
-
if(d0 * d1 > 0.0)
|
6196
|
+
Bx=U1[i0]-U2[i0];
|
6197
|
+
By=U1[i1]-U2[i1];
|
6198
|
+
Cx=V1[i0]-U1[i0];
|
6199
|
+
Cy=V1[i1]-U1[i1];
|
6200
|
+
f=Ay*Bx-Ax*By;
|
6201
|
+
d=By*Cx-Bx*Cy;
|
6202
|
+
if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f))
|
5755
6203
|
{
|
5756
|
-
|
6204
|
+
e=Ax*Cy-Ay*Cx;
|
6205
|
+
if(f>0)
|
6206
|
+
{
|
6207
|
+
if(e>=0 && e<=f) return true;
|
6208
|
+
}
|
6209
|
+
else
|
6210
|
+
{
|
6211
|
+
if(e<=0 && e>=f) return true;
|
6212
|
+
}
|
5757
6213
|
}
|
5758
|
-
return false;
|
5759
|
-
}
|
5760
6214
|
|
5761
|
-
|
5762
|
-
|
5763
|
-
var i0, i1;
|
6215
|
+
/* test edge U2,U1 against V1,V2 */
|
6216
|
+
/* (inline function EDGE_EDGE_TEST) */
|
5764
6217
|
|
5765
|
-
|
5766
|
-
|
5767
|
-
|
5768
|
-
|
5769
|
-
|
6218
|
+
Bx=U2[i0]-U0[i0];
|
6219
|
+
By=U2[i1]-U0[i1];
|
6220
|
+
Cx=V1[i0]-U2[i0];
|
6221
|
+
Cy=V1[i1]-U2[i1];
|
6222
|
+
f=Ay*Bx-Ax*By;
|
6223
|
+
d=By*Cx-Bx*Cy;
|
6224
|
+
if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f))
|
6225
|
+
{
|
6226
|
+
e=Ax*Cy-Ay*Cx;
|
6227
|
+
if(f>0)
|
6228
|
+
{
|
6229
|
+
if(e>=0 && e<=f) return true;
|
6230
|
+
}
|
6231
|
+
else
|
6232
|
+
{
|
6233
|
+
if(e<=0 && e>=f) return true;
|
6234
|
+
}
|
6235
|
+
}
|
6236
|
+
|
6237
|
+
}
|
6238
|
+
|
6239
|
+
/* (inline function EDGE_AGAINST_TRI_EDGES) */
|
5770
6240
|
|
5771
|
-
if(A[0]>A[1])
|
5772
6241
|
{
|
5773
|
-
|
6242
|
+
var Ax,Ay,Bx,By,Cx,Cy,e,d,f;
|
6243
|
+
Ax=V0[i0]-V2[i0];
|
6244
|
+
Ay=V0[i1]-V2[i1];
|
6245
|
+
/* test edge U0,U1 against V2,V0 */
|
6246
|
+
/* (inline function EDGE_EDGE_TEST) */
|
6247
|
+
|
6248
|
+
Bx=U0[i0]-U1[i0];
|
6249
|
+
By=U0[i1]-U1[i1];
|
6250
|
+
Cx=V2[i0]-U0[i0];
|
6251
|
+
Cy=V2[i1]-U0[i1];
|
6252
|
+
f=Ay*Bx-Ax*By;
|
6253
|
+
d=By*Cx-Bx*Cy;
|
6254
|
+
if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f))
|
6255
|
+
{
|
6256
|
+
e=Ax*Cy-Ay*Cx;
|
6257
|
+
if(f>0)
|
5774
6258
|
{
|
5775
|
-
|
5776
|
-
i1=2;
|
6259
|
+
if(e>=0 && e<=f) return true;
|
5777
6260
|
}
|
5778
6261
|
else
|
5779
6262
|
{
|
5780
|
-
|
5781
|
-
i1=1;
|
6263
|
+
if(e<=0 && e>=f) return true;
|
5782
6264
|
}
|
5783
6265
|
}
|
5784
|
-
|
6266
|
+
|
6267
|
+
/* test edge U1,U2 against V2,V0 */
|
6268
|
+
/* (inline function EDGE_EDGE_TEST) */
|
6269
|
+
|
6270
|
+
Bx=U1[i0]-U2[i0];
|
6271
|
+
By=U1[i1]-U2[i1];
|
6272
|
+
Cx=V2[i0]-U1[i0];
|
6273
|
+
Cy=V2[i1]-U1[i1];
|
6274
|
+
f=Ay*Bx-Ax*By;
|
6275
|
+
d=By*Cx-Bx*Cy;
|
6276
|
+
if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f))
|
5785
6277
|
{
|
5786
|
-
|
6278
|
+
e=Ax*Cy-Ay*Cx;
|
6279
|
+
if(f>0)
|
5787
6280
|
{
|
5788
|
-
|
5789
|
-
i1=1;
|
6281
|
+
if(e>=0 && e<=f) return true;
|
5790
6282
|
}
|
5791
6283
|
else
|
5792
6284
|
{
|
5793
|
-
|
5794
|
-
i1=2;
|
6285
|
+
if(e<=0 && e>=f) return true;
|
5795
6286
|
}
|
5796
6287
|
}
|
5797
6288
|
|
5798
|
-
|
5799
|
-
|
5800
|
-
|
5801
|
-
|
6289
|
+
/* test edge U2,U1 against V2,V0 */
|
6290
|
+
/* (inline function EDGE_EDGE_TEST) */
|
6291
|
+
|
6292
|
+
Bx=U2[i0]-U0[i0];
|
6293
|
+
By=U2[i1]-U0[i1];
|
6294
|
+
Cx=V2[i0]-U2[i0];
|
6295
|
+
Cy=V2[i1]-U2[i1];
|
6296
|
+
f=Ay*Bx-Ax*By;
|
6297
|
+
d=By*Cx-Bx*Cy;
|
6298
|
+
if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f))
|
6299
|
+
{
|
6300
|
+
e=Ax*Cy-Ay*Cx;
|
6301
|
+
if(f>0)
|
6302
|
+
{
|
6303
|
+
if(e>=0 && e<=f) return true;
|
6304
|
+
}
|
6305
|
+
else
|
6306
|
+
{
|
6307
|
+
if(e<=0 && e>=f) return true;
|
6308
|
+
}
|
6309
|
+
}
|
6310
|
+
|
6311
|
+
}
|
6312
|
+
|
5802
6313
|
|
5803
6314
|
/* finally, test if tri1 is totally contained in tri2 or vice versa */
|
5804
|
-
|
5805
|
-
|
6315
|
+
/* (inline function POINT_IN_TRI) */
|
6316
|
+
|
6317
|
+
{
|
6318
|
+
var a,b,c,d0,d1,d2;
|
6319
|
+
/* is T1 completly inside T2? */
|
6320
|
+
/* check if V0 is inside tri(U0,U1,U2) */
|
6321
|
+
a=U1[i1]-U0[i1];
|
6322
|
+
b=-(U1[i0]-U0[i0]);
|
6323
|
+
c=-a*U0[i0]-b*U0[i1];
|
6324
|
+
d0=a*V0[i0]+b*V0[i1]+c;
|
6325
|
+
a=U2[i1]-U1[i1];
|
6326
|
+
b=-(U2[i0]-U1[i0]);
|
6327
|
+
c=-a*U1[i0]-b*U1[i1];
|
6328
|
+
d1=a*V0[i0]+b*V0[i1]+c;
|
6329
|
+
a=U0[i1]-U2[i1];
|
6330
|
+
b=-(U0[i0]-U2[i0]);
|
6331
|
+
c=-a*U2[i0]-b*U2[i1];
|
6332
|
+
d2=a*V0[i0]+b*V0[i1]+c;
|
6333
|
+
if(d0*d1>0.0)
|
6334
|
+
{
|
6335
|
+
if(d0*d2>0.0) return true;
|
6336
|
+
}
|
6337
|
+
}
|
6338
|
+
|
6339
|
+
/* (inline function POINT_IN_TRI) */
|
6340
|
+
|
6341
|
+
{
|
6342
|
+
var a,b,c,d0,d1,d2;
|
6343
|
+
/* is T1 completly inside T2? */
|
6344
|
+
/* check if U0 is inside tri(V0,V1,V2) */
|
6345
|
+
a=V1[i1]-V0[i1];
|
6346
|
+
b=-(V1[i0]-V0[i0]);
|
6347
|
+
c=-a*V0[i0]-b*V0[i1];
|
6348
|
+
d0=a*U0[i0]+b*U0[i1]+c;
|
6349
|
+
a=V2[i1]-V1[i1];
|
6350
|
+
b=-(V2[i0]-V1[i0]);
|
6351
|
+
c=-a*V1[i0]-b*V1[i1];
|
6352
|
+
d1=a*U0[i0]+b*U0[i1]+c;
|
6353
|
+
a=V0[i1]-V2[i1];
|
6354
|
+
b=-(V0[i0]-V2[i0]);
|
6355
|
+
c=-a*V2[i0]-b*V2[i1];
|
6356
|
+
d2=a*U0[i0]+b*U0[i1]+c;
|
6357
|
+
if(d0*d1>0.0)
|
6358
|
+
{
|
6359
|
+
if(d0*d2>0.0) return true;
|
6360
|
+
}
|
6361
|
+
}
|
6362
|
+
|
5806
6363
|
|
5807
6364
|
return false;
|
5808
6365
|
}
|
5809
6366
|
|
5810
6367
|
function tri_tri_intersect(V0, V1, V2, U0, U1, U2)
|
5811
6368
|
{
|
5812
|
-
var E1 =
|
5813
|
-
E2 =
|
5814
|
-
N1 =
|
5815
|
-
N2 =
|
5816
|
-
D =
|
5817
|
-
isect1 =
|
5818
|
-
isect2 =
|
6369
|
+
var E1 = bufs.tritri_E1 = bufs.tritri_E1 || vec3.create(),
|
6370
|
+
E2 = bufs.tritri_E2 = bufs.tritri_E2 || vec3.create(),
|
6371
|
+
N1 = bufs.tritri_N1 = bufs.tritri_N1 || vec3.create(),
|
6372
|
+
N2 = bufs.tritri_N2 = bufs.tritri_N2 || vec3.create(),
|
6373
|
+
D = bufs.tritri_D = bufs.tritri_D || vec3.create(),
|
6374
|
+
isect1 = bufs.tritri_isect1 = bufs.tritri_isect1 || vec2.create(),
|
6375
|
+
isect2 = bufs.tritri_isect2 = bufs.tritri_isect2 || vec2.create();
|
5819
6376
|
var d1, d2;
|
5820
6377
|
var du0,du1,du2,dv0,dv1,dv2;
|
5821
6378
|
var du0du1,du0du2,dv0dv1,dv0dv2;
|
@@ -5892,17 +6449,137 @@ function tri_tri_intersect(V0, V1, V2, U0, U1, U2)
|
|
5892
6449
|
|
5893
6450
|
try {
|
5894
6451
|
/* compute interval for triangle 1 */
|
5895
|
-
COMPUTE_INTERVALS
|
6452
|
+
/* (inline function COMPUTE_INTERVALS) */
|
6453
|
+
|
6454
|
+
if(dv0dv1>0.0)
|
6455
|
+
{
|
6456
|
+
/* here we know that dv0dv2<=0.0 */
|
6457
|
+
/* that is dv0, dv1 are on the same side, dv2 on the other or on the plane */
|
6458
|
+
/* (inline function ISECT) */
|
6459
|
+
|
6460
|
+
isect1[0]=vp2+(vp0-vp2)*dv2/(dv2-dv0);
|
6461
|
+
isect1[1]=vp2+(vp1-vp2)*dv2/(dv2-dv1);
|
6462
|
+
|
6463
|
+
}
|
6464
|
+
else if(dv0dv2>0.0)
|
6465
|
+
{
|
6466
|
+
/* here we know that d0d1<=0.0 */
|
6467
|
+
/* (inline function ISECT) */
|
6468
|
+
|
6469
|
+
isect1[0]=vp1+(vp0-vp1)*dv1/(dv1-dv0);
|
6470
|
+
isect1[1]=vp1+(vp2-vp1)*dv1/(dv1-dv2);
|
6471
|
+
|
6472
|
+
}
|
6473
|
+
else if(dv1*dv2>0.0 || dv0!=0.0)
|
6474
|
+
{
|
6475
|
+
/* here we know that d0d1<=0.0 or that dv0!=0.0 */
|
6476
|
+
/* (inline function ISECT) */
|
6477
|
+
|
6478
|
+
isect1[0]=vp0+(vp1-vp0)*dv0/(dv0-dv1);
|
6479
|
+
isect1[1]=vp0+(vp2-vp0)*dv0/(dv0-dv2);
|
6480
|
+
|
6481
|
+
}
|
6482
|
+
else if(dv1!=0.0)
|
6483
|
+
{
|
6484
|
+
/* (inline function ISECT) */
|
6485
|
+
|
6486
|
+
isect1[0]=vp1+(vp0-vp1)*dv1/(dv1-dv0);
|
6487
|
+
isect1[1]=vp1+(vp2-vp1)*dv1/(dv1-dv2);
|
6488
|
+
|
6489
|
+
}
|
6490
|
+
else if(dv2!=0.0)
|
6491
|
+
{
|
6492
|
+
/* (inline function ISECT) */
|
6493
|
+
|
6494
|
+
isect1[0]=vp2+(vp0-vp2)*dv2/(dv2-dv0);
|
6495
|
+
isect1[1]=vp2+(vp1-vp2)*dv2/(dv2-dv1);
|
6496
|
+
|
6497
|
+
}
|
6498
|
+
else
|
6499
|
+
{
|
6500
|
+
/* triangles are coplanar */
|
6501
|
+
return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2);
|
6502
|
+
}
|
6503
|
+
|
5896
6504
|
|
5897
6505
|
/* compute interval for triangle 2 */
|
5898
|
-
COMPUTE_INTERVALS
|
6506
|
+
/* (inline function COMPUTE_INTERVALS) */
|
6507
|
+
|
6508
|
+
if(du0du1>0.0)
|
6509
|
+
{
|
6510
|
+
/* here we know that du0du2<=0.0 */
|
6511
|
+
/* that is du0, du1 are on the same side, du2 on the other or on the plane */
|
6512
|
+
/* (inline function ISECT) */
|
6513
|
+
|
6514
|
+
isect2[0]=up2+(up0-up2)*du2/(du2-du0);
|
6515
|
+
isect2[1]=up2+(up1-up2)*du2/(du2-du1);
|
6516
|
+
|
6517
|
+
}
|
6518
|
+
else if(du0du2>0.0)
|
6519
|
+
{
|
6520
|
+
/* here we know that d0d1<=0.0 */
|
6521
|
+
/* (inline function ISECT) */
|
6522
|
+
|
6523
|
+
isect2[0]=up1+(up0-up1)*du1/(du1-du0);
|
6524
|
+
isect2[1]=up1+(up2-up1)*du1/(du1-du2);
|
6525
|
+
|
6526
|
+
}
|
6527
|
+
else if(du1*du2>0.0 || du0!=0.0)
|
6528
|
+
{
|
6529
|
+
/* here we know that d0d1<=0.0 or that du0!=0.0 */
|
6530
|
+
/* (inline function ISECT) */
|
6531
|
+
|
6532
|
+
isect2[0]=up0+(up1-up0)*du0/(du0-du1);
|
6533
|
+
isect2[1]=up0+(up2-up0)*du0/(du0-du2);
|
6534
|
+
|
6535
|
+
}
|
6536
|
+
else if(du1!=0.0)
|
6537
|
+
{
|
6538
|
+
/* (inline function ISECT) */
|
6539
|
+
|
6540
|
+
isect2[0]=up1+(up0-up1)*du1/(du1-du0);
|
6541
|
+
isect2[1]=up1+(up2-up1)*du1/(du1-du2);
|
6542
|
+
|
6543
|
+
}
|
6544
|
+
else if(du2!=0.0)
|
6545
|
+
{
|
6546
|
+
/* (inline function ISECT) */
|
6547
|
+
|
6548
|
+
isect2[0]=up2+(up0-up2)*du2/(du2-du0);
|
6549
|
+
isect2[1]=up2+(up1-up2)*du2/(du2-du1);
|
6550
|
+
|
6551
|
+
}
|
6552
|
+
else
|
6553
|
+
{
|
6554
|
+
/* triangles are coplanar */
|
6555
|
+
return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2);
|
6556
|
+
}
|
6557
|
+
|
5899
6558
|
} catch(e) {
|
5900
6559
|
if (e == 1) return coplanar_tri_tri(N1, V0, V1, V2, U0, U1, U2);
|
5901
6560
|
throw e;
|
5902
6561
|
}
|
5903
6562
|
|
5904
|
-
SORT
|
5905
|
-
|
6563
|
+
/* (inline function SORT) */
|
6564
|
+
|
6565
|
+
if(isect1[0]> isect1[1])
|
6566
|
+
{
|
6567
|
+
var c;
|
6568
|
+
c=isect1[0];
|
6569
|
+
isect1[0]= isect1[1];
|
6570
|
+
isect1[1]=c;
|
6571
|
+
}
|
6572
|
+
|
6573
|
+
/* (inline function SORT) */
|
6574
|
+
|
6575
|
+
if(isect2[0]> isect1[1])
|
6576
|
+
{
|
6577
|
+
var c;
|
6578
|
+
c=isect2[0];
|
6579
|
+
isect2[0]= isect1[1];
|
6580
|
+
isect1[1]=c;
|
6581
|
+
}
|
6582
|
+
|
5906
6583
|
|
5907
6584
|
if(isect1[1] < isect2[0] || isect2[1] < isect1[0]) return false;
|
5908
6585
|
return true;
|
@@ -5910,7 +6587,7 @@ function tri_tri_intersect(V0, V1, V2, U0, U1, U2)
|
|
5910
6587
|
|
5911
6588
|
var bufs = {};
|
5912
6589
|
|
5913
|
-
|
6590
|
+
var Triangle = Jax.Class.create({
|
5914
6591
|
initialize: function(a, b, c) {
|
5915
6592
|
this.a = vec3.create();
|
5916
6593
|
this.b = vec3.create();
|
@@ -6013,12 +6690,13 @@ function tri_tri_intersect(V0, V1, V2, U0, U1, U2)
|
|
6013
6690
|
return false;
|
6014
6691
|
},
|
6015
6692
|
|
6016
|
-
intersectTriangle: function(t) {
|
6017
|
-
|
6693
|
+
intersectTriangle: function(t, dest) {
|
6694
|
+
if (dest) return slow_tri_tri_intersect(this, t, dest);
|
6695
|
+
else return tri_tri_intersect(this.a, this.b, this.c, t.a, t.b, t.c);
|
6018
6696
|
},
|
6019
6697
|
|
6020
6698
|
updateDescription: function() {
|
6021
|
-
var p = this.
|
6699
|
+
var p = this.plane = this.plane || new Jax.Geometry.Plane(this.a, this.b, this.c);
|
6022
6700
|
var n = p.normal;
|
6023
6701
|
var a = [Math.abs(n.x), Math.abs(n.y), Math.abs(n.z)];
|
6024
6702
|
|
@@ -6059,6 +6737,29 @@ function tri_tri_intersect(V0, V1, V2, U0, U1, U2)
|
|
6059
6737
|
return a >= 0 && (a+b) <= 1;
|
6060
6738
|
}
|
6061
6739
|
});
|
6740
|
+
|
6741
|
+
Object.defineProperty(Triangle.prototype, 0, {
|
6742
|
+
get: function() { return this.a; },
|
6743
|
+
set: function(v) { return this.a = v; },
|
6744
|
+
enumerable: false,
|
6745
|
+
configurable: false
|
6746
|
+
});
|
6747
|
+
|
6748
|
+
Object.defineProperty(Triangle.prototype, 1, {
|
6749
|
+
get: function() { return this.b; },
|
6750
|
+
set: function(v) { return this.b = v; },
|
6751
|
+
enumerable: false,
|
6752
|
+
configurable: false
|
6753
|
+
});
|
6754
|
+
|
6755
|
+
Object.defineProperty(Triangle.prototype, 2, {
|
6756
|
+
get: function() { return this.c; },
|
6757
|
+
set: function(v) { return this.c = v; },
|
6758
|
+
enumerable: false,
|
6759
|
+
configurable: false
|
6760
|
+
});
|
6761
|
+
|
6762
|
+
return Triangle;
|
6062
6763
|
})();
|
6063
6764
|
|
6064
6765
|
Jax.Scene.Frustum = (function() {
|
@@ -6700,12 +7401,15 @@ Jax.Scene.LightManager = (function() {
|
|
6700
7401
|
options = Jax.Util.normalizeOptions(options, {});
|
6701
7402
|
|
6702
7403
|
context.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
6703
|
-
|
7404
|
+
var i;
|
7405
|
+
for (i = 0; i < this._lights.length; i++) {
|
7406
|
+
if (i == 1) context.glBlendFunc(GL_ONE, GL_ONE);
|
6704
7407
|
this._current_light = i;
|
6705
7408
|
this._lights[i].render(context, this.objects, options);
|
6706
|
-
if (i == 0) context.glBlendFunc(GL_ONE, GL_ONE);
|
6707
7409
|
}
|
6708
7410
|
|
7411
|
+
if (i > 0) context.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
7412
|
+
|
6709
7413
|
delete this._current_light;
|
6710
7414
|
},
|
6711
7415
|
|
@@ -6886,12 +7590,19 @@ Jax.Camera = (function() {
|
|
6886
7590
|
var vec;
|
6887
7591
|
if (arguments.length == 3) vec = arguments;
|
6888
7592
|
else vec = vec3.create(vector);
|
7593
|
+
vec3.scale(vec, -1);
|
6889
7594
|
vec3.normalize(vec);
|
6890
7595
|
|
6891
|
-
|
6892
|
-
|
6893
|
-
|
7596
|
+
if (this.fixed_yaw) {
|
7597
|
+
var right = vec3.normalize(vec3.cross(this.fixed_yaw_axis, vec, vec3.create()));
|
7598
|
+
var up = vec3.normalize(vec3.cross(vec, right, vec3.create()));
|
7599
|
+
quat4.fromAxes(vec, right, up, this.rotation);
|
7600
|
+
} else {
|
7601
|
+
var rotquat = vec3.toQuatRotation(storeVecBuf(this, VIEW), vec, tmpRotQuat(this));
|
7602
|
+
quat4.multiply(rotquat, this.rotation, this.rotation);
|
7603
|
+
}
|
6894
7604
|
|
7605
|
+
quat4.normalize(this.rotation);
|
6895
7606
|
this.fireEvent('updated');
|
6896
7607
|
return this;
|
6897
7608
|
},
|
@@ -7079,7 +7790,25 @@ Jax.Camera = (function() {
|
|
7079
7790
|
return this;
|
7080
7791
|
},
|
7081
7792
|
|
7082
|
-
|
7793
|
+
projectMovement: function(forward, strafe, dest) {
|
7794
|
+
if (!strafe) strafe = 0;
|
7795
|
+
if (!dest) dest = vec3.create();
|
7796
|
+
|
7797
|
+
var view = vec3.scale(storeVecBuf(this, VIEW), forward);
|
7798
|
+
var right = vec3.scale(storeVecBuf(this, RIGHT), strafe);
|
7799
|
+
vec3.set(this.position, dest);
|
7800
|
+
vec3.add(view, dest, dest);
|
7801
|
+
vec3.add(right, dest, dest);
|
7802
|
+
|
7803
|
+
return dest;
|
7804
|
+
},
|
7805
|
+
|
7806
|
+
reset: function() {
|
7807
|
+
this.position[0] = this.position[1] = this.position[2] = 0;
|
7808
|
+
this.rotation[0] = this.rotation[1] = this.rotation[2] = 0;
|
7809
|
+
this.rotation[3] = 1;
|
7810
|
+
this.fireEvent('updated');
|
7811
|
+
}
|
7083
7812
|
});
|
7084
7813
|
})();
|
7085
7814
|
|
@@ -7193,22 +7922,23 @@ Jax.World = (function() {
|
|
7193
7922
|
|
7194
7923
|
/* this.current_pass is used by the material */
|
7195
7924
|
|
7196
|
-
this.context.current_pass = Jax.Scene.AMBIENT_PASS;
|
7197
7925
|
this.context.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
7198
7926
|
var unlit = Jax.Util.normalizeOptions(options, {unlit:true});
|
7199
7927
|
|
7200
|
-
if (this.lighting.isEnabled() && (!unlit.material || unlit.material.supportsLighting())) {
|
7928
|
+
if (this.lighting.isEnabled() && (!unlit.material || (unlit.material.supportsLighting && unlit.material.supportsLighting()))) {
|
7929
|
+
/* illumination pass */
|
7930
|
+
this.context.current_pass = Jax.Scene.ILLUMINATION_PASS;
|
7931
|
+
this.lighting.illuminate(this.context, options);
|
7932
|
+
|
7201
7933
|
/* ambient pass - unlit objects only because lit objects get ambient+diffuse+specular in one pass */
|
7934
|
+
this.context.current_pass = Jax.Scene.AMBIENT_PASS;
|
7202
7935
|
for (i = 0; i < this.objects.length; i++)
|
7203
7936
|
if (!this.objects[i].isLit()) {
|
7204
7937
|
unlit.model_index = i;
|
7205
7938
|
this.objects[i].render(this.context, unlit);
|
7206
7939
|
}
|
7207
|
-
|
7208
|
-
/* illumination pass */
|
7209
|
-
this.context.current_pass = Jax.Scene.ILLUMINATION_PASS;
|
7210
|
-
this.lighting.illuminate(this.context, options);
|
7211
7940
|
} else {
|
7941
|
+
this.context.current_pass = Jax.Scene.AMBIENT_PASS;
|
7212
7942
|
for (i = 0; i < this.objects.length; i++) {
|
7213
7943
|
unlit.model_index = i;
|
7214
7944
|
this.objects[i].render(this.context, unlit);
|
@@ -7618,6 +8348,12 @@ Jax.EVENT_METHODS = (function() {
|
|
7618
8348
|
var cumulativeOffset = getCumulativeOffset(self.canvas);
|
7619
8349
|
mouse.x = evt.pageX - cumulativeOffset[0];
|
7620
8350
|
mouse.y = evt.pageY - cumulativeOffset[1];
|
8351
|
+
|
8352
|
+
if (self.canvas) {
|
8353
|
+
if (self.canvas.offsetWidth) mouse.x = mouse.x / self.canvas.offsetWidth * self.canvas.width;
|
8354
|
+
if (self.canvas.offsetHeight) mouse.y = mouse.y / self.canvas.offsetHeight * self.canvas.height;
|
8355
|
+
}
|
8356
|
+
|
7621
8357
|
mouse.y = self.canvas.height - mouse.y; // invert y
|
7622
8358
|
|
7623
8359
|
if (evt.type == 'mouseover') {
|