Skip to content

Commit

Permalink
Merge pull request #54 from MrClock8163/dev
Browse files Browse the repository at this point in the history
v2.3.0
  • Loading branch information
MrClock8163 authored Mar 28, 2024
2 parents 04a168a + 4ab592e commit 95a2dc8
Show file tree
Hide file tree
Showing 41 changed files with 1,710 additions and 569 deletions.
49 changes: 49 additions & 0 deletions Arma3ObjectBuilder/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,54 @@
# Changelog

## [v2.3.0](https://github.com/MrClock8163/Arma3ObjectBuilder/releases/tag/v2.3.0) (Blender 2.90 -> 4.1)

### Added

- Materials tool RVMAT Templates
- import-export:
- P3D:
- support for Underground (VBS) LOD type
- support for Groundlayer (VBS) LOD type
- support for Navigation (VBS) LOD type
- Collisions export option (handling duplicate LOD types)
- Generate Components export option
- LOD copy directives
- Validation tool:
- LOD - Generic ruleset:
- warning for more than 2 UV channels on a LOD object
- LOD - Shadow ruleset:
- warning for unconventinal LOD indices (not 0, 10, 1000, 1010 or 1020)
- warning if LOD has `lodnoshadow = 1` named property
- LOD - Underground (VBS) ruleset
- LOD - Groundlayer (VBS) ruleset
- Rigging tool:
- Add OFP2_ManSkeleton operator
- Debug add-on options tab:
- Preserve Preprocessed LOD Objects

### Changed

- import-export:
- export processes will no longer start if the target file is in use by another application
- backup and temporary export files are now time stamped in the extension to avoid collisions
- P3D:
- handling of unknown LOD types has been improved (the Unknown LOD type can now be used to set any custom LOD signature)
- utilities:
- Find Components now only creates selections for closed components
- Vertex Mass Editing tool:
- Mass From Density now ignores non-closed components and loose vertices
- Rigging tool:
- skeletons and bones are no longer forcibly alphabetically sorted
- hierarchic bone order now has to be maintained manually, depending processed will not try to detect the hierarchy in a mixed order
- Colors tool was moved under new Materials tool
- Preserve Faulty Output add-on option was moved to the newly introduced Debug options tab

### Fixed

- Geometry LOD validation would falsely report not triangulated meshes
- P3D import would crash Blender if Proxy Action was set to Purge
- Find Components would purge all vertex groups under certain circumstances

## [v2.2.1](https://github.com/MrClock8163/Arma3ObjectBuilder/releases/tag/v2.2.1) (Blender 2.90 -> 4.1)

### Added
Expand Down
9 changes: 5 additions & 4 deletions Arma3ObjectBuilder/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# Arma 3 Object Builder

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.
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.

## Main features

- P3D import-export
- ASC import-export
- RTM export
- RTM import-export
- armature reconstruction
- various editing tools
- utility functions

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

## Installation

The add-on can be installed after either downloading a packaged release, or cloning the repository.
For information about add-on installation, visit the official [Blender documentation](https://mrcmodding.gitbook.io/arma-3-object-builder/home) page about add-ons.
The add-on can be installed after either downloading a packaged release, or cloning the repository and manually packing it.
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.

## License

Expand Down
31 changes: 20 additions & 11 deletions Arma3ObjectBuilder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"name": "Arma 3 Object Builder",
"description": "Collection of tools for editing Arma 3 content",
"author": "MrClock (present add-on), Hans-Joerg \"Alwarren\" Frieden (original ArmaToolbox add-on)",
"version": (2, 2, 1),
"version": (2, 3, 0),
"blender": (2, 90, 0),
"location": "Object Builder panels",
"warning": "",
"warning": "Development",
"doc_url": "https://mrcmodding.gitbook.io/arma-3-object-builder/home",
"tracker_url": "https://github.com/MrClock8163/Arma3ObjectBuilder/issues",
"category": "3D View"
Expand Down Expand Up @@ -196,7 +196,8 @@ class A3OB_AT_preferences(bpy.types.AddonPreferences):
items = (
('GENERAL', "General", "General and misc settings", 'PREFERENCES', 0),
('PATHS', "Paths", "File path related settings", 'FILE_TICK', 1),
('DEFAULTS', "Defaults", "Default fallback values", 'RECOVER_LAST', 2)
('DEFAULTS', "Defaults", "Default fallback values", 'RECOVER_LAST', 2),
('DEBUG', "Debug", "Debug options", 'ERROR', 4)
)
)
# General
Expand All @@ -205,10 +206,6 @@ class A3OB_AT_preferences(bpy.types.AddonPreferences):
description = "Display links to the addon documentation in the headers of panels",
default = True
)
preserve_faulty_output: bpy.props.BoolProperty(
name = "Preserve Faulty Output",
description = "Preserve the .temp files if an export failed (could be useful to attach to a bug report)"
)
create_backups: bpy.props.BoolProperty(
name = "Create Backups",
description = "When overwriting an existing output file, create a backup copy (.bak) of the original"
Expand Down Expand Up @@ -264,7 +261,16 @@ class A3OB_AT_preferences(bpy.types.AddonPreferences):
default = "00000000",
get = lambda self: "%08x" % self.flag_face
)

# Debug
preserve_faulty_output: bpy.props.BoolProperty(
name = "Preserve Faulty Output",
description = "Preserve the .temp files if an export failed (could be useful to attach to a bug report)"
)
preserve_preprocessed_lods: bpy.props.BoolProperty(
name = "Preserve Preprocessed LOD Objects",
description = "Preserve the preprocessed LOD meshes that were generated during P3D export"
)

def draw(self, context):
layout = self.layout

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

if self.tabs == 'GENERAL':
box.prop(self, "show_info_links")
box.prop(self, "preserve_faulty_output")
box.prop(self, "create_backups")
row_theme = box.row(align=True)
row_theme.prop(self, "icon_theme", expand=True)
Expand All @@ -299,6 +304,10 @@ def draw(self, context):
row_face = box.row(align=True)
row_face.prop(self, "flag_face_display")
row_face.operator("a3ob.prefs_edit_flag_face", text="", icon='GREASEPENCIL')

elif self.tabs == 'DEBUG':
box.prop(self, "preserve_faulty_output")
box.prop(self, "preserve_preprocessed_lods")


classes = (
Expand All @@ -324,11 +333,11 @@ def draw(self, context):
ui.import_export_asc,
ui.tool_outliner,
ui.tool_mass,
ui.tool_materials,
ui.tool_hitpoint,
ui.tool_paths,
ui.tool_proxies,
ui.tool_validation,
ui.tool_color,
ui.tool_rigging,
ui.tool_utilities,
ui.tool_scripts
Expand Down Expand Up @@ -366,4 +375,4 @@ def unregister():
for cls in reversed(classes):
unregister_class(cls)

print("Unregister done")
print("Unregister done")
3 changes: 2 additions & 1 deletion Arma3ObjectBuilder/io/compression.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@


class LZO_Error(Exception):
pass
def __str__(self):
return "LZO - %s" % super().__str__()


# Decompression algorithm for bit streams compressed with the LZO1X algorithm.
Expand Down
3 changes: 2 additions & 1 deletion Arma3ObjectBuilder/io/data_asc.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@


class ASC_Error(Exception):
pass
def __str__(self):
return "ASC - %s" % super().__str__()


class ASC_File():
Expand Down
86 changes: 50 additions & 36 deletions Arma3ObjectBuilder/io/data_p3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@


class P3D_Error(Exception):
pass
def __str__(self):
return "P3D - %s" % super().__str__()


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

@classmethod
def decode_weight(cls, weight):
if weight == 0:
return 0.0
elif weight == 1:
return 1.0
if weight == 0 or weight == 1:
return weight

value = (256 - weight) / 255

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

@classmethod
def encode_weight(cls, weight):
if weight == 0:
return 0
elif weight == 1:
return 1
if weight == 0 or weight == 1:
return int(weight)

value = round(256 - 255 * weight)

Expand Down Expand Up @@ -232,7 +229,7 @@ def read(cls, file, count_verts, count_faces):
elif not output.name.startswith("#") and not output.name.endswith("#"):
output.data = P3D_TAGG_DataSelection.read(file, count_verts, count_faces)
else:
# Consume unnedded TAGGs
# Consume unneeded TAGGs
file.read(length)
output.active = False

Expand Down Expand Up @@ -283,7 +280,7 @@ class P3D_LOD_Resolution():
VIEW_CARGO_FIRE_GEOMETRY = 17
VIEW_COMMANDER = 18
VIEW_COMMANDER_GEOMETRY = 19
VIEW_COMMANDER_FIRE_EOMETRY = 20
VIEW_COMMANDER_FIRE_GEOMETRY = 20
VIEW_PILOT_GEOMETRY = 21
VIEW_PILOT_FIRE_GEOMETRY = 22
VIEW_GUNNER_GEOMETRY = 23
Expand All @@ -293,18 +290,26 @@ class P3D_LOD_Resolution():
SHADOW_VIEW_PILOT = 27
SHADOW_VIEW_GUNNER = 28
WRECKAGE = 29
UNKNOWN = 30
UNDERGROUND = 30 # Geometry PhysX Old for Arma 3
GROUNDLAYER = 31
NAVIGATION = 32
# SHADOWBUFFER = ...
UNKNOWN = -1

INDEX_MAP = {
(0.0, 0): VISUAL, # Visual
(1.0, 3): VIEW_GUNNER, # View Gunner
(1.1, 3): VIEW_PILOT, # View Pilot
(1.2, 3): VIEW_CARGO, # View Cargo
(1.0, 4): SHADOW, # Shadow
# (1.1, 4): SHADOWBUFFER,
(1.3, 4): GROUNDLAYER, # GroundLayer (VBS)
(2.0, 4): EDIT, # Edit
(1.0, 13): GEOMETRY, # Geometry
(2.0, 13): GEOMETRY_BUOY, # Geometry Buoyancy
(3.0, 13): UNDERGROUND, # Underground (VBS), Geometry PhysX (old) for Arma 3
(4.0, 13): GEOMETRY_PHYSX, # Geometry PhysX
(5.0, 13): NAVIGATION, # Navigation (VBS)
(1.0, 15): MEMORY, # Memory
(2.0, 15): LANDCONTACT, # Land Contact
(3.0, 15): ROADWAY, # Roadway
Expand All @@ -316,7 +321,7 @@ class P3D_LOD_Resolution():
(9.0, 15): VIEW_CARGO_FIRE_GEOMETRY, # View Cargo Fire Geometry
(1.0, 16): VIEW_COMMANDER, # View Commander
(1.1, 16): VIEW_COMMANDER_GEOMETRY, # View Commander Geometry
(1.2, 16): VIEW_COMMANDER_FIRE_EOMETRY, # View Commander Fire Geometry
(1.2, 16): VIEW_COMMANDER_FIRE_GEOMETRY, # View Commander Fire Geometry
(1.3, 16): VIEW_PILOT_GEOMETRY, # View Pilot Geometry
(1.4, 16): VIEW_PILOT_FIRE_GEOMETRY, # View Pilot Fire Geometry
(1.5, 16): VIEW_GUNNER_GEOMETRY, # View Gunner Geometry
Expand All @@ -330,13 +335,12 @@ class P3D_LOD_Resolution():
}

RESOLUTION_POS = { # decimal places in normalized format
0: -1,
3: 3,
4: 4,
5: 4,
16: 2,
26: 3,
30: -1
VIEW_CARGO: 3,
SHADOW: 4,
# SHADOWBUFFER: 4,
EDIT: 4,
VIEW_CARGO_GEOMERTRY: 2,
SHADOW_VIEW_CARGO: 3
}

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

def __eq__(self, other):
return type(self) is type(other) and self.lod == other.lod and self.res == other.res
return type(self) is type(other) and self.get() == other.get()

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

@classmethod
def encode(cls, lod, resolution):
if lod == 0:
if lod == cls.VISUAL or lod == cls.UNKNOWN:
return resolution

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

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

resolution_sign = 0
if pos is not None:
resolution_sign = resolution * 10**(exp - pos)
resolution_sign = (resolution * 10**(exp - pos)) if pos is not None else 0

return coef * 10**exp + resolution_sign

@classmethod
def decode(cls, signature):
if signature < 1e3:
return 0, round(signature)
elif 1e4 <= signature < 2e4:
return 4, round(signature - 1e4)
return cls.VISUAL, round(signature)
elif 1e4 <= signature < 1.2e4:
return cls.SHADOW, round(signature - 1e4)

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

coef = float((num / 10**exp))
base = round(coef)
if exp in [3, 16]:
base = round(coef, 1)
base = round(coef, 1) if exp in (3, 4, 16) else round(coef)

lod = cls.INDEX_MAP.get((base, exp), 30)
lod = cls.INDEX_MAP.get((base, exp), cls.UNKNOWN)
pos = cls.RESOLUTION_POS.get(lod, None)

resolution = 0
if pos is not None:
resolution = int(round((coef - base) * 10**pos, pos))
if lod == cls.UNKNOWN:
return lod, round(signature)

resolution = int(round((coef - base) * 10**pos, pos)) if pos is not None else 0

return lod, resolution

Expand Down Expand Up @@ -833,4 +834,17 @@ def find_lod(self, index = 0, resolution = 0):
if lod.resolution.get() == (index, resolution):
return lod

return None
return None

def get_duplicate_lods(self):
signatures = set()
duplicates = []

for i, lod in enumerate(self.lods):
sign = float(lod.resolution)
if sign in signatures:
duplicates.append(i)
else:
signatures.add(sign)

return duplicates
3 changes: 2 additions & 1 deletion Arma3ObjectBuilder/io/data_rap.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@


class RAP_Error(Exception):
pass
def __str__(self):
return "RAP - %s" % super().__str__()


class CFG_Formatter():
Expand Down
Loading

0 comments on commit 95a2dc8

Please sign in to comment.