Skip to content

Commit 0305c8d

Browse files
authored
Merge pull request #615 from niftools/develop
Develop to master
2 parents c649495 + 33cff83 commit 0305c8d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+714
-413
lines changed

CHANGELOG.rst

+27-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,30 @@
1-
Version v0.1.00
1+
Version v0.1.1
2+
===============
3+
4+
- #591 Expansion of DisplayList processing and small fixes.
5+
- Rigged meshes with DisplayLists will now have functional weights.
6+
- 4-component normals are now handled correctly for DisplayLists.
7+
- Added multiple UV layer support for DisplayLists.
8+
- Rudimentary support for Fallout NV (Fallout New Vegas) by treating it the same as Fallout 3.
9+
- Fixes #582
10+
- Fixes #589
11+
- Fix for animation support for Shin Megami Tensei: Imagine.
12+
- Fixes #584
13+
- Fixes #554 and overhauls/isolates the way the nif geometry data is obtained during export.
14+
- Added option for splitting on tangents (did not happen before). Needs to be disabled for Oblivion head meshes.
15+
- Warn rather than silent fail during egm import.
16+
- Export: Move UV coordinates that are completely in another UV tile to the 0-1 tile.
17+
- Added support for weighted Fallout 4 meshes, fixing #598
18+
- Fixes #599
19+
- Fixes #600
20+
- Add exported tangents to Bully SE.
21+
- Always return copy for get_object_bind to prevent accidental modification.
22+
- Added support for basic (unweighted) Skyrim SE export.
23+
- Change generated module name from generated to nifgen to prevent collision with cobra-tools.
24+
- #592 Update to documentation
25+
- #593 Supported export for Sid Meier's Pirates!.
26+
27+
Version v0.1.0
228
===============
329

430
- #576 Updates to documentation, changelog and makezip.bat (copies over generated folder from cobra-tools).

install/install.bat

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ for %%I in ("%DIR%\..") do set "ROOT=%%~fI"
99
set "NAME=blender_niftools_addon"
1010
set /p VERSION=<%ROOT%\io_scene_niftools\VERSION.txt
1111
for /f %%i in ('git rev-parse --short HEAD') do set HASH=%%i
12-
for /f %%i in ('echo %date%') do set DATE=%%i
12+
:: Use PowerShell to get current date in YYYY-MM-DD format independent of local format
13+
for /f %%i in ('powershell -executionpolicy bypass -Command Get-Date -Format "yyyy-MM-dd"') do set DATE=%%i
1314
set "ZIP_NAME=%NAME%-%VERSION%-%DATE%-%HASH%"
1415

1516
if "%BLENDER_ADDONS_DIR%" == "" if not exist "%BLENDER_ADDONS_DIR%" (

install/makezip.bat

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ mkdir "%DEPS%"
2626

2727
python -m pip install "PyFFI==%PYFFI_VERSION%" --target="%DEPS%"
2828

29-
xcopy "%GENERATED_FOLDER%" "%DEPS%\generated" /s /q /i
29+
xcopy "%GENERATED_FOLDER%" "%DEPS%\nifgen" /s /q /i
3030

3131
xcopy "%ROOT%"\AUTHORS.rst io_scene_niftools
3232
xcopy "%ROOT%"\CHANGELOG.rst io_scene_niftools

install/makezip.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ echo "Creating dependencies folder ${DEPS_OUT:-${BUILD_DIR}/dependencies}"
3434
python -m pip install "PyFFI==${PYFFI_VERSION}" --target="${DEPS_OUT:-${BUILD_DIR}/dependencies}"
3535

3636
echo "Copying loose files"
37-
cp -r "$GENERATED_FOLDER" "${DEPS_OUT:-${BUILD_DIR}/dependencies}/generated"
37+
cp -r "$GENERATED_FOLDER" "${DEPS_OUT:-${BUILD_DIR}/dependencies}/nifgen"
3838
cp "${ROOT}"/AUTHORS.rst "${ADDON_OUT}"
3939
cp "${ROOT}"/CHANGELOG.rst "${ADDON_OUT}"
4040
cp "${ROOT}"/LICENSE.rst "${ADDON_OUT}"

install/zip.ps1

+14-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,20 @@ write ("Existing archive removed successfully")
1313
}
1414

1515
Add-Type -assembly "system.io.compression.filesystem"
16-
[io.compression.zipfile]::CreateFromDirectory($source, $destination, 1, 1)
16+
17+
$EncoderClass=@"
18+
public class FixedEncoder : System.Text.UTF8Encoding {
19+
public FixedEncoder() : base(true) { }
20+
public override byte[] GetBytes(string s) {
21+
s = s.Replace("\\", "/");
22+
return base.GetBytes(s);
23+
}
24+
}
25+
"@
26+
Add-Type -TypeDefinition $EncoderClass
27+
28+
$Encoder = New-Object FixedEncoder
29+
[io.compression.zipfile]::CreateFromDirectory($source, $destination, 1, 1, $Encoder)
1730
If(Test-path $destination) {
1831
write("File successully written")
1932
}

io_scene_niftools/VERSION.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v0.1.0
1+
v0.1.1

io_scene_niftools/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"description": "Import and export files in the NetImmerse/Gamebryo formats (.nif, .kf, .egm)",
5050
"author": "Niftools team",
5151
"blender": (2, 82, 0),
52-
"version": (0, 1, 0), # can't read from VERSION, blender wants it hardcoded
52+
"version": (0, 1, 1), # can't read from VERSION, blender wants it hardcoded
5353
"api": 39257,
5454
"location": "File > Import-Export",
5555
"warning": "Generally stable port of the Niftool's Blender NifScripts, many improvements, still work in progress",
@@ -72,7 +72,7 @@ def locate_dependencies():
7272

7373
with open(os.path.join(current_dir, "VERSION.txt")) as version:
7474
NifLog.info(f"Loading: Blender Niftools Addon: {version.read()}")
75-
import generated.formats.nif as NifFormat
75+
import nifgen.formats.nif as NifFormat
7676
NifLog.info(f"Loading: NifFormat: {NifFormat.__xml_version__}") # todo [generated] update this and library to have actual versioning
7777

7878

io_scene_niftools/egm_import.py

+2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ def execute(self):
6969
b_obj = bpy.context.view_layer.objects.active
7070
if b_obj and b_obj.type == "MESH":
7171
self.morph_anim.import_egm_morphs(b_obj)
72+
else:
73+
NifLog.warn(f'Selected object {b_obj.name} is not a mesh object, nothing will be imported.')
7274
except NifError:
7375
return {'CANCELLED'}
7476

io_scene_niftools/file_io/nif.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939

4040
import os.path as path
4141

42-
import generated.formats.nif as NifFormat
42+
import nifgen.formats.nif as NifFormat
4343

4444
from io_scene_niftools.utils.logging import NifLog, NifError
4545

io_scene_niftools/kf_export.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def execute(self):
8989
data.neosteam = (bpy.context.scene.niftools_scene.game == 'NEOSTEAM')
9090

9191
# scale correction for the skeleton
92-
self.apply_scale(data, round(1 / NifOp.props.scale_correction))
92+
self.apply_scale(data, 1 / NifOp.props.scale_correction)
9393

9494
data.validate()
9595

io_scene_niftools/modules/nif_export/animation/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
from abc import ABC
4040

4141
import bpy
42-
from generated.formats.nif import classes as NifClasses
42+
from nifgen.formats.nif import classes as NifClasses
4343

4444
from io_scene_niftools.modules.nif_export.block_registry import block_store
4545
from io_scene_niftools.utils.singleton import NifOp, NifData

io_scene_niftools/modules/nif_export/animation/material.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
#
3838
# ***** END LICENSE BLOCK *****
3939

40-
from generated.formats.nif import classes as NifClasses
40+
from nifgen.formats.nif import classes as NifClasses
4141

4242
from io_scene_niftools.modules.nif_export.animation import Animation
4343
from io_scene_niftools.modules.nif_export.block_registry import block_store

io_scene_niftools/modules/nif_export/animation/morph.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
#
3838
# ***** END LICENSE BLOCK *****
3939

40-
from generated.formats.nif import classes as NifClasses
40+
from nifgen.formats.nif import classes as NifClasses
4141
from pyffi.formats.egm import EgmFormat
4242

4343
from io_scene_niftools.modules.nif_export.animation import Animation

io_scene_niftools/modules/nif_export/animation/object.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
# ***** END LICENSE BLOCK *****
3939

4040
import bpy
41-
from generated.formats.nif import classes as NifClasses
41+
from nifgen.formats.nif import classes as NifClasses
4242

4343
from io_scene_niftools.modules.nif_export.animation import Animation
4444
from io_scene_niftools.modules.nif_export.block_registry import block_store

io_scene_niftools/modules/nif_export/animation/transform.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
import bpy
4141
import mathutils
4242

43-
from generated.formats.nif import classes as NifClasses
43+
from nifgen.formats.nif import classes as NifClasses
4444

4545
from io_scene_niftools.modules.nif_export.animation import Animation
4646
from io_scene_niftools.modules.nif_export.block_registry import block_store
@@ -69,12 +69,13 @@ def iter_frame_key(fcurves, mathutilclass):
6969
def export_kf_root(self, b_armature=None):
7070
"""Creates and returns a KF root block and exports controllers for objects and bones"""
7171
scene = bpy.context.scene
72-
game = scene.niftools_scene.game
72+
nif_scene = scene.niftools_scene
73+
game = nif_scene.game
7374
if game in ('MORROWIND', 'FREEDOM_FORCE'):
7475
kf_root = block_store.create_block("NiSequenceStreamHelper")
75-
elif game in (
76-
'SKYRIM', 'OBLIVION', 'FALLOUT_3', 'CIVILIZATION_IV', 'ZOO_TYCOON_2', 'FREEDOM_FORCE_VS_THE_3RD_REICH',
77-
'MEGAMI_TENSEI_IMAGINE', 'SID_MEIER_S_PIRATES'):
76+
elif nif_scene.is_bs() or game in (
77+
'CIVILIZATION_IV', 'ZOO_TYCOON_2', 'FREEDOM_FORCE_VS_THE_3RD_REICH',
78+
'SHIN_MEGAMI_TENSEI_IMAGINE', 'SID_MEIER_S_PIRATES'):
7879
kf_root = block_store.create_block("NiControllerSequence")
7980
else:
8081
raise NifError(f"Keyframe export for '{game}' is not supported.")
@@ -87,7 +88,7 @@ def export_kf_root(self, b_armature=None):
8788
b_action = self.get_active_action(b_armature)
8889
for b_bone in b_armature.data.bones:
8990
self.export_transforms(kf_root, b_armature, b_action, b_bone)
90-
if game in ('SKYRIM',):
91+
if nif_scene.is_skyrim():
9192
targetname = "NPC Root [Root]"
9293
else:
9394
# quick hack to set correct target name

io_scene_niftools/modules/nif_export/armature/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def export_bone_flags(self, b_bone, n_node):
8989
n_node.flags = b_bone.niftools.flags
9090
else:
9191
game = bpy.context.scene.niftools_scene.game
92-
if game in ('OBLIVION', 'FALLOUT_3', 'SKYRIM'):
92+
if bpy.context.scene.niftools_scene.is_bs():
9393
# default for Oblivion bones
9494
# note: bodies have 0x000E, clothing has 0x000F
9595
n_node.flags = 0x000E

io_scene_niftools/modules/nif_export/block_registry.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
#
3838
# ***** END LICENSE BLOCK *****
3939

40-
import generated.formats.nif as NifFormat
40+
import nifgen.formats.nif as NifFormat
4141

4242
import io_scene_niftools.utils.logging
4343
from io_scene_niftools.utils import math

io_scene_niftools/modules/nif_export/collision/havok.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
import bpy
4040
import mathutils
4141

42-
from generated.formats.nif import classes as NifClasses
42+
from nifgen.formats.nif import classes as NifClasses
4343

4444
import io_scene_niftools.utils.logging
4545
from io_scene_niftools.modules.nif_export.block_registry import block_store
@@ -57,7 +57,8 @@ class BhkCollision(Collision):
5757
EXPORT_OB_SOLID = True
5858

5959
def __init__(self):
60-
self.HAVOK_SCALE = consts.HAVOK_SCALE
60+
# to be filled during the export process:
61+
self.HAVOK_SCALE = None
6162

6263
def export_collision_helper(self, b_obj, parent_block):
6364
"""Helper function to add collision objects to a node. This function
@@ -77,9 +78,7 @@ def export_collision_helper(self, b_obj, parent_block):
7778
coll_ispacked = (rigid_body.collision_shape == 'MESH')
7879

7980
# Set Havok Scale ratio
80-
b_scene = bpy.context.scene.niftools_scene
81-
if b_scene.user_version == 12 and b_scene.user_version_2 == 83:
82-
self.HAVOK_SCALE = consts.HAVOK_SCALE * 10
81+
self.HAVOK_SCALE = NifData.data.havok_scale
8382

8483
# find physics properties/defaults
8584
# get havok material name from material name
@@ -175,6 +174,7 @@ def export_bhk_collison_object(self, b_obj):
175174
col_filter = b_obj.nifcollision.col_filter
176175

177176
n_col_obj = block_store.create_block("bhkCollisionObject", b_obj)
177+
n_col_obj.flags._value = 0
178178
if layer == NifClasses.OblivionLayer.OL_ANIM_STATIC and col_filter != 128:
179179
# animated collision requires flags = 41
180180
# unless it is a constrainted but not keyframed object
@@ -203,7 +203,7 @@ def export_bhk_blend_controller(self, b_obj, parent_block):
203203

204204
# TODO [collision] Move to collision
205205
def update_rigid_bodies(self):
206-
if bpy.context.scene.niftools_scene.game in ('OBLIVION', 'FALLOUT_3', 'SKYRIM'):
206+
if bpy.context.scene.niftools_scene.is_bs():
207207
n_rigid_bodies = [n_rigid_body for n_rigid_body in block_store.block_to_obj if isinstance(n_rigid_body, NifClasses.BhkRigidBody)]
208208

209209
# update rigid body center of gravity and mass
@@ -244,9 +244,9 @@ def export_bhk_packed_nitristrip_shape(self, b_obj, n_col_mopp):
244244
n_col_shape = block_store.create_block("bhkPackedNiTriStripsShape", b_obj)
245245
# TODO [collision] radius has default of 0.1, but maybe let depend on margin
246246
scale = n_col_shape.scale
247-
scale.x = 0
248-
scale.y = 0
249-
scale.z = 0
247+
scale.x = 1.0
248+
scale.y = 1.0
249+
scale.z = 1.0
250250
scale.w = 0
251251
n_col_shape.scale_copy = scale
252252
n_col_mopp.shape = n_col_shape

io_scene_niftools/modules/nif_export/constraint/__init__.py

+10-6
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,20 @@
4040
import bpy
4141
import mathutils
4242

43-
from generated.formats.nif import classes as NifClasses
43+
from nifgen.formats.nif import classes as NifClasses
4444

4545
import io_scene_niftools.utils.logging
4646
from io_scene_niftools.modules.nif_export.block_registry import block_store
47-
from io_scene_niftools.utils import math, consts
47+
from io_scene_niftools.utils import math
4848
from io_scene_niftools.utils.logging import NifLog
49-
from io_scene_niftools.utils.singleton import NifOp
49+
from io_scene_niftools.utils.singleton import NifOp, NifData
5050

5151

5252
class Constraint:
5353

5454
def __init__(self):
55-
self.HAVOK_SCALE = consts.HAVOK_SCALE
55+
# to be filled during the export process:
56+
self.HAVOK_SCALE = None
5657

5758
def export_constraints(self, b_obj, root_block):
5859
"""Export the constraints of an object.
@@ -70,10 +71,13 @@ def export_constraints(self, b_obj, root_block):
7071
# skip text buffers etc
7172
return
7273

74+
# Set Havok Scale ratio
75+
self.HAVOK_SCALE = NifData.data.havok_scale
76+
7377
for b_constr in b_obj.constraints:
7478
# rigid body joints
7579
if b_constr.type == 'RIGID_BODY_JOINT':
76-
if bpy.context.scene.niftools_scene.game not in ('OBLIVION', 'FALLOUT_3', 'SKYRIM'):
80+
if bpy.context.scene.niftools_scene.is_bs():
7781
NifLog.warn(f"Only Oblivion/Fallout/Skyrim rigid body constraints currently supported: Skipping {b_constr}.")
7882
continue
7983
# check that the object is a rigid body
@@ -126,7 +130,7 @@ def export_constraints(self, b_obj, root_block):
126130
max_friction = 0
127131
else:
128132
# non-malleable typically have 10
129-
if bpy.context.scene.niftools_scene.game == 'FALLOUT_3':
133+
if bpy.context.scene.niftools_scene.is_fo3():
130134
max_friction = 100
131135
else: # oblivion
132136
max_friction = 10

0 commit comments

Comments
 (0)