How to spawn object after 6 min in A-frame webvr? - aframe

I am beginner to A-frame. so is there anyone who can help to solve this stuff,
I am stuck to spawn object after 6 second from starting of WebVR A-Frame in browser.
I can able to see the object in the browser but unable to set spawn time 6-second late from the start time of the WebVR.

You can create an object in js with document.createElement():
var box = document.createElement("a-box")
document.querySelector("a-scene").appendChild(box)
Fiddle here.
For the 6 seconds bit, use setTimeout(function() {}, ms). You can also add an event listener to the scene, listening when the scene was loaded, or when the renderer loop has started
scene.addEventListener("loaded", (e)=>{....
scene.addEventListener("renderstart", (e)=>{...
Docs on scene events here.

Related

Qt measuring rendering time during which application is frozen

I have a Qt application, where, among other things, there is a function render which goes through a list of objects and creates for each an according (subclassed) QGraphicsPathItem which it then puts as a child in a (subclassed) QGraphicsScene. (It is done in the code below through a visitor GGObjConstructor which gets initialized with the variable scene which is the scene where the items are to be added to).
XTimer timer;
timer.start();
gobjlist gobjlis = ogc._gobjectlis;
GGObjConstructor ggoc(scene, z_value, bkground_color);
for(auto obj: gobjlis) {
obj->exec( &ggoc );
}
timer.stop();
My class XTimer is used in an obvious way to measure the time for this proceeding.
Now the problem is: Only the time spent in the loop where all the items are prepared and inserted into the scene is measured by timer. For a typical example with ~165000 items this gives about 7.5 sec as timer-value at reaching timer.stop(). But the application is after these 7.5 sec still frozen, with the screen-window where the scene is to by displayed yet invisible and only after about 25 sec (hand-stopped) suddenly the display window appears with all the items to be displayed.
Now of course I would like to measure these "freeze time" (or time till the application becomes responsive again, or maybe time till display window appears). But I found no way to do this although I looked some time through stackoverflow or the net in general. The best hint I found was
stackoverflow question
The answer there seemed to imply, that it would be not really simple to achieve (overriding paintEvent method and such things).
Question: Is this true? Or is there a simple way to measure the time till the application becomes responsive again/the image is really displayed?
I had a similar problem with an application once, where I wanted to measure the time the app freezes to figure out with logging what was causing these freezes. What I came up was to measure how long the Eventloop of the mainthread was not responding, because this directly corresponds to a frozen app.
The basic idea is to not run a QApplication but inherit from QApplication and override the notify() function. Some apps do this anyway to catch exceptions which would otherwise break the eventloop. Here is some pseudo-code which should bring the idea across:
bool MyApplication::notify( QObject * receiver, QEvent * event )
{
// something like storing current time like:
// auto start = std::chrono::system_clock::now();
// auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(start - end );
// if( elapsed.count() > 1000 ){
// log something like: Mainthread responds again after <elapsed> seconds
// }
// Note that end must be a member variable
// end = start;
return QApplication::notify(receiver, event);
}
Note 1: If your app does not continuesly run through notify() you can for testing purposes introduce a dummy QTimer which triggers faster than the logging time threshold.
Note 2: if you use multiple threads, esp. QThreads it could be necessary to filter the receiver object and perform that code only if the reciever is in the mainthread.
With this code you can log every freeze of the main-thread (frozen GUI) and determine the length of the freeze. With proper logging you can figure out whats causing the freezes.
Keep in mind that this will only log after the freeze has resolved!
Addition:
It is more complicated and slow, but for debugging/investigation purposes you can store the last event and Object-Tree of the reciever and log that as well. Than you even know which was the last event which triggered the freeze and the recieving Object.

How to automatically run a code from javafx new Scene

I am completely new to Java and I am learning it while developing an app for a school project.
Image Link
I want to code the above program. In it ,
The user will click Ready button in screen 1.
Then screen two will appear and an image of a butterfly will be shown in a order given by me[Preset using a CSV file] Like shown in screen 2 and 3.
Finally, a button set will appear in the grid and user has to select the buttons in the order of the butterfly appearance.
I am stuck in finding a way to start screen 2 and automatically play the butterfly sequence.
I tried putting the image.setimage() on the initialize() block in my screen 2 controller with a delay in-between each setimage() . but it dosent work.
Anyone can suggest me a way to handle this kind of task? Thank a lot in advance.
The issues often seen with this kind of code for beginners are doing sleep or some other long-running operation on the application thread to do some animation. However blocking the javafx application thread results in the scene not being updated resulting in a freeze of the gui.
You either need to move the long-running parts of this animation to a background thread and use Platform.runLater for any GUI updates or use something designed for this exact purpose. There are multiple classes that could be useful in the javafx.animation package, but the most convenient of them seems to be Timeline:
Store the sequence of movements in a suitable data structure and use the Timeline to trigger an event handler in regular intervals to update the gui:
List<FieldIndices> fieldIndices = ...
final Iterator<FieldIndices> iterator = fieldIndices.iterator();
final Timeline timeline = new Timeline();
timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(1), evt -> {
if (iterator.hasNext()) {
moveButterfly(iterator.next());
} else {
removeButterfly();
timeline.stop();
}
}));
timeline.setCycleCount(Animation.INDEFINITE); // repeat until stop is called
timeline.play();
Now all that's left for you to implement is reading the data to a list and implementing the logic of moving the butterfly to a new position.
Note that I do not actually recommend using more than 2 scenes: The user will expect the same position for the buttons and the "fields" showing the butterfly. If you design 2 fxmls any adjustment to one of the scene would require you to do the same adjustments to the other scene. This makes the layout hard to maintain. The alternative requires you to create the scene in java code, but the repetitive nature of the scenes makes this a good idea anyways. (The alternative is injecting 16 fields to the controller and collecting them into a suitable data structure; This is error prone and any change of one of the buttons would probably require 16 changes in the fxml. Use a nested for loop and you need to write the logic for creating a button only once storing the buttons in e.g. a nested array can be done at the same time...)
As I understand, you wanna play butterfly sequence once 2nd stage is shown...To achieve that, you could try something like:
List positions = new ArrayList(); //places to show butterfly (e.g. table cells)
secondStage.setOnShown(windowEvent -> {
// update UI with Pltform.runLater()
// moveButerflyTo() is your method to place butterfly on given place
positions.forEach(position -> Platform.runLater(() -> moveButerflyTo(position)));
});
I didn't try this but it do the job...

Can aframe-state-component track state across scenes?

I have an (angular 5 based) a-frame app that has two scenes. I want to keep track of application state such as config parms using the aframe-state-component component. I want to access the cumulative state across both scenes. However, empirically it seems that every time I switch to the other scene all the variables in the state are reset to their initial state.
Also, the fact that you can access the state variables using a statement like:
AFRAME.scenes[0].systems.state.state.score
suggests to me that the state is tied to one scene only (scenes[0] being equal to the current scene).
At first I thought it was an angular issue as the supposed singleton service where I initialized state was being initialized on every scene transfer. But I discovered that linking using the angular router:
this.router.navigate([(evt.target as any).previousSibling.getAttribute('link').href, {}])
Instead of the default:
window.location = this.data.href
Fixed that problem. So it now appears to be an issue with A-frame.
Is the notion that this component can only be used intra-scene and not inter-scene a correct assumption?
Note: I'm also experimenting with angular-redux/store and it seems to have no problem retaining state across scenes, but I'd rather use aframe-state-component as it seems simpler.
You can store in localStorage and restore on load. Something like:
window.addEventListener('beforeunload', () => {
localStorage.setItem('state', JSON.parse(state));
});
initialState: localStorage.getItem('state')
? JSON.parse(localStorage.getItem('state'))
: {
// Initial state...
}
EDIT: Realized you meant for in-app scene changes? You can do something similar. When a scene is unloaded, store it somewhere, then state component checks if it exists?
The state component doesn't seem to store the states, so It would work if you had two scenes on one page:
<a-scene></a-scene>
<a-scene visible="false"></a-scene>
and switch them by setting the visible attribute. I also shows that AFRAME.scenes refer to scenes on the page, since you can log AFRAME.scenes[0] and AFRAME.scenes[1] in the above "example" (or in this fiddle).

A-Frame: How to provide sound fadeout to eliminate audio click upon sound termination

A-frame provides easy to use and powerful audio capabilites via its <sound> component.
After playing around with various sound options such as native html5 for my game (in progress), I came to the conclusion that A-frame sound is the best option because it automatically provides spatialized sound (e.g. that varies with head rotation), as well as varying in intensity as you near the sound source -- things that increase VR presence and all for the cost of defining a simple html tag.
Unfortunately, A-frame doesn't provide a fadeout utility to taper the sound upon stoppage, and thus can generates a distinctly audible and annoying click on some waveforms, esp. sounds that are of variable length and not tapered in the waveform itself (for instance, a space ship's thrust). This is a well known problem with computer audio.
I was able to find some html5 audio solutions and a really good three.js audio three.js audio solution, but I could find none specific to A-frame.
What's the best way to taper out a sound in A-frame to reduce/eliminate this click?
Introduction
A-frame sound audio wraps the three.js positional audio API, which in turns wraps native html 5 audio. Most solutions out there are tailored for either pure html5 or for pure three.js. Since A-frame is a hybrid of the two apis, none of the provided solution are great fits for A-frame.
After two false starts at coming up with something, I disovered tween.js, which is not only built-in to A-frame (don't even have to download the library), but is also a useful API to know for other forms of computer animation. I provide the main solution here as well as a plunker in the hopes that others can find something useful.
Note that you don't need to do this for short burst sounds like bullets firing. These sounds have a fixed lifetime, so presumably whoever creates the waveform makes sure to taper them in and out. Also, I only deal with fade out, not fade in becuase the sound I needed only had problems with fadeout. A general solution would include fadein as well.
Solution
1) We start off with creating a real basic scene onto which we can our audio:
<a-scene>
<a-assets>
<audio id="space-rumble" src="https://raw.githubusercontent.com/vt5491/public/master/assets/sounds/space-rumble.ogg" type="audio/ogg"></audio>
crossorigin="anonymous"
type="audio/ogg"></audio>
</a-assets>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"
sound="src: #space-rumble; volume: 0.9"
></a-box>
</a-scene>
The cube and scene in this solution are really just placeholders -- you don't need to enter VR mode to click the buttons and test the sound.
2) The code presents three buttons: one to start the sound, one to "hard" stop it using the A-frame default, and a third to "easy" stop it using tween to taper it down to zero. A fourth input allows you to vary the taper time. While it might look like quite a bit of code, keep in mind about 50% is just html boilerplate for the buttons, and is not part of the solution "proper":
// created 2017-10-04
function init() {
let main = new Main();
}
function Main() {
let factory = {};
console.log("entered main");
factory.boxEntity = document.querySelector('a-box');
factory.sound = factory.boxEntity.components.sound;
factory.volume = {vol: factory.sound.data.volume};
factory.boxEntity.addEventListener('sound-loaded', ()=> {console.log('sound loaded')});
factory.startBtn =document.querySelector('#btn-start');
factory.startBtn.onclick = ( function() {
this.sound.stopSound();
let initVol = factory.sound.data.volume;
this.volume = {vol: initVol}; //need to do this every time
this.sound.pool.children[0].setVolume(initVol);
console.log(`onClick: volume=${this.sound.pool.children[0].getVolume()}`);
this.sound.currentTime = 0.0;
if( this.tween) {
this.tween.stop();
}
this.sound.playSound();
}).bind(factory);
factory.hardStopBtn =document.querySelector('#btn-hard-stop');
factory.hardStopBtn.onclick = (function() {
this.sound.stopSound();
}).bind(factory);
factory.easyStopBtn =document.querySelector('#btn-easy-stop');
factory.easyStopBtn.onclick = (function() {
let sound = factory.sound;
this.tween = new TWEEN.Tween(this.volume);
this.tween.to(
{vol: 0.0}
, document.querySelector('#fade-out-duration').value);
this.tween.onUpdate(function(obj) {
console.log(`onUpdate: this.vol=${this.vol}`);
sound.pool.children[0].setVolume(this.vol);
console.log(`onUpdate: pool.children[0].getVolume=${sound.pool.children[0].getVolume()}`);
});
// Note: do *not* bind to parent context as tween passes it's info via 'this'
// and not just via callback parms.
// .bind(factory));
this.tween.onComplete(function() {
sound.stopSound();
console.log(`tween is done`);
});
this.tween.start();
// animate is actually optional in this case. Tween will count down on it's
// own clock, but you might want to synchronize with your other updates. If this
// is an a-frame component, then you can just use the 'tick' method.
this.animate();
}).bind(factory);
factory.animate = () => {
let id = requestAnimationFrame(factory.animate);
console.log(`now in animate`);
let result = TWEEN.update();
// cancelAnimationFrame is optional. You might want to invoke this to avoid
// the overhead of repeated animation calls. If you are putting this in an
// a-frame 'tick' callback, and there's other tick activity, you
// don't want to call this.
if(!result) cancelAnimationFrame(id);
}
return factory;
}
Analysis
Here are some relevant items to be aware of.
Mixed API's
I am calling some native A-frame level calls:
sound.playSound()
sound.stopSound()
and one html5 level call:
this.sound.currentTime = 0.0;
but most of the "work" is in three.js level calls:
this.sound.pool.children[0].setVolume(initVol);
This does make it a little confusing, but no single api is "complete" and thus I had to use all three. In particular, we have to do a lot at the level that is wrapped by A-frame. I learned most of this by looking at the aframe source for the sound component
Sound Pools
Aframe allows multiple threads for each sound, so that you can have the same sound fire off before the prior one has completed. This is controlled by the poolSize property on the sound component. I'm only dealing with the first sound. I should probably loop over the pool elements like so:
this.pool.children.forEach(function (sound) {
..do stuff
}
});
But doing the first one has worked well enough so far. Time will tell if this is sustainable.
'this' binding
I chose to implement all the functionality using a factory object pattern, and not placing all the methods and variables in the global document space. This mimics the enviornment you would have if you're implementing in Angular2 or as a native A-frame component. I mention this because we now have callbacks nested inside function nested inside a wrapping "main" function. Thus be aware that "this" binding can come into play. I bound most of the support functions to the factory object, but do not bind the tween callbacks, as they are passed information in their "this" context, and not passed via parms. I had to resort to closures for the callbacks to get access to the instances variables of the containing class. This is just standard javascript "callback hell" stuff, but just keep in mind it can get confusing if you're not careful.
canceled animation
If you have a tick function already, use that to call TWEEN.update(). If you're only fading out sound, then it's overkill to have an animation loop running all the time, so in this example I dynamically start and stop the animation loop.
tween can be chained.
Tweens can be chained in jquery fluent API style as well.
Conclusion
Using tween.js to phase out the sound definitely feels like the right solution. It takes care of a lot of the overhead, and design considerations. It also feels much faster, smoother, and robust than the native html5 calls I previously used. However, it's pretty obvious that it's not trivial to get this working at the application level. A fadeout property, implemented in Tween.js, seems like it should be part of the A-frame sound component itself. But until that time, maybe some people will find some of what I provide here useful in some form. I'm only currently learning about html audio myself so apologies if I'm making this seem harder than it really is.

Flex addEventListener - how to refresh the screen during called event?

I can't seem to find the answer to what I would have thought was a common problem.
What I want to do this is:
1. Show the Open File Dialog
2. Process the file selected
3. During processing the file, report progress to the User
I have a file defined, and am using the browseForOpen and AddEventListener:
public var fileInput:File = new File();
fileInput.browseForOpen("Open file",[filter]);
fileInput.addEventListener(Event.SELECT, onFileSelect);
// Step 2 - function gets called to process the file
private function onFileSelect(e:Event):void
{
// Step 3 - do some processing, and at intervals report progress to the screen
}
My issue is - any changes to the screen within the event listener do not get done until the function is complete.
Any help would be appreciated,
Thanks
Start a timer perhaps and let it check status of a variable(that denotes processing progress) as a separate running function it would not be predisposed to waiting on the parent function.
[ to be clear Im saying call a sperate function from the timer.]
But I am inclined to agree with Flextras.com in that most times I have done this the processing was milliseconds so just didnt get seen.
In Step 3, if you are doing some cpu intensive job(like huge xml parsing), then you might be seeing this NOT updating problem. As Flex is single threaded, you better make use of Green threading concept.
You can read about Green Threading here.

Resources