From e516281da8c3993be8a702e766145eef0153556a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 30 Sep 2015 16:15:52 -0700 Subject: [PATCH] Added closePaint script and removed no longer used spray paint scripts --- examples/closePaint.js | 258 ++++++++++++++++++++++++ examples/entityScripts/sprayPaintCan.js | 252 ----------------------- examples/sprayPaintSpawner.js | 41 ---- 3 files changed, 258 insertions(+), 293 deletions(-) create mode 100644 examples/closePaint.js delete mode 100644 examples/entityScripts/sprayPaintCan.js delete mode 100644 examples/sprayPaintSpawner.js diff --git a/examples/closePaint.js b/examples/closePaint.js new file mode 100644 index 0000000000..dc3e567823 --- /dev/null +++ b/examples/closePaint.js @@ -0,0 +1,258 @@ +// +// closePaint.js +// examples +// +// Created by Eric Levina on 9/30/15. +// Copyright 2015 High Fidelity, Inc. +// +// Run this script to be able to paint on entities you are close to, with hydras. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + +var RIGHT_HAND = 1; +var LEFT_HAND = 0; + +var MIN_POINT_DISTANCE = 0.01; +var MAX_POINT_DISTANCE = 0.5; + +var SPATIAL_CONTROLLERS_PER_PALM = 2; +var TIP_CONTROLLER_OFFSET = 1; + +var TRIGGER_ON_VALUE = 0.3; + +var MAX_DISTANCE = 10; + +var STROKE_WIDTH = 0.02 +var MAX_POINTS_PER_LINE = 60; + + +var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(Camera.getOrientation()))); + + + +function MyController(hand, triggerAction) { + this.hand = hand; + this.strokes = []; + this.painting = false; + + if (this.hand === RIGHT_HAND) { + this.getHandPosition = MyAvatar.getRightPalmPosition; + this.getHandRotation = MyAvatar.getRightPalmRotation; + } else { + this.getHandPosition = MyAvatar.getLeftPalmPosition; + this.getHandRotation = MyAvatar.getLeftPalmRotation; + } + + this.triggerAction = triggerAction; + this.palm = SPATIAL_CONTROLLERS_PER_PALM * hand; + this.tip = SPATIAL_CONTROLLERS_PER_PALM * hand + TIP_CONTROLLER_OFFSET; + + + this.strokeColor = { + red: 200, + green: 20, + blue: 40 + }; + + this.laserPointer = Overlays.addOverlay("circle3d", { + size: { + x: STROKE_WIDTH / 2, + y: STROKE_WIDTH / 2 + }, + color: this.strokeColor, + solid: true, + position: center + }) + this.triggerValue = 0; + this.prevTriggerValue = 0; + var _this = this; + + + this.update = function() { + this.updateControllerState() + this.search(); + if (this.canPaint === true) { + this.paint(this.intersection.intersection, this.intersection.surfaceNormal); + } + }; + + this.paint = function(position, normal) { + // print("POSITION " + position.z) + if (this.painting === false) { + if (this.oldPosition) { + this.newStroke(this.oldPosition); + } else { + this.newStroke(position); + } + this.painting = true; + } + + + + var localPoint = Vec3.subtract(position, this.strokeBasePosition); + //Move stroke a bit forward along normal so it doesnt zfight with mesh its drawing on + localPoint = Vec3.sum(localPoint, Vec3.multiply(normal, 0.001 + Math.random() * .001)); //rand avoid z fighting + + var distance = Vec3.distance(localPoint, this.strokePoints[this.strokePoints.length - 1]); + if (this.strokePoints.length > 0 && distance < MIN_POINT_DISTANCE) { + //need a minimum distance to avoid binormal NANs + return; + } + if(this.strokePoints.length > 0 && distance > MAX_POINT_DISTANCE) { + //Prevents drawing lines accross models + this.painting = false; + return; + } + if(this.strokePoints.length === 0) { + localPoint = {x: 0, y: 0, z: 0}; + } + + this.strokePoints.push(localPoint); + this.strokeNormals.push(normal); + this.strokeWidths.push(STROKE_WIDTH); + Entities.editEntity(this.currentStroke, { + linePoints: this.strokePoints, + normals: this.strokeNormals, + strokeWidths: this.strokeWidths + }); + if (this.strokePoints.length === MAX_POINTS_PER_LINE) { + this.painting = false; + return; + } + this.oldPosition = position + + } + + this.newStroke = function(position) { + this.strokeBasePosition = position; + this.currentStroke = Entities.addEntity({ + position: position, + type: "PolyLine", + color: this.strokeColor, + dimensions: { + x: 50, + y: 50, + z: 50 + }, + lifetime: 100 + }); + this.strokePoints = []; + this.strokeNormals = []; + this.strokeWidths = []; + + this.strokes.push(this.currentStroke); + + } + + this.updateControllerState = function() { + var triggerValue = Controller.getActionValue(this.triggerAction); + if (triggerValue > TRIGGER_ON_VALUE && this.prevTriggerValue <= TRIGGER_ON_VALUE) { + this.squeeze(); + } else if (triggerValue < TRIGGER_ON_VALUE && this.prevTriggerValue >= TRIGGER_ON_VALUE) { + this.release() + } + + this.prevTriggerValue = triggerValue; + } + + this.squeeze = function() { + this.tryPainting = true; + + } + this.release = function() { + this.painting = false; + this.tryPainting = false; + this.canPaint = false; + this.oldPosition = null; + } + this.search = function() { + + // the trigger is being pressed, do a ray test + var handPosition = this.getHandPosition(); + var pickRay = { + origin: handPosition, + direction: Quat.getUp(this.getHandRotation()) + }; + + + this.intersection = Entities.findRayIntersection(pickRay, true); + if (this.intersection.intersects) { + var distance = Vec3.distance(handPosition, this.intersection.intersection); + if (distance < MAX_DISTANCE) { + var displayPoint = this.intersection.intersection; + displayPoint = Vec3.sum(displayPoint, Vec3.multiply(this.intersection.surfaceNormal, .001)); + if (this.tryPainting) { + this.canPaint = true; + } + Overlays.editOverlay(this.laserPointer, { + visible: true, + position: displayPoint, + rotation: orientationOf(this.intersection.surfaceNormal) + }); + + } else { + this.hitFail(); + } + } else { + this.hitFail(); + } + }; + + this.hitFail = function() { + this.canPaint = false; + + Overlays.editOverlay(this.laserPointer, { + visible: false + }); + + } + + this.cleanup = function() { + Overlays.deleteOverlay(this.laserPointer); + this.strokes.forEach(function(stroke) { + Entities.deleteEntity(stroke); + }); + } +} + +var rightController = new MyController(RIGHT_HAND, Controller.findAction("RIGHT_HAND_CLICK")); +var leftController = new MyController(LEFT_HAND, Controller.findAction("LEFT_HAND_CLICK")); + +function update() { + rightController.update(); + leftController.update(); +} + +function cleanup() { + rightController.cleanup(); + leftController.cleanup(); +} + +Script.scriptEnding.connect(cleanup); +Script.update.connect(update); + + +function orientationOf(vector) { + var Y_AXIS = { + x: 0, + y: 1, + z: 0 + }; + var X_AXIS = { + x: 1, + y: 0, + z: 0 + }; + + var theta = 0.0; + + var RAD_TO_DEG = 180.0 / Math.PI; + var direction, yaw, pitch; + direction = Vec3.normalize(vector); + yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); + pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); + return Quat.multiply(yaw, pitch); +} \ No newline at end of file diff --git a/examples/entityScripts/sprayPaintCan.js b/examples/entityScripts/sprayPaintCan.js deleted file mode 100644 index 21613bdeb5..0000000000 --- a/examples/entityScripts/sprayPaintCan.js +++ /dev/null @@ -1,252 +0,0 @@ -(function() { - // Script.include("../libraries/utils.js"); - //Need absolute path for now, for testing before PR merge and s3 cloning. Will change post-merge - - Script.include("../libraries/utils.js"); - GRAB_FRAME_USER_DATA_KEY = "grabFrame"; - this.userData = {}; - - var TIP_OFFSET_Z = 0.14; - var TIP_OFFSET_Y = 0.04; - - var ZERO_VEC = { - x: 0, - y: 0, - z: 0 - } - - var MAX_POINTS_PER_LINE = 40; - var MIN_POINT_DISTANCE = 0.01; - var STROKE_WIDTH = 0.02; - - var self = this; - - var timeSinceLastMoved = 0; - var RESET_TIME_THRESHOLD = 5; - var DISTANCE_FROM_HOME_THRESHOLD = 0.5; - var HOME_POSITION = { - x: 549.12, - y: 495.555, - z: 503.77 - }; - this.getUserData = function() { - - - if (this.properties.userData) { - this.userData = JSON.parse(this.properties.userData); - } - } - - this.updateUserData = function() { - Entities.editEntity(this.entityId, { - userData: JSON.stringify(this.userData) - }); - } - - this.update = function(deltaTime) { - self.getUserData(); - self.properties = Entities.getEntityProperties(self.entityId); - - if (Vec3.length(self.properties.velocity) < 0.1 && Vec3.distance(HOME_POSITION, self.properties.position) > DISTANCE_FROM_HOME_THRESHOLD) { - timeSinceLastMoved += deltaTime; - if (timeSinceLastMoved > RESET_TIME_THRESHOLD) { - self.reset(); - timeSinceLastMoved = 0; - } - } else { - timeSinceLastMoved = 0; - } - - //Only activate for the user who grabbed the object - if (self.userData.grabKey && self.userData.grabKey.activated === true && self.userData.grabKey.avatarId == MyAvatar.sessionUUID) { - if (self.activated !== true) { - //We were just grabbed, so create a particle system - self.grab(); - } - //Move emitter to where entity is always when its activated - self.sprayStream(); - } else if (self.userData.grabKey && self.userData.grabKey.activated === false && self.activated) { - self.letGo(); - } - } - - this.grab = function() { - this.activated = true; - var animationSettings = JSON.stringify({ - fps: 30, - loop: true, - firstFrame: 1, - lastFrame: 10000, - running: true - }); - var PI = 3.141593; - var DEG_TO_RAD = PI / 180.0; - - this.paintStream = Entities.addEntity({ - type: "ParticleEffect", - animationSettings: animationSettings, - position: this.properties.position, - textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png", - emitSpeed: 0, - speedSpread: 0.02, - polarFinish: 2 * DEG_TO_RAD, - emitAcceleration: ZERO_VEC, - emitRate: 100, - particleRadius: 0.01, - color: { - red: 170, - green: 20, - blue: 150 - }, - lifetime: 50, //probably wont be holding longer than this straight - }); - } - - this.letGo = function() { - this.activated = false; - Entities.deleteEntity(this.paintStream); - this.paintStream = null; - } - - this.reset = function() { - Entities.editEntity(self.entityId, { - position: HOME_POSITION, - rotation: Quat.fromPitchYawRollDegrees(0, 0, 0), - angularVelocity: ZERO_VEC, - velocity: ZERO_VEC - }); - } - - this.sprayStream = function() { - var forwardVec = Quat.getFront(Quat.multiply(self.properties.rotation , Quat.fromPitchYawRollDegrees(0, 90, 0))); - forwardVec = Vec3.normalize(forwardVec); - - var upVec = Quat.getUp(self.properties.rotation); - var position = Vec3.sum(self.properties.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z)); - position = Vec3.sum(position, Vec3.multiply(upVec, TIP_OFFSET_Y)) - Entities.editEntity(self.paintStream, { - position: position, - emitOrientation: forwardVec, - emitSpeed: 5 - }); - - //Now check for an intersection with an entity - //move forward so ray doesnt intersect with gun - var origin = Vec3.sum(position, forwardVec); - var pickRay = { - origin: origin, - direction: Vec3.multiply(forwardVec, 2) - } - - var intersection = Entities.findRayIntersection(pickRay, true); - if (intersection.intersects) { - var normal = Vec3.multiply(-1, Quat.getFront(intersection.properties.rotation)); - this.paint(intersection.intersection, normal); - } - - - } - - this.paint = function(position, normal) { - if (!this.painting) { - - this.newStroke(position); - this.painting = true; - } - - if (this.strokePoints.length > MAX_POINTS_PER_LINE) { - this.painting = false; - return; - } - - var localPoint = Vec3.subtract(position, this.strokeBasePosition); - //Move stroke a bit forward along normal so it doesnt zfight with mesh its drawing on - localPoint = Vec3.sum(localPoint, Vec3.multiply(normal, .1)); - - if (this.strokePoints.length > 0 && Vec3.distance(localPoint, this.strokePoints[this.strokePoints.length - 1]) < MIN_POINT_DISTANCE) { - //need a minimum distance to avoid binormal NANs - return; - } - - this.strokePoints.push(localPoint); - this.strokeNormals.push(normal); - this.strokeWidths.push(STROKE_WIDTH); - Entities.editEntity(this.currentStroke, { - linePoints: this.strokePoints, - normals: this.strokeNormals, - strokeWidths: this.strokeWidths - }); - - - } - - this.newStroke = function(position) { - this.strokeBasePosition = position; - this.currentStroke = Entities.addEntity({ - position: position, - type: "PolyLine", - color: { - red: randInt(160, 250), - green: randInt(10, 20), - blue: randInt(190, 250) - }, - dimensions: { - x: 50, - y: 50, - z: 50 - }, - lifetime: 100 - }); - this.strokePoints = []; - this.strokeNormals = []; - this.strokeWidths = []; - - this.strokes.push(this.currentStroke); - } - - this.preload = function(entityId) { - this.strokes = []; - this.activated = false; - this.entityId = entityId; - this.properties = Entities.getEntityProperties(self.entityId); - this.getUserData(); - - //Only activate for the avatar who is grabbing the can! - if (this.userData.grabKey && this.userData.grabKey.activated) { - this.activated = true; - } - if (!this.userData.grabFrame) { - var data = { - relativePosition: { - x: 0, - y: 0, - z: 0 - }, - relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, 0) - } - setEntityCustomData(GRAB_FRAME_USER_DATA_KEY, this.entityId, data); - } - } - - - this.unload = function() { - Script.update.disconnect(this.update); - if(this.paintStream) { - Entities.deleteEntity(this.paintStream); - } - this.strokes.forEach(function(stroke) { - Entities.deleteEntity(stroke); - }); - } - Script.update.connect(this.update); -}); - - - -function randFloat(min, max) { - return Math.random() * (max - min) + min; -} - -function randInt(min, max) { - return Math.floor(Math.random() * (max - min)) + min; -} \ No newline at end of file diff --git a/examples/sprayPaintSpawner.js b/examples/sprayPaintSpawner.js deleted file mode 100644 index 3b9cee6ef4..0000000000 --- a/examples/sprayPaintSpawner.js +++ /dev/null @@ -1,41 +0,0 @@ -// sprayPaintSpawner.js -// -// Created by Eric Levin on 9/3/15 -// Copyright 2015 High Fidelity, Inc. -// -// This is script spwans a spreay paint can model with the sprayPaintCan.js entity script attached -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html - -//Just temporarily using my own bucket here so others can test the entity. Once PR is tested and merged, then the entity script will appear in its proper place in S3, and I wil switch it -// var scriptURL = "https://hifi-public.s3.amazonaws.com/eric/scripts/sprayPaintCan.js?=v6 "; -var scriptURL = Script.resolvePath("entityScripts/sprayPaintCan.js?v2"); -var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; - -var sprayCan = Entities.addEntity({ - type: "Model", - name: "spraycan", - modelURL: modelURL, - position: {x: 549.12, y:495.55, z:503.77}, - rotation: {x: 0, y: 0, z: 0, w: 1}, - dimensions: { - x: 0.07, - y: 0.17, - z: 0.07 - }, - collisionsWillMove: true, - shapeType: 'box', - script: scriptURL, - gravity: {x: 0, y: -0.5, z: 0}, - velocity: {x: 0, y: -1, z: 0} -}); - -function cleanup() { - - // Uncomment the below line to delete sprayCan on script reload- for faster iteration during development - // Entities.deleteEntity(sprayCan); -} - -Script.scriptEnding.connect(cleanup); -