summaryrefslogtreecommitdiff
path: root/NW4RTools/ColladaWriter.cs
diff options
context:
space:
mode:
Diffstat (limited to 'NW4RTools/ColladaWriter.cs')
-rw-r--r--NW4RTools/ColladaWriter.cs118
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) {