diff --git a/examples/tests/scriptableResourceTest.js b/examples/tests/scriptableResourceTest.js deleted file mode 100644 index ad338f3b6b..0000000000 --- a/examples/tests/scriptableResourceTest.js +++ /dev/null @@ -1,76 +0,0 @@ -// -// scriptableResourceTest.js -// examples/tests -// -// Created by Zach Pomerantz on 4/20/16. -// Copyright 2016 High Fidelity, Inc. -// -// Preloads textures to play a simple movie, plays it, and frees those textures. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -// A model exported from blender with a texture named 'Picture' on one face. -var FRAME_URL = "http://hifi-production.s3.amazonaws.com/tutorials/pictureFrame/finalFrame.fbx"; -// A folder full of individual frames. -var MOVIE_URL = "http://hifi-content.s3.amazonaws.com/james/vidtest/"; - -var NUM_FRAMES = 158; // 158 available -var FRAME_RATE = 30; // 30 default - -var center = Vec3.sum( - Vec3.sum(MyAvatar.position, { x: 0, y: 0.5, z: 0 }), - Vec3.multiply(1, Quat.getFront(Camera.getOrientation())) -); - -// Left-pad num with 0s until it is size digits -function pad(num, size) { - var s = num + ""; - while (s.length < size) s = "0" + s; - return s; -} - -var pictureFrameProperties = { - name: 'scriptableResourceTest Picture Frame', - type: 'Model', - position: center, - modelURL: FRAME_URL, - dynamic: true, -} -var pictureFrame = Entities.addEntity(pictureFrameProperties); - -var frames = []; - -// Preload -var numLoading = 0; -for (var i = 1; i <= NUM_FRAMES + 1; i++) { - var padded = pad(i, 3); - var filepath = MOVIE_URL + padded + '.jpg'; - var texture = TextureCache.prefetch(filepath); - frames.push(texture); - if (!texture.loaded) { - numLoading++; - texture.loadedChanged.connect(function() { - numLoading--; - if (!numLoading) play(); - }); - } -} - -function play() { - var frame = 0; - var movieInterval = Script.setInterval(function() { - Entities.editEntity(pictureFrame, { textures: JSON.stringify({ Picture: frames[frame].url }) }) - frame += 1; - if (frame > NUM_FRAMES) { - Script.clearInterval(movieInterval); - Entities.deleteEntity(pictureFrame); - // free the textures at the next garbage collection - while (frames.length) frames.pop(); - // alternatively, the textures can be forcibly freed: - // frames.forEach(function(texture) { texture.release(); }); - Script.requestGarbageCollection(); - } - }, 1000 / FRAME_RATE); -} diff --git a/scripts/developer/tests/scriptableResource/lib.js b/scripts/developer/tests/scriptableResource/lib.js new file mode 100644 index 0000000000..ed3d746061 --- /dev/null +++ b/scripts/developer/tests/scriptableResource/lib.js @@ -0,0 +1,96 @@ +// +// lib.js +// scripts/developer/tests/scriptableResource +// +// Created by Zach Pomerantz on 4/20/16. +// Copyright 2016 High Fidelity, Inc. +// +// Preloads textures to play a simple movie, plays it, and frees those textures. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var NUM_FRAMES = 158; // 158 available +var FRAME_RATE = 30; // 30 default + +function getFrame(callback) { + // A model exported from blender with a texture named 'Picture' on one face. + var FRAME_URL = "http://hifi-production.s3.amazonaws.com/tutorials/pictureFrame/finalFrame.fbx"; + + var model = ModelCache.prefetch(FRAME_URL); + if (model.loaded) { + makeFrame(true); + } else { + model.loadedChanged.connect(makeFrame); + } + + function makeFrame(success) { + if (!success) { throw "Failed to load frame"; } + + var pictureFrameProperties = { + name: 'scriptableResourceTest Picture Frame', + type: 'Model', + position: getPosition(), + modelURL: FRAME_URL, + dynamic: true, + }; + + callback(Entities.addEntity(pictureFrameProperties)); + } + + function getPosition() { + // Always put it 5 meters in front of you + var position = MyAvatar.position; + var yaw = MyAvatar.bodyYaw + MyAvatar.getHeadFinalYaw(); + var rads = (yaw / 180) * Math.PI; + + position.y += 0.5; + position.x += - 5 * Math.sin(rads); + position.z += - 5 * Math.cos(rads); + + print(JSON.stringify(position)); + return position; + } +} + +function prefetch(callback) { + // A folder full of individual frames. + var MOVIE_URL = "http://hifi-content.s3.amazonaws.com/james/vidtest/"; + + var frames = []; + + var numLoading = 0; + for (var i = 1; i <= NUM_FRAMES; ++i) { + var padded = pad(i, 3); + var filepath = MOVIE_URL + padded + '.jpg'; + var texture = TextureCache.prefetch(filepath); + frames.push(texture); + if (!texture.loaded) { + numLoading++; + texture.loadedChanged.connect(function() { + --numLoading; + if (!numLoading) { callback(frames); } + }); + } + } + if (!numLoading) { callback(frames); } + + function pad(num, size) { // left-pad num with zeros until it is size digits + var s = num.toString(); + while (s.length < size) { s = "0" + s; } + return s; + } +} + +function play(model, frames, callback) { + var frame = 0; + var movieInterval = Script.setInterval(function() { + Entities.editEntity(model, { textures: JSON.stringify({ Picture: frames[frame].url }) }); + if (++frame >= frames.length) { + Script.clearInterval(movieInterval); + callback(); + } + }, 1000 / FRAME_RATE); +} + diff --git a/scripts/developer/tests/scriptableResource/movieTest.js b/scripts/developer/tests/scriptableResource/movieTest.js new file mode 100644 index 0000000000..61b2bf7942 --- /dev/null +++ b/scripts/developer/tests/scriptableResource/movieTest.js @@ -0,0 +1,42 @@ +// +// testMovie.js +// scripts/developer/tests/scriptableResource +// +// Created by Zach Pomerantz on 4/27/16. +// Copyright 2016 High Fidelity, Inc. +// +// Preloads textures, plays them on a frame model, and unloads them. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var entity; + +Script.include([ + '../../../developer/utilities/cache/cacheStats.js', + 'lib.js', +], function() { + getFrame(function(frame) { + entity = frame; + prefetch(function(frames) { + play(frame, frames, function() { + // Delete each texture, so the next garbage collection cycle will release them. + + // Setting frames = null breaks the reference, + // but will not delete frames from the calling scope. + // Instead, we must mutate it in-place to free its elements for GC + // (assuming the elements are not held elsewhere). + while (frames.length) { frames.pop(); } + + // Alternatively, forcibly release each texture without relying on GC. + // frames.forEach(function(texture) { texture.release(); }); + + Entities.deleteEntity(entity); + Script.requestGarbageCollection(); + }); + }); + }); +}); + +Script.scriptEnding.connect(function() { entity && Entities.deleteEntity(entity); }); diff --git a/scripts/developer/tests/scriptableResource/prefetchTest.js b/scripts/developer/tests/scriptableResource/prefetchTest.js new file mode 100644 index 0000000000..cda805967e --- /dev/null +++ b/scripts/developer/tests/scriptableResource/prefetchTest.js @@ -0,0 +1,33 @@ +// +// testPrefetch.js +// scripts/developer/tests/scriptableResource +// +// Created by Zach Pomerantz on 4/27/16. +// Copyright 2016 High Fidelity, Inc. +// +// Preloads textures and unloads them. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +Script.include([ + '../../../developer/utilities/cache/cacheStats.js', + 'lib.js', +], function() { + prefetch(function(frames) { + // Delete each texture, so the next garbage collection cycle will release them. + + // Setting frames = null breaks the reference, + // but will not delete frames from the calling scope. + // Instead, we must mutate it in-place to free its elements for GC + // (assuming the elements are not held elsewhere). + while (frames.length) { frames.pop(); } + + // Alternatively, forcibly release each texture without relying on GC. + // frames.forEach(function(texture) { texture.release(); }); + + Script.requestGarbageCollection(); + }); +}); +