From 1fcb90ad7fbcd357ca26c1e197d32984413271f8 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Wed, 27 Jan 2016 13:34:25 -0800 Subject: [PATCH 1/4] checkpoint --- examples/tests/performance/renderableMatrix.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/tests/performance/renderableMatrix.js b/examples/tests/performance/renderableMatrix.js index a1a0153f76..32a65c2afa 100644 --- a/examples/tests/performance/renderableMatrix.js +++ b/examples/tests/performance/renderableMatrix.js @@ -12,11 +12,11 @@ var Entities, Script, print, Vec3, MyAvatar, Camera, Quat; // Useful for testing the rendering, LOD, and octree storage aspects of the system. // -var LIFETIME = 60; +var LIFETIME = 20; // Matrix will be axis-aligned, approximately all in this field of view. // As special case, if zero, grid is centered above your head. var MINIMUM_VIEW_ANGLE_IN_RADIANS = 30 * Math.PI / 180; // 30 degrees -var ROWS_X = 10; +var ROWS_X = 17; var ROWS_Y = 10; var ROWS_Z = 10; var SEPARATION = 10; @@ -55,7 +55,9 @@ var o = Vec3.sum(MyAvatar.position, var totalCreated = 0; var startTime = new Date(); var totalToCreate = ROWS_X * ROWS_Y * ROWS_Z; -print("Creating " + totalToCreate + " entities starting at " + startTime); +print("Creating " + totalToCreate + " " + JSON.stringify(TYPES_TO_USE) + + " entities extending in positive x/y/z from " + JSON.stringify(o) + + ", starting at " + startTime); Script.setInterval(function () { if (!Entities.serversExist() || !Entities.canRez()) { From 5376ba9b7d6ce4da373d7a5a57ed4cd9914bcbca Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Fri, 29 Jan 2016 11:27:27 -0800 Subject: [PATCH 2/4] update to match lod doc --- examples/entityScripts/simpleKeepAway.js | 37 ++++++ .../tests/performance/renderableMatrix.js | 50 ++++++-- examples/tests/performance/simpleKeepAway.js | 113 ++++++++++++++++++ examples/tests/performance/staticEdits.js | 5 +- examples/tests/performance/tribbles.js | 6 +- 5 files changed, 192 insertions(+), 19 deletions(-) create mode 100644 examples/entityScripts/simpleKeepAway.js create mode 100644 examples/tests/performance/simpleKeepAway.js diff --git a/examples/entityScripts/simpleKeepAway.js b/examples/entityScripts/simpleKeepAway.js new file mode 100644 index 0000000000..8550477dbb --- /dev/null +++ b/examples/entityScripts/simpleKeepAway.js @@ -0,0 +1,37 @@ +(function () { + // The attached entity will move away from you if you are too close, checking at distanceRate. + // See tests/performance/simpleKeepAway.js + var entityID, + distanceRate = 1, // hertz + distanceAllowance = 3, // meters + distanceScale = 0.5, // meters/second + distanceTimer; + + function moveDistance() { // every user checks their distance and tries to claim if close enough. + var me = MyAvatar.position, + ball = Entities.getEntityProperties(entityID, ['position']).position; + ball.y = me.y; + var vector = Vec3.subtract(ball, me); + + if (Vec3.length(vector) < distanceAllowance) { + Entities.editEntity(entityID, {velocity: Vec3.multiply(distanceScale, Vec3.normalize(vector))}); + } + } + + this.preload = function (givenEntityID) { + var properties = Entities.getEntityProperties(givenEntityID, ['userData']), + userData = properties.userData && JSON.parse(properties.userData); + entityID = givenEntityID; + if (userData) { + distanceRate = userData.distanceRate || distanceRate; + distanceAllowance = userData.distanceAllowance || distanceAllowance; + distanceScale = userData.distanceScale || distanceScale; + } + + // run all the time by everyone: + distanceTimer = Script.setInterval(moveDistance, distanceRate); + }; + this.unload = function () { + Script.clearTimeout(distanceTimer); + }; +}) diff --git a/examples/tests/performance/renderableMatrix.js b/examples/tests/performance/renderableMatrix.js index 32a65c2afa..f5eb33554a 100644 --- a/examples/tests/performance/renderableMatrix.js +++ b/examples/tests/performance/renderableMatrix.js @@ -11,25 +11,51 @@ var Entities, Script, print, Vec3, MyAvatar, Camera, Quat; // Creates a rectangular matrix of objects with no physical or entity changes after creation. // Useful for testing the rendering, LOD, and octree storage aspects of the system. // +// NOTE: to test the full rendering of the specified number of objects (as opposed to +// testing LOD filtering), you may want to set LOD to manual maximum visibility. var LIFETIME = 20; -// Matrix will be axis-aligned, approximately all in this field of view. -// As special case, if zero, grid is centered above your head. -var MINIMUM_VIEW_ANGLE_IN_RADIANS = 30 * Math.PI / 180; // 30 degrees var ROWS_X = 17; var ROWS_Y = 10; var ROWS_Z = 10; +// Entities will be populated from this list set by the script writer for different tests. +var TYPES_TO_USE = [ 'Box', 'Sphere']; +switch ('primitives') { // Quickly override the above by putting here one of the following case strings. +case 'particles': + TYPES_TO_USE = ['ParticleEffect']; + ROWS_X = ROWS_Z = 6; + break; +case 'lights': + TYPES_TO_USE = ['Light']; + ROWS_X = ROWS_Y = ROWS_Z = 5; + break; +case 'blocks': // 376 triangles/entity + TYPES_TO_USE = ["http://s3.amazonaws.com/hifi-public/marketplace/hificontent/Games/blocks/block.fbx"]; + ROWS_X = ROWS_Y = ROWS_Z = 10; + break; +case 'ramp': // 1,002 triangles/entity + TYPES_TO_USE = ["http://headache.hungry.com/~seth/hifi/curved-ramp.obj"]; + ROWS_X = ROWS_Y = 10; + ROWS_Z = 9; + break; +case 'trees': // 12k triangles/entity + TYPES_TO_USE = ["https://hifi-content.s3.amazonaws.com/ozan/dev/sets/lowpoly_island/CypressTreeGroup.fbx"]; + ROWS_X = ROWS_Z = 6; + ROWS_Y = 1; + break; +case 'web': + TYPES_TO_USE = ['Web']; + ROWS_X = ROWS_Z = 5; + ROWS_Y = 3; + break; +default: + // Just using values from above. +} +// Matrix will be axis-aligned, approximately all in this field of view. +// As special case, if zero, grid is centered above your head. +var MINIMUM_VIEW_ANGLE_IN_RADIANS = 30 * Math.PI / 180; // 30 degrees var SEPARATION = 10; var SIZE = 1; -var TYPES_TO_USE = [ // Entities will be populated from this list set by the script writer for different tests. - 'Box', - 'Sphere', - //'Light', - //'ParticleEffect', - //'Web', - //"https://hifi-content.s3.amazonaws.com/ozan/dev/sets/lowpoly_island/CypressTreeGroup.fbx", - //"http://s3.amazonaws.com/hifi-public/marketplace/hificontent/Games/blocks/block.fbx", -]; var MODEL_SCALE = { x: 1, y: 2, z: 3 }; // how to stretch out models proportionally to SIZE // Note that when creating things quickly, the entity server will ignore data if we send updates too quickly. // like Internet MTU, these rates are set by th domain operator, so in this script there is a RATE_PER_SECOND diff --git a/examples/tests/performance/simpleKeepAway.js b/examples/tests/performance/simpleKeepAway.js new file mode 100644 index 0000000000..d9b43ffbbd --- /dev/null +++ b/examples/tests/performance/simpleKeepAway.js @@ -0,0 +1,113 @@ +"use strict"; +/*jslint nomen: true, plusplus: true, vars: true*/ +var Vec3, Quat, MyAvatar, Entities, Camera, Script, print; +// +// Created by Howard Stearns +// 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 +// +// Drops a bunch of physical spheres which each run an entity script that moves away +// from you once a second if you are within range. +// +// This is a test of how many physical, entity-scripted objects can be around if +// they are mostly not doing anything -- i.e., just the basic overhead of such objects. +// They do need a moment to settle out of active physics after being dropped, but only +// a moment -- that's why they are in a sparse grid. + +var USE_FLAT_FLOOR = true; // Give 'em a flat place to settle on. +var ROWS_X = 30; +var ROWS_Z = 30; +var SEPARATION = 1; // meters +var LIFETIME = 60; // seconds +var DISTANCE_RATE = 1; // hz +var DISTANCE_ALLOWANCE = 3; // meters. Must be this close to cause entity to move +var DISTANCE_SCALE = 0.5; // velocity will be scale x vector from user to entity + +var SIZE = 0.5; +var TYPE = "Sphere"; +// Note that when creating things quickly, the entity server will ignore data if we send updates too quickly. +// like Internet MTU, these rates are set by th domain operator, so in this script there is a RATE_PER_SECOND +// variable letting you set this speed. If entities are missing from the grid after a relog, this number +// being too high may be the reason. +var RATE_PER_SECOND = 600; // The entity server will drop data if we create things too fast. +var SCRIPT_INTERVAL = 100; + +var GRAVITY = { x: 0, y: -9.8, z: 0 }; +var VELOCITY = { x: 0.0, y: 0.1, z: 0 }; + +var DAMPING = 0.75; +var ANGULAR_DAMPING = 0.75; + +var RANGE = 3; +var HOW_FAR_UP = 2; // for uneven ground + +var x = 0; +var z = 0; +var totalCreated = 0; +var xDim = ROWS_X * SEPARATION; +var zDim = ROWS_Z * SEPARATION; +var totalToCreate = ROWS_X * ROWS_Z; +var origin = Vec3.sum(MyAvatar.position, {x: xDim / -2, y: HOW_FAR_UP, z: zDim / -2}); +print("Creating " + totalToCreate + " origined on " + JSON.stringify(MyAvatar.position) + + ", starting at " + JSON.stringify(origin)); +var parameters = JSON.stringify({ + distanceRate: DISTANCE_RATE, + distanceScale: DISTANCE_SCALE, + distanceAllowance: DISTANCE_ALLOWANCE +}); + +var startTime = new Date(); +if (USE_FLAT_FLOOR) { + Entities.addEntity({ + type: 'Box', + name: 'keepAwayFloor', + lifetime: LIFETIME, + collisionsWillMove: false, + color: {red: 255, green: 0, blue: 0}, + position: Vec3.sum(origin, {x: xDim / 2, y: -1 - HOW_FAR_UP, z: zDim / 2}), + dimensions: {x: xDim + SEPARATION, y: 0.2, z: zDim + SEPARATION} + }); +} +Script.setInterval(function () { + if (!Entities.serversExist() || !Entities.canRez()) { + return; + } + + var i, numToCreate = Math.min(RATE_PER_SECOND * (SCRIPT_INTERVAL / 1000.0), totalToCreate - totalCreated); + for (i = 0; i < numToCreate; i++) { + properties = { + userData: parameters, + type: TYPE, + name: "keepAway-" + totalCreated, + position: { + x: origin.x + SIZE + (x * SEPARATION), + y: origin.y, + z: origin.z + SIZE + (z * SEPARATION) + }, + dimensions: {x: SIZE, y: SIZE, z: SIZE}, + color: {red: Math.random() * 255, green: Math.random() * 255, blue: Math.random() * 255}, + velocity: VELOCITY, + damping: DAMPING, + angularDamping: ANGULAR_DAMPING, + gravity: GRAVITY, + collisionsWillMove: true, + lifetime: LIFETIME, + script: Script.resolvePath("../../entityScripts/simpleKeepAway.js") + }; + Entities.addEntity(properties); + totalCreated++; + + x++; + if (x === ROWS_X) { + x = 0; + z++; + print("Created: " + totalCreated); + } + if (z === ROWS_Z) { + print("Total: " + totalCreated + " entities in " + ((new Date() - startTime) / 1000.0) + " seconds."); + Script.stop(); + } + } +}, SCRIPT_INTERVAL); diff --git a/examples/tests/performance/staticEdits.js b/examples/tests/performance/staticEdits.js index 61d75c9a9a..fc0708e741 100644 --- a/examples/tests/performance/staticEdits.js +++ b/examples/tests/performance/staticEdits.js @@ -13,9 +13,8 @@ var Entities, Script, print, Vec3, MyAvatar; // so that you can measure how many edits can be made. // var LIFETIME = 15; -var EDIT_FREQUENCY_TARGET = 60; // hertz var ROWS_X = 10; -var ROWS_Y = 1; +var ROWS_Y = 2; var ROWS_Z = 10; var SEPARATION = 10.0; var SIZE = 1.0; @@ -88,7 +87,7 @@ var creator = Script.setInterval(function () { if (z === ROWS_Z) { print("Total: " + totalCreated + " entities in " + ((new Date() - startTime) / 1000.0) + " seconds."); Script.clearTimeout(creator); - flasher = Script.setInterval(doFlash, Math.ceil((1 / EDIT_FREQUENCY_TARGET) * 1000)); + flasher = Script.setInterval(doFlash, 1000 / 60); // I.e., spin as fast as we have time for. Script.setTimeout(stopFlash, LIFETIME * 1000); } } diff --git a/examples/tests/performance/tribbles.js b/examples/tests/performance/tribbles.js index 1e7b6ddf39..da533f490a 100644 --- a/examples/tests/performance/tribbles.js +++ b/examples/tests/performance/tribbles.js @@ -14,7 +14,7 @@ var Vec3, Quat, MyAvatar, Entities, Camera, Script, print; // The _TIMEOUT parameters can be 0 for no activity, and -1 to be active indefinitely. // -var NUMBER_TO_CREATE = 120; +var NUMBER_TO_CREATE = 200; var LIFETIME = 60; // seconds var EDIT_RATE = 60; // hz var EDIT_TIMEOUT = -1; @@ -41,8 +41,6 @@ var RANGE = 3; var HOW_FAR_IN_FRONT_OF_ME = RANGE * 3; var HOW_FAR_UP = RANGE / 1.5; // higher (for uneven ground) above range/2 (for distribution) -var x = 0; -var z = 0; var totalCreated = 0; var offset = Vec3.sum(Vec3.multiply(HOW_FAR_UP, Vec3.UNIT_Y), Vec3.multiply(HOW_FAR_IN_FRONT_OF_ME, Quat.getFront(Camera.orientation))); @@ -87,7 +85,7 @@ Script.setInterval(function () { gravity: GRAVITY, collisionsWillMove: true, lifetime: LIFETIME, - script: "https://s3.amazonaws.com/hifi-public/scripts/entityScripts/tribble.js" + script: Script.resolvePath("../../entityScripts/tribble.js") }); totalCreated++; From d8069b6dbff90a205974fbacb5bfe8ec449ba082 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 1 Feb 2016 11:28:51 -0800 Subject: [PATCH 3/4] Whitespace and jslinting. --- examples/entityScripts/simpleKeepAway.js | 4 +- .../tests/performance/renderableMatrix.js | 60 +++++++++---------- examples/tests/performance/simpleKeepAway.js | 32 +++++----- 3 files changed, 48 insertions(+), 48 deletions(-) diff --git a/examples/entityScripts/simpleKeepAway.js b/examples/entityScripts/simpleKeepAway.js index 8550477dbb..87beaa8794 100644 --- a/examples/entityScripts/simpleKeepAway.js +++ b/examples/entityScripts/simpleKeepAway.js @@ -14,7 +14,7 @@ var vector = Vec3.subtract(ball, me); if (Vec3.length(vector) < distanceAllowance) { - Entities.editEntity(entityID, {velocity: Vec3.multiply(distanceScale, Vec3.normalize(vector))}); + Entities.editEntity(entityID, {velocity: Vec3.multiply(distanceScale, Vec3.normalize(vector))}); } } @@ -25,7 +25,7 @@ if (userData) { distanceRate = userData.distanceRate || distanceRate; distanceAllowance = userData.distanceAllowance || distanceAllowance; - distanceScale = userData.distanceScale || distanceScale; + distanceScale = userData.distanceScale || distanceScale; } // run all the time by everyone: diff --git a/examples/tests/performance/renderableMatrix.js b/examples/tests/performance/renderableMatrix.js index f5eb33554a..bde420129d 100644 --- a/examples/tests/performance/renderableMatrix.js +++ b/examples/tests/performance/renderableMatrix.js @@ -19,37 +19,37 @@ var ROWS_X = 17; var ROWS_Y = 10; var ROWS_Z = 10; // Entities will be populated from this list set by the script writer for different tests. -var TYPES_TO_USE = [ 'Box', 'Sphere']; +var TYPES_TO_USE = ['Box', 'Sphere']; switch ('primitives') { // Quickly override the above by putting here one of the following case strings. -case 'particles': - TYPES_TO_USE = ['ParticleEffect']; - ROWS_X = ROWS_Z = 6; - break; -case 'lights': - TYPES_TO_USE = ['Light']; - ROWS_X = ROWS_Y = ROWS_Z = 5; - break; -case 'blocks': // 376 triangles/entity - TYPES_TO_USE = ["http://s3.amazonaws.com/hifi-public/marketplace/hificontent/Games/blocks/block.fbx"]; - ROWS_X = ROWS_Y = ROWS_Z = 10; - break; -case 'ramp': // 1,002 triangles/entity - TYPES_TO_USE = ["http://headache.hungry.com/~seth/hifi/curved-ramp.obj"]; - ROWS_X = ROWS_Y = 10; - ROWS_Z = 9; - break; -case 'trees': // 12k triangles/entity - TYPES_TO_USE = ["https://hifi-content.s3.amazonaws.com/ozan/dev/sets/lowpoly_island/CypressTreeGroup.fbx"]; - ROWS_X = ROWS_Z = 6; - ROWS_Y = 1; - break; -case 'web': - TYPES_TO_USE = ['Web']; - ROWS_X = ROWS_Z = 5; - ROWS_Y = 3; - break; -default: - // Just using values from above. + case 'particles': + TYPES_TO_USE = ['ParticleEffect']; + ROWS_X = ROWS_Z = 6; + break; + case 'lights': + TYPES_TO_USE = ['Light']; + ROWS_X = ROWS_Y = ROWS_Z = 5; + break; + case 'blocks': // 376 triangles/entity + TYPES_TO_USE = ["http://s3.amazonaws.com/hifi-public/marketplace/hificontent/Games/blocks/block.fbx"]; + ROWS_X = ROWS_Y = ROWS_Z = 10; + break; + case 'ramp': // 1,002 triangles/entity + TYPES_TO_USE = ["http://headache.hungry.com/~seth/hifi/curved-ramp.obj"]; + ROWS_X = ROWS_Y = 10; + ROWS_Z = 9; + break; + case 'trees': // 12k triangles/entity + TYPES_TO_USE = ["https://hifi-content.s3.amazonaws.com/ozan/dev/sets/lowpoly_island/CypressTreeGroup.fbx"]; + ROWS_X = ROWS_Z = 6; + ROWS_Y = 1; + break; + case 'web': + TYPES_TO_USE = ['Web']; + ROWS_X = ROWS_Z = 5; + ROWS_Y = 3; + break; + default: + // Just using values from above. } // Matrix will be axis-aligned, approximately all in this field of view. // As special case, if zero, grid is centered above your head. diff --git a/examples/tests/performance/simpleKeepAway.js b/examples/tests/performance/simpleKeepAway.js index d9b43ffbbd..05c0dd8159 100644 --- a/examples/tests/performance/simpleKeepAway.js +++ b/examples/tests/performance/simpleKeepAway.js @@ -17,7 +17,7 @@ var Vec3, Quat, MyAvatar, Entities, Camera, Script, print; // a moment -- that's why they are in a sparse grid. var USE_FLAT_FLOOR = true; // Give 'em a flat place to settle on. -var ROWS_X = 30; +var ROWS_X = 30; var ROWS_Z = 30; var SEPARATION = 1; // meters var LIFETIME = 60; // seconds @@ -61,13 +61,13 @@ var parameters = JSON.stringify({ var startTime = new Date(); if (USE_FLAT_FLOOR) { Entities.addEntity({ - type: 'Box', - name: 'keepAwayFloor', - lifetime: LIFETIME, - collisionsWillMove: false, - color: {red: 255, green: 0, blue: 0}, - position: Vec3.sum(origin, {x: xDim / 2, y: -1 - HOW_FAR_UP, z: zDim / 2}), - dimensions: {x: xDim + SEPARATION, y: 0.2, z: zDim + SEPARATION} + type: 'Box', + name: 'keepAwayFloor', + lifetime: LIFETIME, + collisionsWillMove: false, + color: {red: 255, green: 0, blue: 0}, + position: Vec3.sum(origin, {x: xDim / 2, y: -1 - HOW_FAR_UP, z: zDim / 2}), + dimensions: {x: xDim + SEPARATION, y: 0.2, z: zDim + SEPARATION} }); } Script.setInterval(function () { @@ -75,17 +75,17 @@ Script.setInterval(function () { return; } - var i, numToCreate = Math.min(RATE_PER_SECOND * (SCRIPT_INTERVAL / 1000.0), totalToCreate - totalCreated); + var i, properties, numToCreate = Math.min(RATE_PER_SECOND * (SCRIPT_INTERVAL / 1000.0), totalToCreate - totalCreated); for (i = 0; i < numToCreate; i++) { properties = { userData: parameters, type: TYPE, name: "keepAway-" + totalCreated, - position: { - x: origin.x + SIZE + (x * SEPARATION), - y: origin.y, - z: origin.z + SIZE + (z * SEPARATION) - }, + position: { + x: origin.x + SIZE + (x * SEPARATION), + y: origin.y, + z: origin.z + SIZE + (z * SEPARATION) + }, dimensions: {x: SIZE, y: SIZE, z: SIZE}, color: {red: Math.random() * 255, green: Math.random() * 255, blue: Math.random() * 255}, velocity: VELOCITY, @@ -94,7 +94,7 @@ Script.setInterval(function () { gravity: GRAVITY, collisionsWillMove: true, lifetime: LIFETIME, - script: Script.resolvePath("../../entityScripts/simpleKeepAway.js") + script: Script.resolvePath("../../entityScripts/simpleKeepAway.js") }; Entities.addEntity(properties); totalCreated++; @@ -102,7 +102,7 @@ Script.setInterval(function () { x++; if (x === ROWS_X) { x = 0; - z++; + z++; print("Created: " + totalCreated); } if (z === ROWS_Z) { From ae10d4343ccad3042b995a7f1fc47949d35fa014 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Mon, 1 Feb 2016 11:47:33 -0800 Subject: [PATCH 4/4] Add data for a 2k triangle model. --- examples/tests/performance/renderableMatrix.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/tests/performance/renderableMatrix.js b/examples/tests/performance/renderableMatrix.js index bde420129d..46a197a04a 100644 --- a/examples/tests/performance/renderableMatrix.js +++ b/examples/tests/performance/renderableMatrix.js @@ -38,6 +38,11 @@ switch ('primitives') { // Quickly override the above by putting here one of the ROWS_X = ROWS_Y = 10; ROWS_Z = 9; break; + case 'gun': // 2.1k triangles/entity + TYPES_TO_USE = ["https://hifi-content.s3.amazonaws.com/ozan/dev/props/guns/nail_gun/nail_gun.fbx"]; + ROWS_X = ROWS_Y = 10; + ROWS_Z = 7; + break; case 'trees': // 12k triangles/entity TYPES_TO_USE = ["https://hifi-content.s3.amazonaws.com/ozan/dev/sets/lowpoly_island/CypressTreeGroup.fbx"]; ROWS_X = ROWS_Z = 6;