Sign in to follow this  
MatsK

Mesh with relative coordinates

Recommended Posts

MatsK    394
[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]

[code]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.[/code]

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

[font=Verdana, sans-serif][code]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[i] = 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;
}
}
}
}
}
}[/code][/font]





[font=Verdana, sans-serif]Problem is, this doesn't work! [img]http://public.gamedev.net//public/style_emoticons/default/sad.png[/img][/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][code]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();

}[/code][/font]

Share this post


Link to post
Share on other sites
MatsK    394
Ok, so I tried a slightly different approach;

[code]

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[i], ref Effect);
}
}[/code]

[code] public void BlendVertices2()
{
for (int i = 0; i < m_BlendCount; i++)
{
float Weight = m_BlendData[i].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;
}
}[/code]

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

[IMG]http://i40.tinypic.com/ived1z.png[/IMG]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this