Re: Mesh Face/Vertices Relationship Problem

From: Chris Anderson (cmanders_at_nospamplease.swiftdsl.com.au)
Date: 10/18/04


Date: Mon, 18 Oct 2004 16:04:08 +1000

ZMan, you are a genius! You were absolutely correct in that I was not using
the right Vertex Format. I had assumed (wrongly) that since I passed in a
format of PositionOnly, DirectX would just return me back a buffer with just
those values, rather than needing exactly the same format as the buffer was
currently using. DirectX never complained, so I thought that it was OK, and
it never dawned on me that I just needed to change the vertex format. Once
I passed in PositionNormal as the vertex format everything worked correctly
(well almost, a few other minor changes needed to be made)! You would not
believe the number of hours that I have struggled to solve that problem, and
you've solved it just like that! For those who are interested, here is the
final code:

    // Get which vertices surround this face, via the index buffer
    IndexBuffer indexBuffer = mesh.IndexBuffer;
    Face[] indices = (Face[])indexBuffer.Lock(0, typeof(Face),
LockFlags.ReadOnly, mesh.NumberFaces);
    CustomVertex.PositionNormal[] vertices =
(CustomVertex.PositionNormal[])mesh.LockVertexBuffer(typeof(CustomVertex.PositionNormal),
LockFlags.None, mesh.NumberVertices);

    Face faceIntersected = indices[(intersectInfo.FaceIndex)];

    CustomVertex.PositionNormal faceVertex1 = vertices[faceIntersected.v1];
    CustomVertex.PositionNormal faceVertex2 = vertices[faceIntersected.v2];
    CustomVertex.PositionNormal faceVertex3 = vertices[faceIntersected.v3];

    m_selectedPt1 = new Vector3(faceVertex1.X, faceVertex1.Y,
faceVertex1.Z);
    m_selectedPt2 = new Vector3(faceVertex2.X, faceVertex2.Y,
faceVertex2.Z);
    m_selectedPt3 = new Vector3(faceVertex3.X, faceVertex3.Y,
faceVertex3.Z);

    mesh.UnlockVertexBuffer();
    indexBuffer.Unlock();

Thank you again ZMan for your help, it is very much appreciated. Your
explanation of why a mesh has 24 vertices also cleared that up for me and
was a big help too.

Chris

"ZMan" <news-replies@thezbuffer> wrote in message
news:eGC$nBLtEHA.2516@TK2MSFTNGP11.phx.gbl...
> #1 Why does a mesh.box have 24 vertices? Well when you share vertices in
> an index buffer you have to share everything about those vertices colors,
> texture coordinates and also NORMALS. DirectX determines the way to shade
> a face based on the normals at each corner. On most shapes that are
> smoothly shaded you can share the normal by just averaging the normals of
> all the faces that share that vertex. However a cube doesn't need vertex
> normals - the faces are supposed to be flat so you need the normal at each
> vertex to be exactly the same otehrwise the shading would be messed up. So
> since a vertex can only have one normal you have to include each vertex 3
> times, one for each face it is a part of. However there is still some
> savings using index buffers. SInce DX uses triangles as primitives there
> are 12 triangles per cube and therefor 36 possible vertices - some
> vertices can be shared between triangles that are on the same face
> reducing the count to 24 using the index buffer.
>
> #2 You seem to be makng the assumption that the mesh vertices are
> PositionOnly which is not likely to be correct. I think the mesh.{shape}
> methods put normals in for you too. You can determine this by looking at
> the mesh.vertexFormat property. This would mean you were hitting the right
> face but indexing wrongly into the vertex array.
>
> I might have some time to look into the code later but maybe thats enough
> to get you over the hill.
>
> ZMan
>
> "Chris Anderson" <cmanders@nospamplease.swiftdsl.com.au> wrote in message
> news:uJbjweFtEHA.636@TK2MSFTNGP09.phx.gbl...
>> Hi all
>>
>> This question pretty much is a precursor to the question I asked on this
>> newsgroup last week, and got some very helpful responses from ZMan and
>> Michael Walsh. However, I'm having problems even getting to the point
>> where I could use their responses. The problems I am having should be a
>> fairly basic problem for someone who knows what they are doing, but have
>> had me tearing my hair out this weekend and I am obviously missing
>> something.
>>
>> Let me explain the situation:
>>
>> I want the user to be able to select a point on a mesh, and using the
>> intersection information calculate that point on the mesh as a Vector3 in
>> world space. Because I was having problems doing this in my full
>> application, I've created a test harness program that draws a simply cube
>> on the screen (using bits and pieces of Craig Andera's tutorial code),
>> and when the user clicks on a face of the cube it should (to start with),
>> outline the face by drawing lines from surrounding vertex to vertx. I
>> figured this would be a good starting point to visually prove I had the
>> right vertices and their model space coordinates, and then I could get
>> into working out the exact point in space that the user clicked on the
>> mesh. However, I'm having trouble even getting this far. Here is a
>> short list of the problems I am having:
>>
>> - To start with, I'm using the simple Mesh.Box function to create a mesh.
>> However, when I get a vertex count for this mesh, it returns 24 as the
>> answer. I thought a cube would only have 8 vertices though. Now I'm
>> guessing that it's storing the vertices of each triangle separately, but
>> I have no idea why. Isn't an index buffer supposed to reduce the number
>> of vertices required in a mesh? This isn't my big issue, merely an issue
>> in that I am new to 3D programming and can't understand why this would be
>> so. Knowing why might help me understand 3D better. Could it be that
>> Mesh.Box is not creating an index buffer at all (for whatever reason)?
>>
>> - OK, now the big issue. Let me first explain my current understanding
>> of how things (should) hold together, which you might be able to pick
>> holes in. Let's take a cube. It should have 8 vertices (one for each
>> corner). These vertices are indexed in the index buffer, where there
>> should be 36 indices. The cube should also have 12 faces (a cube has 6
>> sides, with each side made up of 2 triangles, thus 6 x 2 = 12). Each
>> face refers to 3 indices in the index buffer, each of which in turn point
>> to the corresponding vertex in the vertex buffer (therefore there should
>> be 3 times as many indices in the index buffer than there are faces: 12 x
>> 3 = 36). Once I can get the 3 vertices surrounding the face, I can use
>> their position to draw lines around that face going from vertex to
>> vertex. Taking a deep breath, does that sound right so far? OK, I'll
>> continue assuming it is. Now for the problem: the IntersectInformation
>> that I get returned from my intersection test returns a FaceIndex. I've
>> tried modifying the attribute buffer changing the colour of the face to
>> visually prove that the intersection has worked. It has. But everything
>> goes wrong when I try to get the coordinates of the vertices surrounding
>> the face. The coordinates of the vertices just aren't what I am
>> expecting, and I get my lines drawn elsewhere. I've also tried
>> disregarding the index buffer, and going straight to the vertices but
>> that doesn't work either.
>>
>> Here are snippets of code that does this calculation:
>>
>> ------------------------------------------------
>> public struct Face
>> {
>> public short v1;
>> public short v2;
>> public short v3;
>> };
>>
>> IndexBuffer indexBuffer = mesh.IndexBuffer;
>> Face[] indices= (Face[])indexBuffer.Lock(0, typeof(Face),
>> LockFlags.ReadOnly, mesh.NumberFaces * 3);
>> CustomVertex.PositionOnly[] vertices =
>> (CustomVertex.PositionOnly[])mesh.LockVertexBuffer(typeof(CustomVertex.PositionOnly),
>> LockFlags.None, mesh.NumberVertices);
>>
>> Face faceIntersected = indices[(intersectInfo.FaceIndex * 3)];
>>
>> CustomVertex.PositionOnly faceVertex1 = vertices[faceIntersected.v1];
>> CustomVertex.PositionOnly faceVertex2 = vertices[faceIntersected.v2];
>> CustomVertex.PositionOnly faceVertex3 = vertices[faceIntersected.v3];
>>
>> m_selectedPt1 = new Vector3(faceVertex1.X, faceVertex1.Y,
>> faceVertex1.Z);
>> m_selectedPt2 = new Vector3(faceVertex2.X, faceVertex2.Y,
>> faceVertex2.Z);
>> m_selectedPt3 = new Vector3(faceVertex3.X, faceVertex3.Y,
>> faceVertex3.Z);
>>
>> mesh.UnlockVertexBuffer();
>> indexBuffer.Unlock();
>>
>> ----------------------------------------------------
>> I've also tried the following alternative code:
>>
>> int firstVertex = (intersectInfo.FaceIndex);
>>
>> m_selectedPt1 = new Vector3(vertices[firstVertex + 0].X,
>> vertices[firstVertex + 0].Y, vertices[firstVertex + 0].Z);
>> m_selectedPt2 = new Vector3(vertices[firstVertex + 1].X,
>> vertices[firstVertex + 1].Y, vertices[firstVertex + 1].Z);
>> m_selectedPt3 = new Vector3(vertices[firstVertex + 2].X,
>> vertices[firstVertex + 2].Y, vertices[firstVertex + 2].Z);
>>
>> ---------------------------
>>
>> For the really helpful people out there :) who would like to run my code
>> to see what's wrong, I've temporarily put my test project up on the web,
>> downloadable from here (the TestMouseIntersection function does the
>> calculations):
>>
>> http://home.swiftdsl.com.au/~snazzy/Cube2.zip
>>
>> - As a side issue, when I use the line function in DirectX, I get crashes
>> or just general slowness. This isn't a big issue to me, but does anyone
>> know whether there are any problems relating to this function?
>>
>> Sorry for the long post, but I'd rather give you everything I know so you
>> don't need to make wild guesses. I really need this problem solved to
>> complete my project, but I think I have come to the limits of my
>> knowledge in overcoming this particular problem. I'd like to put a
>> tutorial up on the web at some stage using my (hopfully soon to be
>> working) test application, and would be happy to credit anyone who could
>> help me solve this problem. There just doesn't seem to be anything on the
>> web that quite does this so I would like to help resolve this so others
>> don't have the same problem I have been having. Any help you could
>> provide me would be very, very much appreciated.
>>
>> Thanks
>>
>> Chris Anderson
>>
>>
>
>



Relevant Pages

  • Re: Mesh Face/Vertices Relationship Problem
    ... arbitrary mesh it could have anything as its vertex format. ... > ZMan, you are a genius! ... >> a face based on the normals at each corner. ... >> reducing the count to 24 using the index buffer. ...
    (microsoft.public.win32.programmer.directx.managed)
  • Re: Mesh Face/Vertices Relationship Problem
    ... index buffer you have to share everything about those vertices colors, ... face based on the normals at each corner. ... However a cube doesn't need vertex normals - ... > I want the user to be able to select a point on a mesh, ...
    (microsoft.public.win32.programmer.directx.managed)
  • Mesh Face/Vertices Relationship Problem
    ... I want the user to be able to select a point on a mesh, ... I've created a test harness program that draws a simply cube on ... is not creating an index buffer at all? ... the IntersectInformation that I get returned from my intersection test ...
    (microsoft.public.win32.programmer.directx.managed)
  • Re: Learning about meshes
    ... I'll retest using an index buffer. ... >> mesh into its vertexes then draw it as a sequence of primitives. ... > not reflect the official views of the Microsoft Corporation. ...
    (microsoft.public.win32.programmer.directx.managed)
  • Re: managed dx9 create new meshes from mesh subsets
    ... You need to optimize the mesh (sorting by attributes) to create the ... >> get Index and vertex array and with attribute table create new array ... > and from them vertex and index buffer. ...
    (microsoft.public.win32.programmer.directx.managed)