diff options
| author | Treeki <treeki@gmail.com> | 2011-03-10 05:27:43 +0100 | 
|---|---|---|
| committer | Treeki <treeki@gmail.com> | 2011-03-10 05:27:43 +0100 | 
| commit | a9ef5367e5696602837900934df9b27ca15d944c (patch) | |
| tree | 43fae8060340ba00bd8bf51b385f430dbe6bad52 /NW4RTools/ObjImporter.cs | |
| parent | 5926616de2bd346f1a1c69c93ff2aaa3c453a2b3 (diff) | |
| download | nw4rtools-a9ef5367e5696602837900934df9b27ca15d944c.tar.gz nw4rtools-a9ef5367e5696602837900934df9b27ca15d944c.zip | |
MapObj lightmap support
Diffstat (limited to 'NW4RTools/ObjImporter.cs')
| -rwxr-xr-x | NW4RTools/ObjImporter.cs | 183 | 
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]]);  				}  			} | 
