I've just made a 3D pointcloud rendering app in JS. This app is able to render +200 000 3D black/white points at 40 FPS for dense heavy clouds. However, I'm now trying to implement colours, and, while I was working on this new feature, I realised that the order in which points were painted on the screen was really important.
I've made another file where I've selected a colour for each point. For example, point 0 is red, point 1 is green and point 2 is blue; so colours are precalculated.
I mean, points that are further from the user should be rendered first and points that are closer should be rendered later. With this technique, if two points overlap, the point which is closer is the one which will appear on the screen.
I made a custom algorithm [O(n^2) pretty slow I know] which sorted all the points (more than 200 000) for the distance from the position of the user (further points first). However, it takes me about 7 seconds to put them in the right order, for and app which was intended to be real-time, and I had to make a workaround for preventing the browser from showing a "this page is not responding" popup.
Is there any other method for rendering 3D coloured points which overlap on the screen? Don't worry, I'm not asking for a piece of code, I just want to know if there's another faster way to achieve this, if possible in pseudo-code.
I already know that I can reduce that time writing a more efficient algorithm but that would still be too slow. Every valid answer will be rewarded with an upvote!
THIS IS WHAT I'VE GOT SO FAR
THIS IS WHAT I'D LIKE TO HAVE
It is not clear why you came up with your O(n^2) time complexity.
You have your array of 200k points. You have some point to which you have to calculate a distance. This is done in O(n). On my machine it is done in 42.142ms.
Now you have to sort your points based on this distance and on my machine it done in 122.358ms. Your sorting algorithm runs in O(n*log(n)). Now you draw the points from furthest to closes and it also runs in O(n).
So I am not sure how you ended up with O(n^2) and why it runs in 7 seconds.
Instead of sorting, you could memorize the rendered pos / distances during the rendering. If you find that a new point that you're about to render is farther than an overlapping point that is already rendered, you skip the new point.
Related
Background
I am creating a game in which you can control multiple people in a community, so obviously, the people need to be able to move on their own, with their own tasks to accomplish. I used the method described in this post about how to move a mesh / object along a path in Three.js. It worked as you can see below but all the people are moving at different speeds than each other. I don't want this.
Question
How do I make them all move at the same speed? And if you have a better solution on how to move a mesh from point to point then please tell me how.
PS: In the post I linked, I used the "fancy movement" part of the answer.
(In the event the fiddle goes away, the previous answer used a slowly incremented variable with path.getPointAt(position) to move the objects along the path.)
The Curve.getPointAt method takes a value that is a percentage along the curve. Because of this calculation, the distance between points (for example 0 and 0.1) will be different based on the length of the curve.
So if curve1 is 10 units long, and curve2 is 100 units long, then:
curve1.getPointAt(0.1) // vector 1 unit from the start of curve1
curve2.getPointAt(0.1) // vector 10 units from the start of curve2
If you're basing your motion on this, then basically the object moving along curve2 will move 10x as fast as the object moving along curve1.
What you want to do instead is determine how many steps the object should take along a path, given a certain "steps/second" or "steps/frame". This is more aligned to the concept of a real physical velocity, rather than one defined by the length of the path being taken.
Let's say you want to travel at 2 units per frame along curve1 and curve2. Now that you're traveling at a fixed rate, you just need to divide the rate by the total length to get the number of "steps" (or in this case, frames) it will take to reach the end of the path.
2 / 10 = 0.2 // this is the point polling percentage for curve 1
2 / 100 = 0.02 // this is the point polling percentage for curve 2
Now, when you move an object along curve1, you will need to use path.getPointAt(0.2), and for curve2 you will use path.getPointAt(0.02).
Looking ahead a little, you might ask what happens when the math doesn't line up outside a perfect example, and you have extra "partial steps" to make it to the end of the curve. Well, that's up to you to decide how to handle it. You could spend an extra frame to finish the motion, or you could look a step ahead during the movement calculation and decide to just send it to the end.
I'm trying to make a little platform game with pure HTML5 and JavaScript. No frameworks.
So in order to make my character jump on top of enemies and floors/walls etc., it needs some proper collision detection algorithms.
Since I'm not usually into doing this. I really have no clue on how to approach the problem.
Should I do a re-check in every frame (it runs in 30 FPS) for all obstacles in the Canvas and see if it collides with my player, or is there a better and faster way to do so?
I even thought of making dynamic maps. So the width, height, x- and y coordinates of the obstacle are stored in an object. Would that make it faster to check if it's colliding with the player?
1. Should I re-check in every frame (it runs on 30 FPS)?
Who says it runs in 30 FPS? I found no such thing in the HTML5 specification. Closest you'll get to have anything to say about the framerate at all is to programmatically call setInterval or the newish, more preferred, requestAnimationFrame function.
However, back to the story. You should always look for collisions as much as you can. Usually, writing games on other platforms where one have a greater ability to measure CPU load, this could be one of those things you might find favorable to scale back some if the CPU has a hard time to follow suit. In JavaScript though, you're out of luck trying to implement advanced solutions like this one.
I don't think there's a shortcut here. The computer has no way of knowing what collided, how, when- and where, if you don't make that computation yourself. And yes, this is usually, if not at all times even, done just before each new frame is painted.
2. A dynamic map?
If by "map" you mean an array-like object or multidimensional array that maps coordinates to objects, then the short answer has to be no. But please do have an array of all objects on the scene. The width, height and coordinates of the object should be stored in variables in the object. Leaking these things would quickly become a burden; rendering the code complex and introduce bugs (please see separation of concerns and cohesion).
Do note that I just said "array of all objects on the scene" =) There is a subtle but most important point in this quote:
Whenever you walk through objects to determine their position and whether they have collided with someone or not. Also have a look at your viewport boundaries and determine whether the object are still "on the scene" or not. For instance, if you have a space craft simulator of some kind and a star just passed the player's viewport from one side to the other and then of the screen, and there is no way for the star to return and become visible again, then there is no reason for the star to be left behind in the system any more. He should be deleted and removed. He should definitely not be stored in an array and become part of a future collision detection with the player's avatar! Such things could dramatically slow down your game.
Bonus: Collision quick tips
Divide the screen into parts. There is no reason for you to look for a collision between two objects if one of them are on left side of the screen, and the other one is on the right side. You could split up the screen into more logical units than just left and right too.
Always strive to have a cheap computation made first. We kind of already did that in the last tip. But even if you now know that two objects just might be in collision with each other, draw two logical squares around your objects. For instance, say you have two 2D airplanes, then there is no reason for you to first look if some part of their wings collide. Draw a square around each airplane, effectively capturing their largest width and their largest height. If these two squares do not overlap, then just like in the last tip, you know they cannot be in collision with each other. But, if your first-phase cheap computation hinted that they might be in collision, pass those two airplanes to another more expensive computation to really look into the matter a bit more.
I am still working on something i wanted to make lots of divs and make them act on physics. I will share somethings that weren't obvious to me at first.
Detect collisions in data first. I was reading the x and y of boxes on screen then checking against other divs. After a week it occurred to me how stupid this was. I mean first i would assign a new value to div, then read it from div. Accessing divs is expensive. Think dom as a rendering stage.
Use webworkers if possible easy.
Use canvas if possible.
And if possible make elements carry a list of elements they should be checked against for collision.(this would be helpful in only certain cases).
I learned that interactive collisions are way more expensive. Because you have to check for changes in environment while in normal interaction you simulate what is going to happen in future, and therefore your animation would be more fluid and more cpu available.
i made something very very early stage just for fun: http://www.lastnoob.com/
I'm trying to record exactly where the mouse moves on a web page (to the pixel). I have the following code, but there are gaps in the resulting data.
var mouse = new Array();
$("html").mousemove(function(e){
mouse.push(e.pageX + "," + e.pageY);
});
But, when I look at the data that is recorded, this is an example of what I see.
76,2 //start x,y
78,5 //moved right two pixels, down three pixels
78,8 //moved down three pixels
This would preferably look more like:
76,2 //start x,y
77,3 //missing
78,4 //missing
78,5 //moved right two pixels, down three pixels
78,6 //missing
78,7 //missing
78,8 //moved down three pixels
Is there a better way to store pixel by pixel mouse movement data? Are my goals too unrealistic for a web page?
You can only save that information as fast as it's given to you. The mousemove events fires at a rate that is determined by the browser, usually topping at 60hz. Since you can certainly move your pointer faster than 60px/second, you won't be able to fill in the blanks unless you do some kind of interpolation.
That sounds like a good idea to me, imagine the hassle (and performance drag) of having 1920 mousemove events firing at once when you jump the mouse to the other side of the screen - and I don't even think the mouse itself polls fast enough, gaming mice don't go further than 1000hz.
See a live framerate test here: http://jsbin.com/ucevar/
On the interpolation, see this question that implements the Bresenham's line algorithm which you can use to find the missing points. This is a hard problem, the PenUltimate app for the iPad implements some amazing interpolation that makes line drawings look completely natural and fluid, but there is nothing about it on the web.
As for storing the data, just push an array of [x,y] instead of a string. A slow event handler function will also slow down the refresh rate, since events will be dropped when left behind.
The mouse doesn't exist at every pixel when you move it. During the update cycle, it actually jumps from point to point in a smooth manner, so to the eye it looks like it hits every point in between, when in fact it just skips around willy-nilly.
I'd recommend just storing the points where the mouse move event was registered. Each interval between two points creates a line, which can be used for whatever it is you need it for.
And, as far as processing efficiency goes...
Processing efficiency is going to depend on a number of factors. What browser is being used, how much memory the computer has, how well the code is optimized for the data-structure, etc.
Rather than prematurely optimize, write the program and then benchmark the slow parts to find out where your bottlenecks are.
I'd probably create a custom Point object with a bunch of functions on the prototype and see how it performs
if that bogs down too much, I'd switch to using object literals with x and y set.
If that bogs down, I'd switch to using two arrays, one for x and one for y and make sure to always set x and y values together.
If that bogs down, I'd try something new.
goto 4
Is there a better way to store pixel by pixel mouse movement data?
What are your criteria for "better"?
Are my goals too unrealistic for a web page?
If your goal is to store a new point each time the cursor enters a new pixel, yes. Also note that browser pixels don't necessarily map 1:1 to screen pixels, especially in the case of CRT monitors where they almost certainly don't.
I'm finishing up a drawing application that uses OpenGL ES 2.0 (WebGL) and JS. Things work pretty well unless I draw with very quick movements. See the image below:
This loop was drawn with a smooth motion, but because JS was only able to get mouse readings at specific locations, the result is faceted. This happens to a certain degree in Photoshop if you have mouse smoothing turned off, though obviously much less because PS has the ability to poll at a much higher rate.
So, I would like to implement some mouse smoothing, but I'm concerned about making sure it's very efficient so that it doesn't bog down the actual pixel drawing operations. I was originally thinking about using the mouse locations that JS is able to grab to generate splines and interpolate between readings to give a smoother result. I'm not sure if this is the best approach, though. If it is, how do I make sure I sample the correct locations on the intermediate spline? Most of the spline equations I've found don't have uniformly-distributed values for t = [0, 1].
Any help/guidance/advice would be very appreciated. Thanks!
Catmull-Rom might be a good one to try, if you haven't already.
http://www.mvps.org/directx/articles/catmull/
I'd pick a minimum segment length and divide up segments that are over that into 1+segmentLength/minSegmentLength sub-segments.
I am creating a platform game in JavaScript using canvas which is entirely tile-based. What is the best method of storing the blocks of items in the game (walls, floors, items)? The thing is every tile can be destroyed or created.
Currently I have a 2D array so I am able to quickly check if an item is at a specific X & Y position. The problem with this is when the user moves and the map needs to scroll, I need to reassign every block. And what happens when the item is at x = 0? I can't use negative indexes.
I would rather the scrolling analogue as aposed to a tile at a time. Also I plan on randomly generating maps as the user moves and if it hasn't previously been generated. So once something is generated, it should stay that way forever.
Another point I should mention is that it will also be multiplayer. So chunking the screen is a great idea until the cached data becomes dirty and needs to get the latest from the database. Gah I'm so new to all this; seems impossible, any help is greatly appreciated.
Since you have infinite levels I'd suggest a structure similar to what you already have, with a slight tweak.
Instead of storing everything in one big array, and moving stuff around inside that array every time the user moves (ouch) instead store 9 chunks of map (each one a size such that it's roughly twice the size of the screen), when the user approaches the edge of the current chunk, dispose the chunks which are offscreen, move all the chunks left, and load new ones into the gap.
Hopefully that was clear, but just in case, here's a diagram:
The lettered squares are the chunks of map, and the red square is the viewport (I drew it slightly too large, remember the viewport is smaller than the black squares). As the viewport moves right, you unload chunks A B and C, move all the others left, and load new data into the right most ones. Since a chunk is twice the width of the screen, you have the time it takes the user to cross the screen to generate/load the level into those chunks. If the user moves around the world fast, you can have a 4x4 set of chunks for extra buffering.
To address the returning to previous chunks of map. there are a couple of ways to do that:
Write out the chunks to hard disk when they're no longer in use (or whatever the equivalent would be in javascript)
Expand your chunk set infinitely in memory. Rather than an array of chunks have an assosciative array which takes x/y position of the chunk, and returns the chunk (or null, which indicates that the user has never been here before and you need to generate it).
Procedurally generate your levels, that's complex but means that once a chunk goes off screen you can just dispose it, and be confident you can regenerate exactly the same chunk again later
There are obviously lots of ways to do this.
If they levels aren't too large, you can keep your original design of a 2d array and use a variable to store the current x/y scroll position. This means that you store all of the map information in memory at all times, and only access the parts you need to display on the screen.
When painting you work out which tile is visible at current scroll position x/y, how many tiles fit on the screen with the current screen width and only paint the ones you need.
If you scroll whole tiles at a time, then its pretty easy. If its a more analog scrolling, you will need some finer grain control of where in the tile you start drawing, or you can cheat and draw the whole set of tiles to an in memory bitmap and then blit that to the drawing canvas with an negative offset.
I once defined this very thing in XML and JSON... I think the JSON serialization would be alot faster and more efficient (not to mention easy) to work with in JavaScript, especially since JSON lends itself so well to variable length lists as you would require for "N" levels in each game.
Using a standard format would also make it more reusable and (ideally) encourage more collaboration (if that's what you're looking for). You can check out my first attempt to create a Video Game schema for level structure.
As fileoffset says, there are many ways to do it, but I highly suggest keeping your level data (i.e. concepts) separate from your rendering (i.e. objects in motion, paths, speed, timing, x/y/z co-ordinate positioning, etc...).
Again, as the article said that area is the most quickly changing, and there's no telling if WebGL, SMIL+SVG, Canvas+Javascript, good ol' Flash/Actionscript or something else will be the best route for you, depending on your needs and the type of game you are developing.