I'm trying to use the ported Three.JS for DART (Three.dart) and load an object file that is lying in my project root, in the root i also have the index.html and main.dart files.
Basically i have been following a demo found at https://github.com/threeDart/three.dart/tree/master/example/web_gl_loader_stl , there isn't one for the OBJLoader class there, but since those examples were written it has been implemented.
The code i'm using to try and load the object is the following:
loader = new OBJLoader();
loader.load('zergling.obj').then((object) {
var geometry = object.geometry;
var mesh = new Mesh(geometry, material);
mesh.position.setValues(0.0, -0.37, -0.6);
mesh.rotation.setValues(-Math.PI / 2, 0.0, 0.0);
mesh.scale.setValues(2.0, 2.0, 2.0);
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add(mesh);
});
The object is a simple zergling. I render the scene later on in the code but it doesn't seem to work.
I have looked at this thread How to load obj model via three.dart? aswell. But no luck after that.
Any comments of how i could proceed? Do you see any problems in the loading code? If not i could provide a gist with the entire codebase.
I don't use Three.dart and I had just a brief look at your code but I assume your code misses to chain subsequent code with .then((..) ...) you need when you call async code
loader.load('zergling.obj').then((object) {
...
}).then((x) {
// here the result is available
renderer = new WebGLRenderer(antialias: true, alpha: false);
renderer.setSize(window.innerWidth, window.innerHeight);
...
});
// here no result has yet been loaded
When you all an async method like load (which returns a future) then only a callback is registered and the following code is executed (after }); in your case. When this synchronous thread has ended the queue of registered callbacks is registered one after another.
The new async/await feature makes it easier to work with such code
Future someFunc() async {
// here the result is available
var object = await loader.load('zergling.obj');
var geometry = object.geometry;
var mesh = new Mesh(geometry, material);
mesh.position.setValues(0.0, -0.37, -0.6);
mesh.rotation.setValues(-Math.PI / 2, 0.0, 0.0);
mesh.scale.setValues(2.0, 2.0, 2.0);
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add(mesh);
}
You need a dev channel Dart version (1.9.0-dev...) in order to be able to use this new feature.
Using async/await doesn't change the execution, it only changes the way the code looks like.
See
https://www.dartlang.org/tools/download-archive/
https://www.dartlang.org/docs/tutorials/futures/
https://www.dartlang.org/articles/futures-and-error-handling/
https://www.dartlang.org/articles/await-async/
loader = new OBJLoader();
loader.load('zergling.obj').then((object) {
var mesh = object;
mesh.position.setValues(0.0, -0.37, -0.6);
mesh.rotation.setValues(-Math.PI / 2, 0.0, 0.0);
mesh.scale.setValues(2.0, 2.0, 2.0);
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add(mesh);
});
This works for me. object is a Object3D.
Related
I'm trying to make a menu where the scene changes when the player clicks a button using the start method. At first, I had it all in the create function with this:
var levelOne = this.add.sprite(200, 400, 'LevelOne').setInteractive();
levelOne.on('pointerdown', function (pointer) {
this.scene.start('play');
});
But this led to an error in which it said that this.scene.start isn't a function.
I looked at a previous example where the method worked, the big difference was that the method was in the update function, so I rewrote my code to have this in the create function:
this.choice = 0;
var levelOne = this.add.sprite(200, 400, 'LevelOne').setInteractive();
levelOne.on('pointerdown', function (pointer) {
this.choice = 1;
//game.settings = {
//gameTimer: 60000
//}
});
And this in the update function:
if (this.choice == 1){
this.scene.start('play');
}
Sadly, this didn't work either and didn't even give an error message. I can't tell what went wrong. Please help.
You have to pass the scene as the context to the event function on(...) (link to the documentation), as the third parameter, so that you can access the scene properties and functions in the event callback.
levelOne.on('pointerdown', function (pointer) {
this.scene.start('play');
}, this); // <-- you have to add "this"
I can't understand in any way.
I need my old application to be cleared.
That is, when I clicked and followed the ajax, some textures that have the same name remain the previous ones, as well as all the properties and others from the previous loading.
if (Object.keys(loader.resources).length) {
// for (var texture in PIXI.utils.TextureCache) {
// var tmp = PIXI.Texture.removeFromCache(texture);
// tmp.destroy(true);
// }
// for (var texture in PIXI.utils.BaseTextureCache) {
// PIXI.utils.BaseTextureCache[texture].destroy(true);
// }
PIXI.utils.BaseTextureCache = PIXI.utils.TextureCache = loader.resources = {};
loader.reset();
app.destroy({
children: true,
texture: true,
baseTexture: true
});
}
Will it be possible to complete the ajax transition application in order to launch a new one with new textures of the same name?
In the download, I tried to add "?Number" to the image address:
let add = function (arr) {
while (!loader.loading) {
for (var i in arr) {
loader.add(i, arr[i] + '?' + new Date().getTime());
}
break;
}
};
But still nothing comes out.
I make the transition through:
$.get(href, function (data) {
//code
});
Everything loads and works fine, except for the pictures.
They hang, and after the transitions, they do not change, but only everything mixes and sometimes we observe it from the previous ones.
Of course, after reloading the page at the current address, everything works as it should, it doesn’t work only on ajax, for some reason the cache is not discarded.
The issue is resolved, everything works, I just forgot to update the variable with resources.
Due to the fact that at the first initialization:
let resource = PIXI.loader.resources;
Which I had in the global area.
Due to the fact that I did not update it, I could not change the textures.
Now, after all the removal and new filling, I substitute again:
resource = PIXI.loader.resources;
And everything began to work as it should.
In context of one of my assignment I was trying to use RappidJS. I was trying the below code for connecting an element by dropping it over another element.
https://resources.jointjs.com/tutorial/connecting-by-dropping
But I am getting exception as below
rappid.min.js:14 Uncaught TypeError: Cannot read property 'start' of null
at child.update (rappid.min.js:14)
at child.onRender (rappid.min.js:14)
at child.e.render (rappid.min.js:14)
at child.configure (rappid.min.js:14)
at child.addTools (rappid.min.js:14)
at child.element:pointerup (diagram.js:106)
at triggerEvents (backbone.js:338)
at triggerApi (backbone.js:322)
at eventsApi (backbone.js:110)
at child.Events.trigger (backbone.js:312)
I also took reference from below link
https://resources.jointjs.com/tutorial/link-tools .
Can any one suggest me what wrong I am doing here.
My code snippet is as below
function attachLinks(paper) {
paper.on({
'element:pointerdown': function (elementView, event) {
event.data = elementView.model.position();
},
'element:pointerup': function (elementView, event, x, y) {
var coordinates = new joint.g.Point(x, y);
var elementAbove = elementView.model;
var elementBelow = this.model.findModelsFromPoint(coordinates).find(function (el) {
return (el.id !== elementAbove.id);
});
// If the two elements are connected already, don't
// connect them again (this is application-specific though).
if (elementBelow && self.graph.getNeighbors(elementBelow).indexOf(elementAbove) === -1) {
// Move the element to the position before dragging.
elementAbove.position(event.data.x, event.data.y);
// Create a connection between elements.
var link = new joint.shapes.standard.Link();
link.source(elementAbove);
link.target(elementBelow);
link.addTo(this.model);
// Add remove button to the link.
var removeLinkTool = new joint.linkTools.Remove();
var tools = new joint.dia.ToolsView({
tools: [ removeLinkTool]
});
var linkView = link.findView(this);
linkView.addTools(tools); // getting exception at this place.
}
}
});
}
This issue is reproducible only in the paper async mode.
Make sure the view for the link is rendered when you add the link tools. For this please use joint.dia.Paper.prototype.requireView().
// It is fine to use the method in the `sync` mode as the view is rendered/updated
// synchronously as soon as the link is added to the graph.
var linkView = link.findView(paper);
// This method makes sure the view is ready to use in the `async` mode.
// It forces the view to render/update synchronously.
var linkView = paper.requireView(link);
Alternatively, you could pass async = false flag when adding the link to the graph to tell the paper to render the particular view synchronously.
link.addTo(graph, { 'async': false });
I would like to register a listener in chrome.webRequest API, like in the following JS example:
var initHttpRequestObserver = function () {
chrome.webRequest.onBeforeSendHeaders.addListener(
function (details) {...},
{urls: ["<all_urls>"]},
["blocking", "requestHeaders"]);
}();
I guess I could use the dart:js, but wanted to use the chrome package and save some time/typing:
Stream<Map> aStream = chrome.webRequest.onBeforeSendHeaders;
Unfortunately, I am not able to find out how to supply the mandatory filter and opt_extraInfoSpec arguments.
After some analyses of the chrome package, it seems like it is not foreseen to invoke addListener with more then one parameter (a callback). The common.dart contains the private method where the actual invocation is being done:
void _ensureHandlerAdded() {
if (!_handlerAdded) {
// TODO: Workaround an issue where the event objects are not properly
// proxied in M35 and after.
var jsEvent = _api[_eventName];
JsObject event = (jsEvent is JsObject ? jsEvent : new JsObject.fromBrowserObject(jsEvent));
event.callMethod('addListener', [_listener]);
_handlerAdded = true;
}
}
Obviously event.callMethod('addListener', [_listener]); is not providing additional parameters.
The "official" chrome package requires a fix. In the meantime one can use the old good dart:js and do the following:
JsObject _OnBeforeSendHeaders = context['chrome']['webRequest']['onBeforeSendHeaders'];
var filter = new JsObject.jsify({"urls": ["<all_urls>"]});
var opt_extraInfoSpec = new JsObject.jsify(["blocking", "requestHeaders"]);
_OnBeforeSendHeaders.callMethod('addListener', [_processCallback, filter, opt_extraInfoSpec]);
i'am using nodejs with express for my webapp and i need to to run continuously
some code which checks if some data change and then update my mongodb.
How can i easily create a background process which runs the whole time together with the main task? So that the background task/process can inform the main task.
What i have tried already:
to solve this problem with a "setInterval" Function in the main process --> I works with no problem but think its not a good idea because it blocks the node event loop
Use child processes -> i could not found a good tutorial on them --> is there a easier method, perhaps a library which could help me?
some background worker libraries -->But do heavy-load tasks on the a child-process and finish but i need to do the work all the time
Update:
Final Solution:
UpdateEvent.js:
var events = require('events');
function Updater(time) {
this.time = time;
this.array = [
{number: 1},
{number: 2}
];
var that;
events.EventEmitter.call(this);
this.init = function()
{
that = this;
console.log("Contructor");
//Start interval
setInterval(that.run,that.time);
};
this.run = function()
{
that.array.forEach(function (item) {
if(item.number === 2)
{
that.emit('Event');
}
});
};
}
Updater.prototype.__proto__ = events.EventEmitter.prototype;
module.exports = Updater;
and then the code that uses it:
server.js:
var Updater = require('./UpdaterEvent');
var u = new Updater(10000);
u.init();
u.on('Event',function () {
console.log("Event catched!");
});
I followed the tutorial at:
http://www.sitepoint.com/nodejs-events-and-eventemitter/
The problem is the way you export your Updater constructor function:
exports.Updater = Updater;
When you require it, you do
var Updater = require('./UpdaterEvent');
and then try to run:
var u = new Updater(10000);
The problem is that you do not expose the function itself, but an object with a property called Updater which contains the function. Hence you either have to export it using
module.exports = Updater;
or you have to require it using:
var Updater = require('./UpdaterEvent').Updater;
Either way, then calling new Updater() will work. At the moment, you try to initialize a new object by calling an object instead of a constructor function, hence the error message:
TypeError: object is not a function
You should look into Events and EventEmitter
You could use child-process you don't really need to since JS is asynchronous. Just create a function for your background process and pass it your eventEmitter object. You can use setInterval or a while(true) loop to continuously check for the data change. When the data changes, call eventEmitter.emit('someEvent'); which will trigger a function in your main task to update your mongoDB.