From 342fb451bd251358068a0dcb10e9dc218b79a176 Mon Sep 17 00:00:00 2001 From: Jonathan Duran Date: Tue, 6 Mar 2012 11:38:39 -0800 Subject: Squashed commit of the following: commit 1cd89d4d06e3a8f2c221628b19cf26a2c69f5d3f Author: Jose Antonio Marquez Date: Tue Mar 6 11:24:25 2012 -0800 Fixing WebGL not available bug commit 84332ab81c1b445195f1d9be8bbeae0725c8e758 Author: Valerio Virgillito Date: Tue Mar 6 10:58:25 2012 -0800 Squashed commit of preload-fix into Master - Requiring all the previously pre-loaded files - RDGE, Codemirror and gl-matrix are not included via a script tag. Signed-off-by: Valerio Virgillito commit 13f52cf0c74f53a919fa864f86669e8155f82961 Merge: dced508 abc04f3 Author: Valerio Virgillito Date: Fri Mar 2 15:46:11 2012 -0800 Merge pull request #93 from imix23ways/Timeline Timeline: Critical bug fixes commit dced508bb19a7bcd467ff1b86b5df5bbec4be794 Merge: 0aeb400 cc772ef Author: Valerio Virgillito Date: Fri Mar 2 15:45:35 2012 -0800 Merge pull request #92 from mqg734/WebGLFixes Selection Tool Fixes for elements flying off into space when they overlap commit 0aeb400070762cf01d83cf9f9ee25a5595098b7f Merge: ff0a956 aabb48a Author: Valerio Virgillito Date: Fri Mar 2 14:05:21 2012 -0800 Merge pull request #94 from ericguzman/PresetsPanel Presets Panel - Fix single-click activation, and transition cut-off bug. commit cc772ef3333ed419d269a2bda7aea5b0150a7bd9 Author: Nivesh Rajbhandari Date: Fri Mar 2 11:34:58 2012 -0800 Fixing flying off into space bug for translate tool too. Signed-off-by: Nivesh Rajbhandari commit abc04f3d50311ed1c21067344bc7e448686f8c5c Author: Jonathan Duran Date: Fri Mar 2 11:26:25 2012 -0800 Timeline Fix timing function Signed-off-by: Jonathan Duran commit aabb48a1c8d34bc968f4c6b0ffee4e31c1d5d286 Author: Eric Guzman Date: Fri Mar 2 11:22:44 2012 -0800 Presets Panel - Fix single-click activation, and transition cut-off bug. Use double-click as the activation event for transition presets. Also fixed the bug when applying a style preset before the transition preset, which disabled transitions after the first one. commit f3207f39ea9d8c1c34246217a23d3a689671903d Author: Nivesh Rajbhandari Date: Fri Mar 2 11:21:29 2012 -0800 Don't draw transform handles if the stage is the target element. Signed-off-by: Nivesh Rajbhandari commit 5425be91e7125c22955b4459a62412ff574e49a8 Author: Jonathan Duran Date: Fri Mar 2 11:11:48 2012 -0800 Timeline: Fix for animation iteration count Add default webkit css properties to allow animations with integer iteration counts. Signed-off-by: Jonathan Duran commit 1760bac1da9218315ad1bacdcf3a157495a049e8 Author: Nivesh Rajbhandari Date: Fri Mar 2 10:48:41 2012 -0800 Fix for jumping issue when moving items that have any 3d on them. We can't translate 3d moves into 2d space due to perspective, so we must update the matrix3d values instead of the top-left values if items have 3d. Signed-off-by: Nivesh Rajbhandari commit 2c04935f0ccb1cb7c98371fc10b43155f2d956c4 Author: Nivesh Rajbhandari Date: Thu Mar 1 22:20:06 2012 -0800 Fix for elements flying off into space when moving elements that overlap. This was happening because our hit record's element and the browser's element from point did not match. Signed-off-by: Nivesh Rajbhandari commit 50058746779f714ed9b0287f49e56c9f0d35593e Merge: 500426d ff0a956 Author: Nivesh Rajbhandari Date: Thu Mar 1 21:49:44 2012 -0800 Merge branch 'refs/heads/ninja-internal' into WebGLFixes commit 500426dea0ca95a6b45be8ea8d132cfdb4d2c940 Author: Nivesh Rajbhandari Date: Thu Mar 1 10:11:39 2012 -0800 Fixed logic error when resizing with the top-left transform handles. Signed-off-by: Nivesh Rajbhandari commit 7980d9bde2b43aa5a494ddf6f1db5c4959a57b91 Author: Nivesh Rajbhandari Date: Thu Mar 1 10:04:15 2012 -0800 Re-fixing IKNinja-940 - Can't select objects when in side/top view. Signed-off-by: Nivesh Rajbhandari commit f04cc0146d8f7573628678613a99c270116768e4 Author: Nivesh Rajbhandari Date: Wed Feb 29 16:45:40 2012 -0800 Last-used material (instead of FlatMaterial) is applied to shape when turning on use WebGL checkbox in the PI. Signed-off-by: Nivesh Rajbhandari Signed-off-by: Jonathan Duran --- js/helper-classes/backup-delete/GLSubpath.js | 1185 ++++++++++++++++++++++++++ 1 file changed, 1185 insertions(+) create mode 100755 js/helper-classes/backup-delete/GLSubpath.js (limited to 'js/helper-classes/backup-delete/GLSubpath.js') diff --git a/js/helper-classes/backup-delete/GLSubpath.js b/js/helper-classes/backup-delete/GLSubpath.js new file mode 100755 index 00000000..f3d8ad36 --- /dev/null +++ b/js/helper-classes/backup-delete/GLSubpath.js @@ -0,0 +1,1185 @@ +/* +This file contains proprietary software owned by Motorola Mobility, Inc.
+No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
+(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. +
*/ + +// Todo: This entire class should be converted to a module +var VecUtils = require("js/helper-classes/3D/vec-utils").VecUtils; + + +function SubpathOffsetPoint(pos, mapPos) { + this.Pos = Vector.create([pos[0],pos[1],pos[2]]); + this.CurveMapPos = Vector.create([mapPos[0], mapPos[1], mapPos[2]]); +} + +function SubpathOffsetTriangle(v0, v1, v2) { + this.v0 = v0; + this.v1 = v1; + this.v2 = v2; + this.n = Vector.create([0,0,1]); //replace with the actual cross product later +} + +function sortNumberAscending(a,b){ + return a-b; +} +function sortNumberDescending(a,b){ + return b-a; +} +function SegmentIntersections(){ + this.paramArray = []; +} + +/////////////////////////////////////////////////////////////////////// +// Class GLSubpath +// representation a sequence of cubic bezier curves. +// Derived from class GLGeomObj +/////////////////////////////////////////////////////////////////////// + +function GLSubpath() { + /////////////////////////////////////////////////// + // Instance variables + /////////////////////////////////////////////////// + this._Anchors = []; + this._BBoxMin = [0, 0, 0]; + this._BBoxMax = [0, 0, 0]; + this._isClosed = false; + + this._samples = []; //polyline representation of this curve + this._sampleParam = []; //parametric distance of samples, within [0, N], where N is # of Bezier curves (=# of anchor points if closed, =#anchor pts -1 if open) + this._anchorSampleIndex = []; //index within _samples corresponding to anchor points + + this._UnprojectedAnchors = []; + + //initially set the _dirty bit so we will construct samples + this._dirty = true; + + //whether or not to use the canvas drawing to stroke/fill + this._useCanvasDrawing = true; + + //the X and Y location of this subpath's canvas in stage world space of Ninja + this._canvasX = 0; + this._canvasY = 0; + + //stroke information + this._strokeWidth = 0.0; + this._strokeColor = [0.4, 0.4, 0.4, 1.0]; + this._strokeMaterial; + this._strokeStyle = "Solid"; + this._materialAmbient = [0.2, 0.2, 0.2, 1.0]; + this._materialDiffuse = [0.4, 0.4, 0.4, 1.0]; + this._materialSpecular = [0.4, 0.4, 0.4, 1.0]; + this._fillColor = [0.4, 0.4, 0.4, 1.0]; + this._fillMaterial; + this._DISPLAY_ANCHOR_RADIUS = 5; + //drawing context + this._world = null; + + //tool that owns this subpath + this._drawingTool = null; + this._planeMat = null; + this._planeMatInv = null; + this._planeCenter = null; + + this.inheritedFrom = GLGeomObj; + this.inheritedFrom(); + + //used to query what the user selected, OR-able for future extensions + this.SEL_NONE = 0; //nothing was selected + this.SEL_ANCHOR = 1; //anchor point was selected + this.SEL_PREV = 2; //previous handle of anchor point was selected + this.SEL_NEXT = 4; //next handle of anchor point was selected + this.SEL_PATH = 8; //the path itself was selected + this._selectMode = this.SEL_NONE; + this._selectedAnchorIndex = -1; + + this._SAMPLING_EPSILON = 0.5; //epsilon used for sampling the curve + this._DEFAULT_STROKE_WIDTH = 20; //use only if stroke width not specified + this._MAX_OFFSET_ANGLE = 10; //max angle (in degrees) between consecutive vectors from curve to offset path + + // (current GLGeomObj complains if buildBuffers/render is added to GLSubpath prototype) + //buildBuffers + // Build the stroke vertices, normals, textures and colors + // Add that array data to the GPU using OpenGL data binding + this.buildBuffers = function () { + return; //no need to do anything for now + }//buildBuffers() + + //render + // specify how to render the subpath in Canvas2D + this.render = function () { + // get the world + var world = this.getWorld(); + if (!world) throw( "null world in subpath render" ); + + // get the context + var ctx = world.get2DContext(); + if (!ctx) throw ("null context in subpath render") + + var numAnchors = this.getNumAnchors(); + if (numAnchors === 0) + return; //nothing to do for empty paths + + ctx.save(); + + this.createSamples(); //dirty bit checked in this function...will generate a polyline representation + var bboxMin = this.getBBoxMin(); + var bboxMax = this.getBBoxMax(); + var bboxWidth = bboxMax[0] - bboxMin[0]; + var bboxHeight = bboxMax[1] - bboxMin[1]; + var bboxMid = Vector.create([0.5 * (bboxMax[0] + bboxMin[0]), 0.5 * (bboxMax[1] + bboxMin[1]), 0.5 * (bboxMax[2] + bboxMin[2])]); + + ctx.clearRect(0, 0, bboxWidth, bboxHeight); + + + ctx.lineWidth = this._strokeWidth; + ctx.strokeStyle = "black"; + if (this._strokeColor) + ctx.strokeStyle = MathUtils.colorToHex( this._strokeColor ); + ctx.fillStyle = "white"; + if (this._fillColor){ + //ctx.fillStyle = MathUtils.colorToHex( this._fillColor ); + var fillColorStr = "rgba("+parseInt(255*this._fillColor[0])+","+parseInt(255*this._fillColor[1])+","+parseInt(255*this._fillColor[2])+","+this._fillColor[3]+")"; + ctx.fillStyle = fillColorStr; + } + var lineCap = ['butt','round','square']; + ctx.lineCap = lineCap[1]; + ctx.beginPath(); + + /* + commenting this out for now because of Chrome bug where coincident endpoints of bezier curve cause the curve to not be rendered + var prevAnchor = this.getAnchor(0); + ctx.moveTo(prevAnchor.getPosX()-bboxMin[0],prevAnchor.getPosY()-bboxMin[1]); + for (var i = 1; i < numAnchors; i++) { + var currAnchor = this.getAnchor(i); + ctx.bezierCurveTo(prevAnchor.getNextX()-bboxMin[0],prevAnchor.getNextY()-bboxMin[1], currAnchor.getPrevX()-bboxMin[0], currAnchor.getPrevY()-bboxMin[1], currAnchor.getPosX()-bboxMin[0], currAnchor.getPosY()-bboxMin[1]); + prevAnchor = currAnchor; + } + if (this._isClosed === true) { + var currAnchor = this.getAnchor(0); + ctx.bezierCurveTo(prevAnchor.getNextX()-bboxMin[0],prevAnchor.getNextY()-bboxMin[1], currAnchor.getPrevX()-bboxMin[0], currAnchor.getPrevY()-bboxMin[1], currAnchor.getPosX()-bboxMin[0], currAnchor.getPosY()-bboxMin[1]); + prevAnchor = currAnchor; + ctx.fill(); + } + */ + + + var numPoints = this._samples.length/3; + ctx.moveTo(this._samples[0]-bboxMin[0],this._samples[1]-bboxMin[1]); + for (var i=0;i=0;i--) { + var newAnchor = new GLAnchorPoint(); + var oldAnchor = this._Anchors[i]; + newAnchor.setPos(oldAnchor.getPosX(),oldAnchor.getPosY(),oldAnchor.getPosZ()); + newAnchor.setPrevPos(oldAnchor.getNextX(),oldAnchor.getNextY(),oldAnchor.getNextZ()); + newAnchor.setNextPos(oldAnchor.getPrevX(),oldAnchor.getPrevY(),oldAnchor.getPrevZ()); + revAnchors.push(newAnchor); + } + if (this._selectedAnchorIndex >= 0){ + this._selectedAnchorIndex = (numAnchors-1) - this._selectedAnchorIndex; + } + this._Anchors = revAnchors; + this._dirty=true; +} + +//remove all the anchor points +GLSubpath.prototype.clearAllAnchors = function () { + this._Anchors = []; + this._isClosed = false; + this._dirty = true; +} + +GLSubpath.prototype.insertAnchorAtParameter = function(index, param) { + if (index+1 >= this._Anchors.length && !this._isClosed) { + return; + } + //insert an anchor after the specified index using the parameter, using De Casteljau subdivision + var nextIndex = (index+1)%this._Anchors.length; + + //build the De Casteljau points + var P0P1 = VecUtils.vecInterpolate(3, this._Anchors[index].getPos(), this._Anchors[index].getNext(), param); + var P1P2 = VecUtils.vecInterpolate(3, this._Anchors[index].getNext(), this._Anchors[nextIndex].getPrev(), param); + var P2P3 = VecUtils.vecInterpolate(3, this._Anchors[nextIndex].getPrev(), this._Anchors[nextIndex].getPos(), param); + + var P0P1P2 = VecUtils.vecInterpolate(3, P0P1, P1P2, param); + var P1P2P3 = VecUtils.vecInterpolate(3, P1P2, P2P3, param); + var anchorPos = VecUtils.vecInterpolate(3, P0P1P2, P1P2P3, param); + + + //update the next of the anchor at index and prev of anchor at nextIndex + var isPrevCoincident = false; + var isNextCoincident = false; + if (VecUtils.vecDist( 3, P0P1, this._Anchors[index].getNext()) < this._SAMPLING_EPSILON) { + //no change to the next point + isPrevCoincident = true; + } else { + this._Anchors[index].setNextPos(P0P1[0], P0P1[1], P0P1[2]); + } + + if (VecUtils.vecDist( 3, P2P3, this._Anchors[nextIndex].getPrev()) < this._SAMPLING_EPSILON) { + //no change to the prev point + isNextCoincident = true; + } else { + this._Anchors[nextIndex].setPrevPos(P2P3[0], P2P3[1], P2P3[2]); + } + + //create a new anchor point + var newAnchor = new GLAnchorPoint(); + + if (isPrevCoincident && isNextCoincident){ + anchorPos[0]=P1P2[0];anchorPos[1]=P1P2[1];anchorPos[2]=P1P2[2]; + newAnchor.setPos(anchorPos[0],anchorPos[1],anchorPos[2]); + newAnchor.setPrevPos(anchorPos[0],anchorPos[1],anchorPos[2]); + newAnchor.setNextPos(anchorPos[0],anchorPos[1],anchorPos[2]); + } else { + newAnchor.setPrevPos(P0P1P2[0], P0P1P2[1], P0P1P2[2]); + newAnchor.setNextPos(P1P2P3[0], P1P2P3[1], P1P2P3[2]); + newAnchor.setPos(anchorPos[0], anchorPos[1], anchorPos[2]); + } + + //insert the new anchor point at the correct index and set it as the selected anchor + this._Anchors.splice(nextIndex, 0, newAnchor); + this._selectedAnchorIndex = nextIndex; + this._dirty = true; +} + +GLSubpath.prototype._checkIntersectionWithSamples = function(startIndex, endIndex, point, radius){ + //check whether the point is within the radius distance from the curve represented as a polyline in _samples + //return the parametric distance along the curve if there is an intersection, else return null + //will assume that the BBox test is performed outside this function + if (endIndex bboxMax[d]){ + bboxMax[d] = controlPts[i][d]; + } + } + } + //check whether the bbox of the control points contains the point within the specified radius + for (var d=0;d<3;d++){ + if (point[d] < (bboxMin[d]-radius)){ + return null; + } + if (point[d] > (bboxMax[d]+radius)){ + return null; + } + } + + //check if the curve is already flat, and if so, check the distance from the segment C0C3 to the point + //measure distance of C1 and C2 to segment C0-C3 + var distC1 = MathUtils.distPointToSegment(controlPts[1], controlPts[0], controlPts[3]); + var distC2 = MathUtils.distPointToSegment(controlPts[2], controlPts[0], controlPts[3]); + var maxDist = Math.max(distC1, distC2); + var threshold = this._SAMPLING_EPSILON; //this should be set outside this function //TODO + if (maxDist < threshold) { //if the curve is flat + var distP = MathUtils.distPointToSegment(point, controlPts[0], controlPts[3]); //TODO we may need to neglect cases where the non-perpendicular distance is used... + if (distP>radius) + return null; + else { + var param = MathUtils.paramPointProjectionOnSegment(point, controlPts[0], controlPts[3]); //TODO this function is already called in distPointToSegment...optimize by removing redundant call + //var param = VecUtils.vecDist(3, point, controlPts[0])/VecUtils.vecDist(3, controlPts[3], controlPts[0]); + if (param<0) + param=0; + if (param>1) + param=1; + + return beginParam + (endParam-beginParam)*param; + } + } + + //subdivide this curve using De Casteljau interpolation + var C0_ = VecUtils.vecInterpolate(3, controlPts[0], controlPts[1], 0.5); + var C1_ = VecUtils.vecInterpolate(3, controlPts[1], controlPts[2], 0.5); + var C2_ = VecUtils.vecInterpolate(3, controlPts[2], controlPts[3], 0.5); + + var C0__ = VecUtils.vecInterpolate(3, C0_, C1_, 0.5); + var C1__ = VecUtils.vecInterpolate(3, C1_, C2_, 0.5); + + var C0___ = VecUtils.vecInterpolate(3, C0__, C1__, 0.5); + + //recursively sample the first half of the curve + var midParam = (endParam+beginParam)*0.5; + var param1 = this._checkIntersection(Vector.create([controlPts[0],C0_,C0__,C0___]), beginParam, midParam, point, radius); + if (param1!==null){ + return param1; + } + + //recursively sample the second half of the curve + var param2 = this._checkIntersection(Vector.create([C0___,C1__,C2_,controlPts[3]]), midParam, endParam, point, radius); + if (param2!==null){ + return param2; + } + + //no intersection, so return null + return null; +} + +//whether the point lies within the bbox given by the four control points +GLSubpath.prototype._isWithinBoundingBox = function(point, ctrlPts, radius) { + var bboxMin = Vector.create([Infinity, Infinity, Infinity]); + var bboxMax = Vector.create([-Infinity,-Infinity,-Infinity]); + for (var i=0;i bboxMax[d]){ + bboxMax[d] = ctrlPts[i][d]; + } + } + } + //check whether the bbox of the control points contains the point within the specified radius + for (var d=0;d<3;d++){ + if (point[d] < (bboxMin[d]-radius)){ + return false; + } + if (point[d] > (bboxMax[d]+radius)){ + return false; + } + } + return true; +} + +GLSubpath.prototype.pickAnchor = function (pickX, pickY, pickZ, radius) { + var numAnchors = this._Anchors.length; + var selAnchorIndex = -1; + var retCode = this.SEL_NONE; + var radSq = radius * radius; + var minDistance = Infinity; + //check if the clicked location is close to the currently selected anchor position + if (this._selectedAnchorIndex>=0 && this._selectedAnchorIndex=0 && this._selectedAnchorIndex=0 && selAnchorIndex === -1) { + var distSq = this._Anchors[this._selectedAnchorIndex].getPrevDistanceSq(pickX, pickY, pickZ); + if (distSq < minDistance && distSq < radSq){ + selAnchorIndex = this._selectedAnchorIndex; + minDistance = distSq; + retCode = retCode | this.SEL_PREV; + } else { + //check the next for this anchor point + distSq = this._Anchors[this._selectedAnchorIndex].getNextDistanceSq(pickX, pickY, pickZ); + if (distSq 1) { + //start with the first anchor position (since the Bezier curve start point is not added in the sample function below) + //this._samples.push(this._Anchors[0].getPosX()); + //this._samples.push(this._Anchors[0].getPosY()); + //this._samples.push(this._Anchors[0].getPosZ()); + + for (var i = 0; i < numAnchors - 1; i++) { + //get the control points + var C0X = this._Anchors[i].getPosX(); + var C0Y = this._Anchors[i].getPosY(); + var C0Z = this._Anchors[i].getPosZ(); + + var C1X = this._Anchors[i].getNextX(); + var C1Y = this._Anchors[i].getNextY(); + var C1Z = this._Anchors[i].getNextZ(); + + var C2X = this._Anchors[i + 1].getPrevX(); + var C2Y = this._Anchors[i + 1].getPrevY(); + var C2Z = this._Anchors[i + 1].getPrevZ(); + + var C3X = this._Anchors[i + 1].getPosX(); + var C3Y = this._Anchors[i + 1].getPosY(); + var C3Z = this._Anchors[i + 1].getPosZ(); + + var beginParam = i; + var endParam = i+1; + this._anchorSampleIndex.push(this._samples.length/3); //index of sample corresponding to anchor i + this._sampleCubicBezier(C0X, C0Y, C0Z, C1X, C1Y, C1Z, C2X, C2Y, C2Z, C3X, C3Y, C3Z, beginParam, endParam); + } //for every anchor point i, except last + + if (this._isClosed) { + var i = numAnchors - 1; + //get the control points + var C0X = this._Anchors[i].getPosX(); + var C0Y = this._Anchors[i].getPosY(); + var C0Z = this._Anchors[i].getPosZ(); + + var C1X = this._Anchors[i].getNextX(); + var C1Y = this._Anchors[i].getNextY(); + var C1Z = this._Anchors[i].getNextZ(); + + var C2X = this._Anchors[0].getPrevX(); + var C2Y = this._Anchors[0].getPrevY(); + var C2Z = this._Anchors[0].getPrevZ(); + + var C3X = this._Anchors[0].getPosX(); + var C3Y = this._Anchors[0].getPosY(); + var C3Z = this._Anchors[0].getPosZ(); + + var beginParam = i; + var endParam = i+1; + this._anchorSampleIndex.push(this._samples.length/3); //index of sample corresponding to anchor i + this._sampleCubicBezier(C0X, C0Y, C0Z, C1X, C1Y, C1Z, C2X, C2Y, C2Z, C3X, C3Y, C3Z, beginParam, endParam); + } else { + this._anchorSampleIndex.push((this._samples.length/3) - 1); //index of sample corresponding to last anchor + } + } //if (numAnchors >== 2) { + + //re-compute the bounding box (this also accounts for stroke width, so assume the stroke width is set) + this.computeBoundingBox(true); + + } //if (this._dirty) + this._dirty = false; +} + +GLSubpath.prototype.computeBoundingBox = function(useSamples){ + this._BBoxMin = [Infinity, Infinity, Infinity]; + this._BBoxMax = [-Infinity, -Infinity, -Infinity]; + if (useSamples) { + var numPoints = this._samples.length/3; + if (numPoints === 0) { + this._BBoxMin = [0, 0, 0]; + this._BBoxMax = [0, 0, 0]; + } else { + for (var i=0;i pt[d]) { + this._BBoxMin[d] = pt[d]; + } + if (this._BBoxMax[d] < pt[d]) { + this._BBoxMax[d] = pt[d]; + } + }//for every dimension d from 0 to 2 + } + } + } + else{ + //build a bbox of the anchor points, not the path itself + var numAnchors = this._Anchors.length; + var anchorPts = [Vector.create([0,0,0]), Vector.create([0,0,0]), Vector.create([0,0,0])]; + if (numAnchors === 0) { + this._BBoxMin = [0, 0, 0]; + this._BBoxMax = [0, 0, 0]; + } else { + for (var i = 0; i < numAnchors; i++) { + anchorPts[0] = (Vector.create([this._Anchors[i].getPosX(),this._Anchors[i].getPosY(),this._Anchors[i].getPosZ()])); + anchorPts[1] = (Vector.create([this._Anchors[i].getPrevX(),this._Anchors[i].getPrevY(),this._Anchors[i].getPrevZ()])); + anchorPts[2] = (Vector.create([this._Anchors[i].getNextX(),this._Anchors[i].getNextY(),this._Anchors[i].getNextZ()])); + + for (var p=0;p<3;p++){ + for (var d = 0; d < 3; d++) { + if (this._BBoxMin[d] > anchorPts[p][d]) { + this._BBoxMin[d] = anchorPts[p][d]; + } + if (this._BBoxMax[d] < anchorPts[p][d]) { + this._BBoxMax[d] = anchorPts[p][d]; + } + }//for every dimension d from 0 to 2 + } //for every anchorPts p from 0 to 2 + } //for every anchor point i + } //else of if (numSamples === 0) { + }//else of if useSamples + + //increase the bbox given the stroke width + for (var d = 0; d < 3; d++) { + this._BBoxMin[d]-= this._strokeWidth/2; + this._BBoxMax[d]+= this._strokeWidth/2; + }//for every dimension d from 0 to 2 +} + +//returns v such that it is in [min,max] +GLSubpath.prototype._clamp = function (v, min, max) { + if (v < min) + return min; + if (v > max) + return max; + return v; +}, + + //input: point sIn in stage-world space, planeMidPt in stage-world space, matrix planeMat that rotates plane into XY (parallel to view plane), inverse of planeMat +//returns: sIn 'unprojected' +GLSubpath.prototype.unprojectPoint = function ( sIn, planeMidPt, planeMat, planeMatInv) +{ + var s = sIn.slice(0); + s[0] -= planeMidPt[0]; s[1] -= planeMidPt[1]; //bring s to the center of the plane + + // unproject the point s + var i; + var viewZ = 1400; + if (MathUtils.fpCmp(viewZ,-s[2]) !== 0){ + z = s[2]*viewZ/(viewZ + s[2]); + var x = s[0]*(viewZ - z)/viewZ, + y = s[1]*(viewZ - z)/viewZ; + s[0] = x; s[1] = y; s[2] = z; + } + + // add the translation back in + s[0] += planeMidPt[0]; s[1] += planeMidPt[1]; + + return s; +}, + +GLSubpath.prototype.computeUnprojectedNDC = function (pos, bboxMid, bboxDim, r, l, t, b, z, zn) { + //unproject pos from stageworld to unprojected state + var ppos = this.unprojectPoint(pos, this._planeCenter, this._planeMat, this._planeMatInv); + + //make the coordinates lie in [-1,1] + var x = (ppos[0] - bboxMid[0]) / bboxDim[0]; + var y = -(ppos[1] - bboxMid[1]) / bboxDim[1]; + + //x and y should never be outside the [-1,1] range + x = this._clamp(x, -1, 1); + y = this._clamp(y, -1, 1); + + //apply the perspective transform + x *= -z * (r - l) / (2.0 * zn); + y *= -z * (t - b) / (2.0 * zn); + + ppos[0] = x; + ppos[1] = y; + ppos[2] = 0; //z; + return ppos; +} + + +GLSubpath.prototype.makeStrokeMaterial = function() +{ + var strokeMaterial; + if (this.getStrokeMaterial()) + strokeMaterial = this.getStrokeMaterial().dup(); + else + strokeMaterial = new FlatMaterial(); + + if (strokeMaterial) + { + strokeMaterial.init(); + //if(!this.getStrokeMaterial() && this._strokeColor) + if(this._strokeColor) + { + strokeMaterial.setProperty("color", this._strokeColor); + } + } + + this._materialArray.push( strokeMaterial ); + this._materialTypeArray.push( "stroke" ); + + return strokeMaterial; +} + +GLSubpath.prototype.makeFillMaterial = function() +{ + var fillMaterial; + if (this.getFillMaterial()) + fillMaterial = this.getFillMaterial().dup(); + else + fillMaterial = new FlatMaterial(); + + if (fillMaterial) + { + fillMaterial.init(); + //if(!this.getFillMaterial() && this._fillColor) + if (this._fillColor) + { + fillMaterial.setProperty("color", this._fillColor); + } + } + + this._materialArray.push( fillMaterial ); + this._materialTypeArray.push( "fill" ); + + return fillMaterial; +} + +GLSubpath.prototype.getNearVertex = function( eyePt, dir ){ + //get the parameters used for computing perspective transformation + var bboxDim = []; + var bboxMid = []; + bboxDim[0] = 0.5 * (this._BBoxMax[0] - this._BBoxMin[0]); + bboxMid[0] = 0.5 * (this._BBoxMax[0] + this._BBoxMin[0]); + bboxDim[1] = 0.5 * (this._BBoxMax[1] - this._BBoxMin[1]); + bboxMid[1] = 0.5 * (this._BBoxMax[1] + this._BBoxMin[1]); + bboxDim[2] = 0.5 * (this._BBoxMax[2] - this._BBoxMin[2]); + bboxMid[3] = 0.5 * (this._BBoxMax[2] + this._BBoxMin[2]); + + // convert the stroke vertices into normalized device coordinates + var world = this.getWorld(); + if (!world) return null; + var aspect = world.getAspect(); + var zn = world.getZNear(), zf = world.getZFar(); + var t = zn * Math.tan(world.getFOV() * Math.PI / 360.0), //top of the frustum + b = -t, //bottom + r = aspect * t, //right + l = -r; //left + + // calculate the object coordinates from their NDC coordinates + var z = -world.getViewDistance(); + + // the eyePt and dir are in WebGL space...we need to convert each anchor point into the WebGL space + var numAnchors = this._Anchors.length; + var selAnchorPpos = null; + var minDistance = Infinity; + for (var i = 0; i < numAnchors; i++) { + var anchorPos = Vector.create([this._Anchors[i].getPosX(), this._Anchors[i].getPosY(), this._Anchors[i].getPosZ()]); + var ppos = this.computeUnprojectedNDC(anchorPos, bboxMid, bboxDim, r, l, t, b, z, zn); + var dist = MathUtils.distPointToRay(ppos, eyePt, dir); + if (dist < minDistance) { + selAnchorPpos = ppos; + minDistance = dist; + } + } + return selAnchorPpos; +} + +GLSubpath.prototype.getNearPoint = function( eyePt, dir ){ + return null; +} + +//returns true if P is left of line through l0 and l1 or on it +GLSubpath.prototype.isLeft = function(l0, l1, P){ + var signedArea = (l1[0]-l0[0])*(P[1] - l0[1]) - (P[0]-l0[0])*(l1[1]-l0[1]); + if (signedArea>=0) + return true; + else + return false; +} +//returns true if 2D point p is contained within 2D quad given by r0,r1,r2,r3 (need not be axis-aligned) +GLSubpath.prototype.isPointInQuad2D = function(r0,r1,r2,r3,p){ + //returns true if the point is on the same side of the segments r0r1, r1r2, r2r3, r3r0 + var isLeft0 = this.isLeft(r0,r1,p); + var isLeft1 = this.isLeft(r1,r2,p); + var isLeft2 = this.isLeft(r2,r3,p); + var isLeft3 = this.isLeft(r3,r0,p); + var andAll = isLeft0 & isLeft1 & isLeft2 & isLeft3; + if (andAll) + return true; + var orAll = isLeft0 | isLeft1 | isLeft2 | isLeft3; + if (!orAll) + return true; + return false; +} + + +GLSubpath.prototype.export = function() +{ + var rtnStr = "type: " + this.geomType() + "\n"; + + rtnStr += "strokeWidth: " + this._strokeWidth + "\n"; + rtnStr += "strokeStyle: " + this._strokeStyle + "\n"; + + rtnStr += "strokeMat: "; + if (this._strokeMaterial) + rtnStr += this._strokeMaterial.getName(); + else + rtnStr += "flatMaterial"; + rtnStr += "\n"; + + rtnStr += "fillMat: "; + if (this._fillMaterial) + rtnStr += this._fillMaterial.getName(); + else + rtnStr += "flatMaterial"; + rtnStr += "\n"; + + var isClosedStr = "false"; + if (this._isClosed) + isClosedStr = "true"; + rtnStr += "isClosed: " + isClosedStr + "\n"; + + //add the anchor points + var numAnchors = this._Anchors.length; + rtnStr += "numAnchors: " + numAnchors + "\n"; + for (var i=0;i this._BBoxMax[0]) return false; + if (y < this._BBoxMin[1]) return false; + if (y > this._BBoxMax[1]) return false; + if (z < this._BBoxMin[2]) return false; + if (z > this._BBoxMax[2]) return false; + + return true; +} + +GLSubpath.prototype.collidesWithPoint = function (x, y) { + if (x < this._BBoxMin[0]) return false; + if (x > this._BBoxMax[0]) return false; + if (y < this._BBoxMin[1]) return false; + if (y > this._BBoxMax[1]) return false; + + return true; +} + -- cgit v1.2.3