Skip to content

Commit

Permalink
Release - 1.6
Browse files Browse the repository at this point in the history
  • Loading branch information
simon50keda committed Feb 24, 2017
1 parent 30f0420 commit 532e992
Show file tree
Hide file tree
Showing 23 changed files with 986 additions and 530 deletions.
7 changes: 1 addition & 6 deletions addon/io_scs_tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"name": "SCS Tools",
"description": "Setup models, Import-Export SCS data format",
"author": "Simon Lusenc (50keda), Milos Zajic (4museman)",
"version": (1, 5, "78732b8"),
"version": (1, 6, "780f5be"),
"blender": (2, 78, 0),
"location": "File > Import-Export",
"wiki_url": "http://modding.scssoft.com/wiki/Documentation/Tools/SCS_Blender_Tools",
Expand Down Expand Up @@ -334,10 +334,6 @@ def register():
type=properties.object.ObjectAnimationInventoryItem
)

bpy.types.World.scs_shader_presets_inventory = CollectionProperty(
type=properties.world.ShaderPresetsInventoryItem
)

bpy.types.World.scs_globals = PointerProperty(
name="SCS Tools Global Variables",
type=properties.world.GlobalSCSProps,
Expand Down Expand Up @@ -413,7 +409,6 @@ def unregister():
del bpy.types.Object.scs_object_part_inventory
del bpy.types.Object.scs_object_variant_inventory
del bpy.types.Object.scs_object_animation_inventory
del bpy.types.World.scs_shader_presets_inventory


if __name__ == "__main__":
Expand Down
9 changes: 4 additions & 5 deletions addon/io_scs_tools/exp/pit.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@
from io_scs_tools.consts import Variant as _VARIANT_consts
from io_scs_tools.exp import tobj as _tobj
from io_scs_tools.internals import looks as _looks
from io_scs_tools.internals import shader_presets as _shader_presets
from io_scs_tools.internals.structure import SectionData as _SectionData
from io_scs_tools.internals.containers import pix as _pix_container
from io_scs_tools.internals.shader_presets import cache as _shader_presets_cache
from io_scs_tools.utils import path as _path_utils
from io_scs_tools.utils import get_scs_globals as _get_scs_globals
from io_scs_tools.utils import get_shader_presets_inventory as _get_shader_presets_inventory
from io_scs_tools.utils.info import get_combined_ver_str
from io_scs_tools.utils.printout import lprint

Expand Down Expand Up @@ -412,11 +411,11 @@ def export(root_object, filepath, used_materials, used_parts):
attribute_sections.append(substance_data)
attribute_cnt += 1

if active_shader_preset_name in _get_shader_presets_inventory() and active_shader_preset_name != "<none>":
if _shader_presets.has_preset(active_shader_preset_name) and active_shader_preset_name != "<none>":

preset = _get_shader_presets_inventory()[active_shader_preset_name]
preset = _shader_presets.get_preset(active_shader_preset_name)
flavors_str = effect_name[len(preset.effect):]
section = _shader_presets_cache.get_section(preset, flavors_str)
section = _shader_presets.get_section(active_shader_preset_name, flavors_str)

# FLAGS
for prop in section.props:
Expand Down
10 changes: 10 additions & 0 deletions addon/io_scs_tools/imp/pit.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,16 @@ def _get_look(section):
mat_alias = sec_prop[1]
elif sec_prop[0] == "Effect":
mat_effect = sec_prop[1]

# HACK for "flipflake" flavor in eut2.truckpaint shader
#
# Flavor was never been visually implemented in Blender as it doesn't effect exported mesh data.
# This means we can "silently" ignore it on import as this flavor
# should be used only trough paint-job definitions for player vehicles.
if mat_effect.startswith("eut2.truckpaint") and mat_effect.find(".flipflake") != -1:
mat_effect = mat_effect.replace(".flipflake", "")
lprint("W Flipflake flavor detected in material %r, ignoring it!", (mat_alias,))

elif sec_prop[0] == "Flags":
mat_flags = sec_prop[1]
elif sec_prop[0] == "AttributeCount":
Expand Down
139 changes: 139 additions & 0 deletions addon/io_scs_tools/internals/callbacks/lighting_east_lock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####

# Copyright (C) 2017: SCS Software

import bpy
from math import pi
from io_scs_tools.consts import SCSLigthing as _LIGHTING_consts
from io_scs_tools.utils import view3d as _view3d_utils
from io_scs_tools.utils import get_scs_globals as _get_scs_globals

_callback = {
"handle": None,
"initial_view_rotation": -1,
"initial_lamp_rotation": 0
}


def _get_diffuse_and_specular_lamps_from_scs_lighting():
if _LIGHTING_consts.scene_name not in bpy.data.scenes:
return None, None

lighting_scene = bpy.data.scenes[_LIGHTING_consts.scene_name]

if _LIGHTING_consts.diffuse_lamp_name not in lighting_scene.objects:
return None, None

diffuse_lamp_obj = lighting_scene.objects[_LIGHTING_consts.diffuse_lamp_name]

if _LIGHTING_consts.specular_lamp_name not in lighting_scene.objects:
return None, None

specular_lamp_obj = lighting_scene.objects[_LIGHTING_consts.specular_lamp_name]

return diffuse_lamp_obj, specular_lamp_obj


def _lightning_east_lock_draw_callback(reset):
# implicitly kill east lock draw callback if Blender has more 3d view spaces,
# because in that case lights can not be properly rotated as no one knows which view should be used as active
if not reset and _view3d_utils.has_multiple_view3d_spaces():
disable()
_get_scs_globals().lighting_east_lock = False
_view3d_utils.tag_redraw_all_regions()
return

# 1. check lighting scene integrity and region data integrity and
# finish callback if everything is not up and ready
diffuse_lamp_obj, specular_lamp_obj = _get_diffuse_and_specular_lamps_from_scs_lighting()
if diffuse_lamp_obj is None or specular_lamp_obj is None:
return

if reset:

east_rotation = _get_scs_globals().lighting_scene_east_direction * pi / 180.0

else:

if not hasattr(bpy.context.region_data, "view_rotation"):
return

current_view_rot = bpy.context.region_data.view_rotation.to_euler('XYZ')
current_view_z_rot = current_view_rot.y + current_view_rot.z # because of axis flipping always combine y and z

# 2. on first run just remember initial rotation and end callback
if _callback["initial_view_rotation"] == -1:
_callback["initial_lamp_rotation"] = diffuse_lamp_obj.rotation_euler[2]
_callback["initial_view_rotation"] = current_view_z_rot
return

# 3. recalculate current east direction
east_rotation = current_view_z_rot - _callback["initial_view_rotation"] + _callback["initial_lamp_rotation"]

# as last apply rotations to lamps
if abs(east_rotation - diffuse_lamp_obj.rotation_euler[2]) > 0.001:
diffuse_lamp_obj.rotation_euler[2] = east_rotation

if abs(east_rotation - specular_lamp_obj.rotation_euler[2]) > 0.001:
specular_lamp_obj.rotation_euler[2] = east_rotation


def correct_lighting_east():
"""Corrects lighting east depending on current rotation of directed lamps in SCS Lighting scene
"""
diffuse_lamp_obj, specular_lamp_obj = _get_diffuse_and_specular_lamps_from_scs_lighting()
if diffuse_lamp_obj is None:
return

_get_scs_globals().lighting_scene_east_direction = (diffuse_lamp_obj.rotation_euler[2] * 180 / pi + 360) % 360


def set_lighting_east():
"""Sets lighting east according to current value set in SCS Globals.
"""
_lightning_east_lock_draw_callback(True)


def enable():
"""Append SCS Lighting east lock callback.
"""
if _callback["handle"]:
disable()

handle_pre_view = bpy.types.SpaceView3D.draw_handler_add(_lightning_east_lock_draw_callback, (False,), 'WINDOW', 'PRE_VIEW')
_callback["handle"] = handle_pre_view
_callback["initial_view_rotation"] = -1
_callback["initial_lamp_rotation"] = 0


def disable():
"""Remove SCS Lighting east lock callback.
"""
if not _callback["handle"]:
return

handle_pre_view = _callback["handle"]
bpy.types.SpaceView3D.draw_handler_remove(handle_pre_view, 'WINDOW')
_callback["handle"] = None
_callback["initial_view_rotation"] = -1
_callback["initial_lamp_rotation"] = 0
60 changes: 31 additions & 29 deletions addon/io_scs_tools/internals/containers/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
from io_scs_tools.utils import property as _property_utils
from io_scs_tools.utils import get_scs_globals as _get_scs_globals
from io_scs_tools.utils.info import get_combined_ver_str
from io_scs_tools.internals import shader_presets as _shader_presets
from io_scs_tools.internals.containers import pix as _pix
from io_scs_tools.internals.containers import sii as _sii
from io_scs_tools.internals.shader_presets import cache as _shader_presets_cache
from io_scs_tools.internals.structure import SectionData as _SectionData
from io_scs_tools.operators.world import SCSPathsInitialization as _SCSPathsInitialization

Expand Down Expand Up @@ -79,27 +79,26 @@ def update_item_in_file(item_pointer, new_value):
return True


def update_shader_presets_path(scs_shader_presets_inventory, shader_presets_filepath):
def update_shader_presets_path(shader_presets_filepath):
"""The function deletes and populates again a list of Shader Preset items in inventory. It also updates corresponding record in config file.
:param shader_presets_filepath: Absolute or relative path to the file with Shader Presets
:type shader_presets_filepath: str
"""
shader_presets_abs_path = _path_utils.get_abs_path(shader_presets_filepath)

if _shader_presets_cache.is_initilized(shader_presets_abs_path):
lprint("I Shader presets cache is up-to date, no update will happen!")
if _shader_presets.is_library_initialized(shader_presets_abs_path):
lprint("I Shader presets library is up-to date, no update will happen!")
return

# CLEAR INVENTORY AND CACHE
scs_shader_presets_inventory.clear()
_shader_presets_cache.clear()
_shader_presets.clear()

# ADD DEFAULT PRESET ITEM "<none>" INTO INVENTORY
_shader_presets.add_section("<none>", "<none>", "", None)

if os.path.isfile(shader_presets_abs_path):

# ADD DEFAULT PRESET ITEM "<none>" INTO INVENTORY
new_shader_preset = scs_shader_presets_inventory.add()
new_shader_preset.name = "<none>"
presets_container = _pix.get_data_from_file(shader_presets_abs_path, ' ')

# ADD ALL SHADER PRESET ITEMS FROM FILE INTO INVENTORY
Expand Down Expand Up @@ -136,19 +135,17 @@ def update_shader_presets_path(scs_shader_presets_inventory, shader_presets_file
shader_flavors = shader.get_prop_value("Flavors")

# create new preset item
new_shader_preset = scs_shader_presets_inventory.add()
new_shader_preset.name = shader.get_prop_value("PresetName")
new_shader_preset.effect = shader.get_prop_value("Effect")

shader_preset_name = shader.get_prop_value("PresetName")
shader_preset_effect = shader.get_prop_value("Effect")
unique_names.append("")
_shader_presets_cache.add_section(new_shader_preset, "", shader)
_shader_presets.add_section(shader_preset_effect, shader_preset_name, "", shader)

if shader_flavors:

for j, flavor_types in enumerate(shader_flavors):

# create new flavor item
flavor_item = new_shader_preset.flavors.add()
_shader_presets.add_flavor(shader_preset_name)

new_unique_names = []
for i, flavor_type in enumerate(flavor_types.split("|")):
Expand All @@ -157,25 +154,24 @@ def update_shader_presets_path(scs_shader_presets_inventory, shader_presets_file
lprint("D Flavor used by shader preset, but not defined: %s", (flavor_type,))
continue

# create new flavor variant item (when flavor has more variants eg. "BLEND_ADD|BLEND_OVER")
flavor_variant = flavor_item.variants.add()
flavor_variant.name = flavors[flavor_type].get_prop_value("Name")
flavor_variant.preset_name = new_shader_preset.name
# create new flavor variant item (there can be more variants eg. "BLEND_ADD|BLEND_OVER")
flavor_variant_name = flavors[flavor_type].get_prop_value("Name")
_shader_presets.add_flavor_variant(shader_preset_name, flavor_variant_name)

# modify and save section as string into cache
for unique_name in unique_names:

new_unique_str = unique_name + "." + flavors[flavor_type].get_prop_value("Name")
full_effect_name = new_shader_preset.effect + new_unique_str
new_unique_str = unique_name + "." + flavor_variant_name
new_full_effect_name = shader_preset_effect + new_unique_str

# check if this shader-flavor combination can exists, if not skip it
if supported_effects_dict and full_effect_name not in supported_effects_dict:
lprint("S Marking none existing effect as dirty: %r", (full_effect_name,))
if supported_effects_dict and new_full_effect_name not in supported_effects_dict:
lprint("S Marking none existing effect as dirty: %r", (new_full_effect_name,))
is_dirty = True
else:
is_dirty = False

section = _shader_presets_cache.get_section(new_shader_preset, unique_name)
section = _shader_presets.get_section(shader_preset_name, unique_name)

for flavor_section in flavors[flavor_type].sections:

Expand All @@ -195,14 +191,14 @@ def update_shader_presets_path(scs_shader_presets_inventory, shader_presets_file
section.sections.append(flavor_section)

new_unique_names.append(new_unique_str)
assert section.set_prop_value("Effect", new_shader_preset.effect + new_unique_str)
_shader_presets_cache.add_section(new_shader_preset, new_unique_str, section, is_dirty=is_dirty)
assert section.set_prop_value("Effect", shader_preset_effect + new_unique_str)
_shader_presets.add_section(shader_preset_effect, shader_preset_name, new_unique_str, section, is_dirty=is_dirty)

unique_names.extend(new_unique_names)

# now as we built cache it's time to clean it up of dirty items (eg. none existing effect combinations) and
# set path from which this cache was initialized
_shader_presets_cache.set_initialized(shader_presets_abs_path)
# now as we built library it's time to clean it up of dirty items (eg. none existing effect combinations) and
# set path from which this library was initialized
_shader_presets.set_library_initialized(shader_presets_abs_path)

update_item_in_file('Paths.ShaderPresetsFilePath', shader_presets_filepath)

Expand Down Expand Up @@ -938,6 +934,12 @@ def apply_settings():
if prop[1] == "BlendFile":
settings_file_valid += 1

# as dump level can be read already (it can be placed above config storage place property),
# reset local variable back to value that was saved with blend file
dump_level = scs_globals.dump_level

break # to avoid further reading of header properties, so dump_level won't be overwritten unintentionally

scs_globals.dump_level = dump_level

# now as last apply all of the file paths
Expand Down
4 changes: 2 additions & 2 deletions addon/io_scs_tools/internals/persistent/file_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
import bpy
from bpy.app.handlers import persistent
from io_scs_tools.internals import looks as _looks
from io_scs_tools.internals import shader_presets as _shader_presets
from io_scs_tools.operators.world import SCSPathsInitialization as _SCSPathsInitialization
from io_scs_tools.utils import material as _material_utils
from io_scs_tools.utils import object as _object_utils
from io_scs_tools.utils import info as _info_utils
from io_scs_tools.utils import get_scs_globals as _get_scs_globals
from io_scs_tools.utils import get_shader_presets_inventory as _get_shader_presets_inventory


@persistent
Expand Down Expand Up @@ -118,7 +118,7 @@ def apply_fixes_for_0_6():
update_func(material)

# ignore already properly set materials
if material.scs_props.active_shader_preset_name in _get_shader_presets_inventory():
if _shader_presets.has_preset(material.scs_props.active_shader_preset_name):
continue

# 3. try to recover "active_shader_preset_name" from none flavor times Blender Tools
Expand Down
11 changes: 11 additions & 0 deletions addon/io_scs_tools/internals/persistent/initialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from bpy.app.handlers import persistent
from io_scs_tools.internals import preview_models as _preview_models
from io_scs_tools.internals.callbacks import open_gl as _open_gl_callback
from io_scs_tools.internals.callbacks import lighting_east_lock as _lighting_east_lock_callback
from io_scs_tools.internals.containers import config as _config_container
from io_scs_tools.internals.connections.wrappers import group as _connections_group_wrapper
from io_scs_tools.utils import get_scs_globals as _get_scs_globals
Expand Down Expand Up @@ -84,6 +85,16 @@ def initialise_scs_dict(scene):
# ADD DRAW HANDLERS
_open_gl_callback.enable(mode=_get_scs_globals().drawing_mode)

# ENABLE LIGHTING EAST LOCK HANDLER
# Blender doesn't call update on properties when file is opened,
# so in case lighting east was locked in saved blend file, we have to manually enable callback for it
# On the other hand if user previously had east locked and now loaded the file without it,
# again we have to manually disable callback.
if _get_scs_globals().lighting_east_lock:
_lighting_east_lock_callback.enable()
else:
_lighting_east_lock_callback.disable()

# as last notify user if his Blender version is outdated
if not _info_utils.is_blender_able_to_run_tools():

Expand Down
Loading

0 comments on commit 532e992

Please sign in to comment.