diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index dae180dad7..6d6876f81b 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -144,16 +144,37 @@ void RenderablePolyLineEntityItem::updateGeometry() { float uCoord, vCoord; uCoord = 0.0f; float uCoordInc = 1.0 / (_vertices.size() / 2); - float accumulatedDistance = 0; - float distanceToLastPoint = 0; + float accumulatedDistance = 0.0f; + float distanceToLastPoint = 0.0f; + float accumulatedStrokeWidth = 0.0f; + bool doesStrokeWidthVary = false; + + for (int i = 0; i < _strokeWidths.size(); i++) { + if (i > 1 && _strokeWidths[i] != _strokeWidths[i - 1]) { + doesStrokeWidthVary = true; + break; + } + } for (int i = 0; i < _vertices.size() / 2; i++) { vCoord = 0.0f; if (!_isUVModeStretch && vertexIndex > 2) { - distanceToLastPoint = glm::abs(glm::distance(_vertices.at(vertexIndex), _vertices.at(vertexIndex - 2))); - float strokeWidth = i > 1 ? _strokeWidths[i] : (_strokeWidths[i - 2] + _strokeWidths[i - 1]) / 2; - uCoord = (_textureAspectRatio * (accumulatedDistance + distanceToLastPoint)) / strokeWidth; + distanceToLastPoint = glm::distance(_vertices.at(vertexIndex), _vertices.at(vertexIndex - 2)); + if (doesStrokeWidthVary) { + //If the stroke varies along the line the texture will stretch more or less depending on the speed + //because it looks better than using the same method as below + accumulatedStrokeWidth += 2 * _strokeWidths[i]; + float strokeWidth = 2 * _strokeWidths[i]; + float newUcoord = glm::ceil((_textureAspectRatio * (accumulatedDistance + distanceToLastPoint)) / (accumulatedStrokeWidth / i)); + float increaseValue = newUcoord - uCoord; + increaseValue = increaseValue > 0 ? increaseValue : 1; + uCoord += increaseValue; + } else { + //If the stroke width is constant then the textures should keep the aspect ratio along the line + uCoord = (_textureAspectRatio * (accumulatedDistance + distanceToLastPoint)) / (2 * _strokeWidths[i]); + } + accumulatedDistance += distanceToLastPoint; } @@ -183,6 +204,7 @@ void RenderablePolyLineEntityItem::updateGeometry() { } */ } + _pointsChanged = false; _normalsChanged = false; _strokeWidthsChanged = false; diff --git a/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicBrush.js b/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicBrush.js index 0cecd214f6..b4c3f5a6ae 100644 --- a/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicBrush.js +++ b/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicBrush.js @@ -10,27 +10,28 @@ function DynamicBrushClass() {} * @param fingerOverlayID: the id of the overlay that shows over the finger when using fingerpaint */ DynamicBrushClass.prototype.onUpdate = function(deltaSeconds, entityIDs) { - //To be implemented on the child + //To be implemented on the child throw "Abstract method onUpdate not implemented"; } /** * This function updates the user data so in the next frame the animation gets the previous values. - * + * * @param entityID: the id of the polyline being animated * @param dynamicBrushObject: the animation object (should be a subclass of dynamicBrush) */ DynamicBrushClass.prototype.updateUserData = function(entityID, dynamicBrushObject) { - //print("Saving class " + dynamicBrushObject.NAME); - var prevUserData = Entities.getEntityProperties(entityID).userData; - if (prevUserData) { - prevUserData = prevUserData == "" ? new Object() : JSON.parse(prevUserData); //preserve other possible user data - if (prevUserData.animations != null && prevUserData.animations[dynamicBrushObject.NAME] != null) { - delete prevUserData.animations[dynamicBrushObject.NAME]; - prevUserData.animations[dynamicBrushObject.NAME] = dynamicBrushObject; - } - Entities.editEntity(entityID, {userData: JSON.stringify(prevUserData)}); - } + //print("Saving class " + dynamicBrushObject.NAME); + var prevUserData = Entities.getEntityProperties(entityID).userData; + if (prevUserData) { + prevUserData = prevUserData == "" ? new Object() : JSON.parse(prevUserData); //preserve other possible user data + if (prevUserData.animations != null && prevUserData.animations[dynamicBrushObject.NAME] != null) { + delete prevUserData.animations[dynamicBrushObject.NAME]; + prevUserData.animations[dynamicBrushObject.NAME] = dynamicBrushObject; + } + prevUserData.timeFromLastAnimation = Date.now(); + Entities.editEntity(entityID, {userData: JSON.stringify(prevUserData)}); + } } DynamicBrush = DynamicBrushClass; diff --git a/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicBrushScript.js b/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicBrushScript.js index 8f3ce58beb..4a9331aeaf 100644 --- a/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicBrushScript.js +++ b/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicBrushScript.js @@ -1,64 +1,34 @@ -(function() { - Script.include("dynamicBrushesList.js"); - var UPDATE_TIME = 33; //run at aproximatelly 30fps +(function() { + Script.include("dynamicBrushesList.js"); + var UPDATE_TIME = 33; //run at aproximatelly 30fps var self = this; this.preload = function(entityID) { - print("After adding script 2 : " + JSON.stringify(Entities.getEntityProperties(entityID))); - self.intervalID = Script.setInterval(function() { - if (Vec3.withinEpsilon(MyAvatar.position, Entities.getEntityProperties(entityID).position, 3)) { - var userData = Entities.getEntityProperties(entityID).userData; - //print("UserData: " + userData); - - if (userData) { - var userDataObject = JSON.parse(userData); - var animationObject = userDataObject.animations; - //print("Playing animation " + JSON.stringify(animationObject)); - var newAnimationObject = null; - Object.keys(animationObject).forEach(function(animationName) { - newAnimationObject = animationObject[animationName]; - //print("Proto 0001: " + JSON.stringify(newAnimationObject)); - newAnimationObject.__proto__ = DynamicBrushesInfo[animationName].proto; - newAnimationObject.onUpdate(UPDATE_TIME, entityID); - }); - } - } - }, UPDATE_TIME); + //print("After adding script 2 : " + JSON.stringify(Entities.getEntityProperties(entityID))); + + self.intervalID = Script.setInterval(function() { + if (Vec3.withinEpsilon(MyAvatar.position, Entities.getEntityProperties(entityID).position, 3)) { + var userData = Entities.getEntityProperties(entityID).userData; + //print("UserData: " + userData); + if (userData) { + var userDataObject = JSON.parse(userData); + var animationObject = userDataObject.animations; + //print("Playing animation " + JSON.stringify(animationObject)); + var newAnimationObject = null; + if (!userDataObject.timeFromLastAnimation) { + userDataObject.timeFromLastAnimation = Date.now(); + } + Object.keys(animationObject).forEach(function(animationName) { + newAnimationObject = animationObject[animationName]; + //print("Proto 0001: " + JSON.stringify(newAnimationObject)); + newAnimationObject.__proto__ = DynamicBrushesInfo[animationName].proto; + //print("time from last draw " + (Date.now() - userDataObject.animations.timeFromLastDraw)); + newAnimationObject.onUpdate(Date.now() - userDataObject.timeFromLastAnimation, entityID); + }); + } + } + }, UPDATE_TIME); }; - this.unload = function() { - Script.clearInterval(self.intervalID); - } + this.unload = function() { + Script.clearInterval(self.intervalID); + } }); -/* -(function() { - Script.include("dynamicBrushesList.js"); - var UPDATE_TIME = 10; - var self = this; - this.preload = function(entityID) { - Script.setTimeout(playAnimations, UPDATE_TIME); - function playAnimations() { - var userData = Entities.getEntityProperties(entityID).userData; - //print("UserData: " + userData); - - if (userData) { - var userDataObject = JSON.parse(userData); - var animationObject = userDataObject.animations; - //print("Playing animation " + JSON.stringify(animationObject)); - var newAnimationObject = null; - Object.keys(animationObject).forEach(function(animationName) { - newAnimationObject = animationObject[animationName]; - //print("Proto 0001: " + JSON.stringify(newAnimationObject)); - newAnimationObject.__proto__ = DynamicBrushesInfo[animationName].proto; - if (userDataObject.isDrawing) { - newAnimationObject.onDraw(UPDATE_TIME, entityID, null); - } else { - newAnimationObject.onUpdate(UPDATE_TIME, entityID, null); - } - }); - } - Script.setTimeout(playAnimations, UPDATE_TIME); - } - }; -});*/ - - - diff --git a/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicBrushesList.js b/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicBrushesList.js index 672d5e6e98..03de3e113c 100644 --- a/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicBrushesList.js +++ b/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicBrushesList.js @@ -4,33 +4,33 @@ Script.include("dynamicTranslationBrush.js"); DynamicBrushesInfo = { DynamicHueBrush: { - isEnabled: false, - proto: DynamicHueBrush.prototype, - settings: null, + isEnabled: false, + proto: DynamicHueBrush.prototype, + settings: null, }, DynamicRotationBrush: { - isEnabled: false, - proto: DynamicRotationBrush.prototype, - settings: null, + isEnabled: false, + proto: DynamicRotationBrush.prototype, + settings: null, }, DynamicTranslationBrush: { - isEnabled: false, - proto: DynamicTranslationBrush.prototype, - settings: null, + isEnabled: false, + proto: DynamicTranslationBrush.prototype, + settings: null, }, } dynamicBrushFactory = function(dynamicBrushName, settings) { switch (dynamicBrushName) { - case "DynamicHueBrush": - return new DynamicHueBrush(settings); - case "DynamicRotationBrush": - return new DynamicRotationBrush(settings); - case "DynamicTranslationBrush": - return new DynamicTranslationBrush(settings); - default: - throw new Error("Could not instantiate " + dynamicBrushName); + case "DynamicHueBrush": + return new DynamicHueBrush(settings); + case "DynamicRotationBrush": + return new DynamicRotationBrush(settings); + case "DynamicTranslationBrush": + return new DynamicTranslationBrush(settings); + default: + throw new Error("Could not instantiate " + dynamicBrushName); } } \ No newline at end of file diff --git a/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicHueBrush.js b/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicHueBrush.js index 7f182be7ad..cf19e9bd34 100644 --- a/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicHueBrush.js +++ b/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicHueBrush.js @@ -2,11 +2,11 @@ Script.include("dynamicBrush.js"); function DynamicHueBrushClass(settings) { - //dynamic brush vars - DynamicBrush.call(this); - print("Starting dynamic hue brush"); - this.hsvColor = {hue: 0, saturation: 1.0, value: 1.0}; - this.dynamicColor = {red: 0, green: 0, blue: 0}; + //dynamic brush vars + DynamicBrush.call(this); + //print("Starting dynamic hue brush"); + this.hsvColor = {hue: 0, saturation: 1.0, value: 1.0}; + this.dynamicColor = {red: 0, green: 0, blue: 0}; } DynamicHueBrushClass.prototype.DYNAMIC_BRUSH_TIME = 10; //inteval in milliseconds to update the brush width; @@ -14,7 +14,7 @@ DynamicHueBrushClass.prototype.DYNAMIC_BRUSH_INCREMENT = 0.5; //linear increment DynamicHueBrushClass.prototype.NAME = "DynamicHueBrush"; //linear increment of brush size; DynamicHueBrushClass.prototype.onUpdate = function(deltaSeconds, entityID) { - print("Dynamic Hue Brush"); + //print("Dynamic Hue Brush"); this.hsvColor.hue = this.hsvColor.hue + ((deltaSeconds * this.DYNAMIC_BRUSH_INCREMENT)/this.DYNAMIC_BRUSH_TIME); this.hsvColor.hue = this.hsvColor.hue >= 360 ? 0 : this.hsvColor.hue; //restart hue cycle this.dynamicColor = this.convertHsvToRgb(this.hsvColor); diff --git a/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicRotationBrush.js b/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicRotationBrush.js index e88c640b2c..32deacf950 100644 --- a/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicRotationBrush.js +++ b/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicRotationBrush.js @@ -2,10 +2,10 @@ Script.include("dynamicBrush.js"); function DynamicRotationBrushClass(settings) { - //dynamic brush vars - DynamicBrush.call(this); - print("Starting dynamic rotation brush"); - this.angle = 0; + //dynamic brush vars + DynamicBrush.call(this); + //print("Starting dynamic rotation brush"); + this.angle = 0; this.activeAxis = settings.axis; } @@ -17,7 +17,7 @@ DynamicRotationBrushClass.prototype.DYNAMIC_BRUSH_INCREMENT = 5; //linear increm DynamicRotationBrushClass.prototype.NAME = "DynamicRotationBrush"; //linear increment of brush size; DynamicRotationBrushClass.prototype.onUpdate = function(deltaSeconds, entityID) { - print("Dynamic rotation this: " + JSON.stringify(rotation)); + //print("Dynamic rotation this: " + JSON.stringify(rotation)); this.angle = this.angle + ((deltaSeconds * this.DYNAMIC_BRUSH_INCREMENT)/this.DYNAMIC_BRUSH_TIME); this.angle = this.angle >= 360 ? 0 : this.angle; //restart hue cycle var rotation = Vec3.multiply(this.angle, this.activeAxis); diff --git a/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicTranslationBrush.js b/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicTranslationBrush.js index 50a3d60b9d..a1905082d0 100644 --- a/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicTranslationBrush.js +++ b/scripts/system/fingerPaint/content/brushes/dynamicBrushes/dynamicTranslationBrush.js @@ -2,12 +2,12 @@ Script.include("dynamicBrush.js"); function DynamicTranslationBrushClass(settings) { - //dynamic brush vars - DynamicBrush.call(this); - print("Starting dynamic Translation brush"); - this.startingPosition = null; - this.translation = 0; - this.activeAxis = settings.axis; + //dynamic brush vars + DynamicBrush.call(this); + //print("Starting dynamic Translation brush"); + this.startingPosition = null; + this.translation = 0; + this.activeAxis = settings.axis; } DynamicTranslationBrushClass.prototype.constructor = DynamicTranslationBrushClass; @@ -19,25 +19,25 @@ DynamicTranslationBrushClass.prototype.MAX_TRANSLATION = 2; DynamicTranslationBrushClass.prototype.NAME = "DynamicTranslationBrush"; //linear increment of brush size; DynamicTranslationBrushClass.prototype.onUpdate = function(deltaSeconds, entityID) { - print("translation this: " + JSON.stringify(this) + " : " + JSON.stringify(this.activeAxis)); - var currentPosition = Entities.getEntityProperties(entityID).position; - //print("currentPosition " + JSON.stringify(currentPosition)); - if (this.startingPosition == null) { - this.startingPosition = currentPosition; - } - this.translation = this.translation + ((deltaSeconds * this.DYNAMIC_BRUSH_INCREMENT)/this.DYNAMIC_BRUSH_TIME); - - var translationVec = Vec3.multiply(this.translation, this.activeAxis); - var nextPosition = { - x: this.startingPosition.x + translationVec.x, - y: this.startingPosition.y + translationVec.y, - z: this.startingPosition.z + translationVec.z - }; + //print("translation this: " + JSON.stringify(this) + " : " + JSON.stringify(this.activeAxis)); + var currentPosition = Entities.getEntityProperties(entityID).position; + //print("currentPosition " + JSON.stringify(currentPosition)); + if (this.startingPosition == null) { + this.startingPosition = currentPosition; + } + this.translation = this.translation + ((deltaSeconds * this.DYNAMIC_BRUSH_INCREMENT)/this.DYNAMIC_BRUSH_TIME); + + var translationVec = Vec3.multiply(this.translation, this.activeAxis); + var nextPosition = { + x: this.startingPosition.x + translationVec.x, + y: this.startingPosition.y + translationVec.y, + z: this.startingPosition.z + translationVec.z + }; - if (Vec3.distance(nextPosition, this.startingPosition) > this.MAX_TRANSLATION) { - this.translation = 0; - nextPosition = this.startingPosition; - } + if (Vec3.distance(nextPosition, this.startingPosition) > this.MAX_TRANSLATION) { + this.translation = 0; + nextPosition = this.startingPosition; + } Entities.editEntity(entityID, {position : nextPosition}); this.parent.updateUserData(entityID, this); } diff --git a/scripts/system/fingerPaint/fingerPaint.js b/scripts/system/fingerPaint/fingerPaint.js index b561459b6a..0c7cb48cba 100644 --- a/scripts/system/fingerPaint/fingerPaint.js +++ b/scripts/system/fingerPaint/fingerPaint.js @@ -27,6 +27,7 @@ rightBrush = null, isBrushColored = false, isLeftHandDominant = false, + isMouseDrawing = false, savedSettings = null, CONTROLLER_MAPPING_NAME = "com.highfidelity.fingerPaint", isTabletDisplayed = false, @@ -45,11 +46,11 @@ //var window = null; //var inkSource = null; - var inkSourceOverlay = null; - // Set path for finger paint hand animations - var RIGHT_ANIM_URL = Script.resourcesPath() + 'avatar/animations/touch_point_closed_right.fbx'; + var inkSourceOverlay = null; + // Set path for finger paint hand animations + var RIGHT_ANIM_URL = Script.resourcesPath() + 'avatar/animations/touch_point_closed_right.fbx'; var LEFT_ANIM_URL = Script.resourcesPath() + 'avatar/animations/touch_point_closed_left.fbx'; - var RIGHT_ANIM_URL_OPEN = Script.resourcesPath() + 'avatar/animations/touch_point_open_right.fbx'; + var RIGHT_ANIM_URL_OPEN = Script.resourcesPath() + 'avatar/animations/touch_point_open_right.fbx'; var LEFT_ANIM_URL_OPEN = Script.resourcesPath() + 'avatar/animations/touch_point_open_left.fbx'; function paintBrush(name) { @@ -66,10 +67,10 @@ strokeNormals, strokeWidths, timeOfLastPoint, - texture = savedSettings.currentTexture, + texture = CONTENT_PATH + "/" + savedSettings.currentTexture.brushName, //'https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Caris_Tessellation.svg/1024px-Caris_Tessellation.svg.png', // Daantje - strokeWidthMultiplier = savedSettings.currentStrokeWidth, - IS_UV_MODE_STRETCH = true, + strokeWidthMultiplier = savedSettings.currentStrokeWidth * 2 + 0.1, + IS_UV_MODE_STRETCH = savedSettings.currentTexture.brushType == "stretch", MIN_STROKE_LENGTH = 0.005, // m MIN_STROKE_INTERVAL = 66, // ms MAX_POINTS_PER_LINE = 70; // Hard-coded limit in PolyLineEntityItem.h. @@ -101,8 +102,8 @@ function setTriggerPressureWidthEnabled(isEnabled) { isTriggerPressureWidthEnabled = isEnabled; } - - function changeUVMode(isUVModeStretch) { + + function changeUVMode(isUVModeStretch) { IS_UV_MODE_STRETCH = isUVModeStretch; } @@ -113,7 +114,7 @@ function getEntityID() { return entityID; } - + function changeTexture(textureURL) { texture = textureURL; } @@ -161,10 +162,8 @@ normals: strokeNormals, strokeWidths: strokeWidths, textures: texture, // Daantje - isUVModeStretch: IS_UV_MODE_STRETCH, + isUVModeStretch: IS_UV_MODE_STRETCH, dimensions: STROKE_DIMENSIONS, - shapeType: "box", - collisionless: true, }); isDrawingLine = true; addAnimationToBrush(entityID); @@ -206,6 +205,8 @@ normals: strokeNormals, strokeWidths: strokeWidths }); + + print(JSON.stringify(Entities.getEntityProperties(entityID))); } } @@ -309,7 +310,7 @@ getStrokeColor: getStrokeColor, getStrokeWidth: getStrokeWidth, getEntityID: getEntityID, - changeUVMode: changeUVMode, + changeUVMode: changeUVMode, setTriggerPressureWidthEnabled: setTriggerPressureWidthEnabled }; } @@ -562,7 +563,7 @@ //Entities //if (inkSource){ // Entities.deleteEntity(inkSource); - // inkSource = null; + // inkSource = null; //} } @@ -601,86 +602,86 @@ pointIndex: !enabled }), true); } - - function updateHandAnimations(){ - var ANIM_URL = (isLeftHandDominant? LEFT_ANIM_URL: RIGHT_ANIM_URL ); - var ANIM_OPEN = (isLeftHandDominant? LEFT_ANIM_URL_OPEN: RIGHT_ANIM_URL_OPEN ); - var handLiteral = (isLeftHandDominant? "left": "right" ); + + function updateHandAnimations(){ + var ANIM_URL = (isLeftHandDominant? LEFT_ANIM_URL: RIGHT_ANIM_URL ); + var ANIM_OPEN = (isLeftHandDominant? LEFT_ANIM_URL_OPEN: RIGHT_ANIM_URL_OPEN ); + var handLiteral = (isLeftHandDominant? "left": "right" ); - //Clear previous hand animation override - restoreAllHandAnimations(); - - //"rightHandGraspOpen","rightHandGraspClosed", - MyAvatar.overrideRoleAnimation(handLiteral + "HandGraspOpen", ANIM_OPEN, 30, false, 19, 20); - MyAvatar.overrideRoleAnimation(handLiteral + "HandGraspClosed", ANIM_URL, 30, false, 19, 20); + //Clear previous hand animation override + restoreAllHandAnimations(); + + //"rightHandGraspOpen","rightHandGraspClosed", + MyAvatar.overrideRoleAnimation(handLiteral + "HandGraspOpen", ANIM_OPEN, 30, false, 19, 20); + MyAvatar.overrideRoleAnimation(handLiteral + "HandGraspClosed", ANIM_URL, 30, false, 19, 20); - //"rightIndexPointOpen","rightIndexPointClosed", - MyAvatar.overrideRoleAnimation(handLiteral + "IndexPointOpen", ANIM_OPEN, 30, false, 19, 20); - MyAvatar.overrideRoleAnimation(handLiteral + "IndexPointClosed", ANIM_URL, 30, false, 19, 20); + //"rightIndexPointOpen","rightIndexPointClosed", + MyAvatar.overrideRoleAnimation(handLiteral + "IndexPointOpen", ANIM_OPEN, 30, false, 19, 20); + MyAvatar.overrideRoleAnimation(handLiteral + "IndexPointClosed", ANIM_URL, 30, false, 19, 20); - //"rightThumbRaiseOpen","rightThumbRaiseClosed", - MyAvatar.overrideRoleAnimation(handLiteral + "ThumbRaiseOpen", ANIM_OPEN, 30, false, 19, 20); - MyAvatar.overrideRoleAnimation(handLiteral + "ThumbRaiseClosed", ANIM_URL, 30, false, 19, 20); + //"rightThumbRaiseOpen","rightThumbRaiseClosed", + MyAvatar.overrideRoleAnimation(handLiteral + "ThumbRaiseOpen", ANIM_OPEN, 30, false, 19, 20); + MyAvatar.overrideRoleAnimation(handLiteral + "ThumbRaiseClosed", ANIM_URL, 30, false, 19, 20); - //"rightIndexPointAndThumbRaiseOpen","rightIndexPointAndThumbRaiseClosed", - MyAvatar.overrideRoleAnimation(handLiteral + "IndexPointAndThumbRaiseOpen", ANIM_OPEN, 30, false, 19, 20); - MyAvatar.overrideRoleAnimation(handLiteral + "IndexPointAndThumbRaiseClosed", ANIM_URL, 30, false, 19, 20); - - //turn off lasers and other interactions - Messages.sendLocalMessage("Hifi-Hand-Disabler", "none"); - Messages.sendLocalMessage("Hifi-Hand-Disabler", handLiteral); - - - - //update ink Source + //"rightIndexPointAndThumbRaiseOpen","rightIndexPointAndThumbRaiseClosed", + MyAvatar.overrideRoleAnimation(handLiteral + "IndexPointAndThumbRaiseOpen", ANIM_OPEN, 30, false, 19, 20); + MyAvatar.overrideRoleAnimation(handLiteral + "IndexPointAndThumbRaiseClosed", ANIM_URL, 30, false, 19, 20); + + //turn off lasers and other interactions + Messages.sendLocalMessage("Hifi-Hand-Disabler", "none"); + Messages.sendLocalMessage("Hifi-Hand-Disabler", handLiteral); + + + + //update ink Source var strokeColor = leftBrush.getStrokeColor(); var strokeWidth = leftBrush.getStrokeWidth()*0.06; - if (inkSourceOverlay == null){ - inkSourceOverlay = Overlays.addOverlay("sphere", { parentID: MyAvatar.sessionUUID, parentJointIndex: MyAvatar.getJointIndex(handLiteral === "left" ? "LeftHandIndex4" : "RightHandIndex4"), localPosition: { x: 0, y: 0, z: 0 }, size: strokeWidth, color: strokeColor , solid: true }); - } else { - Overlays.editOverlay(inkSourceOverlay, { + if (inkSourceOverlay == null){ + inkSourceOverlay = Overlays.addOverlay("sphere", { parentID: MyAvatar.sessionUUID, parentJointIndex: MyAvatar.getJointIndex(handLiteral === "left" ? "LeftHandIndex4" : "RightHandIndex4"), localPosition: { x: 0, y: 0, z: 0 }, size: strokeWidth, color: strokeColor , solid: true }); + } else { + Overlays.editOverlay(inkSourceOverlay, { parentJointIndex: MyAvatar.getJointIndex(handLiteral === "left" ? "LeftHandIndex4" : "RightHandIndex4"), - localPosition: { x: 0, y: 0, z: 0 }, - size: strokeWidth, - color: strokeColor + localPosition: { x: 0, y: 0, z: 0 }, + size: strokeWidth, + color: strokeColor }); - } + } - } - - function restoreAllHandAnimations(){ - //"rightHandGraspOpen","rightHandGraspClosed", - MyAvatar.restoreRoleAnimation("rightHandGraspOpen"); - MyAvatar.restoreRoleAnimation("rightHandGraspClosed"); + } + + function restoreAllHandAnimations(){ + //"rightHandGraspOpen","rightHandGraspClosed", + MyAvatar.restoreRoleAnimation("rightHandGraspOpen"); + MyAvatar.restoreRoleAnimation("rightHandGraspClosed"); - //"rightIndexPointOpen","rightIndexPointClosed", - MyAvatar.restoreRoleAnimation("rightIndexPointOpen"); - MyAvatar.restoreRoleAnimation("rightIndexPointClosed"); + //"rightIndexPointOpen","rightIndexPointClosed", + MyAvatar.restoreRoleAnimation("rightIndexPointOpen"); + MyAvatar.restoreRoleAnimation("rightIndexPointClosed"); - //"rightThumbRaiseOpen","rightThumbRaiseClosed", - MyAvatar.restoreRoleAnimation("rightThumbRaiseOpen"); - MyAvatar.restoreRoleAnimation("rightThumbRaiseClosed"); + //"rightThumbRaiseOpen","rightThumbRaiseClosed", + MyAvatar.restoreRoleAnimation("rightThumbRaiseOpen"); + MyAvatar.restoreRoleAnimation("rightThumbRaiseClosed"); - //"rightIndexPointAndThumbRaiseOpen","rightIndexPointAndThumbRaiseClosed", - MyAvatar.restoreRoleAnimation("rightIndexPointAndThumbRaiseOpen"); - MyAvatar.restoreRoleAnimation("rightIndexPointAndThumbRaiseClosed"); - - //"leftHandGraspOpen","leftHandGraspClosed", - MyAvatar.restoreRoleAnimation("leftHandGraspOpen"); - MyAvatar.restoreRoleAnimation("leftHandGraspClosed"); + //"rightIndexPointAndThumbRaiseOpen","rightIndexPointAndThumbRaiseClosed", + MyAvatar.restoreRoleAnimation("rightIndexPointAndThumbRaiseOpen"); + MyAvatar.restoreRoleAnimation("rightIndexPointAndThumbRaiseClosed"); + + //"leftHandGraspOpen","leftHandGraspClosed", + MyAvatar.restoreRoleAnimation("leftHandGraspOpen"); + MyAvatar.restoreRoleAnimation("leftHandGraspClosed"); - //"leftIndexPointOpen","leftIndexPointClosed", - MyAvatar.restoreRoleAnimation("leftIndexPointOpen"); - MyAvatar.restoreRoleAnimation("leftIndexPointClosed"); + //"leftIndexPointOpen","leftIndexPointClosed", + MyAvatar.restoreRoleAnimation("leftIndexPointOpen"); + MyAvatar.restoreRoleAnimation("leftIndexPointClosed"); - //"leftThumbRaiseOpen","leftThumbRaiseClosed", - MyAvatar.restoreRoleAnimation("leftThumbRaiseOpen"); - MyAvatar.restoreRoleAnimation("leftThumbRaiseClosed"); + //"leftThumbRaiseOpen","leftThumbRaiseClosed", + MyAvatar.restoreRoleAnimation("leftThumbRaiseOpen"); + MyAvatar.restoreRoleAnimation("leftThumbRaiseClosed"); - //"leftIndexPointAndThumbRaiseOpen","leftIndexPointAndThumbRaiseClosed", - MyAvatar.restoreRoleAnimation("leftIndexPointAndThumbRaiseOpen"); - MyAvatar.restoreRoleAnimation("leftIndexPointAndThumbRaiseClosed"); - } + //"leftIndexPointAndThumbRaiseOpen","leftIndexPointAndThumbRaiseClosed", + MyAvatar.restoreRoleAnimation("leftIndexPointAndThumbRaiseOpen"); + MyAvatar.restoreRoleAnimation("leftIndexPointAndThumbRaiseClosed"); + } function pauseProcessing() { //Script.update.disconnect(leftHand.onUpdate); @@ -708,15 +709,18 @@ Messages.subscribe(HIFI_GRAB_DISABLE_MESSAGE_CHANNEL); Messages.subscribe(HIFI_POINTER_DISABLE_MESSAGE_CHANNEL); } - + function enableProcessing() { // Connect controller API to handController objects. leftHand = handController("left"); rightHand = handController("right"); - - - - + + // Connect handController outputs to paintBrush objects. + leftBrush = paintBrush("left"); + leftHand.setUp(leftBrush.startLine, leftBrush.drawLine, leftBrush.finishLine, leftBrush.eraseClosestLine); + rightBrush = paintBrush("right"); + rightHand.setUp(rightBrush.startLine, rightBrush.drawLine, rightBrush.finishLine, rightBrush.eraseClosestLine); + var controllerMapping = Controller.newMapping(CONTROLLER_MAPPING_NAME); controllerMapping.from(Controller.Standard.LT).to(leftHand.onTriggerPress); controllerMapping.from(Controller.Standard.LeftGrip).to(leftHand.onGripPress); @@ -724,15 +728,9 @@ controllerMapping.from(Controller.Standard.RightGrip).to(rightHand.onGripPress); Controller.enableMapping(CONTROLLER_MAPPING_NAME); - // Connect handController outputs to paintBrush objects. - leftBrush = paintBrush("left"); - leftHand.setUp(leftBrush.startLine, leftBrush.drawLine, leftBrush.finishLine, leftBrush.eraseClosestLine); - rightBrush = paintBrush("right"); - rightHand.setUp(rightBrush.startLine, rightBrush.drawLine, rightBrush.finishLine, rightBrush.eraseClosestLine); - - //Change to finger paint hand animation - updateHandAnimations(); - + //Change to finger paint hand animation + updateHandAnimations(); + // Messages channels for enabling/disabling other scripts' functions. Messages.subscribe(HIFI_POINT_INDEX_MESSAGE_CHANNEL); Messages.subscribe(HIFI_GRAB_DISABLE_MESSAGE_CHANNEL); @@ -742,7 +740,7 @@ Script.update.connect(leftHand.onUpdate); Script.update.connect(rightHand.onUpdate); - + // enable window palette /*window = new OverlayWindow({ title: 'Paint Window', @@ -761,8 +759,8 @@ if (message[0] === "color"){ leftBrush.changeStrokeColor(message[1], message[2], message[3]); rightBrush.changeStrokeColor(message[1], message[2], message[3]); - Overlays.editOverlay(inkSourceOverlay, { - color: {red: message[1], green: message[2], blue: message[3]} + Overlays.editOverlay(inkSourceOverlay, { + color: {red: message[1], green: message[2], blue: message[3]} }); return; } @@ -773,9 +771,9 @@ //var dim2 = Math.floor( Math.random()*40 + 5); leftBrush.changeStrokeWidthMultiplier(dim); rightBrush.changeStrokeWidthMultiplier(dim); - Overlays.editOverlay(inkSourceOverlay, { - size: dim * 0.06 - + Overlays.editOverlay(inkSourceOverlay, { + size: dim * 0.06 + }); return; } @@ -785,17 +783,17 @@ //var dim2 = Math.floor( Math.random()*40 + 5); leftBrush.changeTexture(message[1]); rightBrush.changeTexture(message[1]); - - if (message[1] === "content/brushes/paintbrush1.png") { - leftBrush.changeUVMode(true); - rightBrush.changeUVMode(true); - }else if (message[1] === "content/brushes/paintbrush3.png") { - leftBrush.changeUVMode(true); - rightBrush.changeUVMode(true); - }else{ - leftBrush.changeUVMode(false); - rightBrush.changeUVMode(false); - } + + if (message[1] === "content/brushes/paintbrush1.png") { + leftBrush.changeUVMode(true); + rightBrush.changeUVMode(true); + }else if (message[1] === "content/brushes/paintbrush3.png") { + leftBrush.changeUVMode(true); + rightBrush.changeUVMode(true); + }else{ + leftBrush.changeUVMode(false); + rightBrush.changeUVMode(false); + } return; } if (message[0] === "undo"){ @@ -805,7 +803,7 @@ } if (message[0] === "hand"){ isLeftHandDominant = !isLeftHandDominant; - updateHandAnimations(); + updateHandAnimations(); return; } });*/ //uncomment for qml interface @@ -817,8 +815,8 @@ Controller.disableMapping(CONTROLLER_MAPPING_NAME); - Messages.sendLocalMessage("Hifi-Hand-Disabler", "none"); - + Messages.sendLocalMessage("Hifi-Hand-Disabler", "none"); + leftBrush.tearDown(); leftBrush = null; leftHand.tearDown(); @@ -833,14 +831,14 @@ Messages.unsubscribe(HIFI_GRAB_DISABLE_MESSAGE_CHANNEL); Messages.unsubscribe(HIFI_POINTER_DISABLE_MESSAGE_CHANNEL); - - //Restores and clears hand animations - restoreAllHandAnimations(); - - //clears Overlay sphere - Overlays.deleteOverlay(inkSourceOverlay); - inkSourceOverlay = null; - + + //Restores and clears hand animations + restoreAllHandAnimations(); + + //clears Overlay sphere + Overlays.deleteOverlay(inkSourceOverlay); + inkSourceOverlay = null; + // disable window palette //window.close(); //uncomment for qml interface } @@ -856,18 +854,18 @@ savedSettings.customColors = Settings.getValue("customColors", []); savedSettings.currentTab = Settings.getValue("currentTab", 0); savedSettings.currentTriggerWidthEnabled = Settings.getValue("currentTriggerWidthEnabled", true); - - print("Restoring data: " + JSON.stringify(savedSettings)); isLeftHandDominant = savedSettings.currentDrawingHand; } function onButtonClicked() { restoreLastValues(); - isTabletFocused = false; //should always start false so onUpdate updates this variable to true in the beggining var wasFingerPainting = isFingerPainting; isFingerPainting = !isFingerPainting; + if (!isFingerPainting) { + tablet.gotoHomeScreen(); + } button.editProperties({ isActive: isFingerPainting }); print("Finger painting: " + isFingerPainting ? "on" : "off"); @@ -878,10 +876,9 @@ } if (isFingerPainting) { - tablet.gotoWebScreen(APP_URL); + tablet.gotoWebScreen(APP_URL + "?" + encodeURIComponent(JSON.stringify(savedSettings))); enableProcessing(); } - updateHandFunctions(); if (!isFingerPainting) { @@ -913,15 +910,12 @@ event = JSON.parse(event); } switch (event.type) { - case "ready": - //print("Setting up the tablet"); - tablet.emitScriptEvent(JSON.stringify(savedSettings)); - break; case "changeTab": Settings.setValue("currentTab", event.currentTab); break; case "changeColor": if (!isBrushColored) { + print("HMD ACTIVE: " + HMD.active); Settings.setValue("currentColor", event); //print("changing color..."); leftBrush.changeStrokeColor(event.red, event.green, event.blue); @@ -989,11 +983,10 @@ case "undo": //print("Going to undo"); - /** - The undo is called only on the right brush because the undo stack is global, meaning that - calling undoErasing on both the left and right brush would cause the stack to pop twice. - Using the leftBrush instead of the rightBrush would have the exact same effect. - */ + + //The undo is called only on the right brush because the undo stack is global, meaning that + //calling undoErasing on both the left and right brush would cause the stack to pop twice. + //Using the leftBrush instead of the rightBrush would have the exact same effect. rightBrush.undoErasing(); break; @@ -1023,21 +1016,19 @@ } function addAnimationToBrush(entityID) { - //print("Brushes INfo 0" + JSON.stringify(DynamicBrushesInfo)); - Object.keys(DynamicBrushesInfo).forEach(function(animationName) { - print(animationName + "Brushes INfo 0" + JSON.stringify(DynamicBrushesInfo)); - if (DynamicBrushesInfo[animationName].isEnabled) { - var prevUserData = Entities.getEntityProperties(entityID).userData; - prevUserData = prevUserData == "" ? new Object() : JSON.parse(prevUserData); //preserve other possible user data - if (prevUserData.animations == null) { - prevUserData.animations = {}; - } - prevUserData.animations[animationName] = dynamicBrushFactory(animationName, DynamicBrushesInfo[animationName].settings); - Entities.editEntity(entityID, {userData: JSON.stringify(prevUserData)}); - //Entities.editEntity(entityID, {script: Script.resolvePath("content/brushes/dynamicBrushes/dynamicBrushScript.js")}); + Object.keys(DynamicBrushesInfo).forEach(function(animationName) { + print(animationName + "Brushes INfo 0" + JSON.stringify(DynamicBrushesInfo)); + if (DynamicBrushesInfo[animationName].isEnabled) { + var prevUserData = Entities.getEntityProperties(entityID).userData; + prevUserData = prevUserData == "" ? new Object() : JSON.parse(prevUserData); //preserve other possible user data + if (prevUserData.animations == null) { + prevUserData.animations = {}; } - }); - //print("Brushes INfo 1" + JSON.stringify(DynamicBrushesInfo)); + prevUserData.animations[animationName] = dynamicBrushFactory(animationName, DynamicBrushesInfo[animationName].settings); + Entities.editEntity(entityID, {userData: JSON.stringify(prevUserData)}); + //Entities.editEntity(entityID, {script: Script.resolvePath("content/brushes/dynamicBrushes/dynamicBrushScript.js")}); + } + }); } function addElementToUndoStack(item) @@ -1083,6 +1074,57 @@ button.clicked.disconnect(onButtonClicked); tablet.removeButton(button); } + + function getFingerPosition(x, y) { + var pickRay = Camera.computePickRay(x, y); + return Vec3.sum(pickRay.origin, Vec3.multiply(pickRay.direction, 5)); + } + + Controller.mouseMoveEvent.connect(function(event){ + if (rightBrush && rightBrush.isDrawing()) { + rightBrush.drawLine(getFingerPosition(event.x, event.y), 0.03); + } + }); + + Controller.mousePressEvent.connect(function(event){ + print(JSON.stringify(event)); + if (event.isLeftButton) { + rightBrush.startLine(getFingerPosition(event.x, event.y), 0.03); + + } else if (event.isMiddleButton) { + //delete first line in sight + //var pickRay = getFingerPosition(event.x, event.y); + entities = Entities.findEntities(MyAvatar.position, 10); + // Fine polyline entity with closest point within search radius. + for (i = 0, entitiesLength = entities.length; i < entitiesLength; i += 1) { + print("NEAR ENTITIES: " + JSON.stringify(Entities.getEntityProperties(entities[i]))); + } + + var pickRay = Camera.computePickRay(event.x, event.y); + var entityToDelete = Entities.findRayIntersection(pickRay, false, [Entities.findEntities(MyAvatar.position, 1000)], []); + print("Entity to DELETE: " + JSON.stringify(entityToDelete)); + + var line3d = Overlays.addOverlay("line3d", { + start: pickRay.origin, + end: Vec3.sum(pickRay.origin, Vec3.multiply(pickRay.direction, 100)), + color: { red: 255, green: 0, blue: 255}, + lineWidth: 5 + }); + if (entityToDelete.intersects) { + print("Entity to DELETE Properties: " + JSON.stringify(Entities.getEntityProperties(entityToDelete.entityID))); + //Entities.deleteEntity(entityToDelete.entityID); + + } + } + + }); + + Controller.mouseReleaseEvent.connect(function(event){ + isMouseDrawing = false; + if (rightBrush && rightBrush.isDrawing()) { + rightBrush.finishLine(getFingerPosition(event.x, event.y), 0.03); + } + }); setUp(); Script.scriptEnding.connect(tearDown); diff --git a/scripts/system/fingerPaint/html/brushesTab.html b/scripts/system/fingerPaint/html/brushesTab.html index b1a738afbd..496e16249a 100644 --- a/scripts/system/fingerPaint/html/brushesTab.html +++ b/scripts/system/fingerPaint/html/brushesTab.html @@ -1,9 +1,10 @@ + +