jax 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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') {
|