From 8cb5c639fbdb42507be939155d256b7b4aabeeae Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 24 Feb 2014 12:22:10 -0800 Subject: [PATCH 1/3] Added ribbon example that I had lying around. --- examples/ribbon.js | 167 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 examples/ribbon.js diff --git a/examples/ribbon.js b/examples/ribbon.js new file mode 100644 index 0000000000..39bfefaa0a --- /dev/null +++ b/examples/ribbon.js @@ -0,0 +1,167 @@ +// Draws a screensavery rainbow ribbon. + +function vectorMultiply(vector, scalar) { + return [ vector[0] * scalar, vector[1] * scalar, vector[2] * scalar ]; +} + +function vectorAdd(firstVector, secondVector) { + return [ firstVector[0] + secondVector[0], firstVector[1] + secondVector[1], firstVector[2] + secondVector[2] ]; +} + +function vectorSubtract(firstVector, secondVector) { + return [ firstVector[0] - secondVector[0], firstVector[1] - secondVector[1], firstVector[2] - secondVector[2] ]; +} + +function vectorCross(firstVector, secondVector) { + return [ firstVector[1] * secondVector[2] - firstVector[2] * secondVector[1], + firstVector[2] * secondVector[0] - firstVector[0] * secondVector[2], + firstVector[0] * secondVector[1] - firstVector[1] * secondVector[0] ]; +} + +function vectorLength(vector) { + return Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]); +} + +function vectorNormalize(vector) { + return vectorMultiply(vector, 1.0 / vectorLength(vector)); +} + +function vectorClone(vector) { + return [ vector[0], vector[1], vector[2] ]; +} + +function mix(first, second, amount) { + return first + (second - first) * amount; +} + +function vectorMix(firstVector, secondVector, amount) { + return vectorAdd(firstVector, vectorMultiply(vectorSubtract(secondVector, firstVector), amount)); +} + +function randomVector(minVector, maxVector) { + return [ mix(minVector[0], maxVector[0], Math.random()), mix(minVector[1], maxVector[1], Math.random()), + mix(minVector[2], maxVector[2], Math.random()) ]; +} + +function applyToLine(start, end, granularity, fn) { + // determine the number of steps from the maximum length + var steps = Math.max( + Math.abs(Math.floor(start[0] / granularity) - Math.floor(end[0] / granularity)), + Math.abs(Math.floor(start[1] / granularity) - Math.floor(end[1] / granularity)), + Math.abs(Math.floor(start[2] / granularity) - Math.floor(end[2] / granularity))); + var position = vectorClone(start); + var increment = vectorMultiply(vectorSubtract(end, start), 1.0 / steps); + for (var i = 0; i <= steps; i++) { + fn(granularity * Math.floor(position[0] / granularity), + granularity * Math.floor(position[1] / granularity), + granularity * Math.floor(position[2] / granularity), + granularity); + position = vectorAdd(position, increment); + } +} + +function drawLine(start, end, color, granularity) { + applyToLine(start, end, granularity, function(x, y, z, scale) { + Voxels.setVoxel(x, y, z, scale, color[0], color[1], color[2]); + }); +} + +function eraseLine(start, end, granularity) { + applyToLine(start, end, granularity, function(x, y, z, scale) { + Voxels.eraseVoxel(x, y, z, scale); + }); +} + +function getHueColor(hue) { + // see http://en.wikipedia.org/wiki/HSL_and_HSV + var hPrime = hue / 60.0; + var x = Math.floor(255.0 * (1.0 - Math.abs(hPrime % 2.0 - 1.0))); + if (hPrime < 1) { + return [255, x, 0]; + + } else if (hPrime < 2) { + return [x, 255, 0]; + + } else if (hPrime < 3) { + return [0, 255, x]; + + } else if (hPrime < 4) { + return [0, x, 255]; + + } else if (hPrime < 5) { + return [x, 0, 255]; + + } else { // hPrime < 6 + return [255, 0, x]; + } +} + +var UNIT_MIN = [-1.0, -1.0, -1.0]; +var UNIT_MAX = [1.0, 1.0, 1.0]; + +var EPSILON = 0.00001; + +var BOUNDS_MIN = [5.0, 0.0, 5.0]; +var BOUNDS_MAX = [15.0, 10.0, 15.0]; + +var GRANULARITY = 1.0 / 16.0; + +var WIDTH = 0.5; + +var HISTORY_LENGTH = 300; + +var stateHistory = []; +var position; +var velocity; +var hueAngle = 0; +var smoothedOffset; + +function step() { + if (stateHistory.length == 0) { + // start at a random position within the bounds, with a random velocity + position = randomVector(BOUNDS_MIN, BOUNDS_MAX); + do { + velocity = randomVector(UNIT_MIN, UNIT_MAX); + } while (vectorLength(velocity) < EPSILON); + velocity = vectorMultiply(velocity, GRANULARITY * 0.5 / vectorLength(velocity)); + smoothedOffset = [0.0, 0.0, 0.0]; + } + + var right = vectorCross(velocity, [0.0, 1.0, 0.0]); + if (vectorLength(right) < EPSILON) { + right = [1.0, 0.0, 0.0]; + } else { + right = vectorNormalize(right); + } + var up = vectorNormalize(vectorCross(right, velocity)); + var ANGULAR_SPEED = 2.0; + var radians = hueAngle * Math.PI * ANGULAR_SPEED / 180.0; + var offset = vectorAdd(vectorMultiply(right, WIDTH * Math.cos(radians)), vectorMultiply(up, WIDTH * Math.sin(radians))); + var OFFSET_SMOOTHING = 0.9; + smoothedOffset = vectorMix(offset, smoothedOffset, OFFSET_SMOOTHING); + + var state = { start: vectorAdd(position, smoothedOffset), end: vectorSubtract(position, smoothedOffset) }; + drawLine(state.start, state.end, getHueColor(hueAngle), GRANULARITY); + stateHistory.push(state); + if (stateHistory.length > HISTORY_LENGTH) { + var last = stateHistory.shift(); + eraseLine(last.start, last.end, GRANULARITY); + } + + // update position, check against bounds + position = vectorAdd(position, velocity); + for (var i = 0; i < 3; i++) { + if (position[i] < BOUNDS_MIN[i]) { + velocity[i] = -velocity[i]; + position[i] += 2.0 * (BOUNDS_MIN[i] - position[i]); + + } else if (position[i] > BOUNDS_MAX[i]) { + velocity[i] = -velocity[i]; + position[i] += 2.0 * (BOUNDS_MAX[i] - position[i]); + } + } + var MAX_HUE_ANGLE = 360; + hueAngle = (hueAngle + 1) % MAX_HUE_ANGLE; +} + +Script.willSendVisualDataCallback.connect(step); From 40d9fffb7fd054e7a738b9e00868058b1066aa68 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 24 Feb 2014 13:19:32 -0800 Subject: [PATCH 2/3] Fix for warning. --- examples/ribbon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ribbon.js b/examples/ribbon.js index 39bfefaa0a..53f890c368 100644 --- a/examples/ribbon.js +++ b/examples/ribbon.js @@ -117,7 +117,7 @@ var hueAngle = 0; var smoothedOffset; function step() { - if (stateHistory.length == 0) { + if (stateHistory.length === 0) { // start at a random position within the bounds, with a random velocity position = randomVector(BOUNDS_MIN, BOUNDS_MAX); do { From 2cea83a5991e384931f503ecf8fc5c9964ce7760 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 24 Feb 2014 13:36:43 -0800 Subject: [PATCH 3/3] Proper header on ribbon.js, show display name for own avatar. --- examples/ribbon.js | 8 +++++++- interface/src/avatar/Avatar.h | 4 ++-- interface/src/avatar/MyAvatar.cpp | 4 ++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/examples/ribbon.js b/examples/ribbon.js index 53f890c368..7858c744fe 100644 --- a/examples/ribbon.js +++ b/examples/ribbon.js @@ -1,4 +1,10 @@ -// Draws a screensavery rainbow ribbon. +// +// ribbon.js +// hifi +// +// Created by Andrzej Kapolka on 2/24/14. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// function vectorMultiply(vector, scalar) { return [ vector[0] * scalar, vector[1] * scalar, vector[2] * scalar ]; diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index be98254696..9a693f4a86 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -171,6 +171,8 @@ protected: float getPelvisFloatingHeight() const; float getPelvisToHeadLength() const; + void renderDisplayName(); + private: bool _initialized; @@ -178,8 +180,6 @@ private: void renderBody(); void renderBillboard(); - - void renderDisplayName(); }; #endif diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 50b182c20c..ccd7524c4b 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -480,8 +480,8 @@ void MyAvatar::render(bool forceRenderHead) { if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { renderBody(forceRenderHead); } - - //renderDebugBodyPoints(); + setShowDisplayName(true); + renderDisplayName(); if (!_chatMessage.empty()) { int width = 0;