WPF polygons disappearing, flickering, Z-fighting? - c#

I am working with a 3D-WPF Application that contains very larg as well as tiny 3D-Objects at the same time. (a satellite simulation)
To display them at the same time I have to set the NearPlaneDistance to a much lower value than the FarPlaneDistance (factor 10^9 times smaller), which seems to be the root of the problem
Now I have the problem that some polygons disappear (e.g are not drawn) at certain camera settings ( look direction etc. ) -> When the camera moves it flickers. (Example Picture of an MWE i coded just one really big cube and and a very small one)
I suspect this is caused by Z-fighting, but I am not sure because sometimes whole objects disappear, and there is also a big difference between objects ModelVisual3Ds that have been transformed or not.
I tried various combinations of Near and FarPlaneDistances but there is always some problems.
Is there a way to increase the z-Buffer precision or make it logarithmic ?
I know Wikipedia suggest cheating about the distance (making an object smaller to simulate distance), but i thought before getting into that I ask here :)

It's probably z-fighting due to floating point rounding error at those high sizes. The larger the floating point numbers get, the more their accuracy decreases.
You could try scaling everything down by an order of magnitude to get more floating point accuracy. This shouldn't affect your simulation or anything visual as long as you scale everything down equally to match, such as cameras, positions, and entity movement.

Related

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.

Scrolling momentum on mobile devices

I'm trying to get a general smooth scrolling mechanism that I can implement in my mobile applications.
I want it to be generic enough so that it can port to any platform, but I am currently working in C# on the .net Compact Framework.
What I'm doing right now is:
Create a Stopwatch object (in the panel's ctor)
on mouse down start the Stopwatch and save the current mouse point _lastMouse
on mouse move, stop the Stopwatch, and store velocity = (_lastMouse - curMouse) / Stopwatch.TotalSeconds then reset the Stopwatch and start it again
In most cases Stopwatch.TotalSeconds is between 0.02 and 0.03
on mouse up, I pass the velocity value into a smooth scrolling function, and that function continues to scroll the panel until either the end is hit or the increasing friction causes the velocity to be == 0
My problem is in the final step. The velocity values are generally int the 2,000-3,000 pixel range. The velocity is in pixels per second, so this is to be expected. I take the Stopwatch (which should be still running), stop it and I find the elapsed time from last mous move and multiply velocity by Stopwatch.TotalSeconds, get that distance and then reset and start the Stopwatch, then loop back and start all over again.
The expected result is that the elapsed time between refreshes multiplied by the velocity should give me the number of pixels (according to the last mouse move) that I should scroll. My actual result is that sometimes the panel goes flying and sometimes it bearly moves! the gradual slowdown is fine, it's just the beginning velocity that is off
Is there a flaw in the logic? Should I be doing something else?
Thanks for any help!
It seems to me that there are three possible sources of inaccuracy here. Firstly, as "A.R." said, you'll have problems if the granularity of your timer isn't good enough. Have you checked IsHighResolution and Frequency to make sure it's OK?
Secondly, even if your timer is perfect, there may be some inaccuracy in your position measurements, and if you're taking two in very quick succession then it may hurt you. My guess is that this isn't a big deal, but e.g. if you're on a capacitive touchscreen then as the finger lifts off you may get variation in position as the contact area goes down.
Thirdly, the physical motion of the finger (or stylus or mouse or whatever you've got doing the actual input; I'm going to guess a finger) may not be all that well behaved. At the end of a gesture, it may change from being mostly horizontal to being mostly vertical.
All these problems would be substantially mitigated by using a longer sampling period and maybe (try it both ways) ignoring the very last sample or two. So, keep a little circular buffer of recent samples, and when you get the mouse-up look back (say) 100ms or thereabouts and use that to decide your velocity. Or, if you don't want to keep that much history, use a simple IIR filter: every time you get a sample, do something like
filtered_dt = filtered_dt + SMALL*(latest_dt-filtered_dt);
filtered_dx = filtered_dx + SMALL*(latest_dx-filtered_dx);
filtered_dy = filtered_dy + SMALL*(latest_dy-filtered_dy);
where SMALL should be, at a guess, somewhere around 0.2 or so; then use filtered_dx/filtered_dt and filtered_dy/filtered_dt as your velocity estimate. (I think this is better than calculating a velocity every time and filtering that, because e.g. the latter will still blow up if you ever get a spuriously small dt. If in doubt, try both ways.)
If you use the IIR approach, you may still want to make it ignore the very last sample if that turns out to be unreliable; if you remember the latest dt,dx and dy you can do that by undoing the last update: use (filtered_dt-SMALL*latest_dt)/(1-SMALL), etc.
Here's an off-the-wall suggestion that may or may not work. You mentioned that you get more erratic results when there's a "flick" at the end of the gesture. Perhaps you can use that to your advantage: look at, say, how rapidly the estimated velocity is changing right at the end of the gesture, and if it's changing very rapidly then increase the velocity you use somewhat.

Imposing limitations on 4-point image transformation

I'm working on a 4-point image transformation for an application. The user would either drag each corner around to create a valid quadrilateral shape, or use its "bounding box" to resize it vertically, horizontally, and proportionally.
So far, I have the image transformation part working. However, I'm having a hard time imposing limitations to it so that...
The vertices doesn't cross over each other. In another words, I don't allow the user to create an hour-glass shape. It must always be a quadrilateral.
Likewise, the angle between each corner must be greater than 0. Otherwise, the vertices will end up in a line.
It has a minimum size on this image. That is, each corner has to be a certain distance away from each other, and their opposing lines.
The user cannot "flip" the image to its backside. The 4 corners (p1, p2, p3, and p4) must appear in clockwise order.
Concave kite shapes and triangles are valid.
I was wondering if there was a formula or a paper regarding these issues. I do currently have the formulas for finding if 2 line segments intersect (and where), as well as finding the closest point on a line to another point. Most of my implementations hasn't been user-friendly as I liked, as the corners would jump all over the place when imposing restrictions.
P.S. I'm using C# for this project, with DirectX. The application is solely 2D, however.
My suggestion is not to impose restriction but just drawing say just a red wireframe polygon if for you it's unacceptable.
It's more or less like when programmers put restriction on form input fields e.g. begin date must come before end date and don't allow you to type in a date in the begin field that's after the date in the end field... forcing users to tab to end field first, then entering the end date, then tabbing back to the begin field to enter the correct begin date.
Just showing the fields in red is MUCH more usable... and actually requires less coding.
Trapping user mouse movements is rarely a sensible idea. If you can't apply what user is asking just make this evident instead of constraining the movement... may be the user is moving the first vertex and wants to move another vertex later to a position that will make your transform valid (exactly like the two date fields example).
If you really think you MUST prevent invalid positions at all times (and that for example will forbid the user from flipping the image even if your transform would allow a flipping operation without problems) then the simplest solution that comes to my mind is just having an isValid() function and just not moving the keypoint to the new position if it's invalid.
Having code that "slides" around invalid state space areas is IMO quite difficult to handle nicely, also because invalid areas are going to be quite close to "almost invalid" areas.
Even in case "sliding" is a requirement I'd probably go for implementing an implicit isValid() approach by doing a local search around the keypoint position to find what is the closest valid point to the point the user is asking for.
Explicitly computing all sliding possibilities would be a nightmare to get correct and also to maintain if you need to change something in the transformation algorithm (and consequently in what is valid and what is not).
When you start out, and each time the user moves a handle, determine the set of horizontal and vertical lines that the other handles cannot pass, and enforce those boundaries during a drag. This will solve your first problem.
For the second, when the mouse moves during a drag, calculate the distance between the cursor and each of the other 3 handles; if it is less than your defined minimum distance then move the handle in a circular path around the other handle(s).

XNA 2D mouse picking

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

C#: 2D sub-Tile Line intersection

I have some problems getting an algorithm for my game to work and hope someone here can help me. Google didn't seem to be a good help as most solutions just work for full tiles.
In the game units can occupy different positions inside a tile, i.e. they can be in the upper left corner, center, bottom right, ... position of tile (2/3), i.e. (2.2/3.1), (2.5/3.5), (2.8/3.9).
If they move from position (2.2/3.1) to (5.7/4.1) i require a check to see if there is an obstacle in the path.
My current algorithm is:
Starting from (2.2/3.1)
Calculate the angle of the movement (i.e. 70 degree)
Move 0.1 steps in that direction
Check which tile i'm on (floor(p.X)/floor(p.Y))
Repeat from 2
This algorithm works but to me it doesn't look very efficient as an obstacle can be only a full tile, not a part of a tile (units don't collide). If i increase the step size i begin to miss tiles that are only crossed slightly (i.e. you only cross the lowest left corner). Even with a step size of 0.1 it's still possible to miss an obstacle.
I tried to find a solution to take the sub map (all tiles with the corners (floor(start.X)/floor(start.Y)) and (ceil(start.X)/ceil(start.Y)), move through every tile and check mathmatically if it gets crossed. Sadly i seem to lack the required math knowledge for this check.
My last idea was to take all 4 borders of a tile as a line and do line-intersection but that seems to be slower than my original approach.
Any hints?
Thanks.
Instead of tracing the path by stepping along the line - you want to jump right to the next possible tile (the border). This can be calculated fairly simply. I will use your sample numbers above.
Calculate the line eqn (y= .286x + 2.471)
You are starting on tile 2,3 and moving towards tile 5,4. So calculate the y value when x goes to 3 (the border to the tile immediately to the right). It is 3.329.
Then calculate the x value when y goes to 4 (the border to the tile immediately above). It is 5.346.
Starting at 2,3 and moving right gets to 3,3.329. Moving up gets to 5.346,4. You intersect on the right(moving 2 -> 3 on x doesn't move a tile on y). You don't intersect above until you are on tile 5 in the x.
The tile calculated in 4 becomes your new comparison (3,3). Repeat from step 2.
This process only incurs one calculation per tile moved (regardless of your precision or how big the tiles are) and is exact. Note that the values calculated can be stored and reused instead of blindly calculating both intersections over and over. In the above we know (step 4) that we don't move up a tile until x=5. So the entire path can be inferred without another calculation (2,3 -> 3,3 -> 4,3 -> 5,3 -> 5,4).
It is also possible to precalculate all the transistions instead of doing them stepwise although this would only be beneficial if you always need the entire path (you don't since you want to stop processing once you find an obstacle).
Two caveats. Be careful about signs and which way the line is going - many a bug happen by not paying close attention to negative slopes. Also, using reals you almost never will cross diagonally (two borders at once) but you should be aware of it (handle it in the code) just in case.
There is a name for this method but I can't remember it off the top of my head. I believe it might be from Game Programming Gems series but maybe someone else can provide a better reference.

Categories

Resources