Skip to content

Commit bbaecee

Browse files
added blender addon for sar viewing & editing
1 parent 267cff2 commit bbaecee

8 files changed

Lines changed: 2018 additions & 0 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.vscode
2+
__pycache__
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Installation
2+
3+
(Requires Blender 3 or later)
4+
5+
1. Download zip from [Releases](https://github.com/ArthurHeitmann/NierDocs/releases).
6+
7+
2. In Blender: Edit > Preferences > Add-ons > Install
8+
9+
# Usage
10+
11+
# Importing
12+
13+
File > Import > Sar
14+
15+
If you have a map file open (from wd1/wd3/wd5) you can check "Try Applying Offsets". This will try to convert the global game coordinates to local coordinates.
16+
17+
Locations where you can find sar files:
18+
19+
- data002/data012
20+
- st1/st2/st5
21+
- data003/data013
22+
- wd1/wd3
23+
24+
More information [here](../../sar/sarContents.md).
25+
26+
## Exporting
27+
28+
File > Export > Sar
29+
30+
If you have imported multiple sar files into the scene, only one will be exported. The object called "Field-Root" will be used as the root object.
31+
32+
## Editing shapes
33+
34+
| Shape Type Description | Shape Type Id | Things you can edit |
35+
|------------------------|---------------|------------------------------------------------------|
36+
| Sphere | 0 | Core Sphere Loc, Rot, Scale + Edge Sphere Scale |
37+
| Curve/Tube | 1 | Core Curve points + Core/Edge bevel depth |
38+
| Tall Curve | 2 | Parent Loc, Rot + Vertices Pos XY & Vertices Scale Z |
39+
| Cube | 10 | Cube Loc, Rot, Scale |
40+
| Extruded Polygon | 11 | Parent Loc, Rot + Vertex Pos XY |
41+
| Cylinder | 15 | Core Cylinder Loc, Rot, Extrude + Core/Edge Scale XY |
42+
| Sphere with scale ? | 100 | Sphere Loc, Rot, Scale |
43+
| Volume between faces? | 200 | Parent Loc, Rot + Vertex Pos + Modifier Z Property |
44+
45+
## Good to know
46+
47+
Most objects have xml data attached to them in the custom properties. Some interesting properties: "ShapeGroup" objects have "InEvent" and "OutEvent" properties for entering/exiting the shape. The Param property is the distance of the player to the shape.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import os
2+
import bpy
3+
import bpy_extras
4+
from bpy_extras.io_utils import ImportHelper, ExportHelper
5+
import xml.etree.ElementTree as ET
6+
7+
bl_info = {
8+
"name" : "NierSarTools",
9+
"author" : "RaiderB",
10+
"description" : "",
11+
"blender" : (3, 0, 0),
12+
"version" : (0, 1, 0),
13+
"location" : "",
14+
"warning" : "",
15+
"category" : "Generic"
16+
}
17+
18+
19+
class ImportSar(bpy.types.Operator, ImportHelper):
20+
'''Load a Nier:Automata Sar (Skeleton) File.'''
21+
bl_idname = "import_scene.sar"
22+
bl_label = "Import Sar Data"
23+
bl_options = {'PRESET', 'UNDO'}
24+
filename_ext = ".sar"
25+
filter_glob: bpy.props.StringProperty(default="*.sar", options={'HIDDEN'})
26+
27+
tryApplyingOffsets: bpy.props.BoolProperty(name="Try Applying Offsets", default=False)
28+
29+
onlyToXml: bpy.props.BoolProperty(name="Only Convert To XML", default=False)
30+
recursivelyImport: bpy.props.BoolProperty(name="Import all recursively", default=False)
31+
32+
def doImport(self, filepath):
33+
from . import sarImporter
34+
from . import sar
35+
36+
if self.onlyToXml:
37+
xml = sar.bxmToXml(filepath)
38+
with open(filepath + ".xml", "wb") as f:
39+
f.write(ET.tostring(xml))
40+
else:
41+
sarImporter.importSar(filepath, self.tryApplyingOffsets)
42+
43+
def execute(self, context):
44+
if self.recursivelyImport:
45+
directory = os.path.split(self.filepath)[0]
46+
for root, dirs, files in os.walk(directory):
47+
for file in files:
48+
if file.endswith(".sar"):
49+
self.doImport(root + '\\' + file)
50+
print("Imported all file!")
51+
else:
52+
self.doImport(self.filepath)
53+
54+
return {'FINISHED'}
55+
56+
class ExportSar(bpy.types.Operator, ExportHelper):
57+
'''Export a Nier:Automata Sar (Skeleton) File.'''
58+
bl_idname = "export_scene.sar"
59+
bl_label = "Export Sar Data"
60+
bl_options = {'PRESET', 'UNDO'}
61+
filename_ext = ".sar"
62+
filter_glob: bpy.props.StringProperty(default="*.sar", options={'HIDDEN'})
63+
64+
def execute(self, context):
65+
from . import sarExporter
66+
sarExporter.exportSar(self.filepath)
67+
return {'FINISHED'}
68+
69+
def importMenuAdditions(self, context):
70+
self.layout.operator(ImportSar.bl_idname, text="Sar for Nier:Automata (.sar)")
71+
72+
def exportMenuAdditions(self, context):
73+
self.layout.operator(ExportSar.bl_idname, text="Sar for Nier:Automata (.sar)")
74+
75+
def register():
76+
bpy.utils.register_class(ImportSar)
77+
bpy.utils.register_class(ExportSar)
78+
79+
bpy.types.TOPBAR_MT_file_import.append(importMenuAdditions)
80+
bpy.types.TOPBAR_MT_file_export.append(exportMenuAdditions)
81+
82+
def unregister():
83+
bpy.utils.unregister_class(ImportSar)
84+
bpy.utils.unregister_class(ExportSar)
85+
86+
bpy.types.TOPBAR_MT_file_import.remove(importMenuAdditions)
87+
bpy.types.TOPBAR_MT_file_export.remove(exportMenuAdditions)

0 commit comments

Comments
 (0)