DirectX meshes not being displayed properly after switching view and projection matrices - c#

In my program, the meshes were being displayed properly, but when I change the device.transform.view and the device.transform.projection matrices from the left handed to the right handed system, the meshes are not displayed properly anymore, i.e the back faces are being illuminated and the front faces are transparent!
Does anyone have an idea what more needs to be changed to have a proper display
Original matrices:
device.Transform.View = Matrix.LookAtLH(vFrom, vAt, vUp);
device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, fAspect, 0f, 100f);
modification:
device.Transform.View = Matrix.LookAtRH(vFrom, vAt, vUp);
device.Transform.Projection = Matrix.PerspectiveFovRH((float)Math.PI / 4, fAspect, 0f, 100f);

Well I'd expect both of those matrices to fail terribly on the basis that you set the near plane to 0. It really ought to be some small epsilon like 0.0001f.
The other thing to bear in mind is that by swapping the handedness of the system you are most likely inverting the winding order of the tris.
You need to set the culling render state to clockwise instead of anti/counter-clockwise.
ie
dxDevice.SetRenderState( RenderState.CullMode, Cull.Clockwise );

Related

Unity | CircleCollider2D.radius returning same value

I have a project on Unity where I have a 2D space world, where a player (spaceship) is influenced by the gravitational pull of the surrounding planets. But I'm using Newton's law for gravity (F=G*((M*m)/r^2)), and the problem with this is that the gravitational pull will be active throughout the whole level.
So I'm using the Sphere of influence to get a limit as to where the gravity would stop influencing the spaceship, and to do this it requires me to have the radius of the Planet.
The problem is that my Planets don't all have the same size (or "scale"), but the prefabs do. So the CircleCollider component has a radius of 1.5 referring to the original scale. No matter the scale, it stays the same, even when I rescale it manually, the collider gets bigger with it in the scene view, but the value is the same.
So let's say I have Planet1 with a scale of (20,20,20), and Planet2 with a scale of (10,10,10). They have different scales, but their CircleCollider has a value of 1.5, even though it is clearly twice as big in the scene view.
I've looked everywhere and I still haven't found a way of adjusting the CircleCollider.radius value to the scale of the Planet.
I don't necessarily need to get the CircleCollider radius, but just the Planet radius.
So, as I understood colliders visually are correct size so they will work correctly but you trying to get its value and it is returning some kind of local value. So just multiply it by scale!
Vector3 scl = gameObject.transform.scale();
float colliderRadius = radius*scl;
Note: I dont have Unity opened so it is more like pseudo-code.

XNA: Orthographic window resizing without stretching

I've been working on a game project for Windows for a while now. I used to have a static 1600 x 900 resolution, which worked fine for me. But not so much for some of my beta testers.
This got me looking into resolution independence in XNA-based games. I've gone through a lot of the Virtual Resolution systems that draw everything on a RenderTarget2D and stretch that to fit the window size. But that doesn't work for me.
What I want to know is how I could calculate a similar projection matrix as to what Terraria uses. For those who don't know how it works in terraria (now days anyway, I think it used to be different) is that once you resize the game window, you see more stuff on the screen.
Currently my projection matrix is defined as such:
Projection = Matrix.CreateOrthographicOffCenter(-25 * _graphics.Viewport.AspectRatio,
25 * _graphics.Viewport.AspectRatio,
-25, 25,
-1, 1 );
This works when the window's size changes horizontally. I see more stuff sideways and everything is fine. But once I resize the window vertically, everything clamps together.
Is there a way to calculate the projection matrix so that it'd allow me to resize the window both horizontally and vertically?
EDIT:
I am using a camera class indirectly. Everything is in Farseer Physics coordinate space, and when something is getting drawn to the screen, its converted via Viewport.Unproject().
SOLUTION:
As gareththegeek pointed out in the comment section of the chosen answer, my particular projection matrix I was after is formed like this:
Projection = Matrix.CreateOrthographicOffCenter(-(_graphics.Viewport.Width / 1600f * 44),
(_graphics.Viewport.Width / 1600f * 44),
-(_graphics.Viewport.Height / 900f * 25), (_graphics.Viewport.Height / 900f * 25),
-1, 1);
If you include the resolution of the display in the orthographic projection you can achieve the desired effect I think.
Projection = Matrix.CreateOrthographicOffCenter(
0.0f, _graphics.Viewport.Width,
_graphics.Viewport.Height, 0.0f,
-1.0f, 1.0f);

Trying to draw textured cube primitive in XNA with quads

Right now I'm using XNA 4.0 with Windows Phone Developer Tools to create a textured cube using a predefined quad class on MSDN.
The front/back/left/right faces of the cube will draw fine (for every cube that I make), however the top and bottom faces won't render. The rasterizer state's cull mode is set to none and the quad that represents the top face exists, and it seems as if it would draw, but for some reason it won't.
Is there a problem with my code, or is this not happening for some other reason?
Here's the code:
Game1.cs: http://pastebin.com/RHU7jNXA
Quad.cs & Cube.cs: http://pastebin.com/P9gz5q4C
It's because your top and bottom faces have a height to them. They should have 0 height.
Here you are passing in a value as height:
Faces[4] = new Quad(topFaceOrigin, Vector3.Normalize(Vector3.Down), Up, Size, Size);
And then here in Quad constructor it's being used to give incorrect LowerLeft & LowerRight values:
LowerLeft = UpperLeft - (Up * height);
LowerRight = UpperRight - (Up * height);
I would recommend changing how you create all your quads; each face really should have different parameters. Right now all your faces are passing in practically the same stuff.

xna depth of field increase? i see backround color!

i created a scene in 3d max which is pretty huge, the thing is , this represents the galaxy and i will have a camera in there , but because its so big, the camera's view distance isnt covered by all the field , causing the background to be displayed at places, so how can i increase the view distance of my camera to view all the field? This is in XNA, visual studio.
aspectRatio = ((float)viewport.Width) / ((float)viewport.Height);
projectionMatrix = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(40.0f),
this._aspectRatio,
1.0f,
10000.0f); // Increase this number to increase the "depth"

Math - Displaying multiple objects in a single view using trigonometry

It might be that my math is rusty or I'm just stuck in my box after trying to solve this for so long, either way I need your help.
Background: I'm making a 2d-based game in C# using XNA. In that game I want a camera to be able to zoom in/out so that a certain part of objects always are in view. Needless to say, the objects move in two dimensions while the camera moves in three.
Situation: I'm currently using basic trigonometry to calculate which height the camera should be at for all objects to show. I also position the camera between those objects.
It looks something like this:
1.Loop through all objects to find the outer edges of our objects : farRight, farLeft, farUp, farDown.
2.When we know what the edges of what has to be shown are, calculate the center, also known as the camera position:
CenterX = farLeft + (farRight - farLeft) * 0.5f;
CenterY = farUp + (farDown - farUp) * 0.5f;
3.Loop through our edges to find the largest value compared to our camera position, thus the furthest distance from the center of screen.
4.Using the largest distance-value we can easily calculate the needed height to show all of those objects (points):
float T = 90f - Constants.CAMERA_FIELDOFVIEW * 0.5f;
float height = (float)Math.Tan(MathHelper.ToRadians(T)) * (length);
So far so good, the camera positions itself perfectly based on the calculations.
Problem:
a) My rendering target is 1280*720 with a Field of View of 45 degrees, so one always sees a bit more on the X-axis, 560 pixels more actually. This is not a problem per se but more one that on b)...
b) I want the camera to be a bit further out than it is, so that one sees a bit more on what is happening beyond the furthest point. Sure, this happens on the X-axis, but that is technically my flawed logic's result. I want to be able to see more on both the X- and Y-axis and to control this behavior.
Question
Uhm, so to clarify. I would like to have some input on a way to make the camera position itself, creating this state:
Objects won't get closer than say... 150 pixels to the edge of the X-axis and 100 pixels to the edge of the Y-axis. To do this the camera shall position itself along the Z-axis so that the field of view covers it all.
I don't need help with the coding, just the math and logic of calculating the height of my camera. As you probably can see, I have a hard time wrapping this inside my head and even harder time trying to explain it to you.
If anyone out there has been dealing with this or is just better than me at math, I'd appreciate whatever you have to say! :)
Don't you just need to add or subtract 150 or 100 pixels (depending on which edge you are looking at) to each distance measurement in your loop at step 3 and carry this larger value into length at step 4? Or am I missing something.
I can't explore this area further at the moment, but if anyone is having the same issue but is not satisfied by provided answer there is another possibility in XNA.
ViewPort.Unproject()
This nifty feature converts a screen space coordinate to a world space one.
ViewPort.Project()
Does the opposite thing, namely converting world space to screen space. Just thought that someone might want to go further than me. As much as my OCD hates to leave things not perfect, I can't be perfectioning this... yet.

Categories