Skip to content

Commit

Permalink
Beta - 0.5
Browse files Browse the repository at this point in the history
Changelog:
- new and better visualization of SCS materials based on Blender nodes system
- Look system implementation
- Lamp Tools - lamp material preview and helping tool for positioning UV mappings
- Wrap Tool - vertex colors wrapping
- collision Locators support
- added food cistern trailer data to sample_base
- other improvements like:
  - SCS Project Base path can be changed in import screen too
  - SCS Root Object is better visualized to clearly see
    how it is positioned and which axis points where
  - Vertex Colors range adopted to pipeline
    (0.5 is neutral; what is more will be brighten in game; what is less will be darken in game)
  - Added export success info if there is no errors and warnings during export
  • Loading branch information
simon50keda committed Apr 29, 2015
1 parent 11df243 commit 1782e44
Show file tree
Hide file tree
Showing 195 changed files with 165,826 additions and 16,692 deletions.
59 changes: 54 additions & 5 deletions addon/io_scs_tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,25 @@
"name": "SCS Tools",
"description": "Setup models, Import-Export SCS data format",
"author": "Milos Zajic (4museman), Simon Lusenc (50keda)",
"version": (0, 4),
"blender": (2, 70, 0),
"version": (0, 5),
"blender": (2, 73, 0),
"location": "File > Import-Export",
"warning": "WIP - beta version, doesn't include all features!",
"wiki_url": "https://github.com/SCSSoftware/BlenderTools/wiki",
"tracker_url": "",
"tracker_url": "http://forum.scssoft.com/viewforum.php?f=165",
"support": "COMMUNITY",
"category": "Import-Export"}

import bpy
import os
import traceback
from bpy.props import CollectionProperty, StringProperty, PointerProperty
from bpy.props import CollectionProperty, StringProperty, PointerProperty, BoolProperty
from bpy_extras.io_utils import ImportHelper, ExportHelper
from io_scs_tools.imp import pix as _pix_import
from io_scs_tools.internals.callbacks import open_gl as _open_gl_callback
from io_scs_tools.internals.callbacks import persistent as _persistent_callback
from io_scs_tools.utils import get_scs_globals as _get_scs_globals
from io_scs_tools.utils.view3d import switch_layers_visibility as _switch_layers_visibility
from io_scs_tools.utils.printout import lprint


Expand All @@ -60,10 +61,23 @@ class ImportSCS(bpy.types.Operator, ImportHelper):
description="File path used for importing the SCS files",
type=bpy.types.OperatorFileListElement)

scs_project_path_mode = BoolProperty(
default=False,
description="Set currently selected directory as SCS Project Path"
)

directory = StringProperty()
filename_ext = "*.pim"
filter_glob = StringProperty(default=filename_ext, options={'HIDDEN'})

def check(self, context):

if self.scs_project_path_mode:
_get_scs_globals().scs_project_path = os.path.dirname(self.filepath)
self.scs_project_path_mode = False

return True

def execute(self, context):
paths = [os.path.join(self.directory, name.name) for name in self.files]
if not paths:
Expand Down Expand Up @@ -123,7 +137,10 @@ def draw(self, context):
row.prop(scs_globals, "import_pim_file", toggle=True)
if scs_globals.import_pim_file:
row = box2.row()
row.prop(scs_globals, "auto_welding")
row.prop(scs_globals, "use_welding")
if scs_globals.use_welding:
row = box2.row()
row.prop(scs_globals, "welding_precision")
row = box2.row()
row.prop(scs_globals, "import_pit_file", toggle=True)
if scs_globals.import_pit_file:
Expand All @@ -146,6 +163,19 @@ def draw(self, context):
row = box2.row()
row.prop(scs_globals, "include_subdirs_for_pia")

# SCS Project Path
box3 = layout.box()
layout_box_col = box3.column(align=True)
layout_box_col.label('SCS Project Base Path:', icon='FILE_FOLDER')

layout_box_row = layout_box_col.row(align=True)
layout_box_row.alert = not os.path.isdir(scs_globals.scs_project_path)
layout_box_row.prop(scs_globals, 'scs_project_path', text='')

layout_box_row = layout_box_col.row(align=True)
layout_box_row.prop(self, "scs_project_path_mode", toggle=True, text="Set Current Dir as Project Base", icon='SAVE_COPY')

# Debug options
ui.shared.draw_debug_settings(layout)


Expand All @@ -159,6 +189,20 @@ class ExportSCS(bpy.types.Operator, ExportHelper):
filename_ext = ".pim"
filter_glob = StringProperty(default=str("*" + filename_ext), options={'HIDDEN'})

layers_visibilities = []
"""List for storing layers visibility in the init of operator"""

def __init__(self):
"""Constructor used for showing all scene visibility layers.
This provides possibility to updates world matrixes even on hidden objects.
"""
self.layers_visibilities = _switch_layers_visibility([], True)

def __del__(self):
"""Destructor with reverting visible layers.
"""
_switch_layers_visibility(self.layers_visibilities, False)

def execute(self, context):
lprint('D Export From Menu...')

Expand Down Expand Up @@ -235,6 +279,10 @@ def register():
bpy.utils.register_module(__name__)

# PROPERTIES REGISTRATION
bpy.types.Object.scs_object_look_inventory = CollectionProperty(
type=properties.object.ObjectLooksInventory
)

bpy.types.Object.scs_object_part_inventory = CollectionProperty(
type=properties.object.ObjectPartInventory
)
Expand Down Expand Up @@ -339,6 +387,7 @@ def unregister():
del bpy.types.Object.scs_props
del bpy.types.World.scs_globals

del bpy.types.Object.scs_object_look_inventory
del bpy.types.Object.scs_object_part_inventory
del bpy.types.Object.scs_object_variant_inventory
del bpy.types.Object.scs_object_animation_inventory
Expand Down
76 changes: 75 additions & 1 deletion addon/io_scs_tools/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
Constants for data group of map and navigation curves
"""

from enum import Enum


class ConnectionsStorage:
"""Constants related for storage of connections used in custom drawing
Expand Down Expand Up @@ -108,4 +110,76 @@ class Variant:
"""Constants related to 'SCS Variants'
"""
default_name = "default"
"""Default name for variant"""
"""Default name for variant"""


class Look:
"""Constants related to 'SCS Looks'
"""
custom_prop_name = "scs_looks_data"
"""Name of the Blender Custom Property where dictionary for looks will be stored"""
default_name = "default"
"""Default name for look"""


class Material:
"""Constants related to materials
"""
unset_bitmap_filepath = ""
"""Unset value of each texture filepath (used for identifying if this value in material was set)"""
unset_substance = "None"
"""Unset value of material substance (used for identifying if this value in material was set)"""


class LampTools:
"""Constants related to lampmask and it's tools
"""

class VehicleSides(Enum):
"""Defined sides of vehicles.
"""
FrontLeft = 0
FrontRight = 1
RearLeft = 2
RearRight = 3
Middle = 4

class VehicleLampTypes(Enum):
"""Defined lamp types for vehicles.
"""
LeftTurn = 0
RightTurn = 1
Brake = 2
HighBeam = 3
LowBeam = 4
Reverse = 5
DRL = 6
Positional = 7

class AuxiliaryLampColors(Enum):
"""Defined vehicle auxiliary light colors.
"""
White = 0
Orange = 1

class AuxiliaryLampTypes(Enum):
"""Defined lamp types for vehicle auxiliary lights.
"""
Dim = 0
Bright = 1

class TrafficLightTypes(Enum):
"""Defined lamp types for traffic lights.
"""
Red = 0
Yellow = 1
Green = 2


class VertexColorTools:
"""Constants related to vertex color tools
"""

class WrapType:
All = "all"
Selected = "selected"
12 changes: 11 additions & 1 deletion addon/io_scs_tools/exp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ def batch_export(operator_instance, init_obj_list, exclude_switched_off=True, me
global_filepath = os.path.join(scs_project_path, default_export_path.strip(os.sep * 2))

for root_object in game_objects_dict:

# update root object location to invoke update tagging on it and
# then update scene to make sure all children objects will have all transforms up to date
# NOTE: needed because Blender doesn't update objects on invisible layers on it's own
root_object.location = root_object.location
for scene in bpy.data.scenes:
scene.update()

game_object_list = game_objects_dict[root_object]

# GET CUSTOM FILE PATH
Expand Down Expand Up @@ -110,7 +118,9 @@ def batch_export(operator_instance, init_obj_list, exclude_switched_off=True, me
operator_instance.report({'ERROR'}, message.replace("\t", "").replace(" ", ""))
return {'CANCELLED'}

lprint("\nI Export procces completed, summaries are printed below!", report_errors=True, report_warnings=True)
if not lprint("\nI Export procces completed, summaries are printed below!", report_errors=True, report_warnings=True):
operator_instance.report({'INFO'}, "Export successfully completed!")

if len(scs_game_objects_exported) > 0:
print("\n\nEXPORTED GAME OBJECTS:\n" + "=" * 22)
for scs_game_object_export_message in scs_game_objects_exported:
Expand Down
13 changes: 8 additions & 5 deletions addon/io_scs_tools/exp/pic.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from io_scs_tools.utils import get_scs_globals as _get_scs_globals
from io_scs_tools.utils.info import get_tools_version as _get_tools_version
from io_scs_tools.utils.info import get_blender_version as _get_blender_version
from io_scs_tools.utils.object import get_scs_root as _get_scs_root


def _fill_header_section(file_name, sign_export):
Expand Down Expand Up @@ -186,6 +187,8 @@ def _fill_part_sections(locator_list, used_parts):


def _make_common_part(item, index, col_type):
scs_root = _get_scs_root(item)

if not item.scs_props.locator_collider_centered:
if item.scs_props.locator_collider_type == 'Box':
offset_matrix = (item.matrix_world *
Expand All @@ -204,9 +207,9 @@ def _make_common_part(item, index, col_type):
else:
offset_matrix = item.matrix_world

loc, qua, sca = _convert_utils.get_scs_transformation_components(offset_matrix)
loc, qua, sca = _convert_utils.get_scs_transformation_components(scs_root.matrix_world.inverted() * offset_matrix)
else:
loc, qua, sca = _convert_utils.get_scs_transformation_components(item.matrix_world)
loc, qua, sca = _convert_utils.get_scs_transformation_components(scs_root.matrix_world.inverted() * item.matrix_world)

section = _SectionData("Locator")
section.props.append(("Name", _name_utils.tokenize_name(item.name)))
Expand Down Expand Up @@ -235,13 +238,13 @@ def _fill_collision_locator_sections(collision_locator_list):
item.scs_props.locator_collider_box_x, item.scs_props.locator_collider_box_z, item.scs_props.locator_collider_box_y, 0.0)]))
elif loc_type == "Sphere":
# radius
section.props.append(("Parameters", ["&&", (item.scs_props.locator_collider_dia, 0.0, 0.0, 0.0)]))
section.props.append(("Parameters", ["&&", (item.scs_props.locator_collider_dia / 2, 0.0, 0.0, 0.0)]))
elif loc_type == "Capsule":
# radius length
section.props.append(("Parameters", ["&&", (item.scs_props.locator_collider_dia, item.scs_props.locator_collider_len, 0.0, 0.0)]))
section.props.append(("Parameters", ["&&", (item.scs_props.locator_collider_dia / 2, item.scs_props.locator_collider_len, 0.0, 0.0)]))
elif loc_type == "Cylinder":
# radius length
section.props.append(("Parameters", ["&&", (item.scs_props.locator_collider_dia, item.scs_props.locator_collider_len, 0.0, 0.0)]))
section.props.append(("Parameters", ["&&", (item.scs_props.locator_collider_dia / 2, item.scs_props.locator_collider_len, 0.0, 0.0)]))
elif loc_type == "Convex":
section.props.append(("ConvexPiece", piece_index))
piece_index += 1
Expand Down
43 changes: 29 additions & 14 deletions addon/io_scs_tools/exp/pim/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,25 @@ def execute(dirpath, root_object, mesh_objects, model_locators, used_parts, used

mesh_pieces = collections.OrderedDict()

# get initial mesh
mesh = _object_utils.get_mesh(mesh_obj)
_mesh_utils.bm_triangulate(mesh)
mesh.calc_normals_split()
# calculate faces flip state from all ancestors of current object
scale_sign = 1
for scale_axis in mesh_obj.scale:
scale_sign *= scale_axis
face_flip = scale_sign < 0

# calculate transformation matrix for current object (root object transforms are always subtracted!)
mesh_transf_mat = root_object.matrix_world.inverted() * mesh_obj.matrix_world

# calculate transformation matrices for this object
pos_transf_mat = (Matrix.Scale(scs_globals.export_scale, 4) *
_scs_to_blend_matrix().inverted() *
root_object.matrix_world.inverted() *
mesh_obj.matrix_world)
_scs_to_blend_matrix().inverted())

nor_transf_mat = _scs_to_blend_matrix().inverted()

nor_transf_mat = (_scs_to_blend_matrix().inverted() *
root_object.matrix_world.inverted().to_quaternion().to_matrix().to_4x4() *
mesh_obj.matrix_world.to_quaternion().to_matrix().to_4x4())
# get initial mesh
mesh = _object_utils.get_mesh(mesh_obj)
_mesh_utils.bm_prepare_mesh_for_export(mesh, mesh_transf_mat, face_flip)
mesh.calc_normals_split()

missing_uv_layers = {} # stores missing uvs specified by materials of this object
missing_vcolor = False # indicates if object is missing vertex colors
Expand Down Expand Up @@ -196,7 +201,7 @@ def execute(dirpath, root_object, mesh_objects, model_locators, used_parts, used
else:
multiplier = mesh_obj.data.scs_props.vertex_color_multiplier
color = mesh.vertex_colors[0].data[loop_i].color
vcol = (color[0] * multiplier, color[1] * multiplier, color[2] * multiplier, 1.0)
vcol = (color[0] * 2 * multiplier, color[1] * 2 * multiplier, color[2] * 2 * multiplier, 1.0)

# 5. tangent -> loop.tangent; loop.bitangent_sign -> calc_tangents() has to be called before
if pim_materials[pim_mat_name].get_nmap_uv_name(): # calculate tangents only if needed
Expand All @@ -212,6 +217,9 @@ def execute(dirpath, root_object, mesh_objects, model_locators, used_parts, used

mesh_piece.add_triangle(tuple(piece_vert_indices[::-1])) # invert indices because of normals flip

# free normals calculations
_mesh_utils.cleanup_mesh(mesh)

# create part if it doesn't exists yet
part_name = mesh_obj.scs_props.scs_part
if part_name not in pim_parts:
Expand All @@ -233,9 +241,9 @@ def execute(dirpath, root_object, mesh_objects, model_locators, used_parts, used
lprint("W Object '%s' is missing UV layer '%s' specified by materials: %s\n",
(mesh_obj.name, uv_lay_name, missing_uv_layers[uv_lay_name]))
if missing_vcolor:
lprint("W Object '%s' is missing vertex color layer! Default color will be exported (1, 1, 1, 1)!", (mesh_obj.name,))
lprint("W Object '%s' is missing vertex color layer! Default RGB color will be exported (0.5, 0.5, 0.5)!", (mesh_obj.name,))

# report mising data for whole model
# report missing data for whole model
if len(missing_mappings_data) > 0:
for material_name in missing_mappings_data:
lprint("W Material '%s' is missing mapping data! Objects using it are exported with default UV:\n\t %s",
Expand All @@ -246,6 +254,14 @@ def execute(dirpath, root_object, mesh_objects, model_locators, used_parts, used

# create locators data sections
for loc_obj in model_locators:

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

if sca[0] * sca[1] * sca[2] < 0:
lprint("W Model locator %r inside SCS Root Object %r not exported because of invalid scale.\n\t " +
"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:
Expand All @@ -254,7 +270,6 @@ def execute(dirpath, root_object, mesh_objects, model_locators, used_parts, used
if hookup_string != "":
lprint("W The Hookup %r has no expected value!", hookup_string)
hookup = None
pos, qua, sca = _get_scs_transformation_components(loc_obj.matrix_world)

# create locator object for export
locator = Locator(len(pim_locators), name, hookup)
Expand Down
2 changes: 1 addition & 1 deletion addon/io_scs_tools/exp/pim/material.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def __init__(self, index, alias, effect, blend_mat):
# if imported just use custom mappings defined separetly
if blend_mat.scs_props.active_shader_preset_name == "<imported>":

custom_tex_coord_maps = blend_mat.scs_props.shader_custom_tex_coord_maps
custom_tex_coord_maps = blend_mat.scs_props.custom_tex_coord_maps
for custom_tex_coord_map in custom_tex_coord_maps:

if custom_tex_coord_map.value != "":
Expand Down
Loading

0 comments on commit 1782e44

Please sign in to comment.