Skip to content

Commit

Permalink
Release - 2.2
Browse files Browse the repository at this point in the history
  • Loading branch information
simon50keda committed Aug 5, 2021
1 parent 91fc765 commit 66c7fbc
Show file tree
Hide file tree
Showing 40 changed files with 2,434 additions and 432 deletions.
9 changes: 7 additions & 2 deletions addon/io_scs_tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
#
# ##### END GPL LICENSE BLOCK #####

# Copyright (C) 2013-2019: SCS Software
# Copyright (C) 2013-2021: SCS Software

bl_info = {
"name": "SCS Tools",
"description": "Setup models, Import-Export SCS data format",
"author": "Simon Lusenc (50keda), Milos Zajic (4museman)",
"version": (2, 1, "6a6b38a4"),
"version": (2, 2, "325a3a7a"),
"blender": (2, 90, 0),
"location": "File > Import-Export",
"wiki_url": "http://modding.scssoft.com/wiki/Documentation/Tools/SCS_Blender_Tools",
Expand All @@ -33,6 +33,7 @@
import bpy
import os
import traceback
from time import time
from bpy.props import CollectionProperty, StringProperty, PointerProperty, BoolProperty
from bpy_extras.io_utils import ImportHelper, ExportHelper
from io_scs_tools.consts import Icons as _ICONS_consts
Expand Down Expand Up @@ -98,6 +99,8 @@ def execute(self, context):
if not paths:
paths.append(self.path)

start_time = time()

failed_files = []
for filepath in paths:

Expand Down Expand Up @@ -137,6 +140,8 @@ def execute(self, context):

lprint(err_message, tuple(failed_files), report_warnings=1, report_errors=1)

end_time = time()
self.report({'INFO'}, "Import finished and took %.3f sec." % (end_time - start_time))
return {'FINISHED'}

def draw(self, context):
Expand Down
36 changes: 25 additions & 11 deletions addon/io_scs_tools/exp/pim/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####

# Copyright (C) 2013-2019: SCS Software
# Copyright (C) 2013-2021: SCS Software

import os
import collections
Expand Down Expand Up @@ -130,13 +130,16 @@ def execute(dirpath, name_suffix, root_object, armature_object, skeleton_filepat
""":type: dict[str, Piece]"""

# create mesh object data sections
mesh_objects_count = len(mesh_objects)
for mesh_i, mesh_obj in enumerate(mesh_objects):

if mesh_obj.mode != 'OBJECT':
lprint("W Invalid object mode detected on: %r, skipping it on export!", (mesh_obj.name,))
continue

lprint("I Preparing mesh object: %r ...", (mesh_obj.name,))
lprint("I Preparing mesh object: %r - %i/%i (%i%%) ...",
(mesh_obj.name, mesh_i + 1, mesh_objects_count, ((mesh_i + 1) / mesh_objects_count * 100)),
immediate_timeout=2.5)

# create part if it doesn't exists yet
part_name = used_parts.ensure_part(mesh_obj)
Expand Down Expand Up @@ -364,7 +367,7 @@ def execute(dirpath, name_suffix, root_object, armature_object, skeleton_filepat
missing_vcolor_a = True
else:
alpha = mesh.vertex_colors[_MESH_consts.default_vcol + _MESH_consts.vcol_a_suffix].data[loop_i].color[:3]
alpha = (alpha[0] + alpha[1] + alpha[2]) / 3.0 # take avg of colors for alpha
alpha = (alpha[0] + alpha[1] + alpha[2]) / 3.0 # take avg of colors for alpha

# since blender is saving vcolor in 8-bits 0.5 can not be set, thus clamp 128/255 to 0.5 or report to big vcolor otherwise
if 0.5 < alpha <= 0.501960813999176:
Expand Down Expand Up @@ -514,7 +517,12 @@ def execute(dirpath, name_suffix, root_object, armature_object, skeleton_filepat
(list(invalid_objects_for_tangents),))

# create locators data sections
for loc_obj in model_locators:
model_locators_count = len(model_locators)
for loc_i, loc_obj in enumerate(model_locators):

lprint("I Preparing model locator: %r - %i/%i (%i%%) ...",
(loc_obj.name, loc_i + 1, model_locators_count, (loc_i + 1) / model_locators_count * 100),
immediate_timeout=2.5)

pos, qua, sca = _get_scs_transformation_components(root_object.matrix_world.inverted() @ loc_obj.matrix_world)

Expand All @@ -523,15 +531,20 @@ def execute(dirpath, name_suffix, root_object, armature_object, skeleton_filepat
"Model locators must have positive scale!", (loc_obj.name, root_object.name))
continue

name = _name_utils.tokenize_name(loc_obj.name)
hookup_string = loc_obj.scs_props.locator_model_hookup
hookup_id = None
if hookup_string != "":
hookup_id = _hookup_name_to_hookup_id(hookup_string)
if hookup_id is None:
lprint("W Model locator %r has unexpected hookup value %r.", (loc_obj.name, loc_obj.scs_props.locator_model_hookup))
hookup_id = _hookup_name_to_hookup_id(hookup_string)
if hookup_id:
hookup_payload = _object_utils.get_hookup_payload_string(loc_obj)

if len(hookup_payload) > 0:
hookup_id += '#'
hookup_id += hookup_payload

if hookup_string != "" and hookup_id is None:
lprint("W Model locator %r has unexpected hookup value %r.", (loc_obj.name, loc_obj.scs_props.locator_model_hookup))

# create locator object for export
name = _name_utils.tokenize_name(loc_obj.name)
locator = Locator(len(pim_locators), name, hookup_id)
locator.set_position(pos)
locator.set_rotation(qua)
Expand Down Expand Up @@ -578,4 +591,5 @@ def execute(dirpath, name_suffix, root_object, armature_object, skeleton_filepat
# write to file
ind = " "
pim_filepath = os.path.join(dirpath, root_object.name + ".pim" + name_suffix)
return _pix_container.write_data_to_file(pim_container, pim_filepath, ind)
lprint("I Writting PIM file to %r ...", (pim_filepath,), immediate_timeout=0)
return _pix_container.write_data_to_file(pim_container, pim_filepath, ind, print_progress=True)
29 changes: 14 additions & 15 deletions addon/io_scs_tools/exp/pim/piece.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####

# Copyright (C) 2013-2014: SCS Software
# Copyright (C) 2013-2021: SCS Software

from collections import OrderedDict
from io_scs_tools.exp.pim.piece_stream import Stream
Expand Down Expand Up @@ -73,16 +73,14 @@ def __calc_vertex_hash(index, uvs, rgba, tangent):
:rtype: str
"""

frmt = "%.4f"

vertex_hash = str(index)
for uv in uvs:
vertex_hash = ''.join((vertex_hash, frmt % uv[0], frmt % uv[1]))
vertex_hash = "%s%.4f%.4f" % (vertex_hash, uv[0], uv[1])

vertex_hash = ''.join((vertex_hash, frmt % rgba[0], frmt % rgba[1], frmt % rgba[2], frmt % rgba[3]))
vertex_hash = "%s%.4f%.4f%.4f%.4f" % (vertex_hash, rgba[0], rgba[1], rgba[2], rgba[3])

if tangent:
vertex_hash = ''.join((vertex_hash, frmt % tangent[0], frmt % tangent[1], frmt % tangent[2], frmt % tangent[3]))
vertex_hash = "%s%.4f%.4f%.4f%.4f" % (vertex_hash, tangent[0], tangent[1], tangent[2], tangent[3])

return vertex_hash

Expand Down Expand Up @@ -122,16 +120,17 @@ def add_triangle(self, triangle):
:rtype:
"""

if len(triangle) != 3:
return False
else:
# check indecies integrity
for vertex in triangle:
if vertex < 0 or vertex >= self.__vertex_count:
return False
# expensive safety checks not needed for release but keep them for debug purposes
# if len(triangle) != 3:
# return False

# check indecies integrity
for vertex in triangle:
if vertex < 0 or vertex >= self.__vertex_count:
return False

self.__triangles.append(tuple(triangle))
Piece.__global_triangle_count += 1
self.__triangles.append(tuple(triangle))
Piece.__global_triangle_count += 1

return True

Expand Down
27 changes: 14 additions & 13 deletions addon/io_scs_tools/exp/pim/piece_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####

# Copyright (C) 2013-2014: SCS Software
# Copyright (C) 2013-2021: SCS Software


from io_scs_tools.internals.structure import SectionData as _SectionData
Expand Down Expand Up @@ -82,18 +82,19 @@ def add_entry(self, value):
:rtype: bool
"""

if self.__tag == Stream.Types.POSITION and len(value) != 3:
return False
if self.__tag == Stream.Types.NORMAL and len(value) != 3:
return False
if self.__tag == Stream.Types.TANGENT and len(value) != 4:
return False
if self.__tag == Stream.Types.RGB and len(value) != 3:
return False
if self.__tag == Stream.Types.RGBA and len(value) != 4:
return False
if self.__tag == Stream.Types.UV and len(value) != 2:
return False
# expensive safety checks not needed for release but keep them for debug purposes
# if self.__tag == Stream.Types.POSITION and len(value) != 3:
# return False
# if self.__tag == Stream.Types.NORMAL and len(value) != 3:
# return False
# if self.__tag == Stream.Types.TANGENT and len(value) != 4:
# return False
# if self.__tag == Stream.Types.RGB and len(value) != 3:
# return False
# if self.__tag == Stream.Types.RGBA and len(value) != 4:
# return False
# if self.__tag == Stream.Types.UV and len(value) != 2:
# return False

self.__data.append(tuple(value))
return True
Expand Down
40 changes: 28 additions & 12 deletions addon/io_scs_tools/exp/pim_ef/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####

# Copyright (C) 2017-2019: SCS Software
# Copyright (C) 2017-2021: SCS Software

import os
import collections
Expand All @@ -42,6 +42,7 @@
from io_scs_tools.utils.convert import change_to_scs_uv_coordinates as _change_to_scs_uv_coordinates
from io_scs_tools.utils.convert import get_scs_transformation_components as _get_scs_transformation_components
from io_scs_tools.utils.convert import scs_to_blend_matrix as _scs_to_blend_matrix
from io_scs_tools.utils.convert import hookup_name_to_hookup_id as _hookup_name_to_hookup_id
from io_scs_tools.utils.printout import lprint


Expand Down Expand Up @@ -111,12 +112,17 @@ def execute(dirpath, name_suffix, root_object, armature_object, skeleton_filepat
used_bones.add(bone.name)

# create mesh object data sections
for mesh_obj in mesh_objects:
mesh_objects_count = len(mesh_objects)
for mesh_i, mesh_obj in enumerate(mesh_objects):

if mesh_obj.mode != 'OBJECT':
lprint("W Invalid object mode detected on: %r, skipping it on export!", (mesh_obj.name,))
continue

lprint("I Preparing mesh object: %r - %i/%i (%i%%) ...",
(mesh_obj.name, mesh_i + 1, mesh_objects_count, ((mesh_i + 1) / mesh_objects_count * 100)),
immediate_timeout=2.5)

vert_groups = mesh_obj.vertex_groups

# calculate faces flip state from all ancestors of current object
Expand Down Expand Up @@ -419,7 +425,12 @@ def execute(dirpath, name_suffix, root_object, armature_object, skeleton_filepat
(list(objects_with_default_material.keys()),))

# create locators data sections
for loc_obj in model_locators:
model_locators_count = len(model_locators)
for loc_i, loc_obj in enumerate(model_locators):

lprint("I Preparing model locator: %r - %i/%i (%i%%) ...",
(loc_obj.name, loc_i + 1, model_locators_count, (loc_i + 1) / model_locators_count * 100),
immediate_timeout=2.5)

pos, qua, sca = _get_scs_transformation_components(root_object.matrix_world.inverted() @ loc_obj.matrix_world)

Expand All @@ -428,17 +439,21 @@ def execute(dirpath, name_suffix, root_object, armature_object, skeleton_filepat
"Model locators must have positive scale!", (loc_obj.name, root_object.name))
continue

name = _name_utils.tokenize_name(loc_obj.name)
hookup_string = loc_obj.scs_props.locator_model_hookup
if hookup_string != "" and ":" in hookup_string:
hookup = hookup_string.split(':', 1)[1].strip()
else:
if hookup_string != "":
lprint("W The Hookup %r has no expected value!", hookup_string)
hookup = None
hookup_id = _hookup_name_to_hookup_id(hookup_string)
if hookup_id:
hookup_payload = _object_utils.get_hookup_payload_string(loc_obj)

if len(hookup_payload) > 0:
hookup_id += '#'
hookup_id += hookup_payload

if hookup_string != "" and hookup_id is None:
lprint("W Model locator %r has unexpected hookup value %r.", (loc_obj.name, loc_obj.scs_props.locator_model_hookup))

# create locator object for export
locator = Locator(len(pim_locators), name, hookup)
name = _name_utils.tokenize_name(loc_obj.name)
locator = Locator(len(pim_locators), name, hookup_id)
locator.set_position(pos)
locator.set_rotation(qua)
locator.set_scale(sca)
Expand Down Expand Up @@ -484,4 +499,5 @@ def execute(dirpath, name_suffix, root_object, armature_object, skeleton_filepat
# write to file
ind = " "
pim_filepath = os.path.join(dirpath, root_object.name + ".pim" + name_suffix)
return _pix_container.write_data_to_file(pim_container, pim_filepath, ind)
lprint("I Writting PIM file to %r ...", (pim_filepath,), immediate_timeout=0)
return _pix_container.write_data_to_file(pim_container, pim_filepath, ind, print_progress=True)
3 changes: 2 additions & 1 deletion addon/io_scs_tools/exp/pip/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,5 +525,6 @@ def execute(dirpath, filename, name_suffix, prefab_locator_list, offset_matrix,
# write to file
ind = " "
pip_filepath = path.join(dirpath, str(filename + ".pip" + name_suffix))
result = _pix_container.write_data_to_file(pip_container, pip_filepath, ind)
lprint("I Writting PIP file to %r ...", (pip_filepath,), immediate_timeout=0)
result = _pix_container.write_data_to_file(pip_container, pip_filepath, ind, print_progress=True)
return result
4 changes: 2 additions & 2 deletions addon/io_scs_tools/exp/pit.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,9 @@ def get_texture_path_from_material(material, texture_type, export_path):

# search for relative path inside current scs project base and
# possible dlc/mod parent folders; use first found
for infix in ("", "../base/", "../base_vehicle/", "../../base/", "../../base_vehicle/"):
for infix in _path_utils.get_possible_project_infixes(include_zero_infix=True):

curr_path = os.path.join(scs_project_path, infix + texture_raw_path[2:] + ext)
curr_path = os.path.join(scs_project_path, infix + os.sep + texture_raw_path[2:] + ext)

if os.path.isfile(curr_path):

Expand Down
Loading

0 comments on commit 66c7fbc

Please sign in to comment.