Last active
January 3, 2018 22:54
-
-
Save PhilipRosedale/5aee80677b60678a24db7e092cb2209d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// nearbyUpdate.js | |
// examples/entityScripts | |
// | |
// Philip Rosedale, December 26, 2017 | |
// | |
// This entity script is a way to efficiently update entities based on how far away from you they are, | |
// dropping the update rate as a function of distance squared. This works well for the most typical case of a | |
// large number of entities arranged roughly randomly on a sheet. | |
// | |
// This is a simple form of distributed computing, with distant items computed less frequently, and with a | |
// minimal update frequency set by MINIMUM_UPDATE_MSECS, so that you do not update something if someone else | |
// has done it more recently. | |
// | |
var MINIMUM_UPDATE_MSECS = 150; | |
var AVERAGE_UPDATE_SECONDS_PER_METER_SQUARED = 3; | |
(function() { | |
var _this; | |
// this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember | |
// our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) | |
ExampleUpdate = function() { | |
_this = this; | |
}; | |
ExampleUpdate.prototype = { | |
// getDelay() decides how often to check on this entity, based on how far away it is. | |
getDelay: function() { | |
var distance = Vec3.distance(MyAvatar.position, Entities.getEntityProperties(_this.entityID).position); | |
var delay = distance * distance / AVERAGE_UPDATE_SECONDS_PER_METER_SQUARED * 1000 * Math.random(); | |
return delay; | |
}, | |
// preload() will be called when the entity has become visible (or known) to the interface | |
// it gives us a chance to set our local JavaScript object up. In this case it means: | |
// Figure out an initial random delay based on how far we are from the object, | |
preload: function(entityID) { | |
this.entityID = entityID; | |
this.myTimeout = Script.setTimeout(this.maybeUpdate, this.getDelay()); | |
}, | |
// maybeUpdate() is where we check to see if the entity needs to be updated, since someone else | |
// might have updated it. | |
maybeUpdate: function() { | |
if (Date.now() - Entities.getEntityProperties(_this.entityID, "lastEdited").lastEdited / 1000 > MINIMUM_UPDATE_MSECS) { | |
_this.update(); | |
} | |
_this.myTimeout = Script.setTimeout(_this.maybeUpdate, _this.getDelay()); | |
}, | |
// update() is where we do whatever we really want to do to the entity... | |
update: function() { | |
// | |
// In this simple example of a complex system we will wander around looking for other | |
// sphere entities that we are touching/interpenetrating, and swap colors with them if we | |
// are the dominant color in a rock-scissors-paper (RGB) way. | |
// | |
var RED = { red: 255, green: 0, blue: 0 }; | |
var GREEN = { red: 0, green: 255, blue: 0 }; | |
var BLUE = { red: 0, green: 0, blue: 255 }; | |
var MAX_MOVEMENT_UPDATE = 0.0; | |
var properties = Entities.getEntityProperties(_this.entityID, ["position", "dimensions", "color"]); | |
nearbyEntities = Entities.findEntities(properties.position, properties.dimensions.x / 2); | |
// | |
// Check for someone to conquer! | |
// | |
for (i = 0; i < nearbyEntities.length; i++) { | |
var nearbyProperties = Entities.getEntityProperties(nearbyEntities[i], ["position", "color", "type"]); | |
if (properties.color.red && nearbyProperties.color.green) { | |
Entities.editEntity(nearbyEntities[i], { color: RED }) | |
} else if (properties.color.green && nearbyProperties.color.blue) { | |
Entities.editEntity(nearbyEntities[i], { color: GREEN }) | |
} else if (properties.color.blue && nearbyProperties.color.red) { | |
Entities.editEntity(nearbyEntities[i], { color: BLUE }) | |
} | |
} | |
// Move a little! | |
Entities.editEntity(_this.entityID, | |
{ position: Vec3.sum(properties.position, | |
{ x: (Math.random() - 0.5) * MAX_MOVEMENT_UPDATE, | |
y: 0, | |
z: (Math.random() - 0.5) * MAX_MOVEMENT_UPDATE }) | |
} | |
); | |
}, | |
// unload() will be called when our entity is no longer available. It may be because we were deleted, | |
// or because we've left the domain or quit the application. In all cases we want to unhook our connection | |
// to the update signal | |
unload: function(entityID) { | |
Script.clearTimeout(this.myTimeout); | |
}, | |
}; | |
// entity scripts always need to return a newly constructed object of our type | |
return new ExampleUpdate(); | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment