loading mesh like mesh viewer

is there a way and if so how can one load mesh files like the mesh viewer loads them, I took just for kicks the tiger sample and loaded a mesh that a friend made and it dident load right, rotates right off the screen, I dont really understand VC++ much to find my way through the mesh viwer code I am using C#, and help would be great.
[336 byte] By [Smacker] at [2008-1-27]
# 1
Here's a little helper function that loads a mesh and applies all the textures.
You need to provide a Mesh variable, a Material[] and a Texture[] array for each mesh you want to load.


public static Mesh LoadMesh(Device device, string file, ref Material[] meshMaterials, ref Texture[] meshTextures)

{

ExtendedMaterial[] mtrl;

Mesh tempMesh = Mesh.FromFile(file, MeshFlags.Managed, device, out mtrl);

if ((mtrl != null) && (mtrl.Length > 0))

{

meshMaterials = new Material[mtrl.Length];

meshTextures = new Texture[mtrl.Length];

for (int i = 0; i < mtrl.Length; i++)

{

meshMaterials[ i ] = mtrl[ i ].Material3D;

if ((mtrl[ i ].TextureFilename != null) && (mtrl[ i ].TextureFilename.Length > 0))

{

meshTextures[ i ] = TextureLoader.FromFile(device, @"..\..\" + mtrl[ i ].TextureFilename);

}

}

}

return tempMesh;

}

DanielRieck at 2007-9-9 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...
# 2
its really not the loading of the mesh I have a problem with its the placment of the mesh, if you load a mesh in the mesh viewer its always center screen for all meshes that get loaded and they all rotate perfict, thats what I want to know how to do, thanks a ton.
Smacker at 2007-9-9 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...
# 3
Haven't written any DirectX lately (not that I'm any good at it, I just started a few weeks ago), but isn't there a method to get the outer bounds of the mesh - a box that contains the whole object? If you know that, it should be pretty easy to set up the camera and viewport accordingly.
DanielRieck at 2007-9-9 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...
# 4
not sure Im new with all this also, but would love to see a line of code that implements this method, another thing I was wondering is if there is any samples on creating .fx files?
Smacker at 2007-9-9 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...
# 5
Here is c# code to get bounding box. I imagine it ports to C++ rather easily.




float objectRadius = 0.0f;
Vector3 objectCenter = new Vector3();

using (VertexBuffer vb = Mesh.VertexBuffer)
{
GraphicsStream vertexData = vb.Lock(0, 0, LockFlags.None);
objectRadius = Geometry.ComputeBoundingSphere(vertexData,
mesh.NumberVertices,
mesh.VertexFormat,
out objectCenter);
vb.Unlock();
}



also what are you looking for in .fx file. are you looking for an example .fx file or code to implement them in program?

Zwigby at 2007-9-9 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...
# 6
sample on creating a .fx file or information on them/how they work
Smacker at 2007-9-9 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...
# 7
now if im reading the code right its geting he outerbounds of the mesh now how do I set it to a set it in a box on the screen and will all meshes load the same if this all works out?
Smacker at 2007-9-9 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...
# 8
Ok going back to your orignal question. I assume that you load the mesh right, but your problem is that it doesn't rotate correctly. As you said it rotates off the screen. Well that has to do when your rendering it. If you can post the code that renders the mesh including the world matrix used. Next on the agenda, a simple fx file.

well here is a simple .fx file written in HLSL it is very close to C.

//Simple.fx
//Written in HLSL

// The world view and projection matrices
float4x4 WorldViewProj : WORLDVIEWPROJECTION;
sampler TextureSampler;

// Transform our coordinates into world space
void Transform(
in float4 inputPosition : POSITION,
in float2 inputTexCoord : TEXCOORD0,
out float4 outputPosition : POSITION,
out float2 outputTexCoord : TEXCOORD0
)
{
// Transform our position
outputPosition = mul(inputPosition, WorldViewProj);
// Set our texture coordinates
outputTexCoord = inputTexCoord;
}

void TextureColor(
in float2 textureCoords : TEXCOORD0,
out float4 diffuseColor : COLOR0)
{
// Get the texture color
diffuseColor = tex2D(TextureSampler, textureCoords);
};

technique TransformTexture
{
pass P0
{
// shaders
VertexShader = compile vs_1_1 Transform();
PixelShader = compile ps_1_1 TextureColor();
}
}

This code is taken directly from Tom Miller's book. This simple effect file will render a mesh using the programmable pipeline. Basically you pass in the position of the vertices and texture coords and this will transform them to world space and color/texture them. This file doesn't do anything fancy but effect files are where you can do some pretty cool things. Ok now to a little bit of C# to render the mesh with this code.

//Setup code for effect
// Create our effect
Private Effect effect = null;
effect = Effect.FromFile(device, @"simple.fx", null, ShaderFlags.None, null);
effect.Technique = "TransformTexture";
//render method for mesh
//1. setup world matrix
//2. pass effect file worldViewProj for position calc
//3. begin effect pass
//4. render mesh
//5. end effect pass
private void render(){
worldMatrix = Matrix.Translation(0f,0f,0f);
Matrix worldViewProj = worldMatrix * viewMatrix * projMatrix;
effect.SetValue("WorldViewProj", worldViewProj);

int numPasses = effect.Begin(0);
for (int iPass = 0; iPass < numPasses; iPass++)
{
effect.Pass(iPass);
for (int i = 0; i < meshMaterials.Length; i++)
{
device.SetTexture(0, meshTextures[ i ]);
mesh.DrawSubset(i);
}
}
effect.End();
}

That is some quick code for rendering the mesh with the effect file. First you set up the effect and technique. Then use it to render. If you have any questions please don't hesitate to ask. I am not very good at teaching, sorry.

Zwigby at 2007-9-9 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...
# 9
thanks I will take a deeper look into the fx file in a bit, I guess what I beleave might be the problem in the mesh that I am using, I have a few meshes that I have been working with some load the same in the same spot some load smaller and dont rotate right, all I did to check the meshes was load them into the tiger sample that comes with the SDK, when the mesh rotates it goes off the screen

public void Painthome(Start start,Device device,double appTime, float elapsedTime)

{

bool beginSceneCalled = false;

device.Clear(ClearFlags.ZBuffer | ClearFlags.Target, 0x002D32AA, 1.0f,0);

try

{

device.BeginScene();

beginSceneCalled = true;

start.backgroundSprite.Begin(SpriteFlags.AlphaBlend);

start.backgroundTextureSize = new System.Drawing.Rectangle(0,0,800, 600);

start.backgroundSprite.Draw(start.backgroundSpriteTexture,start.backgroundTextureSize,new Vector3(0,0,0),new Vector3(0,0,1),System.Drawing.Color.White);

start.backgroundSprite.End();

start.PmeshZ = 60.0F;

start.LeftnRight = -15.0F;

start.pUpnDown = -5.0F;

start.effect.SetValue("worldViewProjection", start.camera.WorldMatrix * start.viewMatrix * start.camera.ProjectionMatrix);//the effects file Im using is the SampleUI effects file edited to use no pixel shader rendering

start.effect.SetValue("worldMatrix", start.camera.WorldMatrix);

start.effect.Technique = "RenderSceneNoPixelShader";

int passes = start.effect.Begin(0);

Mesh localMesh = start.mesh.LocalMesh;

for (int pass = 0; pass < passes; pass++)

{

start.effect.BeginPass(pass);

for(int i = 0; i < start.mesh.NumberMaterials; i++)

{

start.effect.SetValue("sceneTexture", start.mesh.GetTexture(i));

start.effect.CommitChanges();

start.camera.FrameMove(elapsedTime);//not sure if this is in the right spot but it lets the user spin the mesh

start.viewMatrix.AffineTransformation(1,new Vector3(1,8,0),Microsoft.DirectX.Quaternion.RotationYawPitchRoll(start.y,start.p,start.r),new Vector3(start.LeftnRight,start.pUpnDown,start.PmeshZ));//using this to place the mesh in a set location

}

localMesh.DrawSubset(i);

}

start.effect.EndPass();

}

start.effect.End();

start.HomeDialog.OnRender(elapsedTime);

}

finally

{

if (beginSceneCalled)

device.EndScene();

}

}


as you can see here im not rotating anything just allowing mouse input to spin the mesh around, some spin good(not as good as in the mesh viewer) and some spin really bad, like the whole mesh moves from left to right front to back. sorry I seem to be having a problem explaining this.

Smacker at 2007-9-9 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...
# 10

it was a mesh problem, something to do with the texturing of the meshes, thanks again for the help, but I dont seem to beable to get the lights working right if I set then using device.Lights[0] ect nothing happends any ideas why this might happen?

Smacker at 2007-9-9 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...
# 11
lets see some light code, i bet we can figure it out
Zwigby at 2007-9-9 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...
# 12

public void Painthome(Start start,Device device,double appTime, float elapsedTime)

{

bool beginSceneCalled = false;

device.Clear(ClearFlags.ZBuffer | ClearFlags.Target, 0x002D32AA, 1.0f,0);

try

{
//lights

device.Lights[0].Type = LightType.Directional;

device.Lights[0].Diffuse = System.Drawing.Color.White;

device.Lights[0].Direction = new Vector3()

device.Lights[0].Enabled = true;

//lights

device.BeginScene();

beginSceneCalled = true;

start.backgroundSprite.Begin(SpriteFlags.AlphaBlend);

start.backgroundTextureSize = new System.Drawing.Rectangle(0,0,800, 600);

start.backgroundSprite.Draw(start.backgroundSpriteTexture,start.backgroundTextureSize,new Vector3(0,0,0),new Vector3(0,0,1),System.Drawing.Color.White);

start.backgroundSprite.End();

start.PmeshZ = 60.0F;

start.LeftnRight = -15.0F;

start.pUpnDown = -5.0F;

start.effect.SetValue("worldViewProjection", start.camera.WorldMatrix * start.viewMatrix * start.camera.ProjectionMatrix);//the effects file Im using is the SampleUI effects file edited to use no pixel shader rendering

start.effect.SetValue("worldMatrix", start.camera.WorldMatrix);

start.effect.Technique = "RenderSceneNoPixelShader";

int passes = start.effect.Begin(0);

Mesh localMesh = start.mesh.LocalMesh;

for (int pass = 0; pass < passes; pass++)

{

start.effect.BeginPass(pass);

for(int i = 0; i < start.mesh.NumberMaterials; i++)

{

start.effect.SetValue("sceneTexture", start.mesh.GetTexture(i));

start.effect.CommitChanges();

start.camera.FrameMove(elapsedTime);//not sure if this is in the right spot but it lets the user spin the mesh

start.viewMatrix.AffineTransformation(1,new Vector3(1,8,0),Microsoft.DirectX.Quaternion.RotationYawPitchRoll(start.y,start.p,start.r),new Vector3(start.LeftnRight,start.pUpnDown,start.PmeshZ));//using this to place the mesh in a set location

}

localMesh.DrawSubset(i);

}

start.effect.EndPass();

}

start.effect.End();

start.HomeDialog.OnRender(elapsedTime);

}

finally

{

if (beginSceneCalled)

device.EndScene();

}

}


in the debugger Im looking for the lights value but it says cant obtain value
and unless we have another mesh issue the colors of the meshes are not comming out right.

Smacker at 2007-9-9 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...
# 13
well two things make sure that you give the light a direction which i am sure you do when using the lights and second make sure you set
device.renderstate.lighting = true;

those are my first two guesses and these are easy fixes.

Zwigby at 2007-9-9 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...
# 14
I did both of those and maybe its not my lights, let me explain whats happening.
when I load a mesh the texture color changes, it should be a rust color but shows up as a gray color what could be causing this?
Smacker at 2007-9-9 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...