Jump to content
  • Advertisement
Sign in to follow this  
MatsK

Rendering custom format

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to render a custom format, but not having much luck (the models don't look like they're supposed to).
Here's how I'm reading the format:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace XNAWinForms
{
public struct Face
{
public int AVertexIndex, BVertexIndex, CVertexIndex;
}

public struct BoneBinding
{
public int BoneIndex, FirstVertex, VertexCount, FirstBlendedVert, BlendedVertexCount;
}

public struct BlendData
{
public int WeightFixed, OtherVertexIndex;
}

class Mesh
{
private static int m_Version = 0;

private int m_BoneCount = 0;
private List<string> m_BoneNames = new List<string>();

private int m_FaceCount = 0;
private Face[] m_Faces;

private int m_BndCount = 0;
//private int[,] m_BoneBindings;
private List<BoneBinding> m_BoneBindings = new List<BoneBinding>();

private int m_NumTexVerticies = 0;
private Single[,] m_TexVerticies;

private int m_BlendCount = 0;
//private int[,] m_BlendData;
private List<BlendData> m_BlendData = new List<BlendData>();

private int m_VertexCount = 0;
private Single[,] m_VertexData;

public int TexVertexCount
{
get { return m_NumTexVerticies; }
}

/// <summary>
/// Number of verticies in this mesh.
/// </summary>
public int VertexCount
{
get { return m_VertexCount; }
}

public Single[,] VertexData
{
get { return m_VertexData; }
}

public Single[,] TextureVertData
{
get { return m_TexVerticies; }
}

public int FaceCount
{
get { return m_FaceCount; }
}

public Mesh(string Path)
{
BinaryReader Reader = new BinaryReader(File.Open(Path, FileMode.Open));

m_Version = Endian.SwapInt32(Reader.ReadInt32());

m_BoneCount = Endian.SwapInt32(Reader.ReadInt32());

for (int i = 0; i < m_BoneCount; i++)
{
byte StrLen = Reader.ReadByte();
string BoneName = Encoding.ASCII.GetString(Reader.ReadBytes(StrLen));
m_BoneNames.Add(BoneName);
}

m_FaceCount = Endian.SwapInt32(Reader.ReadInt32());
m_Faces = new Face[m_FaceCount];

for (int i = 0; i < m_FaceCount; i++)
{
m_Faces.AVertexIndex = Endian.SwapInt32(Reader.ReadInt32());
m_Faces.BVertexIndex = Endian.SwapInt32(Reader.ReadInt32());
m_Faces.CVertexIndex = Endian.SwapInt32(Reader.ReadInt32());
}

m_BndCount = Endian.SwapInt32(Reader.ReadInt32());
/*m_BoneBindings = new int[m_BndCount, 5];

for (int i = 0; i < m_BndCount; i++)
for (int j = 0; j < 5; j++)
m_BoneBindings[i, j] = Endian.SwapInt32(Reader.ReadInt32());*/
for (int i = 0; i < m_BndCount; i++)
{
BoneBinding Binding = new BoneBinding();
Binding.BoneIndex = Endian.SwapInt32(Reader.ReadInt32());
Binding.FirstVertex = Endian.SwapInt32(Reader.ReadInt32());
Binding.VertexCount = Endian.SwapInt32(Reader.ReadInt32());
Binding.FirstBlendedVert = Endian.SwapInt32(Reader.ReadInt32());
Binding.BlendedVertexCount = Endian.SwapInt32(Reader.ReadInt32());

m_BoneBindings.Add(Binding);
}

m_NumTexVerticies = Endian.SwapInt32(Reader.ReadInt32());
m_TexVerticies = new Single[m_NumTexVerticies, 3];

switch (m_Version)
{
case 0:
for (int i = 0; i < m_NumTexVerticies; i++)
{
//These coordinates aren't reversed, and the Endian class
//doesn't support swapping Single values, so do it manually...
m_TexVerticies[i, 0] = i;
byte[] XOffset = Reader.ReadBytes(4);
byte[] YOffset = Reader.ReadBytes(4);

Array.Reverse(XOffset);
Array.Reverse(YOffset);

m_TexVerticies[i, 1] = BitConverter.ToSingle(XOffset, 0);
m_TexVerticies[i, 2] = BitConverter.ToSingle(YOffset, 0);
}

break;
default:
for (int i = 0; i < m_NumTexVerticies; i++)
{
m_TexVerticies[i, 0] = i;
m_TexVerticies[i, 1] = Reader.ReadSingle(); //X offset
m_TexVerticies[i, 2] = Reader.ReadSingle(); //Y offset
}

break;
}

m_BlendCount = Endian.SwapInt32(Reader.ReadInt32());
/*m_BlendData = new int[m_BlendCount, 2];

for (int i = 0; i < m_BlendCount; i++)
{
m_BlendData[i, 1] = Endian.SwapInt32(Reader.ReadInt32());
m_BlendData[i, 0] = Endian.SwapInt32(Reader.ReadInt32());
}*/
for (int i = 0; i < m_BlendCount; i++)
{
BlendData Blend = new BlendData();
Blend.WeightFixed = Endian.SwapInt32(Reader.ReadInt32());
Blend.OtherVertexIndex = Endian.SwapInt32(Reader.ReadInt32());
m_BlendData.Add(Blend);
}

m_VertexCount = Endian.SwapInt32(Reader.ReadInt32());
m_VertexData = new Single[m_VertexCount, 7];

switch (m_Version)
{
case 0:
for (int i = 0; i < m_VertexCount; i++)
{
m_VertexData[i, 0] = i;

for (int j = 0; j < 6; j++)
m_VertexData[i, j] = Reader.ReadSingle();
}

break;
default:
for (int i = 0; i < m_VertexCount; i++)
{
m_VertexData[i, 0] = i;

//These coordinates are apparently reversed, but since the file is Big-Endian,
//and the default is reading Little-Endian, there should be no need to convert...
for (int j = 0; j < 6; j++)
m_VertexData[i, j] = Reader.ReadSingle();
}

break;
}
}
}
}



I load it into an XNA structure (VertexPositionNormalTexture) like so:

m_NormVerticies = new VertexPositionNormalTexture[m_CurrentMesh.VertexCount];

for (int i = 0; i < m_CurrentMesh.VertexCount; i++)
{
m_NormVerticies = new VertexPositionNormalTexture();
m_NormVerticies.Position.X = m_CurrentMesh.VertexData[i, 0];
m_NormVerticies.Position.Y = m_CurrentMesh.VertexData[i, 1];
m_NormVerticies.Position.Z = m_CurrentMesh.VertexData[i, 2];
m_NormVerticies.Normal.X = m_CurrentMesh.VertexData[i, 3];
m_NormVerticies.Normal.Y = m_CurrentMesh.VertexData[i, 4];
m_NormVerticies.Normal.Z = m_CurrentMesh.VertexData[i, 5];
}

for (int i = 0; i < m_CurrentMesh.TexVertexCount; i++)
{
m_NormVerticies.TextureCoordinate.X = m_CurrentMesh.TextureVertData[i, 0];
m_NormVerticies.TextureCoordinate.X = m_CurrentMesh.TextureVertData[i, 1];
}

//This should perhaps be 4...
m_QuadCount = m_NormVerticies.Length / 3;

m_LoadComplete = true;



Then render it like so:

// Configure effect
mSimpleEffect.World = this.mWorldMat;
mSimpleEffect.View = this.mViewMat;
mSimpleEffect.Projection = this.mProjectionMat;
mSimpleEffect.DiffuseColor = XNA.Graphics.Color.DarkRed.ToVector3();
mSimpleEffect.CommitChanges();


// Draw
mSimpleEffect.Begin();
mSimpleEffect.Techniques[0].Passes[0].Begin();
/*pDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleList,
triVerts, 0, 1);*/

if (m_NormVerticies != null)
{
if (m_LoadComplete)
{
pDevice.DrawUserPrimitives<VertexPositionNormalTexture>(PrimitiveType.TriangleList, m_NormVerticies,
0, m_QuadCount);
}
}

mSimpleEffect.Techniques[0].Passes[0].End();
mSimpleEffect.End();



Now, can anyone tell me what I'm supposed to be doing with the rest of the data in the mesh? I'm not so much worried about the bonebindings for now, but I'm thinking that the faces (which consists of VertexIndexA, VertexIndexB, VertexIndexC) are important when rendering the mesh. I just don't know what I'm supposed to do with them! Also, what is the blenddata for?

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!