summaryrefslogtreecommitdiff
path: root/NW4RTools/ObjImporter.cs
diff options
context:
space:
mode:
authorTreeki <treeki@gmail.com>2011-03-16 05:14:49 +0100
committerTreeki <treeki@gmail.com>2011-03-16 05:14:49 +0100
commitb625da59b0bbe60a9380dbd00df1ae982e6b5a58 (patch)
treee2622b0c2e235a68ac3c4f8913117e158d3335bf /NW4RTools/ObjImporter.cs
parent51b0e39ceb5962ffd9b22f1b4722d2b243dba60f (diff)
downloadnw4rtools-b625da59b0bbe60a9380dbd00df1ae982e6b5a58.tar.gz
nw4rtools-b625da59b0bbe60a9380dbd00df1ae982e6b5a58.zip
now uses 8-bit vertex data indexes where possible. quite a big optimisation!
Diffstat (limited to 'NW4RTools/ObjImporter.cs')
-rwxr-xr-xNW4RTools/ObjImporter.cs154
1 files changed, 117 insertions, 37 deletions
diff --git a/NW4RTools/ObjImporter.cs b/NW4RTools/ObjImporter.cs
index a1f04b7..5410227 100755
--- a/NW4RTools/ObjImporter.cs
+++ b/NW4RTools/ObjImporter.cs
@@ -652,12 +652,16 @@ namespace NW4RTools {
int pos1 = s.IndexOf('/');
int pos2 = s.IndexOf('/', pos1 + 1);
+ // thanks for generating groups with no texcoords, Max
+ bool hasTexCoord = (pos1 != pos2 - 1);
+
int vnum = int.Parse(s.Substring(0, pos1)) - 1;
- int tcnum = int.Parse(s.Substring(pos1 + 1, pos2 - pos1 - 1)) - 1;
+ int tcnum = hasTexCoord ? (int.Parse(s.Substring(pos1 + 1, pos2 - pos1 - 1)) - 1) : 0;
int nnum = int.Parse(s.Substring(pos2 + 1)) - 1;
UsedVertices[vnum] = true;
- UsedTexCoords[tcnum] = true;
+ if (hasTexCoord)
+ UsedTexCoords[tcnum] = true;
UsedNormals[nnum] = true;
output[i * 3] = (ushort)vnum;
@@ -675,6 +679,19 @@ namespace NW4RTools {
private void EndShape() {
// Let's assemble the display lists.
+ // First off, compute the vertex data arrays so we can decide on whether
+ // to use 8-bit or 16-bit indexes to vertex data
+ ushort[] posIndexes, texCoordIndexes, normalIndexes;
+
+ var posDataArray = ComputeVertexDataArray(Positions, UsedVertices, out posIndexes);
+ var tcDataArray = ComputeVertexDataArray(TexCoords, UsedTexCoords, out texCoordIndexes);
+ var nrmDataArray = ComputeVertexDataArray(Normals, UsedNormals, out normalIndexes);
+
+ bool u16PosIdx = (posDataArray.Length > 255);
+ bool u16TcIdx = (tcDataArray.Length > 255);
+ bool u16NrmIdx = (nrmDataArray.Length > 255);
+
+
// ** Reverse Engineering DL 1 **
// 0x0A : CP command: Vertex Descriptor part 1
// 0x10 : CP command: Vertex Descriptor part 2
@@ -712,15 +729,15 @@ namespace NW4RTools {
// Now create vertex settings
var vs = new VertexSettings();
- vs.PositionDesc = VertexSettings.DescType.Index16;
+ vs.PositionDesc = u16PosIdx ? VertexSettings.DescType.Index16 : VertexSettings.DescType.Index8;
vs.PositionFormat = VertexSettings.CompType.Float32;
vs.PositionCount = VertexSettings.CompCount.Position3;
- vs.TexCoordDesc[0] = VertexSettings.DescType.Index16;
+ vs.TexCoordDesc[0] = u16TcIdx ? VertexSettings.DescType.Index16 : VertexSettings.DescType.Index8;
vs.TexCoordFormat[0] = VertexSettings.CompType.Float32;
vs.TexCoordCount[0] = VertexSettings.CompCount.TexCoord2;
- vs.NormalDesc = VertexSettings.DescType.Index16;
+ vs.NormalDesc = u16NrmIdx ? VertexSettings.DescType.Index16 : VertexSettings.DescType.Index8;
vs.NormalFormat = VertexSettings.CompType.Float32;
vs.NormalCount = VertexSettings.CompCount.Normal3;
@@ -764,12 +781,7 @@ namespace NW4RTools {
// Display List 2 is where all the primitive-related fun happens
- // However, before we do that, let's compute the vertex data arrays
- ushort[] posIndexes, texCoordIndexes, normalIndexes;
-
- var posDataArray = ComputeVertexDataArray(Positions, UsedVertices, out posIndexes);
- var tcDataArray = ComputeVertexDataArray(TexCoords, UsedTexCoords, out texCoordIndexes);
- var nrmDataArray = ComputeVertexDataArray(Normals, UsedNormals, out normalIndexes);
+ // However, before we do that, let's create the vertex data arrays
// todo: better names
var posData = new VertexPosData();
@@ -781,9 +793,11 @@ namespace NW4RTools {
posData.Data = posDataArray;
posData.Save();
+ CurrentShape.PosData = posData;
CurrentModel.VtxPosData.Add("P_" + CurrentModel.VtxPosData.Count.ToString(), posData);
var tcData = new VertexTexCoordData();
+
tcData.ComponentCount = VertexSettings.CompCount.TexCoord2;
tcData.ComponentType = VertexSettings.CompType.Float32;
tcData.EntryCount = (ushort)tcDataArray.Length;
@@ -792,6 +806,7 @@ namespace NW4RTools {
tcData.Data = tcDataArray;
tcData.Save();
+ CurrentShape.TexCoordData[0] = tcData;
CurrentModel.VtxTexCoordData.Add("T_" + CurrentModel.VtxTexCoordData.Count.ToString(), tcData);
var nrmData = new VertexNrmData();
@@ -803,11 +818,8 @@ namespace NW4RTools {
nrmData.Data = nrmDataArray;
nrmData.Save();
- CurrentModel.VtxNrmData.Add("N_" + CurrentModel.VtxNrmData.Count.ToString(), nrmData);
-
- CurrentShape.PosData = posData;
- CurrentShape.TexCoordData[0] = tcData;
CurrentShape.NrmData = nrmData;
+ CurrentModel.VtxNrmData.Add("N_" + CurrentModel.VtxNrmData.Count.ToString(), nrmData);
// For lightmaps, before we get baked lighting working
if (usingLightmaps) {
@@ -815,7 +827,7 @@ namespace NW4RTools {
clrData.ComponentCount = VertexSettings.CompCount.Color4;
clrData.ComponentType = VertexSettings.CompType.UInt8;
clrData.EntryCount = 1;
- clrData.EntrySize = 1;
+ clrData.EntrySize = 4;
clrData.Fraction = 0;
clrData.RawData = new byte[] { 255, 255, 255, 255 };
@@ -836,21 +848,50 @@ namespace NW4RTools {
dl.BeginPrimitives(PrimitiveType.Triangles, 0, (ushort)(Triangles.Count * 3));
foreach (var tri in Triangles) {
- dl.WriteUInt16(posIndexes[tri[6]]);
- dl.WriteUInt16(normalIndexes[tri[7]]);
+ if (u16PosIdx)
+ dl.WriteUInt16(posIndexes[tri[6]]);
+ else
+ dl.WriteByte((byte)posIndexes[tri[6]]);
+ if (u16NrmIdx)
+ dl.WriteUInt16(normalIndexes[tri[7]]);
+ else
+ dl.WriteByte((byte)normalIndexes[tri[7]]);
if (usingLightmaps)
dl.WriteByte(0);
- dl.WriteUInt16(texCoordIndexes[tri[8]]);
- dl.WriteUInt16(posIndexes[tri[3]]);
- dl.WriteUInt16(normalIndexes[tri[4]]);
+ if (u16TcIdx)
+ dl.WriteUInt16(texCoordIndexes[tri[8]]);
+ else
+ dl.WriteByte((byte)texCoordIndexes[tri[8]]);
+
+ if (u16PosIdx)
+ dl.WriteUInt16(posIndexes[tri[3]]);
+ else
+ dl.WriteByte((byte)posIndexes[tri[3]]);
+ if (u16NrmIdx)
+ dl.WriteUInt16(normalIndexes[tri[4]]);
+ else
+ dl.WriteByte((byte)normalIndexes[tri[4]]);
if (usingLightmaps)
dl.WriteByte(0);
- dl.WriteUInt16(texCoordIndexes[tri[5]]);
- dl.WriteUInt16(posIndexes[tri[0]]);
- dl.WriteUInt16(normalIndexes[tri[1]]);
+ if (u16TcIdx)
+ dl.WriteUInt16(texCoordIndexes[tri[5]]);
+ else
+ dl.WriteByte((byte)texCoordIndexes[tri[5]]);
+
+ if (u16PosIdx)
+ dl.WriteUInt16(posIndexes[tri[0]]);
+ else
+ dl.WriteByte((byte)posIndexes[tri[0]]);
+ if (u16NrmIdx)
+ dl.WriteUInt16(normalIndexes[tri[1]]);
+ else
+ dl.WriteByte((byte)normalIndexes[tri[1]]);
if (usingLightmaps)
dl.WriteByte(0);
- dl.WriteUInt16(texCoordIndexes[tri[2]]);
+ if (u16TcIdx)
+ dl.WriteUInt16(texCoordIndexes[tri[2]]);
+ else
+ dl.WriteByte((byte)texCoordIndexes[tri[2]]);
}
}
@@ -858,26 +899,65 @@ namespace NW4RTools {
dl.BeginPrimitives(PrimitiveType.Quads, 0, (ushort)(Quads.Count * 4));
foreach (var quad in Quads) {
- dl.WriteUInt16(posIndexes[quad[9]]);
- dl.WriteUInt16(normalIndexes[quad[10]]);
+ if (u16PosIdx)
+ dl.WriteUInt16(posIndexes[quad[9]]);
+ else
+ dl.WriteByte((byte)posIndexes[quad[9]]);
+ if (u16NrmIdx)
+ dl.WriteUInt16(normalIndexes[quad[10]]);
+ else
+ dl.WriteByte((byte)normalIndexes[quad[10]]);
if (usingLightmaps)
dl.WriteByte(0);
- dl.WriteUInt16(texCoordIndexes[quad[11]]);
- dl.WriteUInt16(posIndexes[quad[6]]);
- dl.WriteUInt16(normalIndexes[quad[7]]);
+ if (u16TcIdx)
+ dl.WriteUInt16(texCoordIndexes[quad[11]]);
+ else
+ dl.WriteByte((byte)texCoordIndexes[quad[11]]);
+
+ if (u16PosIdx)
+ dl.WriteUInt16(posIndexes[quad[6]]);
+ else
+ dl.WriteByte((byte)posIndexes[quad[6]]);
+ if (u16NrmIdx)
+ dl.WriteUInt16(normalIndexes[quad[7]]);
+ else
+ dl.WriteByte((byte)normalIndexes[quad[7]]);
if (usingLightmaps)
dl.WriteByte(0);
- dl.WriteUInt16(texCoordIndexes[quad[8]]);
- dl.WriteUInt16(posIndexes[quad[3]]);
- dl.WriteUInt16(normalIndexes[quad[4]]);
+ if (u16TcIdx)
+ dl.WriteUInt16(texCoordIndexes[quad[8]]);
+ else
+ dl.WriteByte((byte)texCoordIndexes[quad[8]]);
+
+ if (u16PosIdx)
+ dl.WriteUInt16(posIndexes[quad[3]]);
+ else
+ dl.WriteByte((byte)posIndexes[quad[3]]);
+ if (u16NrmIdx)
+ dl.WriteUInt16(normalIndexes[quad[4]]);
+ else
+ dl.WriteByte((byte)normalIndexes[quad[4]]);
if (usingLightmaps)
dl.WriteByte(0);
- dl.WriteUInt16(texCoordIndexes[quad[5]]);
- dl.WriteUInt16(posIndexes[quad[0]]);
- dl.WriteUInt16(normalIndexes[quad[1]]);
+ if (u16TcIdx)
+ dl.WriteUInt16(texCoordIndexes[quad[5]]);
+ else
+ dl.WriteByte((byte)texCoordIndexes[quad[5]]);
+
+ if (u16PosIdx)
+ dl.WriteUInt16(posIndexes[quad[0]]);
+ else
+ dl.WriteByte((byte)posIndexes[quad[0]]);
+ if (u16NrmIdx)
+ dl.WriteUInt16(normalIndexes[quad[1]]);
+ else
+ dl.WriteByte((byte)normalIndexes[quad[1]]);
if (usingLightmaps)
dl.WriteByte(0);
- dl.WriteUInt16(texCoordIndexes[quad[2]]);
+ if (u16TcIdx)
+ dl.WriteUInt16(texCoordIndexes[quad[2]]);
+ else
+ dl.WriteByte((byte)texCoordIndexes[quad[2]]);
}
}