Mesh with relative coordinates

This topic is 2786 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

[font=Verdana, sans-serif]Hey, I'm trying to render a mesh format where the vertices aren't stored with their actual coordinates in the file.[/font]
[font=Verdana, sans-serif]Here's the explanation I got:[/font]

in a mesh, vertices are stored as coordinates relative to the proximal end of the bone that they're attached to. so you need to walk down the bone tree, and then for each vertex, rather than plotting it, move the camera to that position and obtain the absolute position of the camera, and then move back. now you can store that position in the TransformedVertices array. do that for both the fixed and blended vertices then once the array is completely filled up, blend the blended vertices towards their fixed vertices that they're influenced by. then you can draw all the faces for that mesh, and all the vertices will be in the right spots.

[font=Verdana, sans-serif]Here's my attempt to do the above:[/font]

[font=Verdana, sans-serif]public void TransformVertices2(Skeleton Skel) { float[,] LocalCopy; foreach (Bone Bne in Skel.Bones) { foreach (BoneBinding BBinding in m_BoneBindings) { if (BBinding.BoneIndex == Bne.ID) { if (BBinding.FirstVertex != -1) { int VertexCount = 0; if (BBinding.FirstVertex > BBinding.VertexCount) VertexCount = BBinding.FirstVertex - BBinding.VertexCount; else VertexCount = BBinding.VertexCount - BBinding.FirstVertex;[/font] LocalCopy = new float[VertexCount, 6]; Array.Copy(m_VertexData, BBinding.FirstVertex, LocalCopy, 0, VertexCount);[/font] for (int i = 0; i < VertexCount; i++) { //The below is from: http://msdn.microsoft.com/en-us/library/bb197901.aspx //Calculate the camera's current position.[/font] //Set the direction the camera points without rotation. Vector3 CameraReference = Bne.GlobalTranslation; //Camera's position. Vector3 CameraPos = new Vector3(LocalCopy[i, 0], LocalCopy[i, 1], LocalCopy[i, 2]);[/font] Matrix RotationMatrix = Matrix.CreateFromQuaternion(Bne.GlobalRotation); //Create a vector pointing the direction the camera is facing. Vector3 TransformedReference = Vector3.Transform(CameraReference, RotationMatrix); //Calculate the position the camera is looking at. Vector3 CameraLookat = CameraPos + TransformedReference;[/font] m_TransformedVertices = CameraLookat; } } if (BBinding.FirstBlendedVert != -1) { int BlendedVertexCount = 0; if (BBinding.FirstBlendedVert > BBinding.BlendedVertexCount) BlendedVertexCount = BBinding.FirstBlendedVert - BBinding.BlendedVertexCount; else BlendedVertexCount = BBinding.BlendedVertexCount - BBinding.FirstBlendedVert;[/font] LocalCopy = new float[BlendedVertexCount, 6]; Array.Copy(m_VertexData, BBinding.FirstBlendedVert, LocalCopy, 0, BlendedVertexCount);[/font] for (int j = 0; j < BlendedVertexCount; j++) { //The below is from: http://msdn.microsoft.com/en-us/library/bb197901.aspx //Calculate the camera's current position.[/font] //Set the direction the camera points without rotation. Vector3 CameraReference = Bne.GlobalTranslation; //Camera's position. Vector3 CameraPos = new Vector3(LocalCopy[j, 0], LocalCopy[j, 1], LocalCopy[j, 2]);[/font] Matrix RotationMatrix = Matrix.CreateFromQuaternion(Bne.GlobalRotation); //Create a vector pointing the direction the camera is facing. Vector3 TransformedReference = Vector3.Transform(CameraReference, RotationMatrix); //Calculate the position the camera is looking at. Vector3 CameraLookat = CameraPos + TransformedReference;[/font] m_TransformedVertices[j] = CameraLookat; } } } } } }[/font]

[font=Verdana, sans-serif]Problem is, this doesn't work! [/font]
[font=Verdana, sans-serif]Can someone please explain how to implement this algorithm in XNA?[/font]

[font=Verdana, sans-serif]Here's my rendering code:[/font]

[font=Verdana, sans-serif]private void mWinForm_OnFrameRender(GraphicsDevice pDevice) { /*m_SBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.BackToFront, SaveStateMode.SaveState); m_SBatch.Draw(m_BackgroundTex, new Microsoft.Xna.Framework.Rectangle(0, 0, m_BackgroundTex.Width, m_BackgroundTex.Height), Microsoft.Xna.Framework.Graphics.Color.White); m_SBatch.End();*/ Device.RenderState.DepthBufferEnable = true; Device.RenderState.DepthBufferWriteEnable = true; Device.RenderState.AlphaBlendEnable = false; // Configure effect mSimpleEffect.World = this.mWorldMat; mSimpleEffect.View = this.mViewMat; mSimpleEffect.Projection = this.mProjectionMat; if (m_Tex != null) { mSimpleEffect.Texture = m_Tex; mSimpleEffect.TextureEnabled = true; //Disable lights in an attempt to render bodies... //mSimpleEffect.EnableDefaultLighting(); } mSimpleEffect.CommitChanges(); // Draw mSimpleEffect.Begin(); mSimpleEffect.Techniques[0].Passes[0].Begin(); if (m_NormVerticies != null) { if (m_LoadComplete) { if (m_CurrentMesh.IsBodyMesh) { //m_MatrixStack.Push(mSimpleEffect.World); //glLoadIdentity(); //mSimpleEffect.View = Matrix.Identity; m_CurrentMesh.TransformVertices2(m_Skeleton); //mSimpleEffect.View = m_MatrixStack.Pop(); m_CurrentMesh.BlendVertices2(); } foreach (Face Fce in m_CurrentMesh.Faces) { VertexPositionNormalTexture[] Vertex = new VertexPositionNormalTexture[3]; Vertex[0] = m_NormVerticies[Fce.AVertexIndex]; Vertex[1] = m_NormVerticies[Fce.BVertexIndex]; Vertex[2] = m_NormVerticies[Fce.CVertexIndex]; Vertex[0].TextureCoordinate = m_NormVerticies[Fce.AVertexIndex].TextureCoordinate; Vertex[1].TextureCoordinate = m_NormVerticies[Fce.BVertexIndex].TextureCoordinate; Vertex[2].TextureCoordinate = m_NormVerticies[Fce.CVertexIndex].TextureCoordinate; pDevice.DrawUserPrimitives<VertexPositionNormalTexture>(PrimitiveType.TriangleList, Vertex, 0, 1); } } } mSimpleEffect.Techniques[0].Passes[0].End(); mSimpleEffect.End(); }[/font]

Share on other sites
Ok, so I tried a slightly different approach;

 public void TransformVertices2(Bone Bne, ref BasicEffect Effect) { int BoneIndex = 0; Matrix WorldMat = Matrix.CreateWorld(Bne.GlobalTranslation, Vector3.Forward, Vector3.Up); //glMultMatrixf() WorldMat *= Matrix.CreateFromQuaternion(Bne.GlobalRotation); Effect.World = WorldMat; for (BoneIndex = 0; BoneIndex < m_BndCount; BoneIndex++) { if (Bne.BoneName == m_BoneNames[m_BoneBindings[BoneIndex].BoneIndex]) break; } if (BoneIndex < m_BndCount) { for (int i = 0; i < m_BoneBindings[BoneIndex].VertexCount; i++) { uint VertexIndex = (uint)(m_BoneBindings[BoneIndex].FirstVertex + i); Vector3 RelativeVertex = new Vector3(m_VertexData[VertexIndex, 0], m_VertexData[VertexIndex, 1], m_VertexData[VertexIndex, 2]); //Move the world and view to the relative position of the current vertex. WorldMat = Matrix.CreateWorld(RelativeVertex, Vector3.Forward, Vector3.Up); Effect.World = WorldMat; Effect.View = WorldMat; //Get the absolute position of the current vertex. m_TransformedVertices[VertexIndex].X = WorldMat.M34; m_TransformedVertices[VertexIndex].Y = WorldMat.M41; m_TransformedVertices[VertexIndex].Z = WorldMat.M42; //Move back. WorldMat *= Matrix.CreateWorld(new Vector3(-RelativeVertex.X, -RelativeVertex.Y, -RelativeVertex.Z), Vector3.Forward, Vector3.Up); Effect.World = WorldMat; Effect.View = WorldMat; } for (int i = 0; i < m_BoneBindings[BoneIndex].BlendedVertexCount; i++) { uint VertexIndex = (uint)(m_NumFixedVerticies + m_BoneBindings[BoneIndex].FirstBlendedVert + i); Vector3 RelativeVertex = new Vector3(m_VertexData[VertexIndex, 0], m_VertexData[VertexIndex, 1], m_VertexData[VertexIndex, 2]); //Move the world and view to the relative position of the current vertex. WorldMat = Matrix.CreateWorld(RelativeVertex, Vector3.Forward, Vector3.Up); Effect.World = WorldMat; Effect.View = WorldMat; //Get the absolute position of the current vertex. m_TransformedVertices[VertexIndex].X = WorldMat.M34; m_TransformedVertices[VertexIndex].Y = WorldMat.M41; m_TransformedVertices[VertexIndex].Z = WorldMat.M42; //Move back. WorldMat *= Matrix.CreateWorld(new Vector3(-RelativeVertex.X, -RelativeVertex.Y, -RelativeVertex.Z), Vector3.Forward, Vector3.Up); Effect.World = WorldMat; Effect.View = WorldMat; } } if (Bne.Children.Count == 1) TransformVertices2(Bne.Children[0], ref Effect); else if (Bne.Children.Count > 1) { for (int i = 0; i < Bne.Children.Count; i++) TransformVertices2(Bne.Children, ref Effect); } }

 public void BlendVertices2() { for (int i = 0; i < m_BlendCount; i++) { float Weight = m_BlendData.WeightFixed; Vector3 BlendedVertex = m_TransformedVertices[m_NumFixedVerticies + i]; Vector3 FixedVertex = m_TransformedVertices[m_NumFixedVerticies + i]; BlendedVertex.X = Weight * BlendedVertex.X + (1 - Weight) * FixedVertex.X; BlendedVertex.Y = Weight * BlendedVertex.X + (1 - Weight) * FixedVertex.Y; BlendedVertex.Z = Weight * BlendedVertex.X + (1 - Weight) * FixedVertex.Z; m_TransformedVertices[m_NumFixedVerticies + i] = BlendedVertex; } }

This nearly works, but all the vertices are laid out on the same plane! Why?

• Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 13
• 30
• 9
• 16
• 12