aboutsummaryrefslogtreecommitdiff
path: root/js/lib
diff options
context:
space:
mode:
authorhwc4872012-05-15 16:02:27 -0700
committerhwc4872012-05-15 16:02:27 -0700
commitcb37bee07085690d72e69a82e76cae9166e5f0f1 (patch)
tree75949f7b4ebf7c107b4d0ae007e36626fb2aaa67 /js/lib
parent02e5fbb819f02d26a8a7179cf04021a0f6c6ddf6 (diff)
downloadninja-cb37bee07085690d72e69a82e76cae9166e5f0f1.tar.gz
Gradient matching between WebGL and Canvas2D
Diffstat (limited to 'js/lib')
-rwxr-xr-xjs/lib/geom/circle.js119
-rwxr-xr-xjs/lib/geom/rectangle.js183
-rwxr-xr-xjs/lib/rdge/materials/radial-gradient-material.js31
3 files changed, 156 insertions, 177 deletions
diff --git a/js/lib/geom/circle.js b/js/lib/geom/circle.js
index b60ad58f..2ca4c1f5 100755
--- a/js/lib/geom/circle.js
+++ b/js/lib/geom/circle.js
@@ -505,9 +505,9 @@ exports.Circle = Object.create(GeomObj, {
505 if(this._fillColor.gradientMode) { 505 if(this._fillColor.gradientMode) {
506 if(this._fillColor.gradientMode === "radial") { 506 if(this._fillColor.gradientMode === "radial") {
507 gradient = ctx.createRadialGradient(xCtr, yCtr, 0, 507 gradient = ctx.createRadialGradient(xCtr, yCtr, 0,
508 xCtr, yCtr, Math.max(this._width, this._height)/2); 508 xCtr, yCtr, Math.max(this._width, this._height)/2 - lineWidth);
509 } else { 509 } else {
510 gradient = ctx.createLinearGradient(lineWidth/2, this._height/2, this._width-lineWidth, this._height/2); 510 gradient = ctx.createLinearGradient(lineWidth, this._height/2, this._width-lineWidth, this._height/2);
511 } 511 }
512 colors = this._fillColor.color; 512 colors = this._fillColor.color;
513 513
@@ -804,79 +804,44 @@ exports.Circle = Object.create(GeomObj, {
804 } 804 }
805 }, 805 },
806 806
807 /* 807 recalcTexMapCoords: {
808 this.getNearPoint = function( pt, dir ) { 808 value: function(vrts, uvs) {
809 var world = this.getWorld(); 809 var n = vrts.length/3;
810 if (!world) throw( "null world in getNearPoint" ); 810 if (n === 0) return;
811 811 var ivrt = 0, iuv = 0;
812 // get a point on the plane of the circle 812 var uMin = 1.e8, uMax = -1.e8,
813 // the point is in NDC, as is the input parameters 813 vMin = 1.e8, vMax = -1.e8;
814 var mat = this.getMatrix(); 814
815 var plane = [0,0,1,0]; 815 var i, index = 3;
816 plane = MathUtils.transformPlane( plane, mat ); 816 var xMin = vrts[0], xMax = vrts[0],
817 var projPt = MathUtils.vecIntersectPlane ( pt, dir, plane ); 817 yMin = vrts[1], yMax = vrts[1];
818 818 for (i=1; i<n; i++)
819 // transform the projected point back to the XY plane 819 {
820 //var invMat = mat.inverse(); 820 if (vrts[index] < xMin) xMin = vrts[index];
821 var invMat = glmat4.inverse( mat, [] ); 821 else if (vrts[index] > xMax) xMax = vrts[index];
822 var planePt = MathUtils.transformPoint( projPt, invMat ); 822
823 823 if (vrts[index+1] < yMin) yMin = vrts[index+1];
824 // get the normalized device coordinates (NDC) for 824 else if (vrts[index+1] > yMax) yMax = vrts[index+1];
825 // the position and radii. 825
826 var vpw = world.getViewportWidth(), vph = world.getViewportHeight(); 826 index += 3;
827 var xNDC = 2*this._xOffset/vpw, yNDC = -2*this._yOffset/vph, 827 }
828 xRadNDC = this._width/vpw, yRadNDC = this._height/vph; 828 var ovalWidth = xMax - xMin,
829 var projMat = world.makePerspectiveMatrix(); 829 ovalHeight = yMax - yMin;
830 var z = -world.getViewDistance(); 830 for (i=0; i<n; i++) {
831 var planePtNDC = planePt.slice(0); 831 uvs[iuv] = (vrts[ivrt]-xMin)/ovalWidth;
832 planePtNDC[2] = z; 832 if (uvs[iuv] < uMin) uMin = uvs[iuv];
833 planePtNDC = MathUtils.transformHomogeneousPoint( planePtNDC, projMat ); 833 if (uvs[iuv] > uMax) uMax = uvs[iuv];
834 planePtNDC = MathUtils.applyHomogeneousCoordinate( planePtNDC ); 834
835 835 iuv++; ivrt++;
836 // get the gl coordinates 836 uvs[iuv] = (vrts[ivrt]-yMin)/ovalHeight;
837 var aspect = world.getAspect(); 837 if (uvs[iuv] < vMin) vMin = uvs[iuv];
838 var zn = world.getZNear(), zf = world.getZFar(); 838 if (uvs[iuv] > vMax) vMax = uvs[iuv];
839 var t = zn * Math.tan(world.getFOV() * Math.PI / 360.0), 839 iuv++; ivrt += 2;
840 b = -t, 840 }
841 r = aspect*t, 841
842 l = -r; 842 //console.log( "remap" );
843 843 //console.log( "uRange: " + uMin + " => " + uMax );
844 var angle = Math.atan2( planePtNDC[1] - yNDC, planePtNDC[0] - xNDC ); 844 //console.log( "vRange: " + vMin + " => " + vMax );
845 var degrees = angle*180.0/Math.PI; 845 }
846 var objPt = [Math.cos(angle)*xRadNDC + xNDC, Math.sin(angle)*yRadNDC + yNDC, 0]; 846 }
847
848 // convert to GL coordinates
849 objPt[0] = -z*(r-l)/(2.0*zn)*objPt[0];
850 objPt[1] = -z*(t-b)/(2.0*zn)*objPt[1];
851
852 // re-apply the transform
853 objPt = MathUtils.transformPoint( objPt, mat );
854
855 return objPt;
856 };
857 */
858 recalcTexMapCoords: {
859 value: function(vrts, uvs) {
860 var n = vrts.length/3;
861 var ivrt = 0, iuv = 0;
862 var uMin = 1.e8, uMax = -1.e8,
863 vMin = 1.e8, vMax = -1.e8;
864
865 for (var i=0; i<n; i++) {
866 uvs[iuv] = 0.5*(vrts[ivrt]/this._ovalWidth + 1);
867 if (uvs[iuv] < uMin) uMin = uvs[iuv];
868 if (uvs[iuv] > uMax) uMax = uvs[iuv];
869
870 iuv++; ivrt++;
871 uvs[iuv] = 0.5*(vrts[ivrt]/this._ovalHeight + 1);
872 if (uvs[iuv] < vMin) vMin = uvs[iuv];
873 if (uvs[iuv] > vMax) vMax = uvs[iuv];
874 iuv++; ivrt += 2;
875 }
876
877 //console.log( "remap: " + uvs );
878 //console.log( "uRange: " + uMin + " => " + uMax );
879 //console.log( "vRange: " + vMin + " => " + vMax );
880 }
881 }
882}); \ No newline at end of file 847}); \ No newline at end of file
diff --git a/js/lib/geom/rectangle.js b/js/lib/geom/rectangle.js
index 4415af43..8fc80c60 100755
--- a/js/lib/geom/rectangle.js
+++ b/js/lib/geom/rectangle.js
@@ -508,98 +508,99 @@ exports.Rectangle = Object.create(GeomObj, {
508 }, 508 },
509 509
510 render: { 510 render: {
511 value: function() { 511 value: function() {
512 // get the world 512 // get the world
513 var world = this.getWorld(); 513 var world = this.getWorld();
514 if (!world) throw( "null world in rectangle render" ); 514 if (!world) throw( "null world in rectangle render" );
515 515
516 // get the context 516 // get the context
517 var ctx = world.get2DContext(); 517 var ctx = world.get2DContext();
518 if (!ctx) return; 518 if (!ctx) return;
519 519
520 // get some dimensions 520 // get some dimensions
521 var lw = this._strokeWidth; 521 var lw = this._strokeWidth;
522 var w = world.getViewportWidth(), 522 var w = world.getViewportWidth(),
523 h = world.getViewportHeight(); 523 h = world.getViewportHeight();
524 524
525 var c, 525 var c,
526 inset, 526 inset,
527 gradient, 527 gradient,
528 colors, 528 colors,
529 len, 529 len,
530 n, 530 n,
531 position, 531 position,
532 cs; 532 cs;
533 // render the fill 533 // render the fill
534 ctx.beginPath(); 534 ctx.beginPath();
535 if (this._fillColor) { 535 if (this._fillColor) {
536 inset = Math.ceil( lw ) - 0.5; 536 inset = Math.ceil( lw ) - 0.5;
537 537
538 if(this._fillColor.gradientMode) { 538 if(this._fillColor.gradientMode) {
539 if(this._fillColor.gradientMode === "radial") { 539 if(this._fillColor.gradientMode === "radial") {
540 var ww = w - 2*lw, hh = h - 2*lw; 540 var ww = w - 2*lw, hh = h - 2*lw;
541 gradient = ctx.createRadialGradient(w/2, h/2, 0, w/2-this._strokeWidth, h/2, Math.max(ww, hh)/2); 541 //gradient = ctx.createRadialGradient(w/2, h/2, 0, w/2-this._strokeWidth, h/2, Math.max(ww, hh)/2);
542 } else { 542 gradient = ctx.createRadialGradient(w/2, h/2, 0, w/2, h/2, Math.max(ww, hh)/2);
543 gradient = ctx.createLinearGradient(inset/2, h/2, w-inset, h/2); 543 } else {
544 } 544 gradient = ctx.createLinearGradient(inset/2, h/2, w-inset, h/2);
545 colors = this._fillColor.color; 545 }
546 546 colors = this._fillColor.color;
547 len = colors.length; 547
548 548 len = colors.length;
549 for(n=0; n<len; n++) { 549
550 position = colors[n].position/100; 550 for(n=0; n<len; n++) {
551 cs = colors[n].value; 551 position = colors[n].position/100;
552 gradient.addColorStop(position, "rgba(" + cs.r + "," + cs.g + "," + cs.b + "," + cs.a + ")"); 552 cs = colors[n].value;
553 } 553 gradient.addColorStop(position, "rgba(" + cs.r + "," + cs.g + "," + cs.b + "," + cs.a + ")");
554 554 }
555 ctx.fillStyle = gradient; 555
556 556 ctx.fillStyle = gradient;
557 } else { 557
558 c = "rgba(" + 255*this._fillColor[0] + "," + 255*this._fillColor[1] + "," + 255*this._fillColor[2] + "," + this._fillColor[3] + ")"; 558 } else {
559 ctx.fillStyle = c; 559 c = "rgba(" + 255*this._fillColor[0] + "," + 255*this._fillColor[1] + "," + 255*this._fillColor[2] + "," + this._fillColor[3] + ")";
560 } 560 ctx.fillStyle = c;
561 561 }
562 ctx.lineWidth = lw; 562
563 this.renderPath( inset, ctx ); 563 ctx.lineWidth = lw;
564 ctx.fill(); 564 this.renderPath( inset, ctx );
565 ctx.closePath(); 565 ctx.fill();
566 } 566 ctx.closePath();
567 567 }
568 // render the stroke 568
569 ctx.beginPath(); 569 // render the stroke
570 if (this._strokeColor) { 570 ctx.beginPath();
571 inset = Math.ceil( 0.5*lw ) - 0.5; 571 if (this._strokeColor) {
572 572 inset = Math.ceil( 0.5*lw ) - 0.5;
573 if(this._strokeColor.gradientMode) { 573
574 if(this._strokeColor.gradientMode === "radial") { 5