diff options
Diffstat (limited to 'NW4RTools/ColladaWriter.cs')
-rw-r--r-- | NW4RTools/ColladaWriter.cs | 118 |
1 files changed, 115 insertions, 3 deletions
diff --git a/NW4RTools/ColladaWriter.cs b/NW4RTools/ColladaWriter.cs index b2fc5a2..b7c039a 100644 --- a/NW4RTools/ColladaWriter.cs +++ b/NW4RTools/ColladaWriter.cs @@ -19,6 +19,9 @@ namespace NW4RTools { library_geometries LibGeometries; library_visual_scenes LibVisualScenes; + library_images LibImages; + library_materials LibMaterials; + library_effects LibEffects; private ColladaWriter(ResFile file) { CurrentFile = file; @@ -40,8 +43,70 @@ namespace NW4RTools { Collada.asset.unit.meter = 1.0; Collada.asset.up_axis = UpAxisType.Y_UP; - List<object> ColladaItems = new List<object>(); - + var ColladaItems = new List<object>(); + + // First up, before anything else: images and materials + // Compile a list of every texture we use in the model + var usedTextures = new List<string>(); + + foreach (var kv in CurrentModel.Materials) { + foreach (var texInfo in kv.Value.TextureInfos) { + if (!usedTextures.Contains(texInfo.TextureName)) + usedTextures.Add(texInfo.TextureName); + } + } + + // Create a Collada image for these + LibImages = new library_images(); + ColladaItems.Add(LibImages); + + var ImageList = new List<image>(); + var TexGroup = CurrentFile.GetGroup<Texture>("Textures(NW4R)"); + + foreach (var texName in usedTextures) { + var img = new image(); + var tex = TexGroup[texName]; + + img.name = "Texture-" + texName; + img.id = img.name; + img.Item = texName + ".png"; + + ImageList.Add(img); + } + + LibImages.image = ImageList.ToArray(); + + // Make a quick reference material for each one + LibMaterials = new library_materials(); + ColladaItems.Add(LibMaterials); + + var MaterialList = new List<material>(); + + foreach (var kv in CurrentModel.Materials) { + var mat = new material(); + + mat.name = "Material-" + kv.Key; + mat.id = mat.name; + mat.instance_effect = new instance_effect(); + mat.instance_effect.url = "#Material-Effect-" + kv.Key; + + MaterialList.Add(mat); + } + + LibMaterials.material = MaterialList.ToArray(); + + // Now create an effect for each material (this is where all the real work is done!) + LibEffects = new library_effects(); + ColladaItems.Add(LibEffects); + + var EffectList = new List<effect>(); + foreach (var kv in CurrentModel.Materials) { + EffectList.Add(CreateEffectFromMaterial(kv.Key, kv.Value)); + } + + LibEffects.effect = EffectList.ToArray(); + + // Now shapes LibGeometries = new library_geometries(); ColladaItems.Add(LibGeometries); @@ -98,7 +163,7 @@ namespace NW4RTools { origNode.Translation.y, -origNode.Scale.x * sinY, origNode.Scale.y * sinX * cosY, - origNode.Scale.z * cosX * cosY, + origNode.Scale.z * cosX * cosY, origNode.Translation.z, 0, 0, 0, 1 }; @@ -144,6 +209,8 @@ namespace NW4RTools { Array.Resize<instance_geometry>(ref geoArrayCopy, geoArrayCopy.Length + 1); geoArrayCopy[geoArrayCopy.Length - 1] = newGeoEntry; cNode.instance_geometry = geoArrayCopy; + + // TODO: Add material handling, I'll probably have to parse DrawOpa/DrawXlu for this... } /*foreach (var kv in CurrentModel.Shapes) { @@ -172,6 +239,51 @@ namespace NW4RTools { + private effect CreateEffectFromMaterial(string name, Material mat) { + var eff = new effect(); + + eff.id = "Material-Effect-" + name; + eff.name = eff.id; + + // this is based off what colladamax outputs + eff.Items = new effectFx_profile_abstractProfile_COMMON[1]; + var profile = eff.Items[0] = new effectFx_profile_abstractProfile_COMMON(); + + // TODO: handle this correctly for multiple textures ETC and check how bb does it + + // HACK!! + if (mat.TextureInfos.Count == 0) + return eff; + + profile.Items = new object[2]; + + // create a surface newparam + var surfaceParam = new common_newparam_type(); + var surface = new fx_surface_common(); + + surface.type = fx_surface_type_enum.Item2D; + surface.init_from = new fx_surface_init_from_common[1]; + surface.init_from[0] = new fx_surface_init_from_common(); + surface.init_from[0].Value = "Texture-" + mat.TextureInfos[0].TextureName; + + surfaceParam.sid = "Surface-" + mat.TextureInfos[0].TextureName; + surfaceParam.ItemElementName = ItemChoiceType.surface; + surfaceParam.Item = surface; + profile.Items[0] = surfaceParam; + + // now create a sampler newparam + var samplerParam = new common_newparam_type(); + var sampler2d = new fx_sampler2D_common(); + + sampler2d.source = "Surface-" + mat.TextureInfos[0].TextureName; + + samplerParam.ItemElementName = ItemChoiceType.sampler2D; + samplerParam.Item = sampler2d; + profile.Items[1] = samplerParam; + + return eff; + } + private geometry CreateGeometryFromShape(string name, Shape shape) { |