Skip to content

Commit 95a2dc8

Browse files
authored
Merge pull request #54 from MrClock8163/dev
v2.3.0
2 parents 04a168a + 4ab592e commit 95a2dc8

Some content is hidden

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

41 files changed

+1710
-569
lines changed

Arma3ObjectBuilder/CHANGELOG.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,54 @@
11
# Changelog
22

3+
## [v2.3.0](https://github.com/MrClock8163/Arma3ObjectBuilder/releases/tag/v2.3.0) (Blender 2.90 -> 4.1)
4+
5+
### Added
6+
7+
- Materials tool RVMAT Templates
8+
- import-export:
9+
- P3D:
10+
- support for Underground (VBS) LOD type
11+
- support for Groundlayer (VBS) LOD type
12+
- support for Navigation (VBS) LOD type
13+
- Collisions export option (handling duplicate LOD types)
14+
- Generate Components export option
15+
- LOD copy directives
16+
- Validation tool:
17+
- LOD - Generic ruleset:
18+
- warning for more than 2 UV channels on a LOD object
19+
- LOD - Shadow ruleset:
20+
- warning for unconventinal LOD indices (not 0, 10, 1000, 1010 or 1020)
21+
- warning if LOD has `lodnoshadow = 1` named property
22+
- LOD - Underground (VBS) ruleset
23+
- LOD - Groundlayer (VBS) ruleset
24+
- Rigging tool:
25+
- Add OFP2_ManSkeleton operator
26+
- Debug add-on options tab:
27+
- Preserve Preprocessed LOD Objects
28+
29+
### Changed
30+
31+
- import-export:
32+
- export processes will no longer start if the target file is in use by another application
33+
- backup and temporary export files are now time stamped in the extension to avoid collisions
34+
- P3D:
35+
- handling of unknown LOD types has been improved (the Unknown LOD type can now be used to set any custom LOD signature)
36+
- utilities:
37+
- Find Components now only creates selections for closed components
38+
- Vertex Mass Editing tool:
39+
- Mass From Density now ignores non-closed components and loose vertices
40+
- Rigging tool:
41+
- skeletons and bones are no longer forcibly alphabetically sorted
42+
- hierarchic bone order now has to be maintained manually, depending processed will not try to detect the hierarchy in a mixed order
43+
- Colors tool was moved under new Materials tool
44+
- Preserve Faulty Output add-on option was moved to the newly introduced Debug options tab
45+
46+
### Fixed
47+
48+
- Geometry LOD validation would falsely report not triangulated meshes
49+
- P3D import would crash Blender if Proxy Action was set to Purge
50+
- Find Components would purge all vertex groups under certain circumstances
51+
352
## [v2.2.1](https://github.com/MrClock8163/Arma3ObjectBuilder/releases/tag/v2.2.1) (Blender 2.90 -> 4.1)
453

554
### Added

Arma3ObjectBuilder/README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# Arma 3 Object Builder
22

3-
Arma 3 Object Builder is a free community add-on for Blender to help content development for Arma 3. The add-on is based on the ideas of the [ArmAToolbox](https://github.com/AlwarrenSidh/ArmAToolbox) add-on developed by Alwarren.
3+
Arma 3 Object Builder is a free, community add-on for Blender to help content development for Arma 3. The add-on is based on the ideas of the [ArmAToolbox](https://github.com/AlwarrenSidh/ArmAToolbox) add-on developed by Alwarren, but exists as a completely different implementation of a similar workflow, with a great number improved and extended features.
44

55
## Main features
66

77
- P3D import-export
88
- ASC import-export
9-
- RTM export
9+
- RTM import-export
10+
- armature reconstruction
1011
- various editing tools
1112
- utility functions
1213

@@ -16,8 +17,8 @@ The documentation can be found on [GitBook](https://mrcmodding.gitbook.io/arma-3
1617

1718
## Installation
1819

19-
The add-on can be installed after either downloading a packaged release, or cloning the repository.
20-
For information about add-on installation, visit the official [Blender documentation](https://mrcmodding.gitbook.io/arma-3-object-builder/home) page about add-ons.
20+
The add-on can be installed after either downloading a packaged release, or cloning the repository and manually packing it.
21+
For information about add-on installation, visit the official [Blender documentation](https://docs.blender.org/manual/en/latest/editors/preferences/addons.html) page about add-ons.
2122

2223
## License
2324

Arma3ObjectBuilder/__init__.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
"name": "Arma 3 Object Builder",
33
"description": "Collection of tools for editing Arma 3 content",
44
"author": "MrClock (present add-on), Hans-Joerg \"Alwarren\" Frieden (original ArmaToolbox add-on)",
5-
"version": (2, 2, 1),
5+
"version": (2, 3, 0),
66
"blender": (2, 90, 0),
77
"location": "Object Builder panels",
8-
"warning": "",
8+
"warning": "Development",
99
"doc_url": "https://mrcmodding.gitbook.io/arma-3-object-builder/home",
1010
"tracker_url": "https://github.com/MrClock8163/Arma3ObjectBuilder/issues",
1111
"category": "3D View"
@@ -196,7 +196,8 @@ class A3OB_AT_preferences(bpy.types.AddonPreferences):
196196
items = (
197197
('GENERAL', "General", "General and misc settings", 'PREFERENCES', 0),
198198
('PATHS', "Paths", "File path related settings", 'FILE_TICK', 1),
199-
('DEFAULTS', "Defaults", "Default fallback values", 'RECOVER_LAST', 2)
199+
('DEFAULTS', "Defaults", "Default fallback values", 'RECOVER_LAST', 2),
200+
('DEBUG', "Debug", "Debug options", 'ERROR', 4)
200201
)
201202
)
202203
# General
@@ -205,10 +206,6 @@ class A3OB_AT_preferences(bpy.types.AddonPreferences):
205206
description = "Display links to the addon documentation in the headers of panels",
206207
default = True
207208
)
208-
preserve_faulty_output: bpy.props.BoolProperty(
209-
name = "Preserve Faulty Output",
210-
description = "Preserve the .temp files if an export failed (could be useful to attach to a bug report)"
211-
)
212209
create_backups: bpy.props.BoolProperty(
213210
name = "Create Backups",
214211
description = "When overwriting an existing output file, create a backup copy (.bak) of the original"
@@ -264,7 +261,16 @@ class A3OB_AT_preferences(bpy.types.AddonPreferences):
264261
default = "00000000",
265262
get = lambda self: "%08x" % self.flag_face
266263
)
267-
264+
# Debug
265+
preserve_faulty_output: bpy.props.BoolProperty(
266+
name = "Preserve Faulty Output",
267+
description = "Preserve the .temp files if an export failed (could be useful to attach to a bug report)"
268+
)
269+
preserve_preprocessed_lods: bpy.props.BoolProperty(
270+
name = "Preserve Preprocessed LOD Objects",
271+
description = "Preserve the preprocessed LOD meshes that were generated during P3D export"
272+
)
273+
268274
def draw(self, context):
269275
layout = self.layout
270276

@@ -277,7 +283,6 @@ def draw(self, context):
277283

278284
if self.tabs == 'GENERAL':
279285
box.prop(self, "show_info_links")
280-
box.prop(self, "preserve_faulty_output")
281286
box.prop(self, "create_backups")
282287
row_theme = box.row(align=True)
283288
row_theme.prop(self, "icon_theme", expand=True)
@@ -299,6 +304,10 @@ def draw(self, context):
299304
row_face = box.row(align=True)
300305
row_face.prop(self, "flag_face_display")
301306
row_face.operator("a3ob.prefs_edit_flag_face", text="", icon='GREASEPENCIL')
307+
308+
elif self.tabs == 'DEBUG':
309+
box.prop(self, "preserve_faulty_output")
310+
box.prop(self, "preserve_preprocessed_lods")
302311

303312

304313
classes = (
@@ -324,11 +333,11 @@ def draw(self, context):
324333
ui.import_export_asc,
325334
ui.tool_outliner,
326335
ui.tool_mass,
336+
ui.tool_materials,
327337
ui.tool_hitpoint,
328338
ui.tool_paths,
329339
ui.tool_proxies,
330340
ui.tool_validation,
331-
ui.tool_color,
332341
ui.tool_rigging,
333342
ui.tool_utilities,
334343
ui.tool_scripts
@@ -366,4 +375,4 @@ def unregister():
366375
for cls in reversed(classes):
367376
unregister_class(cls)
368377

369-
print("Unregister done")
378+
print("Unregister done")

Arma3ObjectBuilder/io/compression.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66

77
class LZO_Error(Exception):
8-
pass
8+
def __str__(self):
9+
return "LZO - %s" % super().__str__()
910

1011

1112
# Decompression algorithm for bit streams compressed with the LZO1X algorithm.

Arma3ObjectBuilder/io/data_asc.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55

66
class ASC_Error(Exception):
7-
pass
7+
def __str__(self):
8+
return "ASC - %s" % super().__str__()
89

910

1011
class ASC_File():

Arma3ObjectBuilder/io/data_p3d.py

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313

1414

1515
class P3D_Error(Exception):
16-
pass
16+
def __str__(self):
17+
return "P3D - %s" % super().__str__()
1718

1819

1920
# Generic class to consume unneeded TAGG types (eg.: #Hidden#, #Selected#).
@@ -134,10 +135,8 @@ def __init__(self):
134135

135136
@classmethod
136137
def decode_weight(cls, weight):
137-
if weight == 0:
138-
return 0.0
139-
elif weight == 1:
140-
return 1.0
138+
if weight == 0 or weight == 1:
139+
return weight
141140

142141
value = (256 - weight) / 255
143142

@@ -148,10 +147,8 @@ def decode_weight(cls, weight):
148147

149148
@classmethod
150149
def encode_weight(cls, weight):
151-
if weight == 0:
152-
return 0
153-
elif weight == 1:
154-
return 1
150+
if weight == 0 or weight == 1:
151+
return int(weight)
155152

156153
value = round(256 - 255 * weight)
157154

@@ -232,7 +229,7 @@ def read(cls, file, count_verts, count_faces):
232229
elif not output.name.startswith("#") and not output.name.endswith("#"):
233230
output.data = P3D_TAGG_DataSelection.read(file, count_verts, count_faces)
234231
else:
235-
# Consume unnedded TAGGs
232+
# Consume unneeded TAGGs
236233
file.read(length)
237234
output.active = False
238235

@@ -283,7 +280,7 @@ class P3D_LOD_Resolution():
283280
VIEW_CARGO_FIRE_GEOMETRY = 17
284281
VIEW_COMMANDER = 18
285282
VIEW_COMMANDER_GEOMETRY = 19
286-
VIEW_COMMANDER_FIRE_EOMETRY = 20
283+
VIEW_COMMANDER_FIRE_GEOMETRY = 20
287284
VIEW_PILOT_GEOMETRY = 21
288285
VIEW_PILOT_FIRE_GEOMETRY = 22
289286
VIEW_GUNNER_GEOMETRY = 23
@@ -293,18 +290,26 @@ class P3D_LOD_Resolution():
293290
SHADOW_VIEW_PILOT = 27
294291
SHADOW_VIEW_GUNNER = 28
295292
WRECKAGE = 29
296-
UNKNOWN = 30
293+
UNDERGROUND = 30 # Geometry PhysX Old for Arma 3
294+
GROUNDLAYER = 31
295+
NAVIGATION = 32
296+
# SHADOWBUFFER = ...
297+
UNKNOWN = -1
297298

298299
INDEX_MAP = {
299300
(0.0, 0): VISUAL, # Visual
300301
(1.0, 3): VIEW_GUNNER, # View Gunner
301302
(1.1, 3): VIEW_PILOT, # View Pilot
302303
(1.2, 3): VIEW_CARGO, # View Cargo
303304
(1.0, 4): SHADOW, # Shadow
305+
# (1.1, 4): SHADOWBUFFER,
306+
(1.3, 4): GROUNDLAYER, # GroundLayer (VBS)
304307
(2.0, 4): EDIT, # Edit
305308
(1.0, 13): GEOMETRY, # Geometry
306309
(2.0, 13): GEOMETRY_BUOY, # Geometry Buoyancy
310+
(3.0, 13): UNDERGROUND, # Underground (VBS), Geometry PhysX (old) for Arma 3
307311
(4.0, 13): GEOMETRY_PHYSX, # Geometry PhysX
312+
(5.0, 13): NAVIGATION, # Navigation (VBS)
308313
(1.0, 15): MEMORY, # Memory
309314
(2.0, 15): LANDCONTACT, # Land Contact
310315
(3.0, 15): ROADWAY, # Roadway
@@ -316,7 +321,7 @@ class P3D_LOD_Resolution():
316321
(9.0, 15): VIEW_CARGO_FIRE_GEOMETRY, # View Cargo Fire Geometry
317322
(1.0, 16): VIEW_COMMANDER, # View Commander
318323
(1.1, 16): VIEW_COMMANDER_GEOMETRY, # View Commander Geometry
319-
(1.2, 16): VIEW_COMMANDER_FIRE_EOMETRY, # View Commander Fire Geometry
324+
(1.2, 16): VIEW_COMMANDER_FIRE_GEOMETRY, # View Commander Fire Geometry
320325
(1.3, 16): VIEW_PILOT_GEOMETRY, # View Pilot Geometry
321326
(1.4, 16): VIEW_PILOT_FIRE_GEOMETRY, # View Pilot Fire Geometry
322327
(1.5, 16): VIEW_GUNNER_GEOMETRY, # View Gunner Geometry
@@ -330,13 +335,12 @@ class P3D_LOD_Resolution():
330335
}
331336

332337
RESOLUTION_POS = { # decimal places in normalized format
333-
0: -1,
334-
3: 3,
335-
4: 4,
336-
5: 4,
337-
16: 2,
338-
26: 3,
339-
30: -1
338+
VIEW_CARGO: 3,
339+
SHADOW: 4,
340+
# SHADOWBUFFER: 4,
341+
EDIT: 4,
342+
VIEW_CARGO_GEOMERTRY: 2,
343+
SHADOW_VIEW_CARGO: 3
340344
}
341345

342346
def __init__(self, lod = 0, res = 0):
@@ -345,48 +349,45 @@ def __init__(self, lod = 0, res = 0):
345349
self.source = None # field to store the originally read float value for debug purposes
346350

347351
def __eq__(self, other):
348-
return type(self) is type(other) and self.lod == other.lod and self.res == other.res
352+
return type(self) is type(other) and self.get() == other.get()
349353

350354
def __float__(self):
351355
return float(self.encode(self.lod, self.res))
352356

353357
@classmethod
354358
def encode(cls, lod, resolution):
355-
if lod == 0:
359+
if lod == cls.VISUAL or lod == cls.UNKNOWN:
356360
return resolution
357361

358362
lookup = {v: k for k, v in cls.INDEX_MAP.items()}
359363

360364
coef, exp = lookup[lod]
361365
pos = cls.RESOLUTION_POS.get(lod, None)
362366

363-
resolution_sign = 0
364-
if pos is not None:
365-
resolution_sign = resolution * 10**(exp - pos)
367+
resolution_sign = (resolution * 10**(exp - pos)) if pos is not None else 0
366368

367369
return coef * 10**exp + resolution_sign
368370

369371
@classmethod
370372
def decode(cls, signature):
371373
if signature < 1e3:
372-
return 0, round(signature)
373-
elif 1e4 <= signature < 2e4:
374-
return 4, round(signature - 1e4)
374+
return cls.VISUAL, round(signature)
375+
elif 1e4 <= signature < 1.2e4:
376+
return cls.SHADOW, round(signature - 1e4)
375377

376378
num = Decimal(signature)
377379
exp = num.normalize(Context(2)).adjusted()
378380

379381
coef = float((num / 10**exp))
380-
base = round(coef)
381-
if exp in [3, 16]:
382-
base = round(coef, 1)
382+
base = round(coef, 1) if exp in (3, 4, 16) else round(coef)
383383

384-
lod = cls.INDEX_MAP.get((base, exp), 30)
384+
lod = cls.INDEX_MAP.get((base, exp), cls.UNKNOWN)
385385
pos = cls.RESOLUTION_POS.get(lod, None)
386386

387-
resolution = 0
388-
if pos is not None:
389-
resolution = int(round((coef - base) * 10**pos, pos))
387+
if lod == cls.UNKNOWN:
388+
return lod, round(signature)
389+
390+
resolution = int(round((coef - base) * 10**pos, pos)) if pos is not None else 0
390391

391392
return lod, resolution
392393

@@ -833,4 +834,17 @@ def find_lod(self, index = 0, resolution = 0):
833834
if lod.resolution.get() == (index, resolution):
834835
return lod
835836

836-
return None
837+
return None
838+
839+
def get_duplicate_lods(self):
840+
signatures = set()
841+
duplicates = []
842+
843+
for i, lod in enumerate(self.lods):
844+
sign = float(lod.resolution)
845+
if sign in signatures:
846+
duplicates.append(i)
847+
else:
848+
signatures.add(sign)
849+
850+
return duplicates

Arma3ObjectBuilder/io/data_rap.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99

1010
class RAP_Error(Exception):
11-
pass
11+
def __str__(self):
12+
return "RAP - %s" % super().__str__()
1213

1314

1415
class CFG_Formatter():

0 commit comments

Comments
 (0)