201 lines
6.1 KiB
JavaScript
201 lines
6.1 KiB
JavaScript
// moodLight.js
|
|
//
|
|
// This script can be tested in Interface, but should ultimately run as an AC script.
|
|
// Tweens serveral set moodlights.
|
|
//
|
|
// Created by Thijs Wenker on September 21, 2016.
|
|
// Copyright 2016 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
|
|
// Light schedules have the Cycle Percentage as key and the color as value
|
|
var DEFAULT_LIGHT_SCHEDULE = {
|
|
0.0: {red: 247, green: 175, blue: 42},
|
|
0.3334: {red: 250, green: 20, blue: 112},
|
|
0.6667: {red: 0, green: 128, blue: 102},
|
|
};
|
|
|
|
var DEFAULT_LIGHT_SCHEDULE_2 = {
|
|
0.0: {red: 199, green: 43, blue: 0},
|
|
0.3334: {red: 107, green: 3, blue: 148},
|
|
0.6667: {red: 0, green: 13, blue: 150},
|
|
};
|
|
|
|
// Setup your mood-light below
|
|
var moodLights = [
|
|
{
|
|
properties: {
|
|
name: 'color Debug',
|
|
position: {
|
|
x: -27.46241426467896,
|
|
y: 8.558837890625,
|
|
z: -32.07110595703125
|
|
},
|
|
type: 'Sphere'
|
|
},
|
|
schedule: DEFAULT_LIGHT_SCHEDULE
|
|
},
|
|
{
|
|
properties: {
|
|
cutoff: 90,
|
|
dimensions: {
|
|
x: 59.687240600585938,
|
|
y: 59.687240600585938,
|
|
z: 59.687240600585938
|
|
},
|
|
falloffRadius: 100,
|
|
intensity: 2.2999999523162842,
|
|
name: 'RoatingLight1',
|
|
position: {
|
|
x: -4.2,
|
|
y: 8.6062,
|
|
z: -18.0129
|
|
},
|
|
rotation: {
|
|
w: 1,
|
|
x: -1.52587890625e-05,
|
|
y: -1.52587890625e-05,
|
|
z: -1.52587890625e-05
|
|
},
|
|
type: 'Light'
|
|
},
|
|
schedule: DEFAULT_LIGHT_SCHEDULE
|
|
},
|
|
{
|
|
properties: {
|
|
cutoff: 90,
|
|
dimensions: {
|
|
x: 68.6043701171875,
|
|
y: 68.6043701171875,
|
|
z: 68.6043701171875
|
|
},
|
|
falloffRadius: 10,
|
|
intensity: 15,
|
|
name: 'RotatingLight2',
|
|
position: {
|
|
x: -4.2163,
|
|
y: 4.6453,
|
|
z: -18
|
|
},
|
|
rotation: {
|
|
w: 1,
|
|
x: -1.52587890625e-05,
|
|
y: -1.52587890625e-05,
|
|
z: -1.52587890625e-05
|
|
},
|
|
type: 'Light'
|
|
},
|
|
schedule: DEFAULT_LIGHT_SCHEDULE_2
|
|
}
|
|
];
|
|
|
|
// The time it takes for a cycle to 100% complete (1.0)
|
|
var CYCLE_SECONDS = 100; // 5 minutes
|
|
|
|
// MAX_INACTIVE_SECONDS will contineous be added with the age to the lifetime, when the script is inactive the lights will disappear
|
|
var MAX_INACTIVE_SECONDS = 10;
|
|
|
|
// How frequently do we send out updates per second? :
|
|
var UPDATE_FREQUENCY = 50; //Hz
|
|
|
|
const MILLISECONDS_PER_SECOND = 1000;
|
|
|
|
function getNearestArrayValues(array, goal, continuous) {
|
|
var floorValue = null, ceilValue = null;
|
|
array.forEach(function(entry) {
|
|
if ((floorValue === null || entry > floorValue) && entry <= goal) {
|
|
floorValue = entry;
|
|
}
|
|
if ((ceilValue === null || entry < ceilValue) && entry >= goal) {
|
|
ceilValue = entry;
|
|
}
|
|
});
|
|
if (continuous && floorValue === null) {
|
|
floorValue = Math.max.apply(Math, array);
|
|
}
|
|
if (continuous && ceilValue === null) {
|
|
ceilValue = Math.min.apply(Math, array);
|
|
}
|
|
return {
|
|
floor: floorValue,
|
|
ceil: ceilValue
|
|
};
|
|
}
|
|
|
|
function tweeningPercentage(min, max, current) {
|
|
var currentOffset = (current >= min ? (current - min) : (current + 1 - min));
|
|
var dividerOffset = max - min;
|
|
if (min > max) {
|
|
dividerOffset += 1;
|
|
}
|
|
return currentOffset / dividerOffset;
|
|
}
|
|
|
|
function mix(valueA, valueB, mixPercentage) {
|
|
return valueA + mixPercentage * (valueB - valueA);
|
|
}
|
|
|
|
function MoodLight(properties, schedule) {
|
|
this.properties = properties;
|
|
this.schedule = schedule;
|
|
this.properties['lifetime'] = MAX_INACTIVE_SECONDS;
|
|
this.entityID = Entities.addEntity(this.properties);
|
|
this.creationSeconds = Date.now() / MILLISECONDS_PER_SECOND;
|
|
}
|
|
|
|
MoodLight.prototype = {
|
|
properties: null,
|
|
schedule: null,
|
|
entityID: null,
|
|
creationSeconds: null,
|
|
getCurrentColor: function() {
|
|
var percentageOfCycle = ((Date.now() / MILLISECONDS_PER_SECOND) % CYCLE_SECONDS) / CYCLE_SECONDS;
|
|
var minMaxKey = getNearestArrayValues(Object.keys(this.schedule), percentageOfCycle, true);
|
|
var minColor = this.schedule[minMaxKey.floor];
|
|
var maxColor = this.schedule[minMaxKey.ceil];
|
|
var mixPercentage = tweeningPercentage(minMaxKey.floor, minMaxKey.ceil, percentageOfCycle);
|
|
var mixedColor = {
|
|
red: mix(minColor.red, maxColor.red, mixPercentage),
|
|
green: mix(minColor.green, maxColor.green, mixPercentage),
|
|
blue: mix(minColor.blue, maxColor.blue, mixPercentage),
|
|
};
|
|
//print((percentageOfCycle * 100).toFixed(3) + '% ' + JSON.stringify(minColor) + ' mix ( ' + (mixPercentage * 100).toFixed(3) + '% ' + ' ) ' + JSON.stringify(maxColor) + ' = ' + JSON.stringify(mixedColor));
|
|
return mixedColor;
|
|
},
|
|
getNewLifetime: function() {
|
|
return ((Date.now() / MILLISECONDS_PER_SECOND) -this.creationSeconds) + MAX_INACTIVE_SECONDS;
|
|
},
|
|
update: function() {
|
|
var newProperties = {};
|
|
newProperties['lifetime'] = this.getNewLifetime();
|
|
newProperties['color'] = this.getCurrentColor();
|
|
Entities.editEntity(this.entityID, newProperties);
|
|
}
|
|
};
|
|
|
|
var moodLightInstances = [];
|
|
|
|
var initialized = false;
|
|
|
|
function update(deltaTime) {
|
|
if (!initialized) {
|
|
if (Entities.serversExist() && Entities.canRez()) {
|
|
Entities.setPacketsPerSecond(60000);
|
|
moodLights.forEach(function(moodLight) {
|
|
moodLightInstances.push(new MoodLight(moodLight.properties, moodLight.schedule));
|
|
});
|
|
initialized = true;
|
|
Script.update.disconnect(update);
|
|
}
|
|
}
|
|
}
|
|
Script.update.connect(update);
|
|
|
|
Script.setInterval(function() {
|
|
moodLightInstances.forEach(function(moodLight) {
|
|
moodLight.update();
|
|
});
|
|
}, MILLISECONDS_PER_SECOND / UPDATE_FREQUENCY);
|