Skip to content

Commit

Permalink
Merge pull request #461 from niftools/release/v0.0.9
Browse files Browse the repository at this point in the history
Release/v0.0.9
  • Loading branch information
neomonkeus authored Sep 25, 2021
2 parents 44770d3 + f60dc96 commit 89cfac0
Show file tree
Hide file tree
Showing 20 changed files with 408 additions and 179 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@ Version v0.0.9
==============

- #446 Updates to normal and tangent import/export
Export of normals now respects edges that are marked sharp.
Vertices with different UV coordinates get different tangents on export.
Export now uses Blender tangents instead of pyffi tangent generation.
Nif vertex normals are now imported correctly when dealing with non-normalized normals (i.e. not length 1).
When exporting a skinned mesh that uses partitions, that has faces without partitions, the correct faces are now selected.
The normal map Y channel is now inverted when creating a shader on import.
The selection for collision layer now depends on the game.
A NONE game as the default in the scene tab.
Unresolved texture paths are now stored as they are found in the nif file, meaning they remain functional upon re-export.
Body parts use face maps rather than vertex groups.

- #444 Some polygons of "...." not assigned to any body part.The unassigned polygons have been selected in the mesh so they can easily be identified.
- #449 Error while export, Game not set

Expand Down
2 changes: 1 addition & 1 deletion docs/development/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Contents:
User Interface
--------------

* The user first activates the addon via **File** > **User Preferences** > **Addons**.
* The user first activates the addon via **Edit** > **Preferences** > **Addons**.

.. note::

Expand Down
52 changes: 52 additions & 0 deletions docs/development/design/decisions.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
.. _development-design-decisions:

################
Design Decisions
################

.. _development-design-decisions-geometrydata:

*************
Geometry Data
*************

.. _development-design-decisions-geometrydata-tangents:

Tangents
========

Tangents and bitangents are exported from Blender's tangents. This has two caveats:
* These are not the exact same as those of vanilla (Skyrim) assets.
* These tangents will only work completely correctly with normal maps that were generated with those tangents.
The first point is because we do not yet know by which method the vanilla tangents were generated. It is possible
that the generation method differs per model, and that there is no method which matches all vanilla models.

The second point is true for all tangent space normal maps. For more information on normal maps, see
`http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Tangent_Basis the polycount page`_. For information on how
the tangents get used in calculating surface direction, see
`http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-13-normal-mapping/ the OpenGL tutorial`_. The main
characteristics that need to be the same between the renderer (the game) and the normal map baking software are:
* The tangent direction
* Whether the bitangent is calculated per-vertex or per-pixel (see
`https://bgolus.medium.com/generating-perfect-normal-maps-for-unity-f929e673fc57#c473 this page`_).
Making sure that the tangent space is the same for the baker as it is in the nif is done by exporting a common
tangent space. The tangents from Blender are from `http://www.mikktspace.com/ MikkTSpace`_. This standard tangent space
is also an option in xNormal and Substance.

Because the bitangents are stored in the nif file, it can be assumed that they are not per-pixel in-game. Whether the
bitangent is calculated per-vertex or per-pixel is an option in xNormal and Substance. Blender calculates its bitangent
for baking per-pixel, which means that normal maps baked in Blender will not correctly display in-game, though the
difference may be minimal enough not to notice.

Blender tangent and bitangent to nif tangent and bitangent is not 1:1. In Blender, the tangent points in the positive U
direction and the bitangent points in positive V direction (Blender texture coordinates). In nifs, tangents point in
the positive V direction and bitangents point in the positive U direction (nif texture coordinates). Therefore, tangents
and bitangents are swapped between Blender and nif. However, because the nif V coordinate can be calculated from the
Blender V coordinate via::

nif_V = 1 - blender_V

This means that the direction for positive V coordinate is reversed. This results in the conversion as follows.::

nif_tangent = blender_bitangent
nif_bitangent = blender_tangent
3 changes: 2 additions & 1 deletion docs/user/features/armature/armature.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ Armatures
Armature Bones
==============

* The following section deals with Armatures
* The following section deals with Armatures. Note that, in order for any animations to display in Blender like they
would in-game, ``Preserve Volume`` must be turned off in the Armature modifier.

.. _armature-flags:

Expand Down
9 changes: 5 additions & 4 deletions docs/user/features/geometry/geometry.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Double Sided Mesh

- Adds a :class:`~pyffi.formats.nif.NifFormat.NiStencilProperty` or similiar, see :ref:`Properties - Stencil Property
<properties-stencil>` for more info.
- For Skyrim, tick the Shader Property flag "Double Sided" in the Niftools Shader Panel.

.. _geometry-uv:

Expand Down Expand Up @@ -82,14 +83,14 @@ Vertex Color & Alpha
**Example:**

#. :ref:`Create a mesh-object <geometry-mesh>`.
#. Switch to Vertex Paint mode, this automatically adds a base vertex colour layer. Make sure you name this layer 'RGBA'
#. Apply the desired vertex colours evenly to the vertex.
#. Switch to Vertex Paint mode, this automatically adds a base vertex color layer. Make sure you name this layer 'RGBA'
#. Apply the desired vertex colors evenly to the vertex.
#. You can alter the alpha channel using the 'Add Alpha' and 'Erase Alpha' brushes.

**Notes:**

* The Nif format only supports a single colour per vertex, whereas Blender vertex colour per face vertex.
* The Nif format only supports a single color per vertex, whereas Blender vertex color per face vertex.
* Blender treats the vertex as if the faces had been split apart, each face can have a different colour for that vertex.
* `This image should clarify per-face vertex colouring
<http://i211.photobucket.com/albums/bb189/NifTools/Blender/documentation/per_face_vertex_color.jpg>`_
* On export, the scripts will take an average of colours.
* On export, the scripts will create extra vertices for different vertex colors per face.
90 changes: 55 additions & 35 deletions docs/user/features/iosettings/export.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.. _user-features-iosettings-export:
Export Settings
===============
.. _user-features-iosettings-export:

This section explains the import and export settings.

Expand All @@ -9,26 +9,55 @@ This section explains the import and export settings.
This is due to the fact that they are ported directly from the old addon and as such, will functionally remain the
same.

.. _user-features-iosettings-export-scale:
Scale correction
----------------
.. _user-features-iosettings-export-scale:

This value is used to globally re-scale the Blender system of measurement units to the Nif Format units.

* The ratio of a Nif Units (NU) to Blender Units (BU) is 1Bu:0.1Nu. or each NU is about 10x larger than a BU.
* The Blender Niftools Addon applies a default correction of 10
* The default setting ensures the imported model fits into the view Blender viewport.

.. _user-features-iosettings-export-armature:
Armature
--------

.. _user-features-iosettings-export-flattenskin:
Flatten Skin
^^^^^^^^^^^^

This option should remove the hierarchy of the bones in the exported nif. However, it is currently not used in export.
In order to flatten the hierarchy before export with Blender: Select the bones in object mode, then go into edit mode
and use ``Alt+P`` to unparent the bones with the``Clear Parent`` option.

.. _iosettings-padnsort:
Pad & Sort Bones
^^^^^^^^^^^^^^^^

Adjusts the number of bones in a given partition to match the total number of bones used for the dismember instance.

.. _iosettings-maxpartitionbones:
Max Partition Bones
^^^^^^^^^^^^^^^^^^^

The maximum number of bones that a single dismember partition can use before starting a new partition.

.. _iosettings-maxvertexbones:
Max Vertex Bones
^^^^^^^^^^^^^^^^

The maximum number of bone weight values that can be applied to a single vertex.

.. _user-features-iosettings-export-game:
Game
----
.. _user-features-iosettings-export-game:

A list of supported games which the addon will export working nif files.

Process
.. _user-features-iosettings-export-animation:
Animation
-------
.. _user-features-iosettings-export-process:

Determines how to export the data in the blend file.

Expand All @@ -38,46 +67,37 @@ Export options include
* Geometry only (nif) - Only geometry to a single nif.
* Animation only (kf) - Only animation to a single kf.

Smooth Inter-Object Seams
-------------------------
.. _user-features-iosettings-export-smoothseams:

This option combines the normals data for all vertices containing the same XYZ location data along an edge and uses
the same normal tangent and bi-tangent values for all affected vertices.

Use NiBSAnimationNode
---------------------
.. _iosettings-bsanimationnode:
Use NiBSAnimationNode
^^^^^^^^^^^^^^^^^^^^^

NiBSAnimationNode is specific to "The Elder Scrolls - Morrowind" and should only be used when exporting animated
items for that game.

Flatten Skin
------------
.. _user-features-iosettings-export-flattenskin:

This option does something to the thing, no really it does, but I can't tell you because it's a sekret.

Pad & Sort Bones
----------------
.. _iosettings-padnsort:

Adjusts the number of bones in a given partition to match the total number of bones used for the dismember instance.
.. _user-features-io_settings-export-optimise:
Optimise
--------

Max Partition Bones
-------------------
.. _iosettings-maxpartitionbones:
.. _user-features-io_settings-export-stripifygeometries:
Stripify Geometries
^^^^^^^^^^^^^^^^^^^

The maximum number of bones that a single dismember partition can use before starting a new partition.
Export with NiTriStrips instead of NiTriShapes.

Max Vertex Bones
----------------
.. _iosettings-maxvertexbones:
.. _user-features-iosettings-export-stitchstrips:
Stitch Strips
^^^^^^^^^^^^^

The maximum number of bone weight values that can be applied to a single vertex.
Whether to stitch NiTriStrips (if they are used). Important for Civilization IV.

Force DDS
---------
.. _user-features-iosettings-export-forcedds:
Force DDS
^^^^^^^^^

Changes the suffix for the texture file path in the nif to use .dds

.. _user-features-io_settings-export-optimisematerials:
Optimise Materials
^^^^^^^^^^^^^^^^^^

Remove duplicate materials. Currently not used.
3 changes: 2 additions & 1 deletion docs/user/features/properties/shader/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,8 @@ BS Effect Shader Property

.. Describe this type
Skyrim non-PP shader model, used primarily for transparency effects, often as a decal.
Skyrim non-PP shader model, used primarily for transparency effects, often as a decal. Has the same shader flags as
BSLightingShaderProperty.

+-------------------------------+---------------------------------------------------------------+
| Property | Description |
Expand Down
3 changes: 3 additions & 0 deletions io_scene_niftools/kf_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ def execute(self):
directory = os.path.dirname(NifOp.props.filepath)
filebase, fileext = os.path.splitext(os.path.basename(NifOp.props.filepath))

if bpy.context.scene.niftools_scene.game == 'NONE':
raise NifError("You have not selected a game. Please select a game in the scene tab.")

prefix = "x" if bpy.context.scene.niftools_scene.game in ('MORROWIND',) else ""
self.version, data = scene.get_version_data()
# todo[anim] - change to KfData, but create_controller() [and maybe more] has to be updated first
Expand Down
10 changes: 5 additions & 5 deletions io_scene_niftools/modules/nif_export/collision/havok.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def export_collision_helper(self, b_obj, parent_block):

# linear_velocity = b_obj.rigid_body.deactivate_linear_velocity
# angular_velocity = b_obj.rigid_body.deactivate_angular_velocity
layer = b_obj.nifcollision.oblivion_layer
layer = int(b_obj.nifcollision.collision_layer)

# TODO [object][collision][flags] export bsxFlags
# self.export_bsx_upb_flags(b_obj, parent_block)
Expand All @@ -100,7 +100,7 @@ def export_collision_helper(self, b_obj, parent_block):
# bhkCollisionObject -> bhkRigidBody
if not parent_block.collision_object:
# note: collision settings are taken from lowerclasschair01.nif
if layer == "OL_BIPED":
if layer == NifFormat.OblivionLayer.OL_BIPED:
# special collision object for creatures
n_col_obj = self.export_bhk_blend_collision(b_obj)

Expand Down Expand Up @@ -135,7 +135,7 @@ def export_bhk_rigid_body(self, b_obj, n_col_obj):

n_r_body = block_store.create_block("bhkRigidBody", b_obj)
n_col_obj.body = n_r_body
n_r_body.layer = getattr(NifFormat.OblivionLayer, b_obj.nifcollision.oblivion_layer)
n_r_body.layer = int(b_obj.nifcollision.collision_layer)
n_r_body.col_filter = b_obj.nifcollision.col_filter
n_r_body.unknown_short = 0
n_r_body.unknown_int_1 = 0
Expand Down Expand Up @@ -185,11 +185,11 @@ def export_bhk_rigid_body(self, b_obj, n_col_obj):
return n_r_body

def export_bhk_collison_object(self, b_obj):
layer = b_obj.nifcollision.oblivion_layer
layer = int(b_obj.nifcollision.collision_layer)
col_filter = b_obj.nifcollision.col_filter

n_col_obj = block_store.create_block("bhkCollisionObject", b_obj)
if layer == "OL_ANIM_STATIC" and col_filter != 128:
if layer == NifFormat.OblivionLayer.OL_ANIM_STATIC and col_filter != 128:
# animated collision requires flags = 41
# unless it is a constrainted but not keyframed object
n_col_obj.flags = 41
Expand Down
Loading

0 comments on commit 89cfac0

Please sign in to comment.