From 2092acf520e3f346f15e42c76c2f616e7d094c97 Mon Sep 17 00:00:00 2001 From: Jonathan Duran Date: Thu, 9 Feb 2012 12:10:37 -0800 Subject: Squashed commit of the following: commit ce81a3f4387d80f9ac406e73b843fb5dbe9cf432 Merge: e78f431 fba39db Author: Valerio Virgillito Date: Thu Feb 9 11:57:35 2012 -0800 Merge pull request #26 from pushkarjoshi/pentool Pentool commit e78f4312c194d9e8188075cf1fe87e4be22b24e4 Author: Valerio Virgillito Date: Thu Feb 9 11:56:40 2012 -0800 adding oneway to the 3d bindings to fix a bug where the stage was getting selected. Signed-off-by: Valerio Virgillito commit fba39dbb3bd64eddf6162fbf57232089e446fb06 Author: Pushkar Joshi Date: Thu Feb 9 10:50:05 2012 -0800 removing shaders commit fa700027b541ec8f37c55f4fe17da5f78759ebd5 Author: Pushkar Joshi Date: Wed Feb 8 16:06:37 2012 -0800 fill all paths even if they are open commit 18243deb66ab14a014756bfb0be1a52648c7771a Merge: 802e92e 0537f8f Author: Pushkar Joshi Date: Wed Feb 8 15:42:40 2012 -0800 Merge branch 'master' into pentool Conflicts: js/helper-classes/RDGE/GLWorld.js js/helper-classes/RDGE/MaterialsLibrary.js commit 802e92eb70b00849dadacf2c6590d27edbe65d99 Author: Pushkar Joshi Date: Wed Feb 8 15:39:47 2012 -0800 bug fixes for better anchor point rotation and removing snapping on hover and mouse down commit 9b6b228524f14bf65ba60aaf3d0993c8ec5bff2d Author: Pushkar Joshi Date: Tue Feb 7 15:22:11 2012 -0800 some minor bug fixes and code cleanup commit 4bbe42e6d01fd0f81d13357a75b40eae9925dda3 Merge: e7aa17a 8950b34 Author: Pushkar Joshi Date: Tue Feb 7 07:21:27 2012 -0800 Merge branch 'master' into pentool commit e7aa17a9b472640355e95c54841399f6203050d4 Author: Pushkar Joshi Date: Tue Feb 7 07:20:28 2012 -0800 don't use colorToHex function because it only works for 3D color (needs a fix to colorToHex) commit acc500d1f1c76f4e7c93ae1cfea8d925ca95e7b9 Merge: 4d4de64 4222db9 Author: Pushkar Joshi Date: Thu Feb 2 11:28:45 2012 -0800 Merge branch 'working' of c:/Code/github/emueller/ninja-internal/ into pentool commit 4d4de64472603426a73b26cc98ba8206190949b8 Merge: 0e87c02 5233508 Author: Pushkar Joshi Date: Thu Feb 2 11:19:30 2012 -0800 Merge branch 'master' into pentool commit 4222db97e353fb65fab787ba5927d16d9fa4e1f7 Author: hwc487 Date: Wed Feb 1 16:18:26 2012 -0800 Removed a console log and set the Plasma material to animating. commit 30bc466a0ac80f8303e223c19704b90457293cdc Author: hwc487 Date: Wed Feb 1 15:57:20 2012 -0800 Fixed plane orientations for view orientations other than front. commit 11db5a63bda57c630eaf1d8baded9b79ca7ac1f2 Author: hwc487 Date: Wed Feb 1 15:11:21 2012 -0800 listen for the appMouseUp event in the Pan tool commit 823945a2bcb42bbf9c6a1cd0ef723b8f415e557f Author: hwc487 Date: Wed Feb 1 14:39:46 2012 -0800 factor in the zoom factor when drawing the stage compass. commit 0e87c02e74e08c7bf156373b0d2459563e17ecd6 Author: Pushkar Joshi Date: Wed Feb 1 14:38:15 2012 -0800 make GLAnchorPoint functions as part of its prototype commit 5a288b9d3f8e6690149978d9d0e7bea98cc81312 Author: hwc487 Date: Wed Feb 1 14:09:24 2012 -0800 Fix for a marquee zoom bug. commit 715f95cacead0025a57823e4cefa22e618f15df0 Author: hwc487 Date: Wed Feb 1 14:00:06 2012 -0800 mouse wheel for zoom tool commit 62d38a080b2918a0284c854e9bf882bfeeea1e0b Author: Pushkar Joshi Date: Wed Feb 1 13:21:11 2012 -0800 avoid overriding GlGeomObj translate method commit 799369e153baf92eb10f26e91a1ab664900da8ed Merge: b2ce8b8 c0f4374 Author: hwc487 Date: Wed Feb 1 13:06:17 2012 -0800 Merge branch 'ToolFixes' of github.com:mqg734/ninja-internal into working commit b2ce8b819cc85a558d862c04965b7e65a6ce8640 Author: hwc487 Date: Wed Feb 1 13:05:32 2012 -0800 changes to allow minimal rendering ofnon-animated materials. commit ada488781ff815a827e7f5903f2c55773e3be0f3 Author: Pushkar Joshi Date: Wed Feb 1 12:16:11 2012 -0800 when selecting anchor points, first check if the selected anchor position is close enough commit 107f79288ed87a282dd52075640297cc02bdf318 Author: Pushkar Joshi Date: Wed Feb 1 12:00:44 2012 -0800 performance improvement: add most of the GLSubpath functions to its prototype commit c00d5d3072e487be200559f692ce4399222d5fa5 Author: Pushkar Joshi Date: Tue Jan 31 14:25:05 2012 -0800 handle the case of proper redraw when the alt key is held down even after mouse up commit c006b3e75d5e23da63687a04cd30bf56a3a8a80d Merge: f0e3fa6 1d8af9f Author: Pushkar Joshi Date: Tue Jan 31 12:07:43 2012 -0800 Merge branch 'master' into pentool commit f0e3fa691b3c042c9fc49a7a0cde8ddf8100c195 Author: Pushkar Joshi Date: Tue Jan 31 12:05:15 2012 -0800 display the anchor point to be selected on mouse hover commit aa1b4b78d9e1b9cc15529dbf7196b7ac8a88e260 Merge: 0b8d8b2 6066b9b Author: hwc487 Date: Tue Jan 31 10:46:48 2012 -0800 Merge branch 'ToolFixes' of github.com:mqg734/ninja-internal into working Conflicts: js/stage/stage.reel/stage.js commit 0b8d8b2eb595b64ef53440b949f3c5ec891daf8a Merge: 8e43a46 e4837ed Author: hwc487 Date: Tue Jan 31 09:22:56 2012 -0800 Merge branch 'master' of github.com:Motorola-Mobility/ninja-internal into working commit 8e43a46e3d79323fe06dc7771bc611a2c3c85c5c Author: hwc487 Date: Mon Jan 30 16:15:12 2012 -0800 Renderer startup handling of non-animated materials. Changed zoom from the document bar to keep the location center of the viewable portion of the document fixed. commit c41d2c2b749b67921f243fb7594ce0cdb1ccce36 Merge: 86a801c f129a23 Author: hwc487 Date: Mon Jan 30 16:09:00 2012 -0800 Merge branch 'staging' of github.com:Motorola-Mobility/ninja-internal into working commit 972e0ce4df7b332601ad006ca8b7dd9e189a59ef Author: Pushkar Joshi Date: Mon Jan 30 14:38:48 2012 -0800 do the fill before the stroke for the path, so the stroke width renders acc. to user specification commit da7ad067b146200847b543faf288844221dff928 Author: Pushkar Joshi Date: Mon Jan 30 14:30:31 2012 -0800 missed a couple of pen tool property files on last checkin commit 76abbaafb0d90bb1dc9c63a5a5a78ab95bb00420 Author: Pushkar Joshi Date: Mon Jan 30 13:56:33 2012 -0800 Merge pushkar branch on gerritt with github version commit 86a801c057fc3b0580d6130be5740c2ee503444f Author: hwc487 Date: Fri Jan 27 15:52:36 2012 -0800 updated from old repo Signed-off-by: Jonathan Duran --- js/helper-classes/3D/math-utils.js | 18 +- js/helper-classes/RDGE/GLAnchorPoint.js | 239 +- js/helper-classes/RDGE/GLBrushStroke.js | 7 +- js/helper-classes/RDGE/GLCircle.js | 10 +- js/helper-classes/RDGE/GLGeomObj.js | 3 + js/helper-classes/RDGE/GLMaterial.js | 29 + js/helper-classes/RDGE/GLRectangle.js | 9 +- js/helper-classes/RDGE/GLSubpath.js | 2317 ++++++++------------ js/helper-classes/RDGE/GLWorld.js | 229 +- .../RDGE/Materials/BumpMetalMaterial.js | 66 +- js/helper-classes/RDGE/Materials/FlatMaterial.js | 43 +- .../RDGE/Materials/IridescentScalesMaterial.js | 5 +- js/helper-classes/RDGE/Materials/JuliaMaterial.js | 3 + .../RDGE/Materials/KeleidoscopeMaterial.js | 3 + .../RDGE/Materials/LinearGradientMaterial.js | 4 + js/helper-classes/RDGE/Materials/MandelMaterial.js | 4 + js/helper-classes/RDGE/Materials/PlasmaMaterial.js | 2 + js/helper-classes/RDGE/Materials/PulseMaterial.js | 15 +- .../RDGE/Materials/RadialBlurMaterial.js | 3 + .../RDGE/Materials/RadialGradientMaterial.js | 188 +- js/helper-classes/RDGE/Materials/TunnelMaterial.js | 3 + js/helper-classes/RDGE/Materials/TwistMaterial.js | 3 + js/helper-classes/RDGE/Materials/UberMaterial.js | 25 +- js/helper-classes/RDGE/rdge-compiled.js | 102 +- js/helper-classes/RDGE/src/core/script/engine.js | 18 +- .../RDGE/src/core/script/init_state.js | 7 +- js/helper-classes/RDGE/src/core/script/jshader.js | 6 +- js/helper-classes/RDGE/src/core/script/renderer.js | 14 +- .../RDGE/src/core/script/run_state.js | 10 +- js/helper-classes/RDGE/src/core/script/runtime.js | 2 +- 30 files changed, 1609 insertions(+), 1778 deletions(-) (limited to 'js/helper-classes') diff --git a/js/helper-classes/3D/math-utils.js b/js/helper-classes/3D/math-utils.js index 71ed62a0..3d24f76e 100644 --- a/js/helper-classes/3D/math-utils.js +++ b/js/helper-classes/3D/math-utils.js @@ -802,19 +802,21 @@ var MathUtilsClass = exports.MathUtilsClass = Object.create(Object.prototype, { getAxisAngleBetween3DVectors: { value: function (vec1, vec2, axis) { //compute magnitudes of the vectors - var mag1 = VecUtils.vecMag(3, vec1); - var mag2 = VecUtils.vecMag(3, vec2); - - if (mag1 < this.EPSILON || mag2 < this.EPSILON) { - return 0; //if angle 0 is returned nothing from this function should be used - } + var v1n = VecUtils.vecNormalize(3, vec1, 1.0); + var v2n = VecUtils.vecNormalize(3, vec2, 1.0); //angle between the vectors (acos for now...) - var angle = Math.acos(VecUtils.vecDot(3, vec1, vec2) / (mag1 * mag2)); + var angle = Math.acos(VecUtils.vecDot(3, v1n, v2n)); if (Math.abs(angle) < this.EPSILON) { return 0; } + //TODO testing...remove this block + console.log("getAxisAngleBetween3DVectors Angle: "+angle); + if (isNaN(angle)){ + console.log("getAxisAngleBetween3DVectors Angle is NaN"); + } + //TODO end testing block //optionally, if axis is provided, create the axis of rotation as well - var rotAxis = VecUtils.vecCross(3, vec1, vec2); + var rotAxis = VecUtils.vecCross(3, v1n, v2n); rotAxis = VecUtils.vecNormalize(3, rotAxis, 1); axis[0] = rotAxis[0]; axis[1] = rotAxis[1]; diff --git a/js/helper-classes/RDGE/GLAnchorPoint.js b/js/helper-classes/RDGE/GLAnchorPoint.js index 496b6f60..716f59d4 100644 --- a/js/helper-classes/RDGE/GLAnchorPoint.js +++ b/js/helper-classes/RDGE/GLAnchorPoint.js @@ -26,125 +26,136 @@ function GLAnchorPoint() { this._nextX = 0.0; this._nextY = 0.0; this._nextZ = 0.0; - +} // *********** setters ************ - this.setPos = function (x, y, z) { this._x = x; this._y = y; this._z = z; } - this.setPrevPos = function (x, y, z) { this._prevX = x; this._prevY = y; this._prevZ = z; } - this.setNextPos = function (x, y, z) { this._nextX = x; this._nextY = y; this._nextZ = z; } - - this.setPrevFromNext = function () { - //set the previous control point by reflecting the next control point - var dispX = this._nextX - this._x; - var dispY = this._nextY - this._y; - var dispZ = this._nextZ - this._z; - - this._prevX = this._x - dispX; - this._prevY = this._y - dispY; - this._prevZ = this._z - dispZ; - } - this.setNextFromPrev = function () { - //set the previous control point by reflecting the next control point - var dispX = this._prevX - this._x; - var dispY = this._prevY - this._y; - var dispZ = this._prevZ - this._z; - - this._nextX = this._x - dispX; - this._nextY = this._y - dispY; - this._nextZ = this._z - dispZ; - } +GLAnchorPoint.prototype.setPos = function (x, y, z) { this._x = x; this._y = y; this._z = z; } +GLAnchorPoint.prototype.setPrevPos = function (x, y, z) { this._prevX = x; this._prevY = y; this._prevZ = z; } +GLAnchorPoint.prototype.setNextPos = function (x, y, z) { this._nextX = x; this._nextY = y; this._nextZ = z; } - //translate the next point from the translation that was applied to the prev. point - this.translateNextFromPrev = function (tx, ty, tz) { - // *** compute the rotation of the prev vector *** - var oldP = Vector.create([this._prevX + tx - this._x, this._prevY + ty - this._y, this._prevZ + tz - this._z]); - var newP = Vector.create([this._prevX - this._x, this._prevY - this._y, this._prevZ - this._z]); - //compute angle between the two vectors - var axis = Vector.create([0, 0, 0]); - var angle = MathUtils.getAxisAngleBetween3DVectors(oldP, newP, axis); - if (angle === 0) - return; - - // *** compute the vector from anchor to next - var oldN = Vector.create([this._nextX - this._x, this._nextY - this._y, this._nextZ - this._z]); - var rotMat = Matrix.Rotation(-angle, axis); - var newN = MathUtils.transformVector(oldN, rotMat); - - //TEMP for some situations the axis angle computation returns NaNs - if (isNaN(newN[0]) || isNaN(newN[1]) || isNaN(newN[2])) { - return; - } - //end TEMP - this._nextX = this._x + newN[0]; - this._nextY = this._y + newN[1]; - this._nextZ = this._z + newN[2]; - } - //translate the next point from the translation that was applied to the prev. point - this.translatePrevFromNext = function (tx, ty, tz) { - // *** compute the rotation of the next vector *** - var oldN = Vector.create([this._nextX + tx - this._x, this._nextY + ty - this._y, this._nextZ + tz - this._z]); - var newN = Vector.create([this._nextX - this._x, this._nextY - this._y, this._nextZ - this._z]); - //compute angle between the two vectors - var axis = Vector.create([0, 0, 0]); - var angle = MathUtils.getAxisAngleBetween3DVectors(oldN, newN, axis); - if (angle === 0) - return; - - // *** compute the vector from anchor to prev - var oldP = Vector.create([this._prevX - this._x, this._prevY - this._y, this._prevZ - this._z]); - var rotMat = Matrix.Rotation(-angle, axis); - var newP = MathUtils.transformVector(oldP, rotMat); - - //TEMP for some situations the axis angle computation returns NaNs - if (isNaN(newP[0]) || isNaN(newP[1]) || isNaN(newP[2])) { - return; - } - //end TEMP - this._prevX = this._x + newP[0]; - this._prevY = this._y + newP[1]; - this._prevZ = this._z + newP[2]; - } +GLAnchorPoint.prototype.setPrevFromNext = function () { + //set the previous control point by reflecting the next control point + var dispX = this._nextX - this._x; + var dispY = this._nextY - this._y; + var dispZ = this._nextZ - this._z; + this._prevX = this._x - dispX; + this._prevY = this._y - dispY; + this._prevZ = this._z - dispZ; +} +GLAnchorPoint.prototype.setNextFromPrev = function () { + //set the previous control point by reflecting the next control point + var dispX = this._prevX - this._x; + var dispY = this._prevY - this._y; + var dispZ = this._prevZ - this._z; - // ******* modifiers ******* - this.translatePrev = function (x, y, z) { - this._prevX += x; this._prevY += y; this._prevZ += z; - } - this.translateNext = function (x, y, z) { - this._nextX += x; this._nextY += y; this._nextZ += z; - } - this.translate = function (x, y, z) { - this._x += x; this._y += y; this._z += z; - } - this.translateAll = function (x, y, z) { - this.translate(x, y, z); - this.translatePrev(x, y, z); - this.translateNext(x, y, z); - } - + this._nextX = this._x - dispX; + this._nextY = this._y - dispY; + this._nextZ = this._z - dispZ; +} + +//translate the next point from the translation that was applied to the prev. point +GLAnchorPoint.prototype.translateNextFromPrev = function (tx, ty, tz) { + //do nothing if the total translation is zero + var totalTransSq = (tx*tx) + (ty*ty) + (tz*tz); + if (totalTransSq < 0.0000001) + return; - // ********* getters ********** - this.getPosX = function () { return this._x; } - this.getPosY = function () { return this._y; } - this.getPosZ = function () { return this._z; } - this.getPrevX = function () { return this._prevX; } - this.getPrevY = function () { return this._prevY; } - this.getPrevZ = function () { return this._prevZ; } - this.getNextX = function () { return this._nextX; } - this.getNextY = function () { return this._nextY; } - this.getNextZ = function () { return this._nextZ; } - this.getPos = function() { return Vector.create([this._x, this._y, this._z]);} - this.getPrev = function() { return Vector.create([this._prevX, this._prevY, this._prevZ]);} - this.getNext = function() { return Vector.create([this._nextX, this._nextY, this._nextZ]);} - //return the square of distance from passed in point to the anchor position - this.getDistanceSq = function (x, y, z) { - return (this._x - x) * (this._x - x) + (this._y - y) * (this._y - y) + (this._z - z) * (this._z - z); - } - //return sq. of distance to prev. - this.getPrevDistanceSq = function (x, y, z) { - return (this._prevX - x) * (this._prevX - x) + (this._prevY - y) * (this._prevY - y) + (this._prevZ - z) * (this._prevZ - z); + // *** compute the rotation of the prev vector *** + var oldP = Vector.create([this._prevX + tx - this._x, this._prevY + ty - this._y, this._prevZ + tz - this._z]); + var newP = Vector.create([this._prevX - this._x, this._prevY - this._y, this._prevZ - this._z]); + //compute angle between the two vectors + var axis = Vector.create([0, 0, 0]); + var angle = MathUtils.getAxisAngleBetween3DVectors(oldP, newP, axis); + if (angle === 0) + return; + + // *** compute the vector from anchor to next + var oldN = Vector.create([this._nextX - this._x, this._nextY - this._y, this._nextZ - this._z]); + var rotMat = Matrix.Rotation(-angle, axis); + var newN = MathUtils.transformVector(oldN, rotMat); + + //TEMP for some situations the axis angle computation returns NaNs + if (isNaN(newN[0]) || isNaN(newN[1]) || isNaN(newN[2])) { + console.log("NaN in translateNextFromPrev"); + return; } - //return sq. of distance to next - this.getNextDistanceSq = function (x, y, z) { - return (this._nextX - x) * (this._nextX - x) + (this._nextY - y) * (this._nextY - y) + (this._nextZ - z) * (this._nextZ - z); + //end TEMP + this._nextX = this._x + newN[0]; + this._nextY = this._y + newN[1]; + this._nextZ = this._z + newN[2]; +} +//translate the next point from the translation that was applied to the prev. point +GLAnchorPoint.prototype.translatePrevFromNext = function (tx, ty, tz) { + //do nothing if the total translation is zero + var totalTransSq = (tx*tx) + (ty*ty) + (tz*tz); + if (totalTransSq < 0.0000001) + return; + + // *** compute the rotation of the next vector *** + var oldN = Vector.create([this._nextX + tx - this._x, this._nextY + ty - this._y, this._nextZ + tz - this._z]); + var newN = Vector.create([this._nextX - this._x, this._nextY - this._y, this._nextZ - this._z]); + //compute angle between the two vectors + var axis = Vector.create([0, 0, 0]); + var angle = MathUtils.getAxisAngleBetween3DVectors(oldN, newN, axis); + if (angle === 0) + return; + + // *** compute the vector from anchor to prev + var oldP = Vector.create([this._prevX - this._x, this._prevY - this._y, this._prevZ - this._z]); + var rotMat = Matrix.Rotation(-angle, axis); + var newP = MathUtils.transformVector(oldP, rotMat); + + //TEMP for some situations the axis angle computation returns NaNs + if (isNaN(newP[0]) || isNaN(newP[1]) || isNaN(newP[2])) { + return; } + //end TEMP + this._prevX = this._x + newP[0]; + this._prevY = this._y + newP[1]; + this._prevZ = this._z + newP[2]; +} + + +// ******* modifiers ******* +GLAnchorPoint.prototype.translatePrev = function (x, y, z) { + this._prevX += x; this._prevY += y; this._prevZ += z; +} +GLAnchorPoint.prototype.translateNext = function (x, y, z) { + this._nextX += x; this._nextY += y; this._nextZ += z; } +GLAnchorPoint.prototype.translate = function (x, y, z) { + this._x += x; this._y += y; this._z += z; +} +GLAnchorPoint.prototype.translateAll = function (x, y, z) { + this.translate(x, y, z); + this.translatePrev(x, y, z); + this.translateNext(x, y, z); +} + + +// ********* getters ********** +GLAnchorPoint.prototype.getPosX = function () { return this._x; } +GLAnchorPoint.prototype.getPosY = function () { return this._y; } +GLAnchorPoint.prototype.getPosZ = function () { return this._z; } +GLAnchorPoint.prototype.getPrevX = function () { return this._prevX; } +GLAnchorPoint.prototype.getPrevY = function () { return this._prevY; } +GLAnchorPoint.prototype.getPrevZ = function () { return this._prevZ; } +GLAnchorPoint.prototype.getNextX = function () { return this._nextX; } +GLAnchorPoint.prototype.getNextY = function () { return this._nextY; } +GLAnchorPoint.prototype.getNextZ = function () { return this._nextZ; } +GLAnchorPoint.prototype.getPos = function() { return Vector.create([this._x, this._y, this._z]);} +GLAnchorPoint.prototype.getPrev = function() { return Vector.create([this._prevX, this._prevY, this._prevZ]);} +GLAnchorPoint.prototype.getNext = function() { return Vector.create([this._nextX, this._nextY, this._nextZ]);} +//return the square of distance from passed in point to the anchor position +GLAnchorPoint.prototype.getDistanceSq = function (x, y, z) { + return (this._x - x) * (this._x - x) + (this._y - y) * (this._y - y) + (this._z - z) * (this._z - z); +} +//return sq. of distance to prev. +GLAnchorPoint.prototype.getPrevDistanceSq = function (x, y, z) { + return (this._prevX - x) * (this._prevX - x) + (this._prevY - y) * (this._prevY - y) + (this._prevZ - z) * (this._prevZ - z); +} +//return sq. of distance to next +GLAnchorPoint.prototype.getNextDistanceSq = function (x, y, z) { + return (this._nextX - x) * (this._nextX - x) + (this._nextY - y) * (this._nextY - y) + (this._nextZ - z) * (this._nextZ - z); +} + diff --git a/js/helper-classes/RDGE/GLBrushStroke.js b/js/helper-classes/RDGE/GLBrushStroke.js index e3b14bf7..fdf1595c 100644 --- a/js/helper-classes/RDGE/GLBrushStroke.js +++ b/js/helper-classes/RDGE/GLBrushStroke.js @@ -4,10 +4,9 @@ No rights, expressed or implied, whatsoever to this software are provided by Mot (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. */ -// Todo: This shoudl be converted to a module +// Todo: This entire class should be converted to a module var VecUtils = require("js/helper-classes/3D/vec-utils").VecUtils; - /////////////////////////////////////////////////////////////////////// // Class GLBrushStroke // representation a sequence points (polyline) created by brush tool. @@ -141,6 +140,10 @@ function GLBrushStroke() { this._dirty = false; } + this.buildBuffers = function () { + return; //no need to do anything for now + }//buildBuffers() + //render // specify how to render the subpath in Canvas2D this.render = function () { diff --git a/js/helper-classes/RDGE/GLCircle.js b/js/helper-classes/RDGE/GLCircle.js index e6bcba89..942eb528 100644 --- a/js/helper-classes/RDGE/GLCircle.js +++ b/js/helper-classes/RDGE/GLCircle.js @@ -55,14 +55,16 @@ function GLCircle() this.m_world = world; + if(strokeMaterial) - { this._strokeMaterial = strokeMaterial; - } + else + this._strokeMaterial = new FlatMaterial(); + if(fillMaterial) - { this._fillMaterial = fillMaterial; - } + else + this._fillMaterial = new FlatMaterial(); } /////////////////////////////////////////////////////////////////////// diff --git a/js/helper-classes/RDGE/GLGeomObj.js b/js/helper-classes/RDGE/GLGeomObj.js index 62fbf562..5d7497ad 100644 --- a/js/helper-classes/RDGE/GLGeomObj.js +++ b/js/helper-classes/RDGE/GLGeomObj.js @@ -103,6 +103,9 @@ function GLGeomObj() } } } + + var world = this.getWorld(); + if (world) world.restartRenderLoop(); } this.setFillColor = function(c) { this.setMaterialColor(c, "fill"); } diff --git a/js/helper-classes/RDGE/GLMaterial.js b/js/helper-classes/RDGE/GLMaterial.js index 51c27ace..c633f679 100644 --- a/js/helper-classes/RDGE/GLMaterial.js +++ b/js/helper-classes/RDGE/GLMaterial.js @@ -62,6 +62,10 @@ function GLMaterial( world ) this.getShader = function() { return this._shader; } this.getMaterialNode = function() { return this._materialNode; } + // a material can be animated or not. default is not. + // Any material needing continuous rendering should override this method + this.isAnimated = function() { return false; } + /////////////////////////////////////////////////////////////////////// // Common Material Methods @@ -174,6 +178,31 @@ function GLMaterial( world ) // animated materials should implement the update method } + this.registerTexture = function( texture ) + { + // the world needs to know about the texture map + var world = this.getWorld(); + if (!world) + console.log( "**** world not defined for registering texture map: " + texture.lookUpName ); + else + world.textureToLoad( texture ); + } + + this.loadTexture = function( texMapName, wrap, mips ) + { + var tex; + var world = this.getWorld(); + if (!world) + console.log( "world not defined for material with texture map" ); + else + { + var renderer = world.getRenderer(); + tex = renderer.getTextureByName(texMapName, wrap, mips ); + this.registerTexture( tex ); + } + return tex; + } + this.export = function() { // this function should be overridden by subclasses diff --git a/js/helper-classes/RDGE/GLRectangle.js b/js/helper-classes/RDGE/GLRectangle.js index 8535a683..871e9ae4 100644 --- a/js/helper-classes/RDGE/GLRectangle.js +++ b/js/helper-classes/RDGE/GLRectangle.js @@ -72,13 +72,14 @@ function GLRectangle() this._materialSpecular = [0.4, 0.4, 0.4, 1.0]; if(strokeMaterial) - { this._strokeMaterial = strokeMaterial; - } + else + this._strokeMaterial = new FlatMaterial(); + if(fillMaterial) - { this._fillMaterial = fillMaterial; - } + else + this._fillMaterial = new FlatMaterial(); } /////////////////////////////////////////////////////////////////////// diff --git a/js/helper-classes/RDGE/GLSubpath.js b/js/helper-classes/RDGE/GLSubpath.js index 55b7e49a..3200cf59 100644 --- a/js/helper-classes/RDGE/GLSubpath.js +++ b/js/helper-classes/RDGE/GLSubpath.js @@ -4,7 +4,7 @@ No rights, expressed or implied, whatsoever to this software are provided by Mot (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. */ -// Todo: This shoudl be converted to a module +// Todo: This entire class should be converted to a module var VecUtils = require("js/helper-classes/3D/vec-utils").VecUtils; @@ -35,6 +35,7 @@ function SegmentIntersections(){ // representation a sequence of cubic bezier curves. // Derived from class GLGeomObj /////////////////////////////////////////////////////////////////////// + function GLSubpath() { /////////////////////////////////////////////////// // Instance variables @@ -50,14 +51,6 @@ function GLSubpath() { this._UnprojectedAnchors = []; - //offset path samples and the points on the input path they map to - this._offsetPointsLeft = []; - this._offsetPointsRight = []; - - //triangles determined by the offset points - this._offsetTrianglesLeft = []; - this._offsetTrianglesRight = []; - //initially set the _dirty bit so we will construct samples this._dirty = true; @@ -88,7 +81,6 @@ function GLSubpath() { this._planeMatInv = null; this._planeCenter = null; - // initialize the inherited members this.inheritedFrom = GLGeomObj; this.inheritedFrom(); @@ -105,681 +97,545 @@ function GLSubpath() { 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 - ///////////////////////////////////////////////////////// - // Property Accessors/Setters - ///////////////////////////////////////////////////////// - this.setWorld = function (world) { this._world = world; } - this.getWorld = function () { return this._world; } - this.makeDirty = function () {this._dirty = true;} - this.geomType = function () { return this.GEOM_TYPE_CUBIC_BEZIER; } - this.setDrawingTool = function (tool) {this._drawingTool = tool;} - this.getDrawingTool = function () {return this._drawingTool;} - this.setPlaneMatrix = function(planeMat){this._planeMat = planeMat;} - this.setPlaneMatrixInverse = function(planeMatInv){this._planeMatInv = planeMatInv;} - this.setPlaneCenter = function(pc){this._planeCenter = pc;} - - this.getCanvasX = function(){return this._canvasX;} - this.getCanvasY = function(){return this._canvasY;} - this.setCanvasX = function(cx){this._canvasX=cx;} - this.setCanvasY = function(cy){this._canvasY=cy;} - - this.getIsClosed = function () {return this._isClosed;} - this.setIsClosed = function (isClosed) { - if (this._isClosed !== isClosed) { - this._isClosed = isClosed; - this._dirty = true; - } - } - this.getNumAnchors = function () { return this._Anchors.length; } - this.getAnchor = function (index) { return this._Anchors[index]; } - this.addAnchor = function (anchorPt) { - this._Anchors.push(anchorPt); - this._selectedAnchorIndex = this._Anchors.length-1; - this._dirty = true; - } + // (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() - this.insertAnchor = function(anchorPt, index){ - this._Anchors.splice(index, 0, anchorPt); - } + //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" ); - //remove and return anchor at specified index, return null on error - this.removeAnchor = function (index) { - var retAnchor = null; - if (index < this._Anchors.length) { - retAnchor = this._Anchors.splice(index, 1); - this._dirty = true; - } - //deselect the removed anchor if necessary - if (this._selectedAnchorIndex === index){ - this._selectedAnchorIndex = -1; - } - return retAnchor; - } + // get the context + var ctx = world.get2DContext(); + if (!ctx) throw ("null context in subpath render") - //remove all the anchor points - this.clearAllAnchors = function () { - this._Anchors = []; - this._isClosed = false; - this._dirty = true; - } + var numAnchors = this.getNumAnchors(); + if (numAnchors === 0) + return; //nothing to do for empty paths - this.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; + ctx.save(); - //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); + 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])]); - var P0P1P2 = VecUtils.vecInterpolate(3, P0P1, P1P2, param); - var P1P2P3 = VecUtils.vecInterpolate(3, P1P2, P2P3, param); - var anchorPos = VecUtils.vecInterpolate(3, P0P1P2, P1P2P3, param); + ctx.clearRect(0, 0, bboxWidth, bboxHeight); - //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]); + 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(); - 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]); + /* + 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(); } + */ - //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]); + var numPoints = this._samples.length/3; + ctx.moveTo(this._samples[0]-bboxMin[0],this._samples[1]-bboxMin[1]); + for (var i=0;i 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; - } - } +GLSubpath.prototype.insertAnchor = function(anchorPt, index){ + this._Anchors.splice(index, 0, anchorPt); +} - //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; - } - } +//remove and return anchor at specified index, return null on error +GLSubpath.prototype.removeAnchor = function (index) { + var retAnchor = null; + if (index < this._Anchors.length) { + retAnchor = this._Anchors.splice(index, 1); + this._dirty = true; + } + //deselect the removed anchor + this._selectedAnchorIndex = -1; + return retAnchor; +} - //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); +GLSubpath.prototype.deselectAnchorPoint = function(){ + this._selectedAnchorIndex = -1; +} - var C0__ = VecUtils.vecInterpolate(3, C0_, C1_, 0.5); - var C1__ = VecUtils.vecInterpolate(3, C1_, C2_, 0.5); +GLSubpath.prototype.reversePath = function() { + var revAnchors = []; + var numAnchors = this._Anchors.length; + var lastIndex = numAnchors-1; + if (lastIndex<0){ + return; //cannot reverse empty path + } + for (var i=lastIndex;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; +} - var C0___ = VecUtils.vecInterpolate(3, C0__, C1__, 0.5); +//remove all the anchor points +GLSubpath.prototype.clearAllAnchors = function () { + this._Anchors = []; + this._isClosed = false; + this._dirty = true; +} - //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; - } +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]); + } - //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; - } + 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]); + } - //no intersection, so return null - return null; + //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]); } - //whether the point lies within the bbox given by the four control points - this._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]; - } - } + //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]+radius)){ - return false; + if (controlPts[i][d] > bboxMax[d]){ + bboxMax[d] = controlPts[i][d]; } } - return true; } - - //pick the path point closest to the specified location, return null if some anchor point (or its handles) is within radius, else return the parameter distance - this.pickPath = 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; - for (var i = 0; i < numAnchors; i++) { - var distSq = this._Anchors[i].getDistanceSq(pickX, pickY, pickZ); - //check the anchor point - if (distSq < minDistance && distSq < radSq) { - selAnchorIndex = i; - minDistance = distSq; - retCode = retCode | this.SEL_ANCHOR; - } - }//for every anchor i - - //check the prev and next of the selected anchor if the above did not register a hit - if (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 (bboxMax[d]+radius)){ + return null; } - this.setIsClosed(subpath.getIsClosed()); - this.setStrokeWidth(subpath.getStrokeWidth()); } - this.translate = function (tx, ty, tz) { - for (var i=0;iradius) + 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; } - this._dirty = true; } - // _cleanupOffsetSamples (offSamples) - // removes retrograde segments of the offset path samples - // returns the cleaned up offset samples - this._cleanupOffsetSamples = function (offSamples, width) { - var retOffSamples = []; - var numSamples = offSamples.length; - var keepOffSample = []; - for (var i = 0; i < numSamples; i++) { - keepOffSample.push(true); - } - + //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); - //NOTE: this is very slow O(n^2) for now...testing only - //remove any sample that's less than 'width' far from any other boundary segment - for (var i = 0; i < numSamples; i++) { - //build the current offset point - var O = Vector.create([offSamples[i].Pos[0], offSamples[i].Pos[1], offSamples[i].Pos[2]]); - - //iterate over all the path segments - var numPoints = this._samples.length / 3; - for (var j = 0; j < numPoints - 1; j++) { - var C0 = Vector.create([this._samples[3 * j], this._samples[3 * j + 1], this._samples[3 * j + 2]]); //segment startpoint - var C1 = Vector.create([this._samples[3 * (j + 1)], this._samples[3 * (j + 1) + 1], this._samples[3 * (j + 1) + 2]]); //segment endpoint - var distToSeg = MathUtils.distPointToSegment(O, C0, C1); - if (width - distToSeg > 1) { //if the distance is smaller than the width - keepOffSample[i] = false; - break; - } //if (width - distToC > 1 ) { //if the distance is substantially smaller than the width - } //for (var j=0;jstartIndex+1 intersects the segment from endIndex-1->endIndex - var seg0Start = Vector.create([offSamples[startIndex].Pos[0],offSamples[startIndex].Pos[1],offSamples[startIndex].Pos[2]]); - var seg0End = Vector.create([offSamples[startIndex + 1].Pos[0],offSamples[startIndex + 1].Pos[1],offSamples[startIndex + 1].Pos[2]]); - var seg1Start = Vector.create([offSamples[endIndex - 1].Pos[0],offSamples[endIndex - 1].Pos[1],offSamples[endIndex - 1].Pos[2]]); - var seg1End = Vector.create([offSamples[endIndex].Pos[0],offSamples[endIndex].Pos[1],offSamples[endIndex].Pos[2]]); + //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; +} - if (seg0Start.length===0 || seg0End.length ===0 || seg1Start.length===0 ||seg1End.length ===0){ - alert("empty offset point"); +//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]; } - - } //for (var i = 0; i < numSamples; i++) { - - - - return retOffSamples; + } } - - // _triangulateOffset - // generate triangles from offset points and add