Thursday, November 23, 2006

c# 3D max *.obj importer'is

Tęsiant 3d kursinio temą. Kaip minėjau sumąstėm modelius kurt su 3d max'u, o visą animaciją ir t.t. - su openGL. Taigi tenka kažkaip importuot į c# max'o sukurtus modelius (iš max'o exportuojam į *.obj tipą). Sakau gal kam pravers, naudokitės į sveikatą (-.

using System.IO;
namespace OBJLoader
{
public static class Loader
{
public class VERTEX //aprašas vertex'ui
{
public float x, y, z;
}

public class TEXTCOORDS //aprašas textūros koordinatėms
{
public float u, v;
}

public class TRIANGLE //vieno trikampio aprašymas
{
public TRIANGLE()
{
vertex = new VERTEX[3];
}

public VERTEX[] vertex;
}

public class NORMAL //normalės aprašas
{
public NORMAL()
{
vertex = new VERTEX[3];
}

public VERTEX[] vertex;
}

public class TEXTURE //teksturos aprašas
{
public TEXTURE()
{
vertex = new TEXTCOORDS[3];
}

public TEXTCOORDS[] vertex;
}

public class OBJECT3D //visas 3d objektas
{
public int nTriangles; //trikampių kiekis
public TRIANGLE[] triangle; //trikampių masyvas
public NORMAL[] normal; //normalių masyvas
public TEXTURE[] texture; //tekstūrų koordinačių masyvas
}

//-------------------------------------------------------
public static OBJECT3D LoadObject(string FileName)
{
OBJECT3D obj = new OBJECT3D();
VERTEX[] vert = null;
VERTEX[] normal = null;
TEXTCOORDS[] texture = null;

int value, iVertex, iNormal, iTexture, iFace, tmp, iVertexCount, iTextCount;
iFace = iVertex = iNormal = iTexture = iVertexCount = iTextCount = 0;

int fv1, fv11, fv111, fv2, fv22, fv222, fv3, fv33, fv333;
string[] str;

TextReader file = File.OpenText(FileName);
string line;
while ((line = file.ReadLine()) != null)
{
str = line.Split(new char[] {' '}, System.StringSplitOptions.RemoveEmptyEntries);
if (str.Length > 2)
{
if ((str[0] == "#") && (int.TryParse(str[1], out value)))
{
switch (str[2][0])
{
case 'v':
iVertexCount = value;
vert = new VERTEX[iVertexCount];
normal = new VERTEX[iVertexCount];
break;
case 't':
iTextCount = value;
texture = new TEXTCOORDS[iTextCount];
break;
case 'f':
obj.nTriangles = value;
obj.triangle = new TRIANGLE[value];
obj.normal = new NORMAL[value];
obj.texture = new TEXTURE[value];
break;
}
}
}
}

//skaitom duomenis
file.Close();
file = File.OpenText(FileName);
//kadangi obj failiuke dešimtainis simbolis yra taškas
//o pas kai ką nustatymuose pasirinktas kablelis
System.Globalization.NumberFormatInfo nfi = new System.Globalization.NumberFormatInfo();
nfi.CurrencyDecimalSeparator = ".";
while ((line = file.ReadLine()) != null)
{
str = line.Split(new char[] { ' ' }, System.StringSplitOptions.RemoveEmptyEntries);
if ((str.Length == 4) && (str[0] == "v") && (iVertex < iVertexCount))
{
vert[iVertex] = new VERTEX();
vert[iVertex].x = float.Parse(str[1], nfi);
vert[iVertex].y = float.Parse(str[2], nfi);
vert[iVertex].z = float.Parse(str[3], nfi);
iVertex++;
}
else if ((str.Length > 0) && (str[0] == "vt") && (iTexture < iTextCount))
{
texture[iTexture] = new TEXTCOORDS();
texture[iTexture].u = float.Parse(str[1], nfi);
texture[iTexture].v = float.Parse(str[2], nfi);
iTexture++;
}
else if ((str.Length > 0) && (str[0] == "vn") && (iNormal < iVertexCount))
{
normal[iNormal] = new VERTEX();
normal[iNormal].x = float.Parse(str[1], nfi);
normal[iNormal].y = float.Parse(str[2], nfi);
normal[iNormal].z = float.Parse(str[3], nfi);
iNormal++;
}
else if ((str.Length == 4) && (str[0] == "f"))
{
string[] str1 = str[1].Split('/');
string[] str2 = str[2].Split('/');
string[] str3 = str[3].Split('/');
if ((str1.Length > 1) && (str2.Length > 1) && (str3.Length > 1))
{

fv1 = System.Math.Abs(int.Parse(str1[0]));
if (int.TryParse(str1[1], out fv11))
{
fv11 = System.Math.Abs(fv11);
}
else
{
fv11 = -1;
}
if (str1.Length > 2)
{
fv111 = System.Math.Abs(int.Parse(str1[2]));
}
else
{
fv111 = -1;
}

fv2 = System.Math.Abs(int.Parse(str2[0]));
if (int.TryParse(str2[1], out fv22))
{
fv22 = System.Math.Abs(fv22);
}
else
{
fv22 = -1;
}
if (str2.Length > 2)
{
fv222 = System.Math.Abs(int.Parse(str2[2]));
}
else
{
fv222 = -1;
}

fv3 = System.Math.Abs(int.Parse(str3[0]));
if (int.TryParse(str3[1], out fv33))
{
fv33 = System.Math.Abs(fv33);
}
else
{
fv33 = -1;
}
if (str2.Length > 2)
{
fv333 = System.Math.Abs(int.Parse(str3[2]));
}
else
{
fv333 = -1;
}

obj.triangle[iFace] = new TRIANGLE();
obj.texture[iFace] = new TEXTURE();
obj.normal[iFace] = new NORMAL();

for (int i = 0; i < 3; i++ )
{
obj.triangle[iFace].vertex[i] = new VERTEX();
obj.texture[iFace].vertex[i] = new TEXTCOORDS();
obj.normal[iFace].vertex[i] = new VERTEX();
}

tmp = fv1 - 1;
obj.triangle[iFace].vertex[0].x = vert[tmp].x;
obj.triangle[iFace].vertex[0].y = vert[tmp].y;
obj.triangle[iFace].vertex[0].z = vert[tmp].z;

if (fv11 != -1)
{
tmp = fv11 - 1;
obj.texture[iFace].vertex[0].u = texture[tmp].u;
obj.texture[iFace].vertex[0].v = texture[tmp].v;
}
if (fv111 != -1)
{
tmp = fv111 - 1;
obj.normal[iFace].vertex[0].x = normal[tmp].x;
obj.normal[iFace].vertex[0].y = normal[tmp].y;
obj.normal[iFace].vertex[0].z = normal[tmp].z;
}

tmp = fv2 - 1;
obj.triangle[iFace].vertex[1].x = vert[tmp].x;
obj.triangle[iFace].vertex[1].y = vert[tmp].y;
obj.triangle[iFace].vertex[1].z = vert[tmp].z;

if (fv22 != -1)
{
tmp = fv22 - 1;
obj.texture[iFace].vertex[1].u = texture[tmp].u;
obj.texture[iFace].vertex[1].v = texture[tmp].v;
}
if (fv222 != -1)
{
tmp = fv222 - 1;
obj.normal[iFace].vertex[1].x = normal[tmp].x;
obj.normal[iFace].vertex[1].y = normal[tmp].y;
obj.normal[iFace].vertex[1].z = normal[tmp].z;
}

tmp = fv3 - 1;
obj.triangle[iFace].vertex[2].x = vert[tmp].x;
obj.triangle[iFace].vertex[2].y = vert[tmp].y;
obj.triangle[iFace].vertex[2].z = vert[tmp].z;

if (fv33 != -1)
{
tmp = fv33 - 1;
obj.texture[iFace].vertex[2].u = texture[tmp].u;
obj.texture[iFace].vertex[2].v = texture[tmp].v;
}
if (fv333 != -1)
{
tmp = fv333 - 1;
obj.normal[iFace].vertex[2].x = normal[tmp].x;
obj.normal[iFace].vertex[2].y = normal[tmp].y;
obj.normal[iFace].vertex[2].z = normal[tmp].z;
}

iFace++;
}
}
}
file.Close();
return obj;
}
}
}

Beje apribojimai: viename *.obj faile turi būti tik 1 objektas.

No comments: