From a9ef5367e5696602837900934df9b27ca15d944c Mon Sep 17 00:00:00 2001
From: Treeki <treeki@gmail.com>
Date: Thu, 10 Mar 2011 05:27:43 +0100
Subject: MapObj lightmap support

---
 NW4RTools/NW4RTools.pidb              | Bin 582467 -> 583215 bytes
 NW4RTools/ObjImporter.cs              | 183 +++++++++++++++++++++++++---------
 NW4RTools/bin/Debug/NW4RTools.dll     | Bin 235008 -> 236544 bytes
 NW4RTools/bin/Debug/NW4RTools.dll.mdb | Bin 113949 -> 114260 bytes
 4 files changed, 134 insertions(+), 49 deletions(-)

(limited to 'NW4RTools')

diff --git a/NW4RTools/NW4RTools.pidb b/NW4RTools/NW4RTools.pidb
index 6bd6989..fb7e2a9 100644
Binary files a/NW4RTools/NW4RTools.pidb and b/NW4RTools/NW4RTools.pidb differ
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]]);
 				}
 			}
diff --git a/NW4RTools/bin/Debug/NW4RTools.dll b/NW4RTools/bin/Debug/NW4RTools.dll
index d8f19a2..b6af23d 100755
Binary files a/NW4RTools/bin/Debug/NW4RTools.dll and b/NW4RTools/bin/Debug/NW4RTools.dll differ
diff --git a/NW4RTools/bin/Debug/NW4RTools.dll.mdb b/NW4RTools/bin/Debug/NW4RTools.dll.mdb
index 330c38e..dea185a 100644
Binary files a/NW4RTools/bin/Debug/NW4RTools.dll.mdb and b/NW4RTools/bin/Debug/NW4RTools.dll.mdb differ
-- 
cgit v1.2.3