XNA 2D mouse picking - c#

I'm working on a simple 2D Real time strategy game using XNA. Right now I have reached the point where I need to be able to click on the sprite for a unit or building and be able to reference the object associated with that sprite.
From the research I have done over the last three days I have found many references on how to do "Mouse picking" in 3D which does not seem to apply to my situation.
I understand that another way to do this is to simply have an array of all "selectable" objects in the world and when the player clicks on a sprite it checks the mouse location against the locations of all the objects in the array. the problem I have with this approach is that it would become rather slow if the number of units and buildings grows to larger numbers. (it also does not seem very elegant) so what are some other ways I could do this. (Please note that I have also worked over the ideas of using a Hash table to associate the object with the sprite location, and using a 2 dimensional array where each location in the array represents one pixel in the world. once again they seem like rather clunky ways of doing things.)

For up to hundreds of units, it should be fast enough to simply do a linear search O(n) over all the units in the world if the click regions are circles or rectangles. Especially seeing as it will be once per click, not once per frame.
If your units are not circular or rectangular, check against a bounding circle or rectangle first, and if that passes check against the more complicated bounding shape.
For a more detailed answer, here's my answer to a similar question about space partitioning. There I mention bucketed grids and quadtrees as potential structures for performance optimisation.
But you should never do performance optimisation until you have tested and actually do have a performance problem!

If you have a class that manages drawabel objects you could have a static int that you increase every time you make a new object, and save the old one as a local instance of Color in the drawabel object. You can then use the .Net type converter to make its to bye arrays and back, dont remember its name and im on my phoneon a train so can't check for you im afraid.
When you build the color from the byte array just remember to max the alpha channel, and if you happen to get too many objects you might overrun the indexes you can use.. not sure what to do then... probably have all your objects reaquire new colors from 0:0:0:255 again since hopefully some old ones are no longer in use :P
Not sure i made alot of sense but since im on a train thats all i can give you, sorry :)

You could use pixel perfect picking, which scales very well to massive numbers of objects (and has the advantage of being pixel perfect).
Essentially you render your scene using a unique colour for each object. Then you resolve the backbuffer into a texture and get the texture data back, finally you can simply check the pixel underneath the mouse and find out which object the mouse is on.
You can be clever about the information you get back, you can request just the single pixel the mouse is on top of.
Color[] pixel = new Color[1];
texture.GetData(pixel, mousePosition.Y * texture.Width + mousePosition.x, 1);
//pixel[0] == colour of the item the mouse is over. You can now look this up in a dictionary<Color, item>
You should be careful not to stall the pipeline by doing this (causing the CPU to wait for the GPU to render things). The best way to do this is to swap between 2 render targets, and always GetData from the render target you used last frame, this means the data is a frame out of date, but no human has fast enough reactions to notice.
Addendum in response to your comment.
To assign a unique colour to each object, simply increment a byte for each object. When that byte overflows, increment another, and when that one overflows increment another; Then you can use those three bytes as Red, Green and Blue. Remeber to keep alpha at max value, you don't want any see through objects!
To resolve the backbuffer is slightly changed in XNA4. Now you must render to a rendertarget and resolve that. To do this is pretty simple, and outlined by Shawn Hargreaves here

Related

2D Procedural Generation

I'm currently trying to implement procedurally generated tilemaps for an overworld. I'm as far as generating noise and building the tilemaps using different ranges within the generated noise. However, they're very crude as each different 'biome' is just one tile. What is the best way to implement the detailing and edges of each biome? e.g flowers/trees/etc spread out in a forest biome, beach-to-water transition tiles between beach and ocean biome, etc.
For some context, I built an engine in MonoGame with a friend of mine. We implemented a chunk loading system for dynamic generation and infinite scrolling with no load screens(not exactly state of the art, I know, but I was proud of it). Each chunk is 50x50 tiles, and there are 9 chunks loaded at any given time. When the player moves chunks in any direction, the chunks on the opposite corner are unloaded and new ones are loaded in the direction the player is walking. Since the player is starting on the opposite of where chunks are being generated, it hasn't been a problem thus far as the maps are big enough that they're done generating by the time the player gets to them. I'm not sure whether the current method I have in mind is going to change this or not.
Anyway, I'm thinking that I need to determine within each biome a specific set of tiles and generate noise for each biome instance to determine placement of 'detail' tiles specific to that biome. For the edges, I'd just loop through each adjacent tile to determine whether it's a different biome. If so, use the transition tile. However, the whole idea seems very inefficient as that's a ton of noise to generate as well as looping through 7500 tiles every time the player moves chunks. I've been trying to think of a better method, but this is my first foray into procedural generation and I haven't been able to find much online that talks about anything more in-depth than generating noise and using that noise to generate chunks of land. Is there a more efficient method I should use or is my next step going to be optimizing? I can't imagine my method is going to be very efficient or practical due to how much I'm going to be looping through every tile. Anyone have any ideas or suggestions? Thanks in advance.
One idea:
Use noise to generate height, temperature, rain, ... for each chunk
Use generated values to determine the biome for each chunk
For each tile interpolate the generated of the surrounding chunks
Use the interpolated values to select ground textures, plants, ...
That should generate smooth borders between biomes and also different chunks with the same biome can have a different feel.

Comparing 2 bitmaps taken 1 second after another

I was thinking about writing a very simple program to compare 2 ARGB array pixel by pixel. Both images are same resolution, taken with the same camera source.
Since the camera is being hold still, I was expecting it's a fairly simple program to compare bitmap source by
Convert every pixel into Gray scale pixel
Literally compare each pixel from position 0 to N.
Have a isClose method to do an approximate +/- 3.
The result is that I have too much error bits. But when taking JPEG out of it and view it with naked eye, they seem to be identical (which is the case).
Why do you think I am seeing so much error when comparing them?
BTW - I am trying a write a very basic version of motion detection.
If you are tracking a known object you can pre-process your images before you compare them. For example, if it's a ball you're tracking and it appears brighter than its surroundings, you can threshold your greyscale image that will produce an image with only black or white. You then detect what are known as "contours" (see openCV documentation). Once you get the contour you are after (the ball) in any image, you can compare the location of it in each successive image. There are some algorithms that help figure out where a moving object will be next so it helps finding it in the next frame.
Without knowing exactly what you are doing, it's hard to give anything concrete.
And I see you're C#...maybe this will help: .Net (dotNet) wrappers for OpenCV?
b/c the pictures are not the same.
each one you pressed the button of the camera a little differently.
the change is "huge" if you compare pixel by pixel.
I'm not an expert on motion detection, but try to compare averages around a pixel - I think it will give you better results.

Detecting truck wheels

I am currently working on a project which we have a set of photos of trucks going by a camera. I need to detect what type of truck it is (how many wheels it has). So I am using EMGU to try to detect this.
Problem I have is I cannot seem to be able to detect the wheels using EMGU's HoughCircle detection, it doesn't detect all the wheels and will also detect random circles in the foliage.
So I don't know what I should try next, I tried implementing SURF algo to match wheels between them but this does not seem to work either since they aren't exactly the same, is there a way I could implement a "loose" SURF algo?
This is what I start with.
This is what I get after the Hough Circle detection. Many erroneous detections, has some are not even close to having a circle and the back wheels are detected as a single one for some reason.
Would it be possible to either confirm that the detected circle are actually wheels using SURF and matching them between themselves? I am a bit lost on what I should do next, any help would be greatly appreciated.
(sorry for the bad English)
UPDATE
Here is what i did.
I used blob tracking to be able to find the blob in my set of photos. With this I effectively can locate the moving truck. Then i split the rectangle of the blob in two and take the lower half from there i know i get the zone that should contain the wheels which greatly increases the detection. I will then run a light intensity loose check on the wheels i get. Since they are in general more black i should get a decently low value for those and can discard anything that is too white, 180/255 and up. I also know that my circles radius cannot be greater than half the detection zone divided by half.
In this answer I describe an approach that was tested successfully with the following images:
The image processing pipeline begins by either downsampling the input image, or performing a color reduction operation to decrease the amount data (colors) in the image. This creates smaller groups of pixels to work with. I chose to downsample:
The 2nd stage of the pipeline performs a gaussian blur in order to smooth/blur the images:
Next, the images are ready to be thresholded, i.e binarized:
The 4th stage requires executing Hough Circles on the binarized image to locate the wheels:
The final stage of the pipeline would be to draw the circles that were found over the original image:
This approach is not a robust solution. It's meant only to inspire you to continue your search for answers.
I don't do C#, sorry. Good luck!
First, the wheels projections are ellipses and not circles. Second, some background gradient can easily produce circle-like object so there should be no surprise here. The problem with ellipses of course is that they have 5 DOF and not 3DOF as circles. Note thatfive dimensional Hough space becomes impractical. Some generalized Hough transforms can probably solve ellipse problem at the expense of a lot of additional false alarm (FA) circles. To counter FA you have to verify that they really are wheels that belong to a truck and nothing else.
You probably need to start with specifying your problem in terms of objects and backgrounds rather than wheel detection. This is important since objects would create a visual context to detect wheels and background analysis will show how easy would it be to segment a truck (object) on the first place. If camera is static one can use motion to detect background. If background is relatively uniform a gaussian mixture models of its colors may help to eliminate much of it.
I strongly suggest using:
http://cvlabwww.epfl.ch/~lepetit/papers/hinterstoisser_pami11.pdf
and the C# implementation:
https://github.com/dajuric/accord-net-extensions
(take a look at samples)
This algorithm can achieve real-time performance by using more than 2000 templates (20-30 fps) - so you can cover ellipse (projection) and circle shape cases.
You can modify hand tracking sample (FastTemplateMatchingDemo)
by putting your own binary templates (make them in Paint :-))
P.S:
To suppress false-positives some kind of tracking is also incorporated. The link to the library that I have posted also contains some tracking algortihms like: Discrete Kalman Filter and Particle Filter all with samples!
This library is still under development so there is possibility that something will not work.
Please do not hesitate sending me a message.

List Coordinates of Pixels Inside a Triangle

I'm making a game in C# and XNA, and I was trying to come up with a method to render massive terrains without using a tremendous amount of memory or passing the poly limit hard-coded into XNA.
My solution so far is to create a massive heightmap, and that heightmap is loaded into memory at the beginning of the game in the initialization phase. Then, terrain is only generated nearest to the camera. This is accomplished by projecting a triangle whose vertex is the character and the other two endpoints extend to the sides of the character's viewing area. Then, all the pixels inside that triangle on the heightmap are rendered and drawn into the game, thus only rendering what is seen.
The problem is, I've successfully found (I think, can't test until I get terrain rendering) the three vertices of the triangle. Now I need to find a list of the coordinates for every single pixel inside that triangle - whole numbers only, because I just need a list of pixels to render.
I know it sounds a little confusing, so here's the gist of it:
I have an image, and I project a triangle onto that image. The only thing I know about that triangle are the three vertices. I need a list of the pixels inside that triangle.
I've been Googling around for maybe 20 minutes now, and I figured I midas well go ahead and post something here due to the fact that what I'm trying to do isn't all that common. If I find an answer, I'll be sure to post it here.
But until then, can anyone tell me how to accomplish this?
Edit: A formula, please. If you can provide a formula or algorithm, and an explanation, that would be just perfect.
Edit: I've posted a new question, as I've ditched this method of rendering large terrains. The question is here.
Start here:
http://mathworld.wolfram.com/TriangleInterior.html
One of the non-trivial problems, not mentioned there, that you have to deal with is the pixelization along the boundary.

Using DynamicVertexBuffer in XNA 4.0

I read about DynamicVertexBuffer, and how it's supposed to be better for data that changes often. I have a world built up by cubes, and I need to store the cubes' vertices in this buffer to draw them to the screen.
However, not all cubes have vertices (some are air, which is transparent) and not all faces of the cubes need to be drawn either (they are facing each other), so how do I keep track of what vertices are stored where in the buffer? Also, certain faces need to be drawn last, namely the ones with transparency in them (like glass or leaves), and these faces also need to be drawn in a back-to-front order to not mess up the alpha blending.
If all of these vertices are stored arbitrarily in this buffer, how do I know what vertices are where?
Also, the number of vertices can change, but the DynamicVertexBuffer doesn't seem very dynamic to me, since I can't change it's size at all. Do I have to recreate the buffer every time I need to add or remove faces?
Sounds like you are approaching this in the wrong way - assuming you have anything more than a trivial number of cubes in your world. You should store the world (and it's cubes) in a custom data structure that lets you rapidly determine which cubes (and faces) are visible based on the rules of your world from a given point when looking in a given direction.
Then each time you render a scene generate batches of vertex buffers of just these faces. So don't use vertex buffers as the basis for storing the entire geometry of your world. Vertex buffers are a rendering tool, not a world scene graph tool.
These kind of large scale visibility issues are much faster run in code than by the GPU. For example if you are sat at the origin, looking +x, you can immediately ignore all cubes in the -ve x direction, this is a very simple example.
For a more complete example search on oct-tree rendering. This kind of rendering would match your world layout quite nicely.
Final tip - when I say generate batches of vertex buffers - I mean batch you cubes together in ways that minimize changes in the state of the GPU (e.g. same texture, same shader etc). Minimizing changes to the state of the GPU is key to optimizing the rendering - once you've gone as far as you can with culling faces from the render in the first place.

Categories

Resources