I'm trying to make an environement to train a neural network.
At first I just made a 3d canvas and rendered that which worked fine (#canvas in the code), then I converted that to an image.
Later I found out that I needed to convert the canvas to 2d to be able to get the image data I need to input into the AI (according to the advice I got here.
I also discovered a bug which made me call animate() twice.
The weird thing is that if I now try to remove either the image-rendering or the extra call to animate(), the 2d canvas wont render when the camera is moved in Chrome, while it renders irregularly in IE. Any idea how I can fix this?
I have cut down the code to the essentials in this
fiddle, the animation loop is below:
function animate(){
requestAnimationFrame( animate );
movement();
hudUpdate();
//fps-calculation
newTime = Date.now();
sumTime += (newTime - oldTime);
if(framesElapsed === 60){
document.getElementById("fps").innerHTML=
(Math.floor(600000/sumTime))/10;
framesElapsed = 0;
sumTime = 0;
} else {
framesElapsed+=1;
}
oldTime = newTime;
//Converts the canvas to an image and then draws it on a 2d surface.
// CHECKT THIS! Has to be run before renderer.renderer, but will be blank
if movvement occurs and the segment below is left out.
var image = convertCanvasToImage(drawingSurface);
var AIInputImage = convertImageToCanvas(image);
renderer.render(scene, camera);
// CHECK THIS! the above conversion stops working while moving unless the
the line below is present, no idea why..
$("#interim-img").attr("src",drawingSurface.toDataURL("image/png"));
};
animate();
animate();
Edit: updated fiddlelink.
Related
I'm a beginner on here, so apologies in advance for naivety. I've made a simple image on Brackets using Javascript, trying to generate circles with random x and y values, and random colours. There are no issues showing when I open the browser console in Developer Tools, and when I save and refresh, it works. But I was expecting the refresh to happen on a loop through the draw function. Any clues as to where I've gone wrong?
Thanks so much
var r_x
var r_y
var r_width
var r_height
var x
var y
var z
function setup()
{
r_x = random()*500;
r_y = random()*500;
r_width = random()*200;
r_height = r_width;
x = random(1,255);
y= random(1,255);
z= random(1,255);
createCanvas(512,512);
background(255);
}
function draw()
{
ellipse(r_x, r_y, r_width, r_height);
fill(x, y, z);
}
Brackets.io is just your text editor (or IDE if you want to be technical) - so we can remove that from the equation. The next thing that baffles me is that something has to explicitly call your draw() method as well as the setup() method -
I'm thinking that you're working in some sort of library created to simplify working with the Canvas API because in the setup() method you're calling createCanvas(xcord,ycord) and that doesn't exist on it's own. If you want to rabbit hole on that task check out this medium article, it walks you thru all the requirements for creating a canvas element and then drawing on that canvas
Your also confirming that you're drawing at least 1 circle on browser refresh so i think all you need to focus on is 1)initiating your code on load and 2)a loop, and we'll just accept there is magic running in the background that will handle everything else.
At the bottom of the file you're working in add this:
// when the page loads call drawCircles(),
// i changed the name to be more descriptive and i'm passing in the number of circles i want to draw,
// the Boolean pertains to event bubbling
window.addEventListener("load", drawCircles(73), false);
In your drawCircles() method you're going to need to add the loop:
// im using a basic for loop that requires 3 things:
// initialization, condition, evaluation
// also adding a parameter that will let you determine how many circles you want to draw
function drawCircles(numCircles) {
for (let i = 0; i < numCircles; i++) {
ellipse(r_x, r_y, r_width, r_height);
fill(x, y, z);
}
}
here's a link to a codepen that i was tinkering with a while back that does a lot of the same things you are
I hope that helps - good luck on your new learning venture, it's well worth the climb!
Thank you so much for your help! What you say makes sense - I basically deleted the equivalent amount of code from a little training exercise downloaded through coursera, thinking that I could then essentially use it as an empty sandpit to play in. But there's clearly far more going on under the hood!
Thanks again!
I am still new to Three.js and WebGL but I want to get better at it. Could you please check my code having found a solution to a fairly simple problem that I set for myself.
SIMPLE PROBLEM (that took too long to solve):
How can I animate a simple 400 x 400 PLANE MESH from y position 500 (below browser window) to x,y,z position 0 (centre of the browser window) - WITHOUT using Tween.js? I know Tween.js for Three.js is very efficient for simple movements but I wanted to find a solution that involves learning. Use Tween.js and I don't learn anything. And yes, I did hours of research looking at various solutions on StackOverflow and on Mr Doob's code repository on GitHub. After very extensive searching, I couldn't find a solution that gave me exactly what I wanted, namley: A simple vertical upward animation STARTING out of frame AND STOPPING in the centre of the browser window.
MY SOLUTION:
`function animate() {
var newPos = plane.position.y;
plane.translateY( 4 );
function stopHere () {
if (newPos >= 0)
{
plane.position.set( 0, 0, 0);
var stopPlane = plane.position.y = 0;
}
}
requestAnimationFrame(stopHere);
}
function render() {
renderer.render(scene, camera);
animate();
}`
I've posted just the two functions that do all the work. Does anyone see bad practice there? My logic is that
requestAnimationFrame
cannot be in the render(); function, as it needs to be within the scope of the nested function ('stopHere') within
`animate();`
I ran into difficulty approaching it from this direction:
`objMesh.geometry.applyMatrix( new THREE.Matrix4().makeTranslation( 1, 0.1, 0.1 ) ); `
After wrestling with something simple for over a week, I just know it works. To my understanding, I have used a method of the applyMatrix sub-class and made it work. I'm asking for comments because I want to learn Three.js, not bad habits. Please, does anyone see bad practice or bad coding? Many thanks.
ksqInFlight
I am a senior citizen, so my approach is, in your requestAnimationFrame loop:
function fnloop() {
var dy = Math.min(Math.abs(plane.position.y), .01); // max movement
if (Math.abs(dy) >= .000001) {
if (plane.position.y > 0) dy = -dy; // move down if above
plane.position.y += dy; // move up or down
if (Math.abs(plane.position.y) < .000001) alert("Done!");
}
renderer.render(scene, camera);
requestAnimationFrame(fnloop);
}
I'm new to game development. Currently I'm doing a game for js13kgames contest, so the game should be small and that's why I don't use any of modern popular frameworks.
While developing my infinite game loop I found several articles and pieces of advice to implement it. Right now it looks like this:
self.gameLoop = function () {
self.dt = 0;
var now;
var lastTime = timestamp();
var fpsmeter = new FPSMeter({decimals: 0, graph: true, theme: 'dark', left: '5px'});
function frame () {
fpsmeter.tickStart();
now = window.performance.now();
// first variant - delta is increasing..
self.dt = self.dt + Math.min(1, (now-lastTime)/1000);
// second variant - delta is stable..
self.dt = (now - lastTime)/16;
self.dt = (self.dt > 10) ? 10 : self.dt;
self.clearRect();
self.createWeapons();
self.createTargets();
self.update('weapons');
self.render('weapons');
self.update('targets');
self.render('targets');
self.ticks++;
lastTime = now;
fpsmeter.tick();
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
};
So the problem is in self.dt I've eventually found out that first variant is not suitable for my game because it increases forever and the speed of weapons is increasing with it as well (e.g. this.position.x += (Math.cos(this.angle) * this.speed) * self.dt;..
Second variant looks more suitable, but does it correspond to this kind of loop (http://codeincomplete.com/posts/2013/12/4/javascript_game_foundations_the_game_loop/)?
Here' an implementation of an HTML5 rendering system using a fixed time step with a variable rendering time:
http://jsbin.com/ditad/10/edit?js,output
It's based on this article:
http://gameprogrammingpatterns.com/game-loop.html
Here is the game loop:
//Set the frame rate
var fps = 60,
//Get the start time
start = Date.now(),
//Set the frame duration in milliseconds
frameDuration = 1000 / fps,
//Initialize the lag offset
lag = 0;
//Start the game loop
gameLoop();
function gameLoop() {
requestAnimationFrame(gameLoop, canvas);
//Calcuate the time that has elapsed since the last frame
var current = Date.now(),
elapsed = current - start;
start = current;
//Add the elapsed time to the lag counter
lag += elapsed;
//Update the frame if the lag counter is greater than or
//equal to the frame duration
while (lag >= frameDuration){
//Update the logic
update();
//Reduce the lag counter by the frame duration
lag -= frameDuration;
}
//Calculate the lag offset and use it to render the sprites
var lagOffset = lag / frameDuration;
render(lagOffset);
}
The render function calls a render method on each sprite, with a reference to the lagOffset
function render(lagOffset) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
sprites.forEach(function(sprite){
ctx.save();
//Call the sprite's `render` method and feed it the
//canvas context and lagOffset
sprite.render(ctx, lagOffset);
ctx.restore();
});
}
Here's the sprite's render method that uses the lag offset to interpolate the sprite's render position on the canvas.
o.render = function(ctx, lagOffset) {
//Use the `lagOffset` and previous x/y positions to
//calculate the render positions
o.renderX = (o.x - o.oldX) * lagOffset + o.oldX;
o.renderY = (o.y - o.oldY) * lagOffset + o.oldY;
//Render the sprite
ctx.strokeStyle = o.strokeStyle;
ctx.lineWidth = o.lineWidth;
ctx.fillStyle = o.fillStyle;
ctx.translate(
o.renderX + (o.width / 2),
o.renderY + (o.height / 2)
);
ctx.beginPath();
ctx.rect(-o.width / 2, -o.height / 2, o.width, o.height);
ctx.stroke();
ctx.fill();
//Capture the sprite's current positions to use as
//the previous position on the next frame
o.oldX = o.x;
o.oldY = o.y;
};
The important part is this bit of code that uses the lagOffset and the difference in the sprite's rendered position between frames to figure out its new current canvas position:
o.renderX = (o.x - o.oldX) * lagOffset + o.oldX;
o.renderY = (o.y - o.oldY) * lagOffset + o.oldY;
Notice that the oldX and oldY values are being re-calculated each frame at the end of the method, so that they can be used in the next frame to help figure out the difference.
o.oldX = o.x;
o.oldY = o.y;
I'm actually not sure if this interpolation is completely correct or if this is best way to do it. If anyone out there reading this knows that it's wrong, please let us know :)
The modern version of requestAnimationFrame now sends in a timestamp that you can use to calculate elapsed time. When your desired time interval has elapsed you can do your update, create and render tasks.
Here's example code:
var lastTime;
var requiredElapsed = 1000 / 10; // desired interval is 10fps
requestAnimationFrame(loop);
function loop(now) {
requestAnimationFrame(loop);
if (!lastTime) { lastTime = now; }
var elapsed = now - lastTime;
if (elapsed > requiredElapsed) {
// do stuff
lastTime = now;
}
}
This isn't really an answer to your question, and without knowing more about the particular game I can't say for sure if it will help you, but do you really need to know dt (and FPS)?
In my limited forays into JS game development I've found that often you don't really need to to calculate any kind of dt as you can usually come up with a sensible default value based on your expected frame rate, and make anything time-based (such as weapon reloading) simply work based on the number of ticks (i.e. a bow might take 60 ticks to reload (~1 second # ~60FPS)).
I usually use window.setTimeout() rather than window.requestAnimationFrame(), which I've found generally provides a more stable frame rate which will allow you to define a sensible default to use in place of dt. On the down-side the game will be more of a resource hog and less performant on slower machines (or if the user has a lot of other things running), but depending on your use case those may not be real concerns.
Now this is purely anecdotal advice so you should take it with a pinch of salt, but it has served me pretty well in the past. It all depends on whether you mind the game running more slowly on older/less powerful machines, and how efficient your game loop is. If it's something simple that doesn't need to display real times you might be able to do away with dt completely.
At some point you will want to think about decoupling your physics from your rendering. Otherwise your players could have inconsistent physics. For example, someone with a beefy machine getting 300fps will have very sped up physics compared to someone chugging along at 30fps. This could manifest in the first player cruising around in a mario-like scrolling game at super speed and the other player crawling at half speed (if you did all your testing at 60fps). A way to fix that is to introduce delta time steps. The idea is that you find the time between each frame and use that as part of your physics calculations. It keeps the gameplay consistent regardless of frame rate. Here is a good article to get you started: http://gafferongames.com/game-physics/fix-your-timestep/
requestAnimationFrame will not fix this inconsistency, but it is still a good thing to use sometimes as it has battery saving advantages. Here is a source for more info http://www.chandlerprall.com/2012/06/requestanimationframe-is-not-your-logics-friend/
I did not check the logic of the math in your code .. however here what works for me:
GameBox = function()
{
this.lastFrameTime = Date.now();
this.currentFrameTime = Date.now();
this.timeElapsed = 0;
this.updateInterval = 2000; //in ms
}
GameBox.prototype.gameLoop = function()
{
window.requestAnimationFrame(this.gameLoop.bind(this));
this.lastFrameTime = this.currentFrameTime;
this.currentFrameTime = Date.now();
this.timeElapsed += this.currentFrameTime - this.lastFrameTime ;
if(this.timeElapsed >= this.updateInterval)
{
this.timeElapsed = 0;
this.update(); //modify data which is used to render
}
this.render();
}
This implementation is idenpendant from the CPU-speed(ticks). Hope you can make use of it!
A great solution to your game engine would be to think in objects and entities. You can think of everything in your world as objects and entities. Then you want to make a game object manager that will have a list of all your game objects. Then you want to make a common communication method in the engine so game objects can make event triggers. The entities in your game for example a player would not need to inherent from anything to get the ability to render to the screen or have collision detection. You would simple make common methods in the entity that the game engine is looking for. Then let the game engine handle the entity as it would like. Entities in your game can be created or destroyed at anytime in the game so you should not hard-code any entities at all in the game loop.
You will want other objects in your game engine to respond to event triggers that the engine has received. This can be done using methods in the entity that the game engine will check to see if the method is available and if it is would pass the events to the entity. Do not hard code any of your game logic into the engine it messes up portability and limits your ability to expand on the game later on.
The problem with your code is first your calling different objects render and updates not in the correct order. You need to call ALL your updates then call ALL your renders in that order. Another is your method of hard coding objects into the loop is going to give you a lot of problems, when you want one of the objects to no longer be in the game or if you want to add more objects into the game later on.
Your game objects will have an update() and a render() your game engine will look for that function in the object/entity and call it every frame. You can get very fancy and make the engine work in a way to check if the game object/entity has the functions prior to calling them. for example maybe you want an object that has an update() but never renders anything to the screen. You could make the game object functions optional by making the engine check prior to calling them. Its also good practice to have an init() function for all game objects. When the game engine starts up the scene and creates the objects it will start by calling the game objects init() when first creating the object then every frame calling update() that way you can have a function that you only run one time on creation and another that runs every frame.
delta time is not really needed as window.requestAnimationFrame(frame); will give you ~60fps. So if you're keeping track of the frame count you can tell how much time has passed. Different objects in your game can then, (based off of a set point in the game and what the frame count was) determine how long its been doing something based off its new frame count.
window.requestAnimationFrame = window.requestAnimationFrame || function(callback){window.setTimeout(callback,16)};
gameEngine = function () {
this.frameCount=0;
self=this;
this.update = function(){
//loop over your objects and run each objects update function
}
this.render = function(){
//loop over your objects and run each objects render function
}
this.frame = function() {
self.update();
self.render();
self.frameCount++;
window.requestAnimationFrame(frame);
}
this.frame();
};
I have created a full game engine located at https://github.com/Patrick-W-McMahon/Jinx-Engine/ if you review the code at https://github.com/Patrick-W-McMahon/Jinx-Engine/blob/master/JinxEngine.js you will see a fully functional game engine built 100% in javascript. It includes event handlers and permits action calls between objects that are passed into the engine using the event call stack. check out some of the examples https://github.com/Patrick-W-McMahon/Jinx-Engine/tree/master/examples where you will see how it works. The engine can run around 100,000 objects all being rendered and executed per frame at a rate of 60fps. This was tested on a core i5. different hardware may vary. mouse and keyboard events are built into the engine. objects passed into the engine just need to listen for the event passed by the engine. Scene management and multi scene support is currently being built in for more complex games. The engine also supports high pixel density screens.
Reviewing my source code should get you on the track for building a more fully functional game engine.
I would also like to point out that you should have requestAnimationFrame() called when you're ready to repaint and not prior (aka at the end of the game loop). One good example why you should not call requestAnimationFrame() at the beginning of the loop is if you're using a canvas buffer. If you call requestAnimationFrame() at the beginning, then begin to draw to the canvas buffer you can end up having it draw half of the new frame with the other half being the old frame. This will happen on every frame depending on the time it takes to finish the buffer in relation to the repaint cycle (60fps). But at the same time you would end up overlapping each frame so the buffer will get more messed up as it loops over its self. This is why you should only call requestAnimationFrame() when the buffer is fully ready to draw to the canvas. by having the requestAnimationFrame() at the end you can have it skip a repaint if the buffer is not ready to draw and so every repaint is drawn as it is expected. The position of requestAnimationFrame() in the game loop has a big difference.
Is it possible to create a dynamic animation by applying transformations to the bones of a 3D model using three.js? I tried moving and rotating the bones of a SkinnedMesh, but the mesh was not updated.
loader = new THREE.JSONLoader();
loader.load('/JS-Projects/Virtual-Jonah/Modelos/initialPose.js',function jsonReady( geometry )
{
mesh = new THREE.SkinnedMesh( geometry, new THREE.MeshNormalMaterial({skinning : true}) );
mesh.scale.set( 10, 10, 10 );
mesh.position.z = mesh.position.y = mesh.position.x = 0;
mesh.geometry.dynamic = true;
scene.add( mesh );
var index = 0;
for (var i = 0; i < mesh.bones.length; i++)
{
if (mesh.bones[i].name == "forearm_R")
{
index = i;
break;
}
}
setInterval (function ()
{
mesh.bones[index].useQuaternion = false;
mesh.bones[index].position.z += 10;
mesh.bones[index].matrixAutoUpdate = true;
mesh.bones[index].matrixWorldNeedsUpdate = true;
mesh.geometry.verticesNeedUpdate = true;
mesh.geometry.normalsNeedUpdate = true;
renderer.render(scene, camera);
}, 33);
renderer.render(scene, camera);
});
The model I am using was created with makeHuman (nightly build), exported to Collada, imported in Blender and exported to the three.js JSON model. The link to the model is the following:
https://www.dropbox.com/sh/x1606vnaoghes1y/gG_BcZcEKd/initial
Thank you!
Yes, you can!
You need to set mesh.skeleton.bones[i], both mesh.skeleton.bones[i].rotation and mesh.skeleton.bones[i].position. Rotation is of type Euler. Position is of type Vector3. I have actually tested this using my code from here https://github.com/lucasdealmeidasm/three-mm3d (that includes a working skinned mesh with bone-attachable objects) and one can indeed do that.
Note that Inateno's answer is very wrong, there are many instances where this is necessary.
For example, in a FPS, one uses both dynamic and non-dynamic animation.
When a character runs and holds a gun, the direction he points the gun at is dynamically set (one could use mesh.skeleton.bones[i].rotation where "i" is the index for bone assigned to the arm for that) while the rest of the animation, including the walking, is made in the editor and loaded. One can, in three.js, use "THREE.AnimationHandler.update(delta);" and then change single bones' position and rotation in code to solve those issues.
I know you can export a bone driven animation from Blender in JSON format, for use in THREE.js, there are a few tutorials of that around the web. I hope this helps. Good Luck.
If I understund you want to create animations yourself inside the code ?
You are note supposed to do this, in Unity you have a simple animation editor, you never manipulate bones directly in code.
It's long, boring, unperforming. To animate a model use animation directly.
Here's a result of animation with some bones manipulation but there is an animation over.
http://threejs.org/examples/webgl_animation_skinning_morph.html
Here is a tutorial about making simple animation if you need http://blog.romanliutikov.com/post/60461559240/rigging-and-skeletal-animation-in-three-js
And here a related post about animations problems just in case
Blender exports a three.js animation - bones rotate strangely
Hope this will help you :)
I am trying to visualise a reinforcement agent moving through a 2d grid. I coded up a visualisation using canvas, and everytime my agent makes a move I try to update the grid. I was hoping to see an animation, but instead I see nothing until the agent has completed all this moves and I see the final state. If I step through with Google Chromes Developer tools then I can see the individual steps. I do not think it is a problem of my code just running to fast, because each step takes a couple of seconds.
My implementation is as follows, with the function gridWorld() called once to create a new object and executeAction called every time I want to draw. As shown I have used ctx.save(), and ctx.restore(), but that is only an attempt to solve this problem, and it seems to have made no difference.
Thanks
var execute gridWorld = function(action) {
var canvas = document.getElementById("grid");
this.ctx = canvas.getContext("2d");
this.executeAction = function(action) {
this.ctx.save()
// ... Do reinforcement learning stuff
// For every cell in grid, do:
this.ctx.fillStyle = "rgb(244,0,0)"
this.ctx.fillRect(positionX, poisitonY, 10,10)
this.ctx.restore();
}
}
Even if the code takes a long time to execute, the browser will not update the display until there is an actual break in the code. Use setTimeout() to cause a break in code execution whenever you want the canvas to update.
Your not going to see animations because they are happening way too fast. You need to break them up like in the following example.
Live Demo
If I did something like this for example
for(x = 0; x < 256; x++){
player.x = x;
ctx.fillStyle = "#000";
ctx.fillRect(0,0,256,256);
ctx.fillStyle = "#fff";
ctx.fillRect(player.x,player.y,4,4);
}
You would only ever see the player at the end of the board every time that function is called, and you wouldn't see any of the animations in between, because the loop runs too fast. Thats why in my live demo I do it in small increments and call the draw every 15 milliseconds so you have a chance to actually see whats being put on the canvas.