summaryrefslogtreecommitdiff
path: root/NW4RTools/ObjImporter.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xNW4RTools/ObjImporter.cs183
1 files changed, 134 insertions, 49 deletions
diff --git a/NW4RTools/ObjImporter.cs b/NW4RTools/ObjImporter.cs
index 1606028..78294bd 100755
--- a/NW4RTools/ObjImporter.cs
+++ b/NW4RTools/ObjImporter.cs
@@ -6,13 +6,25 @@ using NW4RTools.Models;
namespace NW4RTools {
public class ObjImporter {
+ public enum LightmapType {
+ None,
+ Map,
+ MapObj
+ }
+
public static void ImportModel(string basePath, TextReader tr, ResFile file, string modelName) {
- new ObjImporter(basePath, file, tr).ImportModel(modelName);
+ new ObjImporter(basePath, file, tr).ImportModel(modelName, LightmapType.None);
+ }
+
+ public static void ImportModel(string basePath, TextReader tr, ResFile file, string modelName, LightmapType lightmapType) {
+ new ObjImporter(basePath, file, tr).ImportModel(modelName, lightmapType);
}
- private const bool Lightmaps = true;
+ LightmapType Lightmap;
+
+ string LightmapName1, LightmapName2;
string BasePath;
ResFile CurrentFile;
@@ -32,10 +44,21 @@ namespace NW4RTools {
Input = tr;
}
- public void ImportModel(string modelName) {
+ public void ImportModel(string modelName, LightmapType lmt) {
var modelGroup = CurrentFile.CreateModelGroup();
var texGroup = CurrentFile.CreateTextureGroup();
+ Lightmap = lmt;
+
+ string lmID = "";
+ if (lmt == ObjImporter.LightmapType.Map)
+ lmID = "m";
+ else if (lmt == ObjImporter.LightmapType.MapObj)
+ lmID = "mo";
+
+ LightmapName1 = "lm_01" + lmID;
+ LightmapName2 = "lm_02" + lmID;
+
// OK, so here's what I'm going to do:
// I'll read the file into an internal array and process commands as they come.
@@ -56,23 +79,22 @@ namespace NW4RTools {
// Set current material (usemtl):
// -- A different material will be assigned for the current shape.
- if (Lightmaps) {
- var lm01m = new Texture();
-
- lm01m.Images = new System.Drawing.Bitmap[1];
- lm01m.Images[0] = new System.Drawing.Bitmap(Path.Combine(BasePath, "images/lm_01m.png"));
-
- lm01m.Format = TextureFormat.I8;
+ if (Lightmap != LightmapType.None) {
+ var lm01 = new Texture();
+ var lm02 = new Texture();
- var lm02m = new Texture();
+ lm01.Images = new System.Drawing.Bitmap[1];
+ lm01.Images[0] = new System.Drawing.Bitmap(Path.Combine(BasePath, string.Format("images/{0}.png", LightmapName1)));
+
+ lm01.Format = TextureFormat.I8;
- lm02m.Images = new System.Drawing.Bitmap[1];
- lm02m.Images[0] = new System.Drawing.Bitmap(Path.Combine(BasePath, "images/lm_02m.png"));
+ lm02.Images = new System.Drawing.Bitmap[1];
+ lm02.Images[0] = new System.Drawing.Bitmap(Path.Combine(BasePath, string.Format("images/{0}.png", LightmapName2)));
- lm02m.Format = TextureFormat.I8;
+ lm02.Format = TextureFormat.I8;
- CurrentFile.GetTextureGroup().Add("lm_01m", lm01m);
- CurrentFile.GetTextureGroup().Add("lm_02m", lm02m);
+ CurrentFile.GetTextureGroup().Add(LightmapName1, lm01);
+ CurrentFile.GetTextureGroup().Add(LightmapName2, lm02);
}
@@ -244,7 +266,7 @@ namespace NW4RTools {
currentMaterial.ChanCtrls[0].Flags = 0x3F;
currentMaterial.ChanCtrls[0].MatColor.Rgba = 0xFFFFFFFF;
currentMaterial.ChanCtrls[0].AmbColor.Rgba = 0xFFFFFFFF;
- currentMaterial.ChanCtrls[0].FlagC = Lightmaps ? (uint)0x701 : (uint)0x702;
+ currentMaterial.ChanCtrls[0].FlagC = (Lightmap != ObjImporter.LightmapType.None) ? (uint)0x701 : (uint)0x702;
currentMaterial.ChanCtrls[0].FlagA = 0x700;
currentMaterial.ChanCtrls[1] = new ChanCtrl();
@@ -254,7 +276,7 @@ namespace NW4RTools {
currentMaterial.ChanCtrls[1].FlagC = 0;
currentMaterial.ChanCtrls[1].FlagA = 0;
- if (!Lightmaps) {
+ if (Lightmap == ObjImporter.LightmapType.None) {
currentMaterial.TexCoordGenCount = 1;
currentMaterial.ChanCount = 1;
currentMaterial.TevStageCount = 2;
@@ -322,7 +344,8 @@ namespace NW4RTools {
currentMaterial.TexCoordGenDL = texCoordGenDL.GetBuffer();
} else {
- // These are taken from mtSand on CS_W1
+ // Map: These are taken from mtGake on CS_W1
+ // MapObj: Taken from cobKinokoRed
currentMaterial.TexCoordGenCount = 3;
currentMaterial.ChanCount = 1;
currentMaterial.TevStageCount = 3;
@@ -371,7 +394,10 @@ namespace NW4RTools {
tevColorDL.LoadBPReg(0xE3800000);
tevColorDL.LoadBPReg(0xE4800000);
tevColorDL.LoadBPReg(0xE5800000);
- tevColorDL.LoadBPReg(0xE68FF000);
+ if (Lightmap == ObjImporter.LightmapType.Map)
+ tevColorDL.LoadBPReg(0xE68FF000);
+ else if (Lightmap == ObjImporter.LightmapType.MapObj)
+ tevColorDL.LoadBPReg(0xE6800000);
tevColorDL.LoadBPReg(0xE7800000);
tevColorDL.AddPadding(24);
tevColorDL.End();
@@ -428,25 +454,23 @@ namespace NW4RTools {
currentMaterial.TextureInfos.Add(texInfo);
- // Now add the lm_01m and lm_02m
- var lm01m = new TextureInfo();
- lm01m.TextureName = "lm_01m";
- lm01m.TexMapID = 1;
- lm01m.TlutID = 1;
-
- lm01m.MinFilt = 1;
- lm01m.MagFilt = 1;
+ // Now add the lightmaps
+ var lm01 = new TextureInfo();
+ lm01.TextureName = LightmapName1;
+ lm01.TexMapID = 1;
+ lm01.TlutID = 1;
+
+ lm01.MinFilt = lm01.MagFilt = 1;
- var lm02m = new TextureInfo();
- lm02m.TextureName = "lm_02m";
- lm02m.TexMapID = 2;
- lm02m.TlutID = 2;
+ var lm02 = new TextureInfo();
+ lm02.TextureName = LightmapName2;
+ lm02.TexMapID = 2;
+ lm02.TlutID = 2;
- lm02m.MinFilt = 1;
- lm02m.MagFilt = 1;
+ lm02.MinFilt = lm02.MagFilt = 1;
- currentMaterial.TextureInfos.Add(lm01m);
- currentMaterial.TextureInfos.Add(lm02m);
+ currentMaterial.TextureInfos.Add(lm01);
+ currentMaterial.TextureInfos.Add(lm02);
break;
@@ -493,7 +517,7 @@ namespace NW4RTools {
dl.LoadBPReg(0x27FFFFFF);
dl.AddPadding(11);
- if (!Lightmaps) {
+ if (Lightmap == ObjImporter.LightmapType.None) {
shader.TevStageCount = 2;
shader.Unk1 = 0x00FFFFFF;
shader.Unk2 = 0xFFFFFFFF;
@@ -514,21 +538,38 @@ namespace NW4RTools {
shader.Unk2 = 0xFFFFFFFF;
dl.LoadBPReg(0xFEFFFFF0);
- dl.LoadBPReg(0xF6E338C0);
- dl.LoadBPReg(0x283C0049);
- dl.LoadBPReg(0xC008F8AF);
- dl.LoadBPReg(0xC208F80F);
- dl.LoadBPReg(0xC108FFD0);
- dl.LoadBPReg(0xC308E270);
+ if (Lightmap == ObjImporter.LightmapType.Map) {
+ dl.LoadBPReg(0xF6E338C0);
+ dl.LoadBPReg(0x283C0049);
+ dl.LoadBPReg(0xC008F8AF);
+ dl.LoadBPReg(0xC208F80F);
+ dl.LoadBPReg(0xC108FFD0);
+ dl.LoadBPReg(0xC308E270);
+ } else if (Lightmap == ObjImporter.LightmapType.MapObj) {
+ dl.LoadBPReg(0xF6E3F8C0);
+ dl.LoadBPReg(0x28052040);
+ dl.LoadBPReg(0xC0C8F8AF);
+ dl.LoadBPReg(0xC208F8AE);
+ dl.LoadBPReg(0xC1C8FCF0);
+ dl.LoadBPReg(0xC308FFF0);
+ }
dl.LoadBPReg(0x10000000);
dl.LoadBPReg(0x11000000);
dl.AddPadding(3);
dl.LoadBPReg(0xFEFFFFF0);
- dl.LoadBPReg(0xF7003EF0);
- dl.LoadBPReg(0x293BF052);
- dl.LoadBPReg(0xC4080A8E);
- dl.AddPadding(5);
- dl.LoadBPReg(0xC508E370);
+ if (Lightmap == ObjImporter.LightmapType.Map) {
+ dl.LoadBPReg(0xF7003EF0);
+ dl.LoadBPReg(0x293BF052);
+ dl.LoadBPReg(0xC4080A8E);
+ dl.AddPadding(5);
+ dl.LoadBPReg(0xC508E370);
+ } else if (Lightmap == ObjImporter.LightmapType.MapObj) {
+ dl.LoadBPReg(0xF70038C0);
+ dl.LoadBPReg(0x293BF3C9);
+ dl.LoadBPReg(0xC408F860);
+ dl.AddPadding(5);
+ dl.LoadBPReg(0xC508FFF0);
+ }
dl.AddPadding(5);
dl.LoadBPReg(0x12000000);
}
@@ -651,6 +692,8 @@ namespace NW4RTools {
// 0xB6 : Dynamic CP command: TexCoord 7 Array Pointer
// 0xBC : Dynamic CP command: TexCoord 7 Array Stride
+ bool usingLightmaps = (Lightmap != ObjImporter.LightmapType.None);
+
// Now create vertex settings
var vs = new VertexSettings();
vs.PositionDesc = VertexSettings.DescType.Index16;
@@ -665,6 +708,12 @@ namespace NW4RTools {
vs.NormalFormat = VertexSettings.CompType.Float32;
vs.NormalCount = VertexSettings.CompCount.Normal3;
+ if (Lightmap != ObjImporter.LightmapType.None) {
+ vs.ColorDesc[0] = VertexSettings.DescType.Index8;
+ vs.ColorFormat[0] = VertexSettings.CompClrType.RGBA8;
+ vs.ColorCount[0] = VertexSettings.CompCount.Color4;
+ }
+
uint vd1, vd2, vat1, vat2, vat3;
vs.GetDesc(out vd1, out vd2);
vs.GetAttrFmt(out vat1, out vat2, out vat3);
@@ -672,7 +721,12 @@ namespace NW4RTools {
// I might need to create XFMEM_VTXSPECS...
// test_lift uses 0x14. According to Dolphin's src, this means:
// numcolors = 0, numnormals = 1 (just normal), numtextures = 1. Makes sense.
- byte vtxSpecs = 0 | (1 << 2) | (1 << 4);
+ // If lightmaps, then use: numcolors = 1, numnormals = 1, numtextures = 3
+ byte vtxSpecs;
+ if (usingLightmaps)
+ vtxSpecs = 1 | (1 << 2) | (3 << 4);
+ else
+ vtxSpecs = 0 | (1 << 2) | (1 << 4);
var dl1 = new DisplayListWriter();
dl1.AddPadding(10);
@@ -739,24 +793,47 @@ namespace NW4RTools {
CurrentShape.TexCoordData[0] = tcData;
CurrentShape.NrmData = nrmData;
+ // For lightmaps, before we get baked lighting working
+ if (usingLightmaps) {
+ var clrData = new VertexClrData();
+ clrData.ComponentCount = VertexSettings.CompCount.Color4;
+ clrData.ComponentType = VertexSettings.CompType.UInt8;
+ clrData.EntryCount = 1;
+ clrData.EntrySize = 1;
+ clrData.Fraction = 0;
+ clrData.RawData = new byte[] { 255, 255, 255, 255 };
+
+ CurrentModel.VtxClrData.Add("C_" + CurrentModel.VtxClrData.Count.ToString(), clrData);
+ CurrentShape.ClrData[0] = clrData;
+ }
+
+
var dl = new DisplayListWriter();
// face writing here is reversed because the wind order seems to be wrong
// dunno if it applies to models exported from everything, or just Maya
// or maybe it's a setting specified in one of the structs
+ // 0 bytes are for colour indexes
+
if (Triangles.Count > 0) {
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 (usingLightmaps)
+ dl.WriteByte(0);
dl.WriteUInt16(texCoordIndexes[tri[8]]);
dl.WriteUInt16(posIndexes[tri[3]]);
dl.WriteUInt16(normalIndexes[tri[4]]);
+ if (usingLightmaps)
+ dl.WriteByte(0);
dl.WriteUInt16(texCoordIndexes[tri[5]]);
dl.WriteUInt16(posIndexes[tri[0]]);
dl.WriteUInt16(normalIndexes[tri[1]]);
+ if (usingLightmaps)
+ dl.WriteByte(0);
dl.WriteUInt16(texCoordIndexes[tri[2]]);
}
}
@@ -767,15 +844,23 @@ namespace NW4RTools {
foreach (var quad in Quads) {
dl.WriteUInt16(posIndexes[quad[9]]);
dl.WriteUInt16(normalIndexes[quad[10]]);
+ if (usingLightmaps)
+ dl.WriteByte(0);
dl.WriteUInt16(texCoordIndexes[quad[11]]);
dl.WriteUInt16(posIndexes[quad[6]]);
dl.WriteUInt16(normalIndexes[quad[7]]);
+ if (usingLightmaps)
+ dl.WriteByte(0);
dl.WriteUInt16(texCoordIndexes[quad[8]]);
dl.WriteUInt16(posIndexes[quad[3]]);
dl.WriteUInt16(normalIndexes[quad[4]]);
+ if (usingLightmaps)
+ dl.WriteByte(0);
dl.WriteUInt16(texCoordIndexes[quad[5]]);
dl.WriteUInt16(posIndexes[quad[0]]);
dl.WriteUInt16(normalIndexes[quad[1]]);
+ if (usingLightmaps)
+ dl.WriteByte(0);
dl.WriteUInt16(texCoordIndexes[quad[2]]);
}
}