blender_niftools_addon
blender_niftools_addon copied to clipboard
Mesh collision export bugs (Oblivion)
Overview
Exporting models with a trishape collision throws errors, and even with those fixed, the resulting collision is incorrect. Possibly affects games other than Oblivion, that's just what I'm testing on.
Version
io_scene_niftools 0.0.6 & 0.0.7dev Blender 2.93.3 Windows 10 x64
Reproduction
- Open the attached nif_mesh_collision.blend
- Attempt to export
or
- Import meshes/architecture/anvil/anvilaltar01.nif
- Attempt to export
Expected Result
Successful export and working collision in-game.
Actual Result
Various errors, collision not present in-game.
Possible Fixes
-
Element-wise multiplication: operator * is used instead of @ in export_collision_packed() from modules\nif_export\collision\havok.py, replacing with @ fixes it.
-
'int' object has no attribute 'material': three uses of .material.material in dependencies\pyffi\formats\nif_init_.py, replacing with ".material" fixes it. Possibly a leftover from https://github.com/niftools/pyffi/issues/37
-
No collision in-game: the scale of collision subshapes is initialized to 0, then never gets updated. Under export_bhk_packed_nitristrip_shape() in modules\nif_export\collision\havok.py, setting to (1,1,1) works as a bandaid.
Additional information
Exporting the same repro file as convex hull throws different errors, but I haven't looked into those.
As an aside, a successful export creates a separate NiNode for each Havok material. Commit https://github.com/niftools/blender_niftools_addon/commit/ba93ac7108104ef7ffc33287a93644c603e828d5 mentions "the usual mopp issues" as the reasoning, but it's ten years later, niftools forums, bethforums and steam forums are all dead and I'm left wondering what the "usual issues" were, and if they ever applied to Oblivion. Well, tessource (heh) is alive, but I haven't found an answer there.
I just wanted to report that exporting collision geometry doesn't work. When I import a (vanilla) model with collision geometry and export again immediately, I get this error:
TypeError: Element-wise multiplication: not supported between 'Vector' and 'Matrix' types
Element-wise multiplication: operator * is used instead of @ in export_collision_packed() from modules\nif_export\collision\havok.py, replacing with @ fixes it.
I just created a PR to add this fix. Blender's documentation also mentions this as necessary in https://wiki.blender.org/wiki/Reference/Release_Notes/2.80/Python_API.
I'm having similar issues with importing & exporting a model for Fallout New Vegas.
Having this set to "Bounds" causes the issue, tho changing it off that means the resulting Nif file won't have any collision.
This is in combination with having this option set to "Mesh", having it on any of the primitive shapes work but doesn't result in the desired collision needed.
Blender Info Log
```Dev: Sys variable not set
Executing - Niftools : Blender Niftools Addon v0.0.14(running on Blender 3.2.0, PyFFI 2.2.4.dev3)
Exporting ...\Models\OMR_House2.nif
Exporting
Exporting geometry and animation
Writing NIF version 0x14020007
Exporting <bpy_struct, Object("NVDLC02_Store") at 0x0000011323B9AB08> as NiNode block
Exporting <bpy_struct, Object("NVDLC02_Store:0") at 0x0000011323B9A408>
Exporting <bpy_struct, Object("NVDLC02_Store:0") at 0x0000011323B9A408> as NiTriShape block
Renaming material 'noname.009' to ''
Exporting NiMaterialProperty block
Exporting BSShaderPPLightingProperty block
Exporting <bpy_struct, Object("NVDLC02_Store:0") at 0x0000011323B9A408> as NiTriShapeData block
Exporting <bpy_struct, Object("NVDLC02_Store:1") at 0x0000011323B99D08>
Exporting <bpy_struct, Object("NVDLC02_Store:1") at 0x0000011323B99D08> as NiTriShape block
Exporting NiStencilProperty block
Renaming material 'noname.010' to ''
Merging materials 'b''' and 'b''' (they are identical in nif)
Exporting NiMaterialProperty block
Exporting BSShaderPPLightingProperty block
Exporting <bpy_struct, Object("NVDLC02_Store:1") at 0x0000011323B99D08> as NiTriShapeData block
Exporting <bpy_struct, Object("NVDLC02_Store:3") at 0x0000011323B99608>
Exporting <bpy_struct, Object("NVDLC02_Store:3") at 0x0000011323B99608> as NiTriShape block
Renaming material 'noname.011' to ''
Merging materials 'b''' and 'b''' (they are identical in nif)
Exporting NiMaterialProperty block
Exporting BSShaderPPLightingProperty block
Exporting <bpy_struct, Object("NVDLC02_Store:3") at 0x0000011323B99608> as NiTriShapeData block
Exporting <bpy_struct, Object("Object01") at 0x0000011323B98F08> as NiNode block
Exporting <bpy_struct, Object("Object01:0") at 0x0000011323B98808>
Exporting <bpy_struct, Object("Object01:0") at 0x0000011323B98808> as NiTriShape block
Renaming material 'noname.001' to ''
Merging materials 'b''' and 'b''' (they are identical in nif)
Exporting NiMaterialProperty block
Exporting BSShaderPPLightingProperty block
Exporting <bpy_struct, Object("Object01:0") at 0x0000011323B98808> as NiTriShapeData block
Exporting <bpy_struct, Object("Object01:5") at 0x0000011323B98108>
Exporting <bpy_struct, Object("Object01:5") at 0x0000011323B98108> as NiTriShape block
Exporting NiAlphaProperty block
Renaming material 'noname.003' to ''
Merging materials 'b''' and 'b''' (they are identical in nif)
Exporting NiMaterialProperty block
Exporting BSShaderPPLightingProperty block
Exporting <bpy_struct, Object("Object01:5") at 0x0000011323B98108> as NiTriShapeData block
Exporting <bpy_struct, Object("Object03:2") at 0x00000113272E7908>
Exporting <bpy_struct, Object("Object03:2") at 0x00000113272E7908> as NiTriShape block
Exporting NiAlphaProperty block
Renaming material 'noname.007' to ''
Merging materials 'b''' and 'b''' (they are identical in nif)
Exporting NiMaterialProperty block
Exporting BSShaderPPLightingProperty block
Exporting <bpy_struct, Object("Object03:2") at 0x00000113272E7908> as NiTriShapeData block
Exporting <bpy_struct, Object("Triangle Mesh Collision") at 0x00000113272E6B08> as bhkCollisionObject block
Exporting <bpy_struct, Object("Triangle Mesh Collision") at 0x00000113272E6B08> as bhkRigidBody block
Exporting <bpy_struct, Object("Triangle Mesh Collision") at 0x00000113272E6B08> as bhkMoppBvTreeShape block
Exporting <bpy_struct, Object("Triangle Mesh Collision") at 0x00000113272E6B08> as bhkPackedNiTriStripsShape block
Python: Traceback (most recent call last):
File "C:\Users\...\AppData\Roaming\Blender Foundation\Blender\3.2\scripts\addons\io_scene_niftools\operators\nif_export_op.py", line 140, in execute
return NifExport(self, context).execute()
File "C:\Users\...\AppData\Roaming\Blender Foundation\Blender\3.2\scripts\addons\io_scene_niftools\nif_export.py", line 136, in execute
root_block = self.objecthelper.export_root_node(self.root_objects, filebase)
File "C:\Users\...\AppData\Roaming\Blender Foundation\Blender\3.2\scripts\addons\io_scene_niftools\modules\nif_export\object\__init__.py", line 106, in export_root_node
self.export_node(b_obj, None)
File "C:\Users\...\AppData\Roaming\Blender Foundation\Blender\3.2\scripts\addons\io_scene_niftools\modules\nif_export\object\__init__.py", line 218, in export_node
self.export_children(b_obj, node)
File "C:\Users\...\AppData\Roaming\Blender Foundation\Blender\3.2\scripts\addons\io_scene_niftools\modules\nif_export\object\__init__.py", line 234, in export_children
self.export_node(b_child, temp_parent)
File "C:\Users\...\AppData\Roaming\Blender Foundation\Blender\3.2\scripts\addons\io_scene_niftools\modules\nif_export\object\__init__.py", line 167, in export_node
if self.export_collision(b_obj, n_parent):
File "C:\Users\...\AppData\Roaming\Blender Foundation\Blender\3.2\scripts\addons\io_scene_niftools\modules\nif_export\object\__init__.py", line 255, in export_collision
self.bhk_helper.export_collision_helper(b_obj, node)
File "C:\Users\...\AppData\Roaming\Blender Foundation\Blender\3.2\scripts\addons\io_scene_niftools\modules\nif_export\collision\havok.py", line 127, in export_collision_helper
self.export_collision_packed(b_obj, n_col_body, layer, n_havok_mat)
File "C:\Users\...\AppData\Roaming\Blender Foundation\Blender\3.2\scripts\addons\io_scene_niftools\modules\nif_export\collision\havok.py", line 525, in export_collision_packed
vertices = [vert.co * transform for vert in b_mesh.vertices]
File "C:\Users\...\AppData\Roaming\Blender Foundation\Blender\3.2\scripts\addons\io_scene_niftools\modules\nif_export\collision\havok.py", line 525, in <listcomp>
vertices = [vert.co * transform for vert in b_mesh.vertices]
TypeError: Element-wise multiplication: not supported between 'Vector' and 'Matrix' types```
Blender 3.2 Blender Niftools Addon - v0.0.14
Similarly just importing the plain vanilla mesh gives the same error when trying to export it. The imported model has 2 objects with their collision shapes set to "Mesh", changing it to "Box" allows the model to be exported again but ofcourse doesn't result in the desired collision.
The vanilla model is located in HonestHearts - Main.bsa\meshes\nvdlc02\architecture\rangerbuildings\nvdlc02store.nif
Dunno if i'm allowed to upload it here, been trying to export collisions for a week now :x
Regarding anvilaltar01.nif
, it currently can be imported and exported and has collision in-game, but the collision mesh is raised above where it is supposed to be. The below screenshot is from NifSkope but it is the same in-game.
Tested using: https://github.com/Candoran2/new-pyffi/commit/3f958920d4d13aa8388248b9242906ee3a15b123 https://github.com/Candoran2/nifxml/commit/d0ab9271e2c2bf75eacb46082b93e1d304b551e6 https://github.com/Candoran2/blender_nif_plugin/commit/074489a44fcaf8657f969b3d10e7887b460b49be Blender 3.4.1, python 3.11.1, Windows 11
but the collision mesh is raised above where it is supposed to be.
Right, the collision's transforms don't get applied properly because export_collision_packed() multiplies vertex coordinates by the object's transform matrix instead of the other way around. Easy fix (should be "transform @ vert.co").
it is the same in-game
This isn't the case, using the same setup as yours. You can check in-game with "tmg" console command. That's because the collision scale is still initialized to zero, as I mentioned in the opening post. The game seems to only care about the one called "Scale Copy" in NifSkope. And really, this can also be filed as a NifSkope bug, as it fails to display havok shapes at their correct scale.
There is also an additional bug that affects export of detailed collision. Anything above 1k verts seems to crash the game. Splitting it up into chunks with no other changes works. The 3DSMax plugins export the same collision fine in its entirety, and some vanilla models use much more complex collision (testcloudrulerint.nif with 2.5k verts).
For me it is indeed the same in-game. I made sure to check with "tmg".
Here is the .nif with the raised collision mesh. It was created from the anvilaltar01.nif of the GOG version. anvilaltar01.zip
Well, this is curious, but there is an explanation. The scale of this specific object instance is set to 0.91 in editor, which apparently acts as an override for nif scale value, rather than a coefficient. If you open CS and change it to 1.0, the collision will disappear. Same if you drop a new copy of it anywhere.
I can mostly confirm what you said about no collision at scale 1.0. I tried placing a new scale 1.0 altar with the exported model and it could largely be walked through as if there were no collision. It was not entirely without collision, though. There was a small amount of collision in the center of it.