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