diff --git a/addons/io_scene_swbf_msh/msh_material_gather.py b/addons/io_scene_swbf_msh/msh_material_gather.py index c3fdace..4fa3f3d 100644 --- a/addons/io_scene_swbf_msh/msh_material_gather.py +++ b/addons/io_scene_swbf_msh/msh_material_gather.py @@ -54,6 +54,9 @@ def _read_material_props_rendertype(props) -> Rendertype: return _RENDERTYPES_MAPPING[props.rendertype] def _read_material_props_flags(props) -> MaterialFlags: + if "REFRACTION" in props.rendertype: + return MaterialFlags.BLENDED_TRANSPARENCY + flags = MaterialFlags.NONE if props.blended_transparency: diff --git a/addons/io_scene_swbf_msh/msh_material_properties.py b/addons/io_scene_swbf_msh/msh_material_properties.py index 81c8a3e..bc01d19 100644 --- a/addons/io_scene_swbf_msh/msh_material_properties.py +++ b/addons/io_scene_swbf_msh/msh_material_properties.py @@ -3,23 +3,19 @@ import bpy from bpy.props import StringProperty, BoolProperty, EnumProperty, FloatVectorProperty, IntProperty from bpy.types import PropertyGroup +from .msh_material_ui_strings import * UI_MATERIAL_RENDERTYPES = ( - ('NORMAL_BF2', "00 Normal (SWBF2)", "Normal Material. Unlike you there is nothing inherently awesome " - "about this material. By default it has per-vertex diffuse " - "lighting and can also have a detail map."), - ('SCROLLING_BF2', "03 Scrolling (SWBF2)", "Scrolling Material"), - ('ENVMAPPED_BF2', "06 Envmapped (SWBF2)", "Envmapped Material"), - ('ANIMATED_BF2', "07 Animated (SWBF2)", "Animated Material"), - ('REFRACTION_BF2', "22 Refractive (SWBF2)", "Refractive Material"), - ('BLINK_BF2', "25 Blink (SWBF2)", "Blinking Material\n\n" - "Note: If you see any statues while using this material you " - "are advised **not** to blink (or take your eyes off the statue under any circumstances) " - "and immediately make your way to a crowded public space."), - ('NORMALMAPPED_TILED_BF2', "24 Normalmapped Tiled (SWBF2)", "Normalmapped Tiled Material"), - ('NORMALMAPPED_ENVMAPPED_BF2', "26 Normalmapped Envmapped (SWBF2)", "Normalmapped Envmapped Material"), - ('NORMALMAPPED_BF2', "27 Normalmapped (SWBF2)", "Normalmapped Material"), - ('NORMALMAPPED_TILED_ENVMAPPED_BF2', "26 Normalmapped Tiled Envmapped (SWBF2)", "Normalmapped Tiled Envmapped Material")) + ('NORMAL_BF2', "00 Normal (SWBF2)", UI_RENDERTYPE_NORMAL_BF2_DESC), + ('SCROLLING_BF2', "03 Scrolling (SWBF2)", UI_RENDERTYPE_SCROLLING_BF2_DESC), + ('ENVMAPPED_BF2', "06 Envmapped (SWBF2)", UI_RENDERTYPE_ENVMAPPED_BF2_DESC), + ('ANIMATED_BF2', "07 Animated (SWBF2)", UI_RENDERTYPE_ANIMATED_BF2_DESC), + ('REFRACTION_BF2', "22 Refractive (SWBF2)", UI_RENDERTYPE_REFRACTION_BF2_DESC), + ('BLINK_BF2', "25 Blink (SWBF2)", UI_RENDERTYPE_BLINK_BF2_DESC), + ('NORMALMAPPED_TILED_BF2', "24 Normalmapped Tiled (SWBF2)", UI_RENDERTYPE_NORMALMAPPED_TILED_BF2_DESC), + ('NORMALMAPPED_ENVMAPPED_BF2', "26 Normalmapped Envmapped (SWBF2)", UI_RENDERTYPE_NORMALMAPPED_ENVMAPPED_BF2_DESC), + ('NORMALMAPPED_BF2', "27 Normalmapped (SWBF2)", UI_RENDERTYPE_NORMALMAPPED_BF2_DESC), + ('NORMALMAPPED_TILED_ENVMAPPED_BF2', "29 Normalmapped Tiled Envmapped (SWBF2)", UI_RENDERTYPE_NORMALMAPPED_TILED_ENVMAPPED_BF2_DESC)) def _make_anim_length_entry(length): from math import sqrt @@ -86,23 +82,20 @@ class MaterialProperties(PropertyGroup): default=False) perpixel: BoolProperty(name="Per-Pixel Lighting", - description="Use per-pixel lighting instead of per-vertex for diffuse lighting. " - "Be warned due to the way SWBFII handles per-pixel lighting this " - "adds an extra draw call for each segment using the material.", + description="Use per-pixel lighting instead of per-vertex for diffuse lighting.", default=False) specular: BoolProperty(name="Specular Lighting", description="Use specular lighting as well as diffuse lighting. A gloss map " - "In the diffuse map's and normal map's alpha channel can be used " + "in the diffuse map's and normal map's alpha channel can be used " "to attenuate the specular lighting's strength. (More transparent = less strong).\n\n" - - "Be warned due to the way SWBFII handles specular lighting this " - "adds an extra draw call for each segment using the material.", + "The Specular Colour controls the colour of the reflected specular highlights, " + "like the diffuse map but for specular lighting and global across the material.", default=False) doublesided: BoolProperty(name="Doublesided", - description="Disable backface culling, " - "causing both sides of the material to be rasterized.", + description="Disable backface culling, causing both sides of the surface to be drawn. " + "Usually only the front facing surface is drawn.", default=False) detail_map_tiling_u: IntProperty(name="Detail Map Tiling U", @@ -205,41 +198,41 @@ class MaterialPropertiesPanel(bpy.types.Panel): layout.prop(material_props, "rendertype") layout.prop(material_props, "specular_color") - layout.label(text="Transparency Flags: ") - row = layout.row() - row.prop(material_props, "blended_transparency") - row.prop(material_props, "additive_transparency") - row.prop(material_props, "hardedged_transparency") - - layout.label(text="Material Flags: ") - row = layout.row() - row.prop(material_props, "unlit") - row.prop(material_props, "glow") - row = layout.row() - row.prop(material_props, "perpixel") - row.prop(material_props, "specular") - layout.prop(material_props, "doublesided") - if "REFRACTION" not in material_props.rendertype: + layout.label(text="Transparency Flags: ") + row = layout.row() + row.prop(material_props, "blended_transparency") + row.prop(material_props, "additive_transparency") + row.prop(material_props, "hardedged_transparency") + + layout.label(text="Material Flags: ") + row = layout.row() + row.prop(material_props, "unlit") + row.prop(material_props, "glow") + row = layout.row() + row.prop(material_props, "perpixel") + row.prop(material_props, "specular") + layout.prop(material_props, "doublesided") + layout.label(text="Material Data: ") row = layout.row() - if "SCROLLING" in material_props.rendertype: - row.prop(material_props, "scroll_speed_u") - row.prop(material_props, "scroll_speed_v") - elif "ANIMATED" in material_props.rendertype: - row.prop(material_props, "animation_length") - row = layout.row() - row.prop(material_props, "animation_speed") - elif "BLINK" in material_props.rendertype: - row.prop(material_props, "blink_min_brightness") - row.prop(material_props, "blink_speed") - elif "NORMALMAPPED_TILED" in material_props.rendertype: - row.prop(material_props, "normal_map_tiling_u") - row.prop(material_props, "normal_map_tiling_v") - elif "REFRACTION" not in material_props.rendertype: - row.prop(material_props, "detail_map_tiling_u") - row.prop(material_props, "detail_map_tiling_v") + if "SCROLLING" in material_props.rendertype: + row.prop(material_props, "scroll_speed_u") + row.prop(material_props, "scroll_speed_v") + elif "ANIMATED" in material_props.rendertype: + row.prop(material_props, "animation_length") + row = layout.row() + row.prop(material_props, "animation_speed") + elif "BLINK" in material_props.rendertype: + row.prop(material_props, "blink_min_brightness") + row.prop(material_props, "blink_speed") + elif "NORMALMAPPED_TILED" in material_props.rendertype: + row.prop(material_props, "normal_map_tiling_u") + row.prop(material_props, "normal_map_tiling_v") + else: + row.prop(material_props, "detail_map_tiling_u") + row.prop(material_props, "detail_map_tiling_v") layout.label(text="Texture Maps: ") layout.prop(material_props, "diffuse_map") diff --git a/addons/io_scene_swbf_msh/msh_material_ui_strings.py b/addons/io_scene_swbf_msh/msh_material_ui_strings.py new file mode 100644 index 0000000..2dd115d --- /dev/null +++ b/addons/io_scene_swbf_msh/msh_material_ui_strings.py @@ -0,0 +1,106 @@ +""" UI strings that are too long to have in msh_materials_properties.py """ + +UI_RENDERTYPE_DETAIL_MAP_DESC = \ + "Can optionally have a Detail Map." + +UI_RENDERTYPE_DETAIL_MAP_TILING_DESC = \ + "Tiling for the detail map can specified " \ + "with Detail Map Tiling U and Detail Map Tiling V." + +UI_RENDERTYPE_ENV_MAP_DESC = \ + "Uses an Environment Map to show reflections on the model. " \ + "Useful for anything you want to look reflective or metallic." \ + "\n\n" \ + "The reflections from the Environment Map are affected by " \ + "Specular Colour. And if Specular Material Flag is checked then " \ + "reflections will be affected by the Gloss Map." + +UI_RENDERTYPE_NORMAL_MAP_DESC = \ + "Enables the use of a Normal Map with the material." + +UI_RENDERTYPE_NORMAL_MAP_TILING_DESC = \ + "Tiling for the normal map can be controlled with Normal Map " \ + "Tiling U and Normal Map Tiling V." + +UI_RENDERTYPE_NORMAL_PER_PIXEL_DESC = \ + "This rendertype also enables per-pixel lighting." + +UI_RENDERTYPE_NORMAL_BF2_DESC = f"""\ +Basic material. + +{UI_RENDERTYPE_DETAIL_MAP_DESC} {UI_RENDERTYPE_DETAIL_MAP_TILING_DESC} +""" + +UI_RENDERTYPE_SCROLLING_BF2_DESC = f"""\ +Like Normal except the textures have scrolling. Useful for water, monitors with scrolling content, interlaced holograms, etc. + +Scroll speed and direction is specified with Scroll Speed U and Scroll Speed V. + +{UI_RENDERTYPE_DETAIL_MAP_DESC} The Detail Map will not be affected by scrolling. +""" + +UI_RENDERTYPE_ENVMAPPED_BF2_DESC = f"""\ +{UI_RENDERTYPE_ENV_MAP_DESC} + +{UI_RENDERTYPE_DETAIL_MAP_DESC} {UI_RENDERTYPE_DETAIL_MAP_TILING_DESC} +""" + +UI_RENDERTYPE_ANIMATED_BF2_DESC = f"""\ +Use an animated texture. The animation's frames should be packed into NxN squares where N is the square root of the number of frames in the animation. So a 25 frame animation should be packed into 5x5 squares in the Diffuse Map. + +Set frame count with Animation Length and frame rate with Animation Speed. + +{UI_RENDERTYPE_DETAIL_MAP_DESC} The Detail Map will not be subject to animation. +""" + +UI_RENDERTYPE_REFRACTION_BF2_DESC = f"""\ +Distorts/refracts the scene behind the material. + +The Diffuse Map's alpha channel controls the visibility of the scene while the Distortion Map controls the distortion. + +When distortion is not needed but transparency is the Normal rendertype should be used as this one comes at a performance cost. +""" + +UI_RENDERTYPE_BLINK_BF2_DESC = f"""\ +Oscillates the diffuse strength of the material between full strength and a supplied strength. + +Blink Minimum Brightness sets the strength of the material's diffuse at the bottom of the "blink". Blink Speed sets the speed of the blinking. + +{UI_RENDERTYPE_DETAIL_MAP_DESC} +""" + +UI_RENDERTYPE_NORMALMAPPED_BF2_DESC = f"""\ +{UI_RENDERTYPE_NORMAL_MAP_DESC} + +{UI_RENDERTYPE_DETAIL_MAP_DESC} {UI_RENDERTYPE_DETAIL_MAP_TILING_DESC} + +{UI_RENDERTYPE_NORMAL_PER_PIXEL_DESC} +""" + +UI_RENDERTYPE_NORMALMAPPED_TILED_BF2_DESC = f"""\ +{UI_RENDERTYPE_NORMAL_MAP_DESC} {UI_RENDERTYPE_NORMAL_MAP_TILING_DESC} + +{UI_RENDERTYPE_DETAIL_MAP_DESC} + +{UI_RENDERTYPE_NORMAL_PER_PIXEL_DESC} +""" + +UI_RENDERTYPE_NORMALMAPPED_ENVMAPPED_BF2_DESC = f"""\ +{UI_RENDERTYPE_NORMAL_MAP_DESC} + +{UI_RENDERTYPE_ENV_MAP_DESC} + +{UI_RENDERTYPE_DETAIL_MAP_DESC} {UI_RENDERTYPE_DETAIL_MAP_TILING_DESC} + +{UI_RENDERTYPE_NORMAL_PER_PIXEL_DESC} +""" + +UI_RENDERTYPE_NORMALMAPPED_TILED_ENVMAPPED_BF2_DESC = f"""\ +{UI_RENDERTYPE_NORMAL_MAP_DESC} {UI_RENDERTYPE_NORMAL_MAP_TILING_DESC} + +{UI_RENDERTYPE_ENV_MAP_DESC} + +{UI_RENDERTYPE_DETAIL_MAP_DESC} + +{UI_RENDERTYPE_NORMAL_PER_PIXEL_DESC} +""" \ No newline at end of file diff --git a/docs/images/materials.png b/docs/images/materials.png new file mode 100644 index 0000000..dbb00c1 Binary files /dev/null and b/docs/images/materials.png differ diff --git a/docs/reference_manual.md b/docs/reference_manual.md new file mode 100644 index 0000000..cfa2f09 --- /dev/null +++ b/docs/reference_manual.md @@ -0,0 +1,156 @@ +## Collision Primitives +Collision primitives are the game's (according to the docs) lightweight method of adding collision to an +object and are preferred to collision meshes where reasonable. + +> TODO: Finish writing this section. + +## Materials +Since Blender's sophisticated materials are a poor fit for what .msh files can represent the addon defines +custom properties for representing .msh materials. It then exposes these through a UI panel under Blender's +Material context. + +![.msh Material Panel](images/materials.png) + +> TODO: Explain why some .msh rendertypes were left out of the addon. (The short answer is they're either redundant or outright unused.) +> TODO: Document what rendertypes/flags are multipass and cause the model to be drawn more than once. And explain the implications of that. + +### Materials.Rendertype +Rendertypes in .msh materials confer unique information about how the material. Such as +if the materials textures scroll or if the material has an environment map. + +> One could argue that "rendertype" should be stylized as "render type". I thought about that and decided I'd rather spend time writing the addon than thinking about that. + +#### Materials.Rendertype.Normal (SWBF2) +Basic material. + +Can optionally have a Detail Map. Tiling for the detail map can specified with Detail Map Tiling U and Detail Map Tiling V. + +#### Materials.Rendertype.Scrolling (SWBF2) +Like Normal except the textures have scrolling. Useful for water, monitors with scrolling content, interlaced holograms, etc. + +Scroll speed and direction is specified with Scroll Speed U and Scroll Speed V. + +Can optionally have a Detail Map. The Detail Map will not be affected by scrolling. + +#### Materials.Rendertype.Envmapped (SWBF2) +Uses an Environment Map to show reflections on the model. Useful for anything you want to look reflective or +metallic. + +The reflections from the Environment Map are affected by Specular Colour. And if Specular Material Flag is checked then reflections will be affected by the Gloss Map. + +Can optionally have a Detail Map. Tiling for the detail map can specified with Detail Map Tiling U and Detail Map Tiling V. + +#### Materials.Rendertype.Animated (SWBF2) +Use an animated texture. The animation's frames should be packed into NxN squares where N is the square root of the number of frames in the animation. So a 25 frame animation should be packed into 5x5 squares in the Diffuse Map. + +Set frame count with Animation Length and frame rate with Animation Speed. + +Can optionally have a Detail Map. The Detail Map will not be subject to animation. + +#### Materials.Rendertype.Refraction (SWBF2) +Distorts/refracts the scene behind the material. + +The Diffuse Map's alpha channel controls the visibility of the scene while the Distortion Map controls the distortion. + +When distortion is not needed but transparency is the Normal rendertype should be used as this one comes at a performance cost. + +The Material Flags are not exposed by the addon for this rendertype as most are unsupported by it. The Blended Transparency flag is supported and **required** but is set automatically by the addon. + +#### Materials.Rendertype.Blink (SWBF2) +Oscillates the diffuse strength of the material between full strength and a supplied strength. + +Blink Minimum Brightness sets the strength of the material's diffuse at the bottom of the "blink". Blink Speed sets the speed of the blinking. + +Can optionally have a Detail Map. + +#### Materials.Rendertype.Normalmapped (SWBF2) +Enables the use of a Normal Map with the material. + +Can optionally have a Detail Map. Tiling for the detail map can specified with Detail Map Tiling U and Detail Map Tiling V. + +This rendertype also enables per-pixel lighting. + +#### Materials.Rendertype.Normalmapped Tiled (SWBF2) +Enables the use of a Normal Map with the material. Tiling for the normal map can be controlled with Normal Map Tiling U and Normal Map Tiling V. + +Can optionally have a Detail Map. + +This rendertype also enables per-pixel lighting. + +#### Materials.Rendertype.Normalmapped Envmapped (SWBF2) +Enables the use of a Normal Map with the material. + +Uses an Environment Map to show reflections on the model. Useful for anything you want to look reflective or +metallic. + +The reflections from the Environment Map are affected by Specular Colour. And if Specular Material Flag is checked then reflections will be affected by the Gloss Map. + +Can optionally have a Detail Map. Tiling for the detail map can specified with Detail Map Tiling U and Detail Map Tiling V. + +This rendertype also enables per-pixel lighting. + +#### Materials.Rendertype.Normalmapped Envmapped (SWBF2) +Enables the use of a Normal Map with the material. Tiling for the normal map can be controlled with Normal Map Tiling U and Normal Map Tiling V + +Uses an Environment Map to show reflections on the model. Useful for anything you want to look reflective or +metallic. + +The reflections from the Environment Map are affected by Specular Colour. And if Specular Material Flag is checked then reflections will be affected by the Gloss Map. + +Can optionally have a Detail Map. + +This rendertype also enables per-pixel lighting. + +### Materials.Transparency Flags + +> TODO: Improve this section. + +#### Materials.Transparency Flags.Blended +Regular alpha blended transparency. + +#### Materials.Transparency Flags.Additive +Additive transparency, objects behind the material will appear brighter because the material will be "added" on top of the scene. + +> TODO: Explain the difference between Blended + Additive vs just Additive + +#### Materials.Transparency Flags.Hardedged +Hardedged/alpha cutout/clip transparency. Any point on the material with an alpha value below the threshold of 0.5/0x80/128 will be discarded. Useful for leaves, flowers, wire fences and all sorts. + +### Materials.Flags + +#### Materials.Flags.Unlit +Makes the material unlit/emissive. Useful for anything that is meant to be giving light but not reflecting any/much. + +#### Materials.Flags.Glow +Same as 'Unlit' but also enables the use of a Glow Map in the diffuse texture's alpha channel. The material will be significantly significantly brightened based on how opaque the glowmap is. + +#### Materials.Flags.Per-Pixel Lighting +Calculate lighting per-pixel instead of per-vertex for diffuse lighting. + +#### Materials.Flags.Specular Lighting +Use specular lighting as well as diffuse lighting. A Gloss Map in the diffuse map's and normal map's alpha channel can be used to attenuate the specular lighting's strength. (More transparent = less strong). + +The Specular Colour controls the colour of the reflected specular highlights, like the diffuse map but for specular lighting and global across the material. + +#### Materials.Flags.Doublesided +Disable backface culling, causing both sides of the surface to be drawn. Usually only the front facing surface is drawn. + +### Materials.Data +> TODO: Write this section + +### Materials.Texture Maps +> TODO: Write this section + +### Materials.Rendertypes Table +| Rendertype | `ATRB` Data0 | `ATRB` Data1 | `ATRB` Number | `ATRB` Number Hex | +| ------------------------------------ |:------------------------:|:-------------------:|:-------------:| -----------------:| +| Normal (SWBF2) | Detail Map Tiling U | Detail Map Tiling V | 00 | 00 | +| Scrolling (SWBF2) | Scroll Speed U | Scroll Speed V | 03 | 03 | +| Envmapped (SWBF2) | Detail Map Tiling U | Detail Map Tiling V | 06 | 06 | +| Animated (SWBF2) | Animation Length | Animation Speed | 07 | 07 | +| Refractive (SWBF2) | Detail Map Tiling U | Detail Map Tiling V | 22 | 16 | +| Normalmapped Tiled (SWBF2) | Normal Map Tiling U | Normal Map Tiling V | 24 | 18 | +| Blink (SWBF2) | Blink Minimum Brightness | Blink Speed | 25 | 19 | +| Normalmapped Envmapped (SWBF2) | Detail Map Tiling U | Detail Map Tiling V | 26 | 1A | +| Normalmapped (SWBF2) | Detail Map Tiling U | Detail Map Tiling V | 27 | 1B | +| Normalmapped Tiled Envmapped (SWBF2) | Normal Map Tiling U | Normal Map Tiling V | 29 | 1D |