Jump to content

  • Log In with Google      Sign In   
  • Create Account


Mesh with relative coordinates


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
1 reply to this topic

#1 MatsK   Members   -  Reputation: 223

Like
0Likes
Like

Posted 25 February 2012 - 09:33 AM

Hey, I'm trying to render a mesh format where the vertices aren't stored with their actual coordinates in the file.
Here's the explanation I got:

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.

Here's my attempt to do the above:

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;
					}
				}
			}
		}
	}
}






Problem is, this doesn't work! Posted Image
Can someone please explain how to implement this algorithm in XNA?




Here's my rendering 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();

}


Sponsor:

#2 MatsK   Members   -  Reputation: 223

Like
0Likes
Like

Posted 26 February 2012 - 04:35 PM

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

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;
            }
        }

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

Posted Image




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS