summaryrefslogtreecommitdiff
path: root/NW4RTools
diff options
context:
space:
mode:
Diffstat (limited to 'NW4RTools')
-rw-r--r--NW4RTools/BrresReader.cs11
-rw-r--r--NW4RTools/Models/VertexData.cs49
-rw-r--r--NW4RTools/NW4RTools.csproj3
-rw-r--r--NW4RTools/ObjWriter.cs65
-rw-r--r--NW4RTools/VertexSettings.cs234
-rwxr-xr-xNW4RTools/bin/Debug/NW4RTools.dllbin36352 -> 40448 bytes
-rw-r--r--NW4RTools/bin/Debug/NW4RTools.dll.mdbbin12709 -> 13672 bytes
7 files changed, 320 insertions, 42 deletions
diff --git a/NW4RTools/BrresReader.cs b/NW4RTools/BrresReader.cs
index 49f2edb..288ff1e 100644
--- a/NW4RTools/BrresReader.cs
+++ b/NW4RTools/BrresReader.cs
@@ -340,6 +340,8 @@ namespace NW4RTools {
private void LoadVertexDataBase(InputStream ins, Models.VertexDataBase n) {
+ int startPos = ins.Position;
+
UInt32 size = ins.ReadUInt32();
Int32 mdlOffset = ins.ReadInt32();
@@ -349,13 +351,18 @@ namespace NW4RTools {
// Note: we're relying on this value to be correct, for Shape mappings
n.Index = ins.ReadUInt32();
- n.ComponentCount = (CompCount)ins.ReadUInt32();
- n.ComponentType = (CompType)ins.ReadUInt32();
+ n.ComponentCount = (VertexSettings.CompCount)ins.ReadUInt32();
+ n.ComponentType = (VertexSettings.CompType)ins.ReadUInt32();
n.Fraction = ins.ReadByte();
n.EntrySize = ins.ReadByte();
n.EntryCount = ins.ReadUInt16();
+ int structEndPos = ins.Position;
+
+ ins.Seek(startPos + dataOffset);
n.Data = ins.ReadBytes(n.EntrySize * n.EntryCount);
+
+ ins.Seek(structEndPos);
}
private Dictionary<int, Models.VertexPosData> VtxPosIndexLookup;
diff --git a/NW4RTools/Models/VertexData.cs b/NW4RTools/Models/VertexData.cs
index b1f65cd..5b1a50a 100644
--- a/NW4RTools/Models/VertexData.cs
+++ b/NW4RTools/Models/VertexData.cs
@@ -1,31 +1,11 @@
using System;
namespace NW4RTools.Models {
- public enum CompCount {
- Position2 = 0,
- Position3 = 1,
- Normal3 = 0,
- Color3 = 0,
- Color4 = 1,
- TexCoord1 = 0,
- TexCoord2 = 1
- }
-
-
- public enum CompType {
- UInt8 = 0,
- Int8 = 1,
- UInt16 = 2,
- Int16 = 3,
- Float32 = 4
- }
-
-
public abstract class VertexDataBase {
public UInt32 Index;
- public CompCount ComponentCount;
- public CompType ComponentType;
+ public VertexSettings.CompCount ComponentCount;
+ public VertexSettings.CompType ComponentType;
public byte Fraction /* Not used for colours */, EntrySize;
public UInt16 EntryCount;
@@ -46,18 +26,19 @@ namespace NW4RTools.Models {
for (int i = 0; i < ret.Length; i++) {
switch (ComponentType) {
- case CompType.UInt8:
+ case VertexSettings.CompType.UInt8:
break;
- case CompType.Int8:
+ case VertexSettings.CompType.Int8:
ret[i] = (float)ins.ReadSByte() * scale;
break;
- case CompType.UInt16:
+ case VertexSettings.CompType.UInt16:
ret[i] = (float)ins.ReadUInt16() * scale;
break;
- case CompType.Int16:
+ case VertexSettings.CompType.Int16:
ret[i] = (float)ins.ReadInt16() * scale;
+ //Console.WriteLine("Output into {0}: {3:X} {1} with scale {2}", i, ret[i], scale, v);
break;
- case CompType.Float32:
+ case VertexSettings.CompType.Float32:
ret[i] = ins.ReadFloat();
break;
default:
@@ -80,9 +61,9 @@ namespace NW4RTools.Models {
public override int GetRealCount() {
switch (ComponentCount) {
- case CompCount.Position2:
+ case VertexSettings.CompCount.Position2:
return 2;
- case CompCount.Position3:
+ case VertexSettings.CompCount.Position3:
return 3;
default:
return -1;
@@ -97,7 +78,7 @@ namespace NW4RTools.Models {
public override int GetRealCount() {
switch (ComponentCount) {
- case CompCount.Normal3:
+ case VertexSettings.CompCount.Normal3:
return 3;
default:
return -1;
@@ -112,9 +93,9 @@ namespace NW4RTools.Models {
public override int GetRealCount() {
switch (ComponentCount) {
- case CompCount.Color3:
+ case VertexSettings.CompCount.Color3:
return 3;
- case CompCount.Color4:
+ case VertexSettings.CompCount.Color4:
return 4;
default:
return -1;
@@ -131,9 +112,9 @@ namespace NW4RTools.Models {
public override int GetRealCount() {
switch (ComponentCount) {
- case CompCount.TexCoord1:
+ case VertexSettings.CompCount.TexCoord1:
return 1;
- case CompCount.TexCoord2:
+ case VertexSettings.CompCount.TexCoord2:
return 2;
default:
return -1;
diff --git a/NW4RTools/NW4RTools.csproj b/NW4RTools/NW4RTools.csproj
index 954271d..8f9aa75 100644
--- a/NW4RTools/NW4RTools.csproj
+++ b/NW4RTools/NW4RTools.csproj
@@ -20,6 +20,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
@@ -28,6 +29,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -53,6 +55,7 @@
<Compile Include="ObjWriter.cs" />
<Compile Include="Enums.cs" />
<Compile Include="DisplayList.cs" />
+ <Compile Include="VertexSettings.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
diff --git a/NW4RTools/ObjWriter.cs b/NW4RTools/ObjWriter.cs
index 72a134c..297ae58 100644
--- a/NW4RTools/ObjWriter.cs
+++ b/NW4RTools/ObjWriter.cs
@@ -93,7 +93,26 @@ namespace NW4RTools {
private void WriteShape(Models.Shape shape) {
- // parse the DisplayList
+ // first, parse the first DisplayList to get the attr info
+ // for now we'll hardcode the offsets. must be fixed later
+
+ var firstDL = new InputStream(shape.DisplayList1);
+ firstDL.Seek(0x0C);
+ UInt32 vtxDesc1 = firstDL.ReadUInt32();
+ firstDL.Seek(0x12);
+ UInt32 vtxDesc2 = firstDL.ReadUInt32();
+ firstDL.Seek(0x22);
+ UInt32 vtxAttr1 = firstDL.ReadUInt32();
+ firstDL.Seek(0x28);
+ UInt32 vtxAttr2 = firstDL.ReadUInt32();
+ firstDL.Seek(0x2E);
+ UInt32 vtxAttr3 = firstDL.ReadUInt32();
+
+ var vs = new VertexSettings();
+ vs.SetDesc(vtxDesc1, vtxDesc2);
+ vs.SetAttrFmt(vtxAttr1, vtxAttr2, vtxAttr3);
+
+ // now parse the second DisplayList
int posOffset = VtxPosOffsets[shape.PosData];
int nrmOffset = shape.NrmData == null ? -1 : VtxNrmOffsets[shape.NrmData];
@@ -106,22 +125,56 @@ namespace NW4RTools {
break;
byte cmd = dl.ReadByte();
- PrimitiveType prim = (PrimitiveType)cmd;
+ if (cmd == 0)
+ break;
+
+ PrimitiveType prim = (PrimitiveType)((cmd >> 3) & 7);
int vtxCount = dl.ReadUInt16();
Output.WriteLine("# Primitive: {0} ({1} vertices)", prim, vtxCount);
- // I wonder if INDEX8 is ever used here?
- // Going with INDEX16 for now.
+ // first, parse it into a list of vertices
+ GXIndexedVertex[] vtxs = new GXIndexedVertex[vtxCount];
+ string[] pVtxs = new string[vtxCount];
+
+ for (int i = 0; i < vtxCount; i++) {
+ vtxs[i].LoadFrom(dl, vs);
+
+ string tc = (vtxs[i].TexCoords[0] == -1) ? "" : (tcOffset + vtxs[i].TexCoords[0]).ToString();
+ string n = (vtxs[i].Normal == -1) ? "" : (nrmOffset + vtxs[i].Normal).ToString();
+ pVtxs[i] = String.Format(" {0}/{1}/{2}", posOffset + vtxs[i].Position, tc, n);
+ }
switch (prim) {
+ case PrimitiveType.Triangles:
+ for (int i = 0; i < vtxCount; i += 3) {
+ Output.WriteLine("f {0} {1} {2}", pVtxs[i], pVtxs[i + 1], pVtxs[i + 2]);
+ }
+
+ break;
+
case PrimitiveType.TriangleStrip:
// De-stripify it!
-
+ for (int i = 2; i < vtxCount; i++) {
+ Output.Write("f");
+ if ((i & 1) == 0) {
+ // Even number
+ Output.Write(pVtxs[i - 2]);
+ Output.Write(pVtxs[i - 1]);
+ Output.Write(pVtxs[i]);
+ } else {
+ // Odd number
+ Output.Write(pVtxs[i - 1]);
+ Output.Write(pVtxs[i - 2]);
+ Output.Write(pVtxs[i]);
+ }
+ Output.WriteLine();
+ }
break;
default:
- throw new NotImplementedException();
+ Output.WriteLine("# UNIMPLEMENTED");
+ return;
}
}
}
diff --git a/NW4RTools/VertexSettings.cs b/NW4RTools/VertexSettings.cs
new file mode 100644
index 0000000..5eac02a
--- /dev/null
+++ b/NW4RTools/VertexSettings.cs
@@ -0,0 +1,234 @@
+using System;
+
+namespace NW4RTools {
+ public struct GXIndexedVertex {
+ public int Position;
+ public int Normal;
+
+ public int[] Colors;
+ public int[] TexCoords;
+
+
+
+ public void LoadFrom(InputStream ins, VertexSettings vs) {
+ if (vs.PNMatrixIndexExists)
+ throw new NotImplementedException();
+ if (vs.TexCoordMatrixIndexExists[0])
+ throw new NotImplementedException();
+ // won't bother with the rest
+
+ switch (vs.PositionDesc) {
+ case VertexSettings.DescType.Direct:
+ throw new NotImplementedException();
+ case VertexSettings.DescType.None:
+ throw new NotImplementedException();
+ case VertexSettings.DescType.Index8:
+ Position = ins.ReadByte();
+ if (Position == 0xFF)
+ Position = -1;
+ break;
+ case VertexSettings.DescType.Index16:
+ Position = ins.ReadUInt16();
+ if (Position == 0xFFFF)
+ Position = -1;
+ break;
+ }
+
+ // not sure how to detect NBT3 yet
+ switch (vs.NormalDesc) {
+ case VertexSettings.DescType.Direct:
+ throw new NotImplementedException();
+ case VertexSettings.DescType.None:
+ Normal = -1;
+ break;
+ case VertexSettings.DescType.Index8:
+ Normal = ins.ReadByte();
+ if (Normal == 0xFF)
+ Normal = -1;
+ break;
+ case VertexSettings.DescType.Index16:
+ Normal = ins.ReadUInt16();
+ if (Normal == 0xFFFF)
+ Normal = -1;
+ break;
+ }
+
+ Colors = new int[2];
+
+ for (int i = 0; i < 2; i++) {
+ switch (vs.ColorDesc[i]) {
+ case VertexSettings.DescType.Direct:
+ throw new NotImplementedException();
+ case VertexSettings.DescType.None:
+ Colors[i] = -1;
+ break;
+ case VertexSettings.DescType.Index8:
+ Colors[i] = ins.ReadByte();
+ if (Colors[i] == 0xFF)
+ Colors[i] = -1;
+ break;
+ case VertexSettings.DescType.Index16:
+ Colors[i] = ins.ReadUInt16();
+ if (Colors[i] == 0xFFFF)
+ Colors[i] = -1;
+ break;
+ }
+ }
+
+ TexCoords = new int[8];
+
+ for (int i = 0; i < 8; i++) {
+ switch (vs.TexCoordDesc[i]) {
+ case VertexSettings.DescType.Direct:
+ throw new NotImplementedException();
+ case VertexSettings.DescType.None:
+ TexCoords[i] = -1;
+ break;
+ case VertexSettings.DescType.Index8:
+ TexCoords[i] = ins.ReadByte();
+ if (TexCoords[i] == 0xFF)
+ TexCoords[i] = -1;
+ break;
+ case VertexSettings.DescType.Index16:
+ TexCoords[i] = ins.ReadUInt16();
+ if (TexCoords[i] == 0xFFFF)
+ TexCoords[i] = -1;
+ break;
+ }
+ }
+ }
+ }
+
+
+
+ public class VertexSettings {
+ public enum DescType {
+ None,
+ Direct,
+ Index8,
+ Index16
+ }
+
+ public enum CompCount {
+ Position2 = 0,
+ Position3 = 1,
+ Normal3 = 0,
+ NBT = 1,
+ NBT3 = 2,
+ Color3 = 0,
+ Color4 = 1,
+ TexCoord1 = 0,
+ TexCoord2 = 1
+ }
+
+ public enum CompType {
+ UInt8 = 0,
+ Int8 = 1,
+ UInt16 = 2,
+ Int16 = 3,
+ Float32 = 4
+ }
+
+
+ public bool PNMatrixIndexExists;
+ public bool[] TexCoordMatrixIndexExists;
+ public DescType PositionDesc, NormalDesc;
+ public DescType[] ColorDesc, TexCoordDesc;
+
+ public CompCount PositionCount, NormalCount;
+ public CompCount[] ColorCount, TexCoordCount;
+
+ public CompType PositionFormat, NormalFormat;
+ public CompType[] ColorFormat, TexCoordFormat;
+
+ public byte PositionFrac;
+ public byte[] TexCoordFrac;
+
+
+
+ public VertexSettings() {
+ TexCoordMatrixIndexExists = new bool[8];
+
+ ColorDesc = new DescType[2];
+ TexCoordDesc = new DescType[8];
+
+ ColorCount = new CompCount[2];
+ TexCoordCount = new CompCount[8];
+
+ ColorFormat = new CompType[2];
+ TexCoordFormat = new CompType[8];
+
+ TexCoordFrac = new byte[8];
+ }
+
+
+ public void SetDesc(UInt32 val1, UInt32 val2) {
+ PNMatrixIndexExists = ((val1 & 1) != 0);
+
+ for (int i = 0; i < 8; i++)
+ TexCoordMatrixIndexExists[i] = ((val1 & (2 << i)) != 0);
+
+ PositionDesc = (DescType)((val1 & 0x600) >> 9);
+ NormalDesc = (DescType)((val1 & 0x1800) >> 11);
+ ColorDesc[0] = (DescType)((val1 & 0x6000) >> 13);
+ ColorDesc[1] = (DescType)((val1 & 0x18000) >> 15);
+
+ for (int i = 0; i < 8; i++)
+ TexCoordDesc[i] = (DescType)((val2 & (3 << (i * 2))) >> (i * 2));
+ }
+
+ public void SetAttrFmt(UInt32 val1, UInt32 val2, UInt32 val3) {
+ PositionCount = (CompCount)(val1 & 1);
+ PositionFormat = (CompType)((val1 & 0xE) >> 3);
+ PositionFrac = (byte)((val1 & 0x1F0) >> 4);
+
+ // note: this field is special
+ bool IsNormalSet = ((val1 & 0x200) != 0);
+ bool UseNormalIndex3 = ((val1 & 0x80000000) != 0);
+ NormalCount = IsNormalSet ? (UseNormalIndex3 ? CompCount.NBT3 : CompCount.NBT) : CompCount.Normal3;
+ NormalFormat = (CompType)((val1 & 0x1C00) >> 10);
+
+ ColorCount[0] = (CompCount)((val1 & 0x2000) >> 13);
+ ColorFormat[0] = (CompType)((val1 & 0x1C000) >> 14);
+
+ ColorCount[1] = (CompCount)((val1 & 0x20000) >> 17);
+ ColorFormat[1] = (CompType)((val1 & 0x1C0000) >> 18);
+
+ TexCoordCount[0] = (CompCount)((val1 & 0x200000) >> 21);
+ TexCoordFormat[0] = (CompType)((val1 & 0x1C00000) >> 22);
+ TexCoordFrac[0] = (byte)((val1 & 0x3E000000) >> 25);
+
+ // set in various cases, see libogc gx.c for info
+ bool ByteDequant = ((val1 & 0x40000000) != 0);
+
+ TexCoordCount[1] = (CompCount)(val2 & 0x1);
+ TexCoordFormat[1] = (CompType)((val2 & 0xE) >> 1);
+ TexCoordFrac[1] = (byte)((val2 & 0x1F0) >> 4);
+
+ TexCoordCount[2] = (CompCount)((val2 & 0x200) >> 9);
+ TexCoordFormat[2] = (CompType)((val2 & 0x1C00) >> 10);
+ TexCoordFrac[2] = (byte)((val2 & 0x3E000) >> 13);
+
+ TexCoordCount[3] = (CompCount)((val2 & 0x40000) >> 18);
+ TexCoordFormat[3] = (CompType)((val2 & 0x380000) >> 19);
+ TexCoordFrac[3] = (byte)((val2 & 0x3E000000) >> 22);
+
+ TexCoordCount[4] = (CompCount)((val2 & 0x8000000) >> 27);
+ TexCoordFormat[4] = (CompType)((val2 & 0x70000000) >> 28);
+ TexCoordFrac[4] = (byte)(val3 & 0x1F);
+
+ TexCoordCount[5] = (CompCount)((val3 & 0x20) >> 5);
+ TexCoordFormat[5] = (CompType)((val3 & 0x1C0) >> 6);
+ TexCoordFrac[5] = (byte)((val3 & 0x3E00) >> 9);
+
+ TexCoordCount[6] = (CompCount)((val3 & 0x4000) >> 14);
+ TexCoordFormat[6] = (CompType)((val3 & 0x38000) >> 15);
+ TexCoordFrac[6] = (byte)((val3 & 0x7C0000) >> 18);
+
+ TexCoordCount[7] = (CompCount)((val3 & 0x800000) >> 23);
+ TexCoordFormat[7] = (CompType)((val3 & 0x7000000) >> 24);
+ TexCoordFrac[7] = (byte)((val3 & 0xF8000000) >> 27);
+ }
+ }
+}
+
diff --git a/NW4RTools/bin/Debug/NW4RTools.dll b/NW4RTools/bin/Debug/NW4RTools.dll
index a1602c8..b0fe3d4 100755
--- a/NW4RTools/bin/Debug/NW4RTools.dll
+++ b/NW4RTools/bin/Debug/NW4RTools.dll
Binary files differ
diff --git a/NW4RTools/bin/Debug/NW4RTools.dll.mdb b/NW4RTools/bin/Debug/NW4RTools.dll.mdb
index f4fb376..9b65235 100644
--- a/NW4RTools/bin/Debug/NW4RTools.dll.mdb
+++ b/NW4RTools/bin/Debug/NW4RTools.dll.mdb
Binary files differ