Odd geometry with 3D models XNA + Blender - c#

Ok, this is hard to explain without pictures. I made a very limited model of a glock in Blender with an extruded cube making up the base and a scaled cube making up the barrel.
In Blender, It looks fine:
However, after exporting the model to .fbx and loading it into the compiler, it comes out like this:
I don't know exactly what is going on. Everything on the model is properly UV Mapped and the coordinates are correct, It just seems the translation is.. off..
Here is my drawModel code:
private void DrawModel(Model model, Matrix world, Matrix view, Matrix projection)
{
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = world;
effect.View = view;
effect.Projection = projection;
}
mesh.Draw();
}
}
Any pointers will be helpful!
EDIT: After Applying rotation, location, and scale, I was able to get them in the right position, but why does it look transparent?
Thank you for all the help!

As Nikola mentioned, in the later versions of Blender, they have proper XNA support.
Here's a screenshot of the settings I chose when exporting a model:

Why this happens:
Your Depth Buffer is not enabled, so when your GPU draws the barrel first, then the stock/handle, the handle is drawn on top of the barrel, even though some parts of it are supposed to be invisible because they would be hidden by the barrel.
How to fix:
Enable Depth Buffer as other answer suggests. And/Or order meshes in your model based on distance from camera, and draw tehm in order from the nearset to the farthest. This may not seem usefull now, but when you start working with transparent objects, you will see why this is a good thing to learn.

Enable depth buffer:
GraphicsDevice.DepthStencilState = DepthStencilStates.Default;
And to Draw a model in Xna you can follow this tutorial, that shows how the bone transforms have to be applied to get the meshes in right position.

Related

Model expands on moving horizontally in unity

I am moving a .obj 3D model horizontally and upon reaching the extreme left it expands which looks really weird.
I even tried to change projection from perspective to orthographic and it makes it look even weirder.
// simple movement code
void Update ()
{
transform.Translate(Input.GetAxis("Horizontal") * Time.deltaTime * 3, 0f, 0f);
}
It's an unavoidable effect of rendering a 3D space on a 2D plane.
The only way to eliminate perspective distortion is to resort to
something like fisheye projection, which makes the image appear
distorted in a circular fashion. Or go orthographic.
Edge Distortion on Camera - Unity Forums

Drawing a specific region of a 3D scene to a larger canvas/viewport

I have a 3D scene of which I want to draw a specific region onto a larger canvas/viewport (think like a magnifying glass).
Something like the following image:
I want to maintain any perspective effects, simply moving my camera to the specified region wouldn't give that effect.
I gathered from http://www.mvps.org/DirectX/articles/tilerender/index.htm that it's possible to do some trickery with the Projection Matrix but I couldn't figure out the math behind getting a more specific subsection/region than what is described in that article.
If we assume the coordinates described in the article, x0y0 would be the exact center of the scene, x-1y1 would be the top-left and x1y-1 would be the bottom-right of the scene.
I would, for example, want to render the region ranging from x-0.75y0.75 to x-0.25y0.25.
I have a Projection matrix and a View matrix separately available. I am using the SharpDX library and my Projection matrix is Right-Handed(which seems the flip the y-coordinates described above).
How do I calculate the Scale/Translation matrices that I need to multiply my Projection matrix with? Or, alternatively, what other ways are there to tackle this issue?
Psuedo-code would be something like this:
public Matrix GetProjectionRegion(float topLeftX, float topLeftY, float bottomRightX, float bottomRightY)
{
var magicMatrix = Matrix.Identity;;
//some magic
return magicMatrix;
}
ProjectionMatrix *= GetProjectionRegion(-0.75f, 0.75f, -0.25f, 0.25f);
EDIT:
I am currently creating my Projection matrix using one of two methods:
ProjectionMatrix = Matrix.PerspectiveFovRH(FOV, Width / Height, NearPlane, FarPlane);
or
ProjectionMatrix = Matrix.OrthoOffCenterRH(_topLeft.X, _bottomRight.X, _topLeft.Y, _bottomRight.Y, NearPlane, FarPlane);
Nearplane is 75 farplane is 5000000; Width/Height/_topLeft/_topRight are all pixel formats as far as I remember.
The matrices are used Row-Major.
If you really want to do a very basic mechanism for zooming in, you could cheat with your camera matrix, that is the "World" in your world view projection matrix.
The zoom could be tackled through proximity to the location. Nothing more. BUT, if you are determined, you could also scale that World matrix also, which would then enlarge all objects, therefore effectively zoom.

Draw 3D model at coordinates in C# xna?

i'm drawing several primitives with a camera class that supplies with view, world and projection. With these i can move the camera and see all 3 of my primitives. The problem is that i now wan't to add a 3d model in the project, but the ways i know of to draw a 3d model won't work with the camera class. I have tried using:
Matrix[] transforms = new Matrix[mymodel.Bones.Count];
mymodel.CopyAbsoluteBoneTransformsTo(transforms);
foreach (ModelMesh mesh in mymodel.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms[mesh.ParentBone.Index] *
Matrix.CreateRotationY(0.0f)
* Matrix.CreateTranslation(modelposistion);
effect.View = Matrix.CreateLookAt(cameraPosistion, Vector3.Zero, Vector3.Up);
effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, 1.0f, 10000.0f);
}
mesh.Draw();
}
But this draws the model in the center of the screen, while i want it stationary, so i can view other models in the same project.
Any help to how this can be achieved?
If I understand your problem: "as you move your camera, the model follows".
Most likely, it isn't following, you are just moving the camera without changing where the camera is "looking at". Your view matrix calls for it to look at (camera to be pointed at) Vector3.Zero no matter what position the camera is altered to. This means that if your model position does not change, and your view matrix is always looking at the same world location, then the model will not appear to change position. It may get bigger or smaller or you might see it from different angles, but it will always be in the same spot on your screen. It's because your telling the camera to always look at the same position in your world.
Changing the camera position isn't enough to freely look around your world, you must also change where the camera is looking at ( the 2nd param of the View matrix).
Also, it is best to think of the camera as having just a view and projection matrices. The world matrix should be thought of as part of (or supplied by) the model.

multiple matrices in c# xna phone app

I've created the beginnings of a windows phone app. It's a mix of two popular online tutorials
http://rbwhitaker.wikidot.com/simple-3d-animation
http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series1/Terrain_from_file.php
The code I've made is here
http://pastebin.com/5VusJpB0
I've added some code to catch the use of the accelerometer but it's all going a bit wrong! The code I've copied from the two examples have both declared world, view and projection matrices. One set for aircraft model in rbwhitakers code and the other set for the terrain from riemers code. I believe the matrices are the problem but I don't quite understand how they work. I only need one camera view so I need to lose a view matrix and it only needs one projection declaration right so I need to lose another projection matrix?. I'm guessing they should both share the same world but have different positions in that world. Can somebody help a noob out and see the problem?!
Thank you.
You are on the right track to solving this. Both the terrain and the model (and any other drawn item) should share the same view and projection matrices. Each item, however, should have it's own world matrix.
The world matrix represents the individual item's position and orientation relative to world space.
Think of the view matrix as the camera's position and orientation in the world. In actuality it is an inverse of that, but can be thought of as that for mind's eye conceptualizing.
The projection matrix is somewhat analogous with a lens attached to the camera (the view matrix) as it modifies the way the world is seen from the camera's perspective.
Just as when viewing a movie you are looking at many actors or props at any given moment (each with it's own position and orientation (world matrix) in the scene), you view them through a single camera at a time (shared view matrix) which is fitted with a single lens at a time(the projection matrix)

XNA Texturing issue

Ok, I've been trying a lot of new things lately, and I've had a few stopping points. I decided to leave 3d because I figured I just didn't and couldn't understand the coding involved. I'm pretty good at math though, so I figured I would give it another shot.
I'm trying to learn 3d XNA in c#, I've recently worked out 2d and wish to move on. My problem is that with (in my opinion) the most basic of 3d shapes, a cube, I run into problems. After successfully exporting my cube from blender (after the 7th try >_>) and importing it into XNA, I can't get a texture to correctly show on the cube, so I downloaded a cube model from a sample source code file, and attempted to use that, and it's default texture, and I still have problems.
Basically, the code to draw the cube is:
foreach (ModelMesh mesh in model.Meshes)
{
GraphicsDevice.RasterizerState = RasterizerState.CullClockwise;
foreach (BasicEffect effect in mesh.Effects)
{
effect.TextureEnabled = true;
//effect.Texture = texture;
effect.World = world;
effect.View = view;
effect.Projection = projection;
effect.LightingEnabled = false;
}
mesh.Draw();
}
The RenderState and LightingEnabled are new, attempting to fix it myself, when I use my own texture, the texture looks like it's being stretched, and isn't showing the entire image on the cube, but all faces look the same, so it's not wrapping it.
Also, to see all the faces I rotate the cube like:
position -= new Vector3(0, 0.00f, 0.0100f);
angley += 0.01f;
anglez += 0.01f;
world = Matrix.CreateScale(1.5f) * Matrix.CreateRotationZ(anglez) * Matrix.CreateRotationY(angley) * Matrix.CreateTranslation(position);
The z change is so I could test another theory.
The default texture is a sandish texture, I'm not sure if it's stretching, because it's almost a solid color. But the box itself seems to be oddly represented (it looks as though I can see through the near faces, and I'm looking at the backs of the opposing ones)
I'm hoping someone can give me a hand, it just seems like it should be much simpler then it seems to be, to draw a simple textured cube, and most of the tutorials online are from older versions of XNA, so the code doesn't match up, and I get lost when trying to replace it with current code. (On tutorials that create a cube in code, rather then a model.)
Anyways, thanks for any answers.
EDIT 1:
Drawing this cube with CreateOrthographic makes it look correct (the first one uses perspective) but still no texture love :(
EDIT 2:
When I use my cube it's stretched, when I use the one from the source, it's a solid color.
EDIT 3:
I probably would have gotten an answer sooner had I mentioned I was displaying FPS using a font/spritebatch. When I was working out why it wouldn't work, and comparing it to a sample that DID work, I found it, Now, does anyone know how to make that work?
To myself, and anyone else encountering this problem >.<
Are you using:
SpriteBatch.begin()
to do anything in your code? If so, this is screwing up with the way your program renders in 3d, check out this link (for pre XNA 4.0):
http://blogs.msdn.com/b/shawnhar/archive/2006/11/13/spritebatch-and-renderstates.aspx
And this link if you using XNA 4.0:
http://blogs.msdn.com/b/shawnhar/archive/2010/06/18/spritebatch-and-renderstates-in-xna-game-studio-4-0.aspx
The line in particular that fixed this issue was:
GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
Adding that before the foreach loop fixed this problem for me, but you may need to try the other lines in that article
To anyone else reading this, Good luck with your XNA dreams :D

Categories

Resources