diff options
Diffstat (limited to 'js/helper-classes/3D')
-rw-r--r-- | js/helper-classes/3D/math-utils.js | 115 | ||||
-rw-r--r-- | js/helper-classes/3D/snap-manager.js | 17 |
2 files changed, 111 insertions, 21 deletions
diff --git a/js/helper-classes/3D/math-utils.js b/js/helper-classes/3D/math-utils.js index 71ed62a0..37044763 100644 --- a/js/helper-classes/3D/math-utils.js +++ b/js/helper-classes/3D/math-utils.js | |||
@@ -8,7 +8,9 @@ No rights, expressed or implied, whatsoever to this software are provided by Mot | |||
8 | // Class Utils | 8 | // Class Utils |
9 | // Math Utility functions | 9 | // Math Utility functions |
10 | /////////////////////////////////////////////////////////////////////// | 10 | /////////////////////////////////////////////////////////////////////// |
11 | var VecUtils = require("js/helper-classes/3D/vec-utils").VecUtils; | 11 | var VecUtils = require("js/helper-classes/3D/vec-utils").VecUtils, |
12 | ViewUtils = require("js/helper-classes/3D/view-utils").ViewUtils, | ||
13 | Rectangle = require("js/helper-classes/3D/rectangle").Rectangle; | ||
12 | 14 | ||
13 | var MathUtilsClass = exports.MathUtilsClass = Object.create(Object.prototype, { | 15 | var MathUtilsClass = exports.MathUtilsClass = Object.create(Object.prototype, { |
14 | /////////////////////////////////////////////////////////////////////// | 16 | /////////////////////////////////////////////////////////////////////// |
@@ -536,6 +538,99 @@ var MathUtilsClass = exports.MathUtilsClass = Object.create(Object.prototype, { | |||
536 | } | 538 | } |
537 | }, | 539 | }, |
538 | 540 | ||
541 | rectsOverlap: | ||
542 | { | ||
543 | value: function( pt, width, height, elt ) | ||
544 | { | ||
545 | // only consider rectangles with non-zero area | ||
546 | if ((width == 0) || (height == 0)) return false; | ||
547 | |||
548 | // get the mins/maxs of the onput rectangle | ||
549 | var xMin, xMax, yMin, yMax; | ||
550 | if (width > 0) { xMin = pt[0]; xMax = pt[0] + width; } | ||
551 | else { xMax = pt[0]; xMin = pt[0] + width; } | ||
552 | if (height > 0) { yMin = pt[1]; yMax = pt[1] + height; } | ||
553 | else { yMax = pt[1]; yMin = pt[1] + height; } | ||
554 | |||
555 | // get the bounds of the element in global screen space | ||
556 | var bounds = ViewUtils.getElementViewBounds3D( elt ); | ||
557 | var bounds3D = []; | ||
558 | for (var i=0; i<4; i++) | ||
559 | bounds3D[i] = ViewUtils.localToGlobal( bounds[i], elt ); | ||
560 | |||
561 | // get the min/maxs for the element | ||
562 | var xMinElt = bounds3D[0][0], xMaxElt = bounds3D[0][0], | ||
563 | yMinElt = bounds3D[0][1], yMaxElt = bounds3D[0][1]; | ||
564 | for (var i=1; i<4; i++) | ||
565 | { | ||
566 | if (bounds3D[i][0] < xMinElt) xMinElt = bounds3D[i][0]; | ||
567 | else if (bounds3D[i][0] > xMaxElt) xMaxElt = bounds3D[i][0]; | ||
568 | if (bounds3D[i][1] < yMinElt) yMinElt = bounds3D[i][1]; | ||
569 | else if (bounds3D[i][1] > yMaxElt) yMaxElt = bounds3D[i][1]; | ||
570 | } | ||
571 | |||
572 | // test 1. Overall bounding box test | ||
573 | if ((xMaxElt < xMin) || (xMinElt > xMax) || (yMaxElt < yMin) || (yMinElt > yMax)) | ||
574 | return false; | ||
575 | |||
576 | // test 2. See if any of the corners of the element are contained in the rectangle | ||
577 | var rect = Object.create(Rectangle, {}); | ||
578 | rect.set( pt[0], pt[1], width, height ); | ||
579 | for (var i=0; i<4; i++) | ||
580 | { | ||
581 | if (rect.contains( bounds3D[i][0], bounds3D[i][1] )) return true; | ||
582 | } | ||
583 | |||
584 | // test 3. Bounding box tests on individual edges of the element | ||
585 | for (var i=0; i<4; i++) | ||
586 | { | ||
587 | var pt0 = bounds3D[i], | ||
588 | pt1 = bounds3D[(i+1)%4]; | ||
589 | |||
590 | // get the extremes of the edge | ||
591 | if (pt0[0] < pt1[0]) { xMinElt = pt0[0]; xMaxElt = pt1[0]; } | ||
592 | else { xMaxElt = pt0[0]; xMinElt = pt1[0]; } | ||
593 | if (pt0[1] < pt1[1]) { yMinElt = pt0[1]; yMaxElt = pt1[1]; } | ||
594 | else { yMaxElt = pt0[1]; yMinElt = pt1[1]; } | ||
595 | |||
596 | if ((xMaxElt < xMin) || (xMinElt > xMax) || (yMaxElt < yMin) || (yMinElt > yMax)) | ||
597 | continue; | ||
598 | else | ||
599 | { | ||
600 | // intersect the element edge with the 4 sides of the rectangle | ||
601 | // vertical edges | ||
602 | var xRect = xMin; | ||
603 | for (var j=0; j<2; j++) | ||
604 | { | ||
605 | if ((xMinElt < xRect) && (xMaxElt > xRect)) | ||
606 | { | ||
607 | var t = (xRect - pt0[0])/(pt1[0] - pt0[0]); | ||
608 | var y = pt0[1] + t*(pt1[1] - pt0[1]); | ||
609 | if ((y >= yMin) && (y <= yMax)) return true; | ||
610 | } | ||
611 | xRect = xMax; | ||
612 | } | ||
613 | |||
614 | // horizontal edges | ||
615 | var yRect = yMin; | ||
616 | for (var j=0; j<2; j++) | ||
617 | { | ||
618 | if ((yMinElt < yRect) && (yMaxElt > yRect)) | ||
619 | { | ||
620 | var t = (yRect - pt0[1])/(pt1[1] - pt0[1]); | ||
621 | var x = pt0[0] + t*(pt1[0] - pt0[0]); | ||
622 | if ((x >= xMin) && (x <= xMax)) return true; | ||
623 | } | ||
624 | yRect = yMax; | ||
625 | } | ||
626 | } | ||
627 | } | ||
628 | |||
629 | // if we get here there is no overlap | ||
630 | return false; | ||
631 | } | ||
632 | }, | ||
633 | |||
539 | /////////////////////////////////////////////////////////////////////// | 634 | /////////////////////////////////////////////////////////////////////// |
540 | // Bezier Methods | 635 | // Bezier Methods |
541 | /////////////////////////////////////////////////////////////////////// | 636 | /////////////////////////////////////////////////////////////////////// |
@@ -802,19 +897,21 @@ var MathUtilsClass = exports.MathUtilsClass = Object.create(Object.prototype, { | |||
802 | getAxisAngleBetween3DVectors: { | 897 | getAxisAngleBetween3DVectors: { |
803 | value: function (vec1, vec2, axis) { | 898 | value: function (vec1, vec2, axis) { |
804 | //compute magnitudes of the vectors | 899 | //compute magnitudes of the vectors |
805 | var mag1 = VecUtils.vecMag(3, vec1); | 900 | var v1n = VecUtils.vecNormalize(3, vec1, 1.0); |
806 | var mag2 = VecUtils.vecMag(3, vec2); | 901 | var v2n = VecUtils.vecNormalize(3, vec2, 1.0); |
807 | |||
808 | if (mag1 < this.EPSILON || mag2 < this.EPSILON) { | ||
809 | return 0; //if angle 0 is returned nothing from this function should be used | ||
810 | } | ||
811 | //angle between the vectors (acos for now...) | 902 | //angle between the vectors (acos for now...) |
812 | var angle = Math.acos(VecUtils.vecDot(3, vec1, vec2) / (mag1 * mag2)); | 903 | var angle = Math.acos(VecUtils.vecDot(3, v1n, v2n)); |
813 | if (Math.abs(angle) < this.EPSILON) { | 904 | if (Math.abs(angle) < this.EPSILON) { |
814 | return 0; | 905 | return 0; |
815 | } | 906 | } |
907 | //TODO testing...remove this block | ||
908 | console.log("getAxisAngleBetween3DVectors Angle: "+angle); | ||
909 | if (isNaN(angle)){ | ||
910 | console.log("getAxisAngleBetween3DVectors Angle is NaN"); | ||
911 | } | ||
912 | //TODO end testing block | ||
816 | //optionally, if axis is provided, create the axis of rotation as well | 913 | //optionally, if axis is provided, create the axis of rotation as well |
817 | var rotAxis = VecUtils.vecCross(3, vec1, vec2); | 914 | var rotAxis = VecUtils.vecCross(3, v1n, v2n); |
818 | rotAxis = VecUtils.vecNormalize(3, rotAxis, 1); | 915 | rotAxis = VecUtils.vecNormalize(3, rotAxis, 1); |
819 | axis[0] = rotAxis[0]; | 916 | axis[0] = rotAxis[0]; |
820 | axis[1] = rotAxis[1]; | 917 | axis[1] = rotAxis[1]; |
diff --git a/js/helper-classes/3D/snap-manager.js b/js/helper-classes/3D/snap-manager.js index 3af7d8cf..0a950658 100644 --- a/js/helper-classes/3D/snap-manager.js +++ b/js/helper-classes/3D/snap-manager.js | |||
@@ -970,13 +970,12 @@ var SnapManager = exports.SnapManager = Montage.create(Component, { | |||
970 | value: function( screenPt, hitRecs ) { | 970 | value: function( screenPt, hitRecs ) { |
971 | // start at the stage. | 971 | // start at the stage. |
972 | var stage = this.getStage(); | 972 | var stage = this.getStage(); |
973 | //var stagePt = viewUtils.parentToChild( screenPt, stage ); | ||
974 | 973 | ||
975 | // the root should be the 'view' canvas, so the first matrix is the camera | 974 | // the root should be the 'view' canvas, so the first matrix is the camera |
976 | viewUtils.setViewportObj( stage ); | 975 | viewUtils.setViewportObj( stage ); |
977 | 976 | ||
978 | MathUtils.makeDimension3( screenPt ); | 977 | MathUtils.makeDimension3( screenPt ); |
979 | this.hSnapToElements( stage, screenPt, hitRecs, 0, screenPt ); | 978 | this.hSnapToElements( stage, hitRecs, 0, screenPt ); |
980 | 979 | ||
981 | return; | 980 | return; |
982 | } | 981 | } |
@@ -984,7 +983,7 @@ var SnapManager = exports.SnapManager = Montage.create(Component, { | |||
984 | 983 | ||
985 | hSnapToElements : | 984 | hSnapToElements : |
986 | { | 985 | { |
987 | value: function( elt, parentPt, hitRecs, depth, globalScrPt ) | 986 | value: function( elt, hitRecs, depth, globalScrPt ) |
988 | { | 987 | { |
989 | // hit test the current object | 988 | // hit test the current object |
990 | var hit; | 989 | var hit; |
@@ -993,11 +992,9 @@ var SnapManager = exports.SnapManager = Montage.create(Component, { | |||
993 | // if the element is in the 2D cache snapping is done there | 992 | // if the element is in the 2D cache snapping is done there |
994 | if (elt.elementModel && !elt.elementModel.isIn2DSnapCache) | 993 | if (elt.elementModel && !elt.elementModel.isIn2DSnapCache) |
995 | { | 994 | { |
996 | var scrPt = viewUtils.parentToChild( parentPt, elt, false ); | 995 | hit = this.snapToElement( elt, globalScrPt ); |
997 | hit = this.snapToElement( elt, scrPt, globalScrPt ); | ||
998 | if (hit) | 996 | if (hit) |
999 | { | 997 | { |
1000 | //hitRecs.push( hit ); | ||
1001 | if (!hit.checkType()) | 998 | if (!hit.checkType()) |
1002 | { | 999 | { |
1003 | console.log( "invalid hit record: " + hit.getTypeString() ); | 1000 | console.log( "invalid hit record: " + hit.getTypeString() ); |
@@ -1016,17 +1013,14 @@ var SnapManager = exports.SnapManager = Montage.create(Component, { | |||
1016 | } | 1013 | } |
1017 | // test the rest of the tree | 1014 | // test the rest of the tree |
1018 | var n = elt.childElementCount; | 1015 | var n = elt.childElementCount; |
1019 | var eltPt = viewUtils.parentToChild( parentPt, elt, true ); | ||
1020 | if (n > 0) | 1016 | if (n > 0) |
1021 | { | 1017 | { |
1022 | for (var i=0; i<n; i++) | 1018 | for (var i=0; i<n; i++) |
1023 | { | 1019 | { |
1024 | var child = elt.children[i]; | 1020 | var child = elt.children[i]; |
1025 | //var childPt = viewUtils.parentToChild( sc |