Exception inside runPreRender running 8th Wall Web with ownRunLoop=false - 8thwall-web

Is there an example that uses an app owned run loop (using ownRunLoop=false) somewhere?
When I create a trivial example based on the three.js app:
const onxrloaded = () => {
const canvas = document.getElementById('camerafeed')
// Open the camera and start running the camera run loop.
XR.run({canvas, ownRunLoop:false})
function render() {
XR.runPreRender(Date.now());
XR.runPostRender(Date.now());
}
function animate() {
requestAnimationFrame( animate );
render();
}
animate();
}
window.onload = () => {window.XR ? onxrloaded() : window.addEventListener('xrloaded', onxrloaded)}
I get the following error:
xrweb.js:3 Uncaught TypeError: Cannot read property '_c8EmAsm_flushTrace' of undefined
at Object.V [as runPreRender] (VM737 xrweb.js:3)
at render (index.js:121)
at animate (index.js:126)
at onxrloaded (index.js:128)
at window.onload (index.js:131)
Any thoughts on what the issue could be?

You might want to make sure that onStart has been called before calling runPre/PostRender.

Related

Implementing Three.js SSAOPass in AFrame

I was able to successfully integrate Threejs Effect composer in aframe as a component by exporting everything as THREE.Effectcomposer, THREE.SSAOPass etc. and adding the effect inside a aframe component and i tweaked the AFrame renderer to update the effects in the scene. OutlinePass from threejs worked fine in this code but SSAO is not working and i don't get any errors. Please someone help me figure out the problem. the code for SSAOPass looks like this
AFRAME.registerComponent('ssao', {
init: function () {
this.el.addEventListener('that', evt => this.onEnter());
this.el.addEventListener('mouseleave', evt => this.onLeave());
setTimeout(() => this.el.emit("that"), 2000);
},
onEnter: function () {
const scene = this.el.sceneEl.object3D;
const camera = this.el.sceneEl.camera;
const renderer = this.el.sceneEl.renderer;
const render = renderer.render;
const composer = new THREE.EffectComposer(renderer);
//let renderPass = new THREE.RenderPass(scene, camera);
//let outlinePass = new THREE.OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera);
const ssaoPass = new THREE.SSAOPass( scene, camera, window.innerWidth, window.innerHeight );
//composer.addPass(renderPass);
//composer.addPass(outlinePass);
ssaoPass.kernelRadius = 16;
composer.addPass( ssaoPass );
// let objects = [];
// this.el.object3D.traverse(node => {
// if (!node.isMesh) return;
// objects.push(node);
// });
// outlinePass.selectedObjects = objects;
// outlinePass.renderToScreen = true;
// outlinePass.edgeStrength = this.data.strength;
// outlinePass.edgeGlow = this.data.glow;
// outlinePass.visibleEdgeColor.set(this.data.color);
// HACK the AFRAME render method (a bit ugly)
const clock = new THREE.Clock();
this.originalRenderMethod = render;
let calledByComposer = false;
renderer.render = function () {
if (calledByComposer) {
render.apply(renderer, arguments);
} else {
calledByComposer = true;
composer.render(clock.getDelta());
calledByComposer = false;
}
};
},
onLeave: function () {
this.el.sceneEl.renderer.render = this.originalRenderMethod;
},
remove: function () {
this.onLeave();
}
});
I have also created a glitch project which i am sharing here. Please feel free to join and collaborate in my project
Edit link: https://glitch.com/edit/#!/accessible-torpid-partridge
Site link:https://accessible-torpid-partridge.glitch.me
Thanks in advance
The code is correct, all you need is to tweak the exposed SSAOShader uniforms: SSAOPass.kernelRadius, SSAOPass.minDistance, SSAOPass.maxDistance - like in the Three.js example.
Keep in mind - the scale in the example is huge, so the values will need to be different in a default aframe scene.
It's a good idea to be able to dynamically update a component (via setAttribute() if you properly handle updates), so you can see what's going on in realtime. Something like I did here - SSAO in a-frame (also based on Don McCurdys gist.
I've used some basic HTML elements, most threejs examples use dat.GUI - it is made for demo / debug tweaks.

How to close previous EventSource

<button onclick="hoge()">hoge</button>
<script>
function hoge(){
if(es){
es.close()
}
var es = new EventSource('/hoge')
es.onmessage = function(e) {
console.log(e)
}
}
</script>
I want to save resources, so it clicked and start connect EventSource.
The new connection start each time clicked, so I want to disconnect the previous connection.
I tried the above code but it didn't work. How should I do please.
You don't have the actual scope of the first EventSource when you call the function the second time, so the variable es is empty for you even though you have an EventSource already instantiated.
I am not sure why do you close and recreate the EventSource in the first place, but here is a solution for your exact problem:
Try this:
<script>
var eventSource;
function hoge(){
if(eventSource){
eventSource.close()
}
eventSource = new EventSource('/hoge')
eventSource.onmessage = function(e) {
console.log(e)
}
}
</script>
Have in mind that the eventSource is located in the global scope(or in other words, it is directly attached to the window object in the context of a browser) this way, so you might want to wrap the whole code in a module or at least in another function. In short, use this:
<script>
(function() {
var eventSource;
function hoge(){
if(eventSource){
eventSource.close()
}
eventSource = new EventSource('/hoge')
eventSource.onmessage = function(e) {
console.log(e)
}
}
})();
</script>

requestAnimationFrame type error in object

hi i'm trying to use requestAnimationFrame for my game and I actually use this code below, but as you can see ".bind()" create every loop a new function that slow down my game... I'm looking for a "efficient" solution for the best perfomance, thank you in advance :D
function myClass() {
this.loop = function() {
window.requestAnimationFrame(this.loop.bind(this));
/* here myGameLoop */
}
this.loop();
}
above code works but is slow.. instead this "standard" code give me "Type error":
window.requestAnimationFrame(this);
I have also found e tried this Q&A: requestAnimationFrame attached to App object not Window works just ONE time then give the same "Type error" :(
try if you don't believe me: http://jsfiddle.net/ygree/1 :'(
Without knowing the whole story of your object (what else is in there); you could simplify life by just doing this:
function myClass() {
var iHavAccessToThis = 1;
function loop() {
iHavAccessToThis++;
/* here myGameLoop */
requestAnimationFrame(loop);
}
loop();
//if you need a method to start externally use this instead of the above line
this.start = function() { loop() }
//...
return this;
}
Now you don't need to bind anything and you access local scope which is fast.
And then call:
var class1 = new myClass();
class1.start();

dojo 1.7+ timer/setInterval misunderstanding

I have a javascript code that creates a simple clock.
define([
"dojo/_base/declare",
"dojo/dom",
"dojo/date/locale",
"dojo/_base/event"
],
function(declare, dom, locale, event) {
return declare([], {
...
...
createClock : function() {
html_time = dom.byId("time");
window.setInterval(this.tick(), 1000);
}
});
});
JS code is working correctly! Also, I have a html code:
<body>
<script>
require([ "gui/common/Clock"
],
function(Clock) {
var clock = new Clock();
clock.createClock();
});
</script>
Current time: <span id="time"></span>
...
But if I run the code in the browser, then I get an error:
Error: useless setInterval call (missing quotes around argument?)
[Break On This Error]
window.setInterval(this.tick(), 1000);
In the browser the time appears, but it does not tick. Anybody can explain what is my problem?
Do not execute the method: window.setInterval(this.tick, 1000);
Also to execute tick in this scope, use lang.hitch as of dojo/_base/lang module:
window.setInterval(lang.hitch(this, "tick"), 1000);
You can find some inspiration in my answer to How to do something while a dojo xhr request is waiting or loading.

Getting External Interface to work with swf object, can't figure out what I'm doing wrong

I'm using swf object to embed a swf. I'm trying to user external interface to to call a flash function from JS, but having trouble. I've searched all the docs, read a ton of stuff, and I'm convinced I'm doing it right. Can anyone point out where the problem might be?
var flashvars = {};
var params = {wmode:"opaque", allowscriptaccess:"always" };
var attributes = {id:"MySwf", name:"MySwf"};
swfobject.embedSWF("MySwf.swf", "flashContent", "600", "400", "9.0.0", "swfs/expressInstall.swf", flashvars, params, attributes,function(e){
if(e.success){
_flashRef = e.ref;
testExternalInterface();
}else{
alert("We are sorry, flash is required to view this content.");
}
});
function testExternalInterface(){
var swf = document.getElementById("MySwf");
swf.sendMeTheGoods("TEST TEST");
};
Above is the embed code and js function in my flash I have
if (ExternalInterface.available)
{
trace("adding external interface");
ExternalInterface.addCallback("sendMeTheGoods", sendMeTheGoods);
}
public function sendMeTheGoods(text:String):void
{
trace("setting vars")
trace(text);
txtYouSent.text = text;
}
I'm getting the error Uncaught TypeError: Object # has no method 'sendMeTheGoods'
I've tried both referenceing document.getElementById("MySwf"); and document.getElementById("flashContent"); and I get the error both ways. Any suggestions?
the external interface API is not immediately available, it takes a second for it to be ready. your callback is likely happening before Flash Player has initialized the EI API. try adding a delay in the callback, delaying the invocation of your 'test' function.
var swf = navigator.appName.indexOf("Microsoft") != -1 ? window["MySwf"] : document["MySwf"];