def _create_trigger_locator(trp_name, trp_action, trp_range, trp_reset_delay, trp_flags, trp_position, scs_trigger_actions_inventory): locator = _object_utils.create_locator_empty(trp_name, trp_position, (0, 0, 0), (1, 1, 1), 0.1, 'Prefab') if locator: locator.scs_props.locator_prefab_type = 'Trigger Point' action_value = _inventory.get_item_name(scs_trigger_actions_inventory, trp_action, report_errors=True) locator.scs_props.locator_prefab_tp_action = action_value locator.scs_props.locator_prefab_tp_range = trp_range locator.scs_props.locator_prefab_tp_reset_delay = trp_reset_delay locator.scs_props.locator_prefab_tp_manual_activ = ( trp_flags & _PL_consts.TPF.MANUAL) != 0 locator.scs_props.locator_prefab_tp_sphere_trigger = ( trp_flags & _PL_consts.TPF.SPHERE) != 0 locator.scs_props.locator_prefab_tp_partial_activ = ( trp_flags & _PL_consts.TPF.PARTIAL) != 0 locator.scs_props.locator_prefab_tp_onetime_activ = ( trp_flags & _PL_consts.TPF.ONETIME) != 0 return locator
def _create_traffic_light_locator( tsem_name, tsem_position, tsem_rotation, tsem_type, tsem_id, tsem_intervals, tsem_cycle, tsem_profile, scs_tsem_profile_inventory ): locator = _object_utils.create_locator_empty(tsem_name, tsem_position, tsem_rotation, (1, 1, 1), 0.1, 'Prefab') if locator: locator.scs_props.locator_prefab_type = 'Traffic Semaphore' locator.scs_props.locator_prefab_tsem_id = str(tsem_id) # try to set semaphore profile only if it has some value if tsem_profile != "": tsem_profile_value = _inventory.get_item_name(scs_tsem_profile_inventory, tsem_profile, report_errors=True) locator.scs_props.locator_prefab_tsem_profile = tsem_profile_value locator.scs_props.locator_prefab_tsem_type = str(tsem_type) locator.scs_props.locator_prefab_tsem_gs = tsem_intervals[0] locator.scs_props.locator_prefab_tsem_os1 = tsem_intervals[1] locator.scs_props.locator_prefab_tsem_rs = tsem_intervals[2] locator.scs_props.locator_prefab_tsem_os2 = tsem_intervals[3] locator.scs_props.locator_prefab_tsem_cyc_delay = tsem_cycle return locator
def _create_trigger_locator( trp_name, trp_action, trp_range, trp_reset_delay, trp_flags, trp_position, scs_trigger_actions_inventory ): locator = _object_utils.create_locator_empty(trp_name, trp_position, (0, 0, 0), (1, 1, 1), 0.1, 'Prefab') if locator: locator.scs_props.locator_prefab_type = 'Trigger Point' action_value = _inventory.get_item_name(scs_trigger_actions_inventory, trp_action, report_errors=True) locator.scs_props.locator_prefab_tp_action = action_value locator.scs_props.locator_prefab_tp_range = trp_range locator.scs_props.locator_prefab_tp_reset_delay = trp_reset_delay locator.scs_props.locator_prefab_tp_manual_activ = (trp_flags & _PL_consts.TPF.MANUAL) != 0 locator.scs_props.locator_prefab_tp_sphere_trigger = (trp_flags & _PL_consts.TPF.SPHERE) != 0 locator.scs_props.locator_prefab_tp_partial_activ = (trp_flags & _PL_consts.TPF.PARTIAL) != 0 locator.scs_props.locator_prefab_tp_onetime_activ = (trp_flags & _PL_consts.TPF.ONETIME) != 0 return locator
def _create_spawn_locator(spawn_name, spawn_position, spawn_rotation, spawn_type): locator = _object_utils.create_locator_empty(spawn_name, spawn_position, spawn_rotation, (1, 1, 1), 0.1, 'Prefab') if locator: locator.scs_props.locator_prefab_type = 'Spawn Point' locator.scs_props.locator_prefab_spawn_type = str(spawn_type) return locator
def _create_node_locator(node_name, node_index, node_position, node_direction): locator = _object_utils.create_locator_empty( node_name, node_position, (math.radians(node_direction[0]), math.radians(node_direction[1]), math.radians(node_direction[2])), (1, 1, 1), 0.1, 'Prefab') if locator: locator.scs_props.locator_prefab_type = 'Control Node' locator.scs_props.locator_prefab_con_node_index = str(node_index) return locator
def _create_spawn_locator( spawn_name, spawn_position, spawn_rotation, spawn_type ): locator = _object_utils.create_locator_empty(spawn_name, spawn_position, spawn_rotation, (1, 1, 1), 0.1, 'Prefab') if locator: locator.scs_props.locator_prefab_type = 'Spawn Point' locator.scs_props.locator_prefab_spawn_type = str(spawn_type) return locator
def _create_map_locator( map_name, map_visual_flags, map_nav_flags, map_position, ): locator = _object_utils.create_locator_empty(map_name, map_position, (0, 0, 0), (1, 1, 1), 0.1, 'Prefab') if locator: locator.scs_props.locator_prefab_type = 'Map Point' # visual flags locator.scs_props.locator_prefab_mp_road_over = (map_visual_flags & _PL_consts.MPVF.ROAD_OVER) != 0 locator.scs_props.locator_prefab_mp_no_outline = (map_visual_flags & _PL_consts.MPVF.NO_OUTLINE) != 0 locator.scs_props.locator_prefab_mp_no_arrow = (map_visual_flags & _PL_consts.MPVF.NO_ARROW) != 0 locator.scs_props.locator_prefab_mp_road_size = str(map_visual_flags & _PL_consts.MPVF.ROAD_SIZE_MASK) locator.scs_props.locator_prefab_mp_road_offset = str(map_visual_flags & _PL_consts.MPVF.ROAD_OFFSET_MASK) if map_visual_flags & _PL_consts.MPVF.CUSTOM_COLOR1 != 0: locator.scs_props.locator_prefab_mp_custom_color = str(_PL_consts.MPVF.CUSTOM_COLOR1) elif map_visual_flags & _PL_consts.MPVF.CUSTOM_COLOR2 != 0: locator.scs_props.locator_prefab_mp_custom_color = str(_PL_consts.MPVF.CUSTOM_COLOR2) elif map_visual_flags & _PL_consts.MPVF.CUSTOM_COLOR3 != 0: locator.scs_props.locator_prefab_mp_custom_color = str(_PL_consts.MPVF.CUSTOM_COLOR3) # navigation flags locator.scs_props.locator_prefab_mp_prefab_exit = (map_nav_flags & _PL_consts.MPNF.PREFAB_EXIT) != 0 if map_nav_flags & _PL_consts.MPNF.NAV_NODE_START != 0: if map_nav_flags & _PL_consts.MPNF.NAV_NODE_0 != 0: locator.scs_props.locator_prefab_mp_assigned_node = str(_PL_consts.MPNF.NAV_NODE_0) elif map_nav_flags & _PL_consts.MPNF.NAV_NODE_1 != 0: locator.scs_props.locator_prefab_mp_assigned_node = str(_PL_consts.MPNF.NAV_NODE_1) elif map_nav_flags & _PL_consts.MPNF.NAV_NODE_2 != 0: locator.scs_props.locator_prefab_mp_assigned_node = str(_PL_consts.MPNF.NAV_NODE_2) elif map_nav_flags & _PL_consts.MPNF.NAV_NODE_3 != 0: locator.scs_props.locator_prefab_mp_assigned_node = str(_PL_consts.MPNF.NAV_NODE_3) elif map_nav_flags & _PL_consts.MPNF.NAV_NODE_4 != 0: locator.scs_props.locator_prefab_mp_assigned_node = str(_PL_consts.MPNF.NAV_NODE_4) elif map_nav_flags & _PL_consts.MPNF.NAV_NODE_5 != 0: locator.scs_props.locator_prefab_mp_assigned_node = str(_PL_consts.MPNF.NAV_NODE_5) elif map_nav_flags & _PL_consts.MPNF.NAV_NODE_6 != 0: locator.scs_props.locator_prefab_mp_assigned_node = str(_PL_consts.MPNF.NAV_NODE_6) dest_nodes = [] for index in range(_PL_consts.PREFAB_NODE_COUNT_MAX): if map_nav_flags >> index & 1 != 0: dest_nodes.append(str(index)) locator.scs_props.locator_prefab_mp_dest_nodes = set(dest_nodes) return locator
def _create_sign_locator(sign_name, sign_position, sign_rotation, sign_model_id, sign_part, scs_sign_model_inventory): locator = _object_utils.create_locator_empty(sign_name, sign_position, sign_rotation, (1, 1, 1), 0.1, 'Prefab') if locator: locator.scs_props.locator_prefab_type = 'Sign' sign_model_value = _inventory.get_item_name(scs_sign_model_inventory, sign_model_id, report_errors=True) locator.scs_props.locator_prefab_sign_model = sign_model_value locator.scs_props.scs_part = sign_part return locator
def _create_sign_locator( sign_name, sign_position, sign_rotation, sign_model_id, sign_part, scs_sign_model_inventory ): locator = _object_utils.create_locator_empty(sign_name, sign_position, sign_rotation, (1, 1, 1), 0.1, 'Prefab') if locator: locator.scs_props.locator_prefab_type = 'Sign' sign_model_value = _inventory.get_item_name(scs_sign_model_inventory, sign_model_id, report_errors=True) locator.scs_props.locator_prefab_sign_model = sign_model_value locator.scs_props.scs_part = sign_part return locator
def _create_nav_locator(nav_locator_data): """.""" name = nav_locator_data['np_name'] position = nav_locator_data['np_pos'] if nav_locator_data['np_qua']: direction = nav_locator_data['np_qua'] else: direction = nav_locator_data['np_dir'] direction = (math.radians(direction[0]), math.radians(direction[1]), math.radians(direction[2])) locator = _object_utils.create_locator_empty(name, position, direction, (1, 1, 1), 0.1, 'Prefab') if locator: locator.scs_props.locator_prefab_type = 'Navigation Point' return locator
def _create_nav_locator(nav_locator_data): """.""" name = nav_locator_data['np_name'] position = nav_locator_data['np_pos'] if nav_locator_data['np_qua']: direction = nav_locator_data['np_qua'] else: direction = nav_locator_data['np_dir'] direction = ( math.radians(direction[0]), math.radians(direction[1]), math.radians(direction[2]) ) locator = _object_utils.create_locator_empty(name, position, direction, (1, 1, 1), 0.1, 'Prefab') if locator: locator.scs_props.locator_prefab_type = 'Navigation Point' return locator
def _create_node_locator( node_name, node_index, node_position, node_direction ): locator = _object_utils.create_locator_empty(node_name, node_position, ( math.radians(node_direction[0]), math.radians(node_direction[1]), math.radians(node_direction[2]) ), (1, 1, 1), 0.1, 'Prefab') if locator: locator.scs_props.locator_prefab_type = 'Control Node' locator.scs_props.locator_prefab_con_node_index = str(node_index) return locator
def load_pim_file(context, filepath, terrain_points_trans=None, preview_model=False): """Loads the actual PIM file type. This is used also for loading of 'Preview Models'. :param filepath: File path to be imported :type filepath: str :param preview_model: Load geomety as Preview Model :type preview_model: bool :param terrain_points_trans: transitional structure with filled terrain points from PIP; or None :type terrain_points_trans: io_scs_tools.imp.transition_structs.terrain_points.TerrainPntsTrans | None :return: ({'FINISHED'}, objects, skinned_objects, locators, armature, skeleton) or preview model object :rtype: tuple | bpy.types.Object """ # create empty terrain points transitional structure if none is passed if terrain_points_trans is None: terrain_points_trans = TerrainPntsTrans() scs_globals = _get_scs_globals() ind = ' ' pim_container = _pix_container.get_data_from_file(filepath, ind) # LOAD HEADER format_version, source, f_type, f_name, source_filename, author = get_header( pim_container) if format_version not in (1, ): lprint( '\nE Unknown PIM.EF file version! Version %r is not currently supported by PIM.EF importer.', format_version) return {'CANCELLED'}, None, None, [], None, None # LOAD GLOBALS (vertex_count, face_count, edge_count, material_count, piece_count, part_count, bone_count, locator_count, skeleton, piece_skin_count) = get_global(pim_container) # DATA LOADING materials_data = {} objects_data = {} parts_data = {} locators_data = {} bones = {} skin_streams = [] piece_skin_data = {} for section in pim_container: if section.type == 'Material': if scs_globals.import_pim_file: material_i, materials_alias, materials_effect = get_material_properties( section) # print('\nmaterials_alias: %r' % materials_alias) # print(' materials_effect: %s' % materials_effect) # suport legacy format without index if not material_i: material_i = len(materials_data.keys()) materials_data[material_i] = [ materials_alias, materials_effect, ] elif section.type == 'Piece': if scs_globals.import_pim_file: ob_index, ob_material, ob_vertex_cnt, ob_edge_cnt, ob_face_cnt, ob_stream_cnt = get_piece_properties( section) piece_name = 'piece_' + str(ob_index) (mesh_vertices, mesh_normals, mesh_tangents, mesh_rgb, mesh_rgba, mesh_scalars, mesh_uv, mesh_uv_aliases, mesh_tuv, mesh_faces, mesh_face_materials, mesh_edges) = _get_piece_streams(section) objects_data[ob_index] = ( context, piece_name, mesh_vertices, mesh_normals, mesh_tangents, mesh_rgb, mesh_rgba, mesh_scalars, mesh_uv, mesh_uv_aliases, mesh_tuv, mesh_faces, mesh_face_materials, mesh_edges, ) # print('piece_name: %s' % piece_name) # print('ob_material: %s' % ob_material) # print('mesh_vertices: %s' % mesh_vertices) # print('mesh_rgba 1: %s' % str(mesh_rgba)) # print('mesh_uv count: %s' % len(mesh_uv)) # print('mesh_triangles: %s' % mesh_triangles) # print('mesh_faces: %s' % mesh_faces) # print('mesh_face_materials: %s' % mesh_face_materials) # print('mesh_edges: %s' % mesh_edges) # print('piece_count: %s' % str(piece_count)) piece_count -= 1 elif section.type == 'Part': if scs_globals.import_pim_file: part_name, part_piece_count, part_locator_count, part_pieces, part_locators = get_part_properties( section) # print('\npart_name: %r' % part_name) # print(' part_piece_count: %i' % part_piece_count) # print(' part_locator_count: %i' % part_locator_count) # print(' part_pieces: %s' % str(part_pieces)) # print(' part_locators: %s' % str(part_locators)) if part_pieces is not None and isinstance(part_pieces, int): part_pieces = [part_pieces] if part_locators is not None and isinstance( part_locators, int): part_locators = [part_locators] parts_data[part_name] = ( part_pieces, part_locators, ) elif section.type == 'Locator': if scs_globals.import_pim_file: loc_index, loc_name, loc_hookup, loc_position, loc_rotation, loc_scale = get_locator_properties( section) # print('\nloc_index: %r' % loc_index) # print(' loc_name: %s' % loc_name) # if loc_hookup: # print(' loc_hookup: %s' % loc_hookup) # print(' loc_position: %s' % loc_position) # print(' loc_rotation: %s' % loc_rotation) # print(' loc_scale: %s' % str(loc_scale)) locators_data[loc_index] = ( loc_name, loc_hookup, loc_position, loc_rotation, loc_scale, ) # BONES elif section.type == 'Bones': if scs_globals.import_pis_file: bones = get_bones_properties(section, scs_globals.import_pis_file) # print('\nbones: %r' % str(bones)) # SKINNING elif section.type == 'Skin': # Always only one skin in current SCS game implementation. if scs_globals.import_pim_file and scs_globals.import_pis_file: skin_stream_cnt, skin_streams = get_skin_properties(section) # print('\nskin_stream_cnt: %r' % skin_stream_cnt) # print('skin_data: %r\n' % str(skin_data)) elif section.type == "PieceSkin": if scs_globals.import_pim_file and scs_globals.import_pis_file: skin_piece_idx, skin_stream_cnt, skin_piece_streams = get_piece_skin_properties( section) piece_skin_data[skin_piece_idx] = skin_piece_streams piece_skin_count -= 1 # CREATE MATERIALS if scs_globals.import_pim_file and not preview_model: lprint('\nI MATERIALS:') for mat_i in materials_data: mat = bpy.data.materials.new(materials_data[mat_i][0]) mat.scs_props.mat_effect_name = materials_data[mat_i][1] materials_data[mat_i].append(materials_data[mat_i][0]) materials_data[mat_i][0] = mat.name lprint('I Created Material "%s"...', mat.name) # PREPARE VERTEX GROUPS FOR SKINNING object_skinning = {} if scs_globals.import_pim_file and scs_globals.import_pis_file and bones: if skin_streams: # global skinning section for skin_stream in skin_streams: for stream_i, stream in enumerate(skin_stream): for data in stream[ 5]: # index 5 is data block, see _get_skin_stream # print(' ORIGIN - data: %s' % str(data)) for rec in data['clones']: obj = objects_data[rec[0]][1] # piece name if obj not in object_skinning: object_skinning[obj] = {} vertex = rec[1] for weight in data['weights']: vg = bones[weight[0]] if vg not in object_skinning[obj]: object_skinning[obj][vg] = {} vw = weight[1] object_skinning[obj][vg][vertex] = vw elif piece_skin_data: # or skinning per piece for piece_idx, piece_skin_streams in piece_skin_data.items(): obj = objects_data[piece_idx][1] # piece name for skin_stream in piece_skin_streams: for stream_i, stream in enumerate(skin_stream): for data in stream[ 5]: # index 5 is data block, see _get_skin_stream # print(' ORIGIN - data: %s' % str(data)) for vertex_idx in data['vertex_indices']: if obj not in object_skinning: object_skinning[obj] = {} for weight in data['weights']: vg = bones[weight[0]] if vg not in object_skinning[obj]: object_skinning[obj][vg] = {} vw = weight[1] object_skinning[obj][vg][vertex_idx] = vw # CREATE OBJECTS lprint('\nI OBJECTS:') objects = [] skinned_objects = [] for obj_i in objects_data: # print('objects_data[obj_i]: %s' % str(objects_data[obj_i])) obj = _create_piece( objects_data[obj_i][0], # context objects_data[obj_i][1], # piece_name objects_data[obj_i][2], # mesh_vertices objects_data[obj_i][3], # mesh_normals objects_data[obj_i][4], # mesh_tangents objects_data[obj_i][5], # mesh_rgb objects_data[obj_i][6], # mesh_rgba objects_data[obj_i][7], # mesh_scalars object_skinning, objects_data[obj_i][8], # mesh_uv objects_data[obj_i][9], # mesh_uv_aliases objects_data[obj_i][10], # mesh_tuv objects_data[obj_i][11], # mesh_faces objects_data[obj_i][12], # mesh_face_materials objects_data[obj_i][13], # mesh_edges terrain_points_trans, materials_data, ) piece_name = objects_data[obj_i][1] if obj: # make sure that objects are using Z depth calculation # comes handy when we have any kind of transparent materials. # Moreover as this property doesn't do any change on # none transparent materials we can easily set this to all imported objects obj.show_transparent = True if piece_name in object_skinning: skinned_objects.append(obj) else: objects.append(obj) lprint('I Created Object "%s"...', (obj.name, )) # PARTS for part in parts_data: # print('parts_data["%s"]: %s' % (str(part), str(parts_data[part]))) if parts_data[part][0] is not None: if obj_i in parts_data[part][0]: # print(' obj_i: %s - part: %s - parts_data[part][0]: %s' % (obj_i, part, parts_data[part][0])) obj.scs_props.scs_part = part.lower() else: lprint('E "%s" - Object creation FAILED!', piece_name) if preview_model: bases = [] # get the bases of newly created objects for override for base in bpy.context.scene.object_bases: if base.object in objects: bases.append(base) override = { 'window': bpy.context.window, 'screen': bpy.context.screen, 'blend_data': bpy.context.blend_data, 'scene': bpy.context.scene, 'region': None, 'area': None, 'active_object': objects[0], 'selected_editable_bases': bases } bpy.ops.object.join(override) return objects[0] # CREATE MODEL LOCATORS locators = [] if scs_globals.import_pim_file and not preview_model: lprint('\nI MODEL LOCATORS:') for loc_i in locators_data: # print('locators_data[loc_i]: %s' % str(locators_data[loc_i])) loc = _object_utils.create_locator_empty( locators_data[loc_i][0], # loc_name locators_data[loc_i][2], # loc_position locators_data[loc_i][3], # loc_rotation locators_data[loc_i][4], # loc_scale 1.0, # loc_size 'Model', # loc_type locators_data[loc_i][1], # loc_hookup ) # loc = create_locator( # locators_data[loc_i][0], # loc_name # locators_data[loc_i][1], # loc_hookup # locators_data[loc_i][2], # loc_position # locators_data[loc_i][3], # loc_rotation # locators_data[loc_i][4], # loc_scale # 'Model', ## loc_type # ) locator_name = locators_data[loc_i][0] if loc: lprint('I Created Locator "%s"...', locator_name) locators.append(loc) for part in parts_data: # print('parts_data[part]: %s' % str(parts_data[part])) if parts_data[part][1] is not None: if loc_i in parts_data[part][1]: # print(' loc_i: %s - part: %s - parts_data[part][1]: %s' % (loc_i, part, parts_data[part][1])) loc.scs_props.scs_part = part.lower() else: lprint('E "%s" - Locator creation FAILED!', locator_name) # CREATE SKELETON (ARMATURE) armature = None if scs_globals.import_pis_file and bones: bpy.ops.object.add(type='ARMATURE', enter_editmode=False) bpy.ops.object.editmode_toggle() for bone in bones: bpy.ops.armature.bone_primitive_add(name=bone) bpy.ops.object.editmode_toggle() # bpy.context.object.data.show_names = True armature = bpy.context.object # ADD ARMATURE MODIFIERS TO SKINNED OBJECTS for obj in skinned_objects: # print('...adding Armature modifier to %r...' % str(obj.name)) bpy.context.view_layer.objects.active = obj bpy.ops.object.modifier_add(type='ARMATURE') arm_modifier = None for modifier in obj.modifiers: if modifier.type == 'ARMATURE': arm_modifier = modifier break if arm_modifier: arm_modifier.object = armature obj.parent = armature # WARNING PRINTOUTS if piece_count < 0: lprint('W More Pieces found than were declared!') if piece_count > 0: lprint('W Some Pieces not found, but were declared!') if piece_skin_count > 0: lprint("W More PieceSkins found than were declared!") if piece_skin_count < 0: lprint("W Some PieceSkins not found, but were declared!") return {'FINISHED' }, objects, locators, armature, skeleton, materials_data.values()
def load(filepath): scs_globals = _get_scs_globals() print("\n************************************") print("** SCS PIC Importer **") print("** (c)2014 SCS Software **") print("************************************\n") ind = ' ' pic_container = _pix_container.get_data_from_file(filepath, ind) # TEST PRINTOUTS # ind = ' ' # for section in pic_container: # print('SEC.: "%s"' % section.type) # for prop in section.props: # print('%sProp: %s' % (ind, prop)) # for data in section.data: # print('%sdata: %s' % (ind, data)) # for sec in section.sections: # print_section(sec, ind) # print('\nTEST - Source: "%s"' % pic_container[0].props[1][1]) # print('') # TEST EXPORT # path, file = os.path.splitext(filepath) # export_filepath = str(path + '_reex' + file) # result = pix_write.write_data(pic_container, export_filepath, ind) # if result == {'FINISHED'}: # Print(dump_level, '\nI Test export succesful! The new file:\n "%s"', export_filepath) # else: # Print(dump_level, '\nE Test export failed! File:\n "%s"', export_filepath) # LOAD HEADER ''' NOTE: skipped for now as no data needs to be readed format_version, source, f_type, f_name, source_filename, author = _get_header(pic_container) ''' # LOAD GLOBALS ''' NOTE: skipped for now as no data needs to be readed vertex_count, triangle_count, material_count, piece_count, part_count, locator_count = _get_global(pic_container) ''' # LOAD MATERIALS if 0: # NOTE: NO MATERIALS USED FOR COLLIDERS AT A MOMENT! loaded_materials = [] for section in pic_container: if section.type == 'Material': material_alias, material_effect = _get_material(section) lprint('I Adding a Material Alias: "%s"', material_alias) loaded_materials.append(material_alias) # PRINT "MATERIAL SETTINGS" TO CONSOLE... if 0: import pprint pp = pprint.PrettyPrinter(indent=1) print("=== MATERIAL SETTINGS ==========================") pp.pprint(material_effect) print("==================================================") # LOAD PARTS parts = [] for section in pic_container: if section.type == "Part": (name, pieces, locators) = _get_part(section) parts.append({ "name": name, "pieces": pieces, "locators": locators }) # LOAD (CONVEX) PIECES pieces = [] for section in pic_container: if section.type == 'Piece': pieces.append(_get_piece(section)) # LOAD AND CREATE LOCATORS import_scale = scs_globals.import_scale locators = [] for section in pic_container: if section.type == 'Locator': (locator_name, locator_index, locator_position, locator_rotation, locator_alias, locator_weight, locator_type, locator_parameters, locator_convex_piece) = _get_locator(section) lprint('I Adding a Locator: "%s"', locator_name) locator = _object_utils.create_locator_empty( locator_name, locator_position, locator_rotation, (1, 1, 1), 1.0, 'Collision') locator.scs_props.scs_part = _get_locator_part( parts, locator_index) locator.scs_props.locator_collider_centered = True locator.scs_props.locator_collider_mass = locator_weight locator.scs_props.locator_collider_type = locator_type if locator_type == 'Box': locator.scs_props.locator_collider_box_x = locator_parameters[ 0] * import_scale locator.scs_props.locator_collider_box_y = locator_parameters[ 2] * import_scale locator.scs_props.locator_collider_box_z = locator_parameters[ 1] * import_scale elif locator_type in ('Sphere', 'Capsule', 'Cylinder'): locator.scs_props.locator_collider_dia = locator_parameters[ 0] * 2 * import_scale locator.scs_props.locator_collider_len = locator_parameters[ 1] * import_scale elif locator_type == 'Convex': piece_index, piece_material, verts, faces = pieces[ locator_convex_piece] if verts and faces: # BOUNDING BOX DATA CREATION AND SPACE CONVERSION min_val = [None, None, None] max_val = [None, None, None] scs_verts = [] for vert in verts: scs_vert = _convert_utils.change_to_scs_xyz_coordinates( vert, import_scale) scs_verts.append(scs_vert) min_val, max_val = _math_utils.evaluate_minmax( scs_vert, min_val, max_val) bbox, bbcenter = _math_utils.get_bb(min_val, max_val) # FACE FLIPPING flipped_faces = _mesh_utils.flip_faceverts(faces) # COLLIDER CREATION geom_data = (scs_verts, flipped_faces, bbox, bbcenter) _object_utils.add_collider_convex_locator( geom_data, {}, locator) locators.append(locator) # DATA BUILDING # WARNING PRINTOUTS # if piece_count < 0: Print(dump_level, '\nW More Pieces found than were declared!') # if piece_count > 0: Print(dump_level, '\nW Some Pieces not found, but were declared!') # if dump_level > 1: print('') print("************************************") return {'FINISHED'}, locators
def load_pim_file(context, filepath, terrain_points_trans=None, preview_model=False): """Loads the actual PIM file type. This is used also for loading of 'Preview Models'. :param filepath: File path to be imported :type filepath: str :param preview_model: Load geomety as Preview Model :type preview_model: bool :param terrain_points_trans: transitional structure with filled terrain points from PIP; or None :type terrain_points_trans: io_scs_tools.imp.transition_structs.terrain_points.TerrainPntsTrans | None :return: ({'FINISHED'}, objects, skinned_objects, locators, armature, skeleton) or preview model object :rtype: tuple | bpy.types.Object """ # create empty terrain points transitional structure if none is passed if terrain_points_trans is None: terrain_points_trans = TerrainPntsTrans() scs_globals = _get_scs_globals() lprint("I Reading data from PIM file...") ind = ' ' pim_container = _pix_container.get_data_from_file(filepath, ind) lprint("I Assembling data...") # LOAD HEADER format_version, source, f_type, f_name, source_filename, author = get_header( pim_container) if format_version not in (5, ): lprint( '\nE Unknown PIM file version! Version %r is not currently supported by PIM importer.', format_version) return {'CANCELLED'}, None, None, [], None, None # LOAD GLOBALS (vertex_count, face_count, edge_count, material_count, piece_count, part_count, bone_count, locator_count, skeleton, piece_skin_count) = get_global(pim_container) # DATA LOADING materials_data = {} objects_data = {} parts_data = {} locators_data = {} bones = {} skin_streams = [] piece_skin_data = {} for section in pim_container: if section.type == 'Material': if scs_globals.import_pim_file: material_i, materials_alias, materials_effect = get_material_properties( section) # print('\nmaterials_alias: %r' % materials_alias) # print(' materials_effect: %s' % materials_effect) # suport legacy format without index if not material_i: material_i = len(materials_data.keys()) materials_data[material_i] = [ materials_alias, materials_effect, ] elif section.type == 'Piece': if scs_globals.import_pim_file: ob_index, ob_material, ob_vertex_cnt, ob_edge_cnt, ob_face_cnt, ob_stream_cnt = get_piece_properties( section) piece_name = 'piece_' + str(ob_index) # print('Piece %i going to "get_piece_5_streams"...' % ob_index) (mesh_vertices, mesh_normals, mesh_tangents, mesh_rgb, mesh_rgba, mesh_scalars, mesh_uv, mesh_tuv, mesh_triangles) = _get_piece_streams(section) points_to_weld_list = {} if mesh_normals: # print('Piece %i going to "make_posnorm_list"...' % ob_index) if scs_globals.import_use_welding: points_to_weld_list = _mesh_utils.make_points_to_weld_list( mesh_vertices, mesh_normals, mesh_rgb, mesh_rgba, scs_globals.import_welding_precision) objects_data[ob_index] = ( context, piece_name, ob_material, mesh_vertices, mesh_normals, mesh_tangents, mesh_rgb, mesh_rgba, mesh_scalars, mesh_uv, mesh_tuv, mesh_triangles, points_to_weld_list, ) # print('piece_name: %s' % piece_name) # print('ob_material: %s' % ob_material) # print('mesh_vertices: %s' % mesh_vertices) # print('mesh_rgba 1: %s' % str(mesh_rgba)) # print('mesh_uv count: %s' % len(mesh_uv)) # print('mesh_triangles: %s' % mesh_triangles) # print('mesh_faces: %s' % mesh_faces) # print('mesh_face_materials: %s' % mesh_face_materials) # print('mesh_edges: %s' % mesh_edges) # print('piece_count: %s' % str(piece_count)) piece_count -= 1 elif section.type == 'Part': if scs_globals.import_pim_file: part_name, part_piece_count, part_locator_count, part_pieces, part_locators = get_part_properties( section) # print('\npart_name: %r' % part_name) # print(' part_piece_count: %i' % part_piece_count) # print(' part_locator_count: %i' % part_locator_count) # print(' part_pieces: %s' % str(part_pieces)) # print(' part_locators: %s' % str(part_locators)) if part_pieces is not None and isinstance(part_pieces, int): part_pieces = [part_pieces] if part_locators is not None and isinstance( part_locators, int): part_locators = [part_locators] parts_data[part_name] = ( part_pieces, part_locators, ) elif section.type == 'Locator': if scs_globals.import_pim_file: loc_index, loc_name, loc_hookup, loc_position, loc_rotation, loc_scale = get_locator_properties( section) # print('\nloc_index: %r' % loc_index) # print(' loc_name: %s' % loc_name) # if loc_hookup: # print(' loc_hookup: %s' % loc_hookup) # print(' loc_position: %s' % loc_position) # print(' loc_rotation: %s' % loc_rotation) # print(' loc_scale: %s' % str(loc_scale)) locators_data[loc_index] = ( loc_name, loc_hookup, loc_position, loc_rotation, loc_scale, ) # BONES elif section.type == 'Bones': if scs_globals.import_pis_file: bones = get_bones_properties(section, scs_globals.import_pis_file) # print('\nbones: %r' % str(bones)) # SKINNING elif section.type == 'Skin': # Always only one skin in current SCS game implementation. if scs_globals.import_pim_file and scs_globals.import_pis_file: skin_stream_cnt, skin_streams = get_skin_properties(section) # print('\nskin_stream_cnt: %r' % skin_stream_cnt) # print('skin_data: %r\n' % str(skin_data)) elif section.type == "PieceSkin": if scs_globals.import_pim_file and scs_globals.import_pis_file: skin_piece_idx, skin_stream_cnt, skin_piece_streams = get_piece_skin_properties( section) piece_skin_data[skin_piece_idx] = skin_piece_streams piece_skin_count -= 1 # CREATE MATERIALS if scs_globals.import_pim_file and not preview_model: lprint("\nI ------ Creating materials: ------") for mat_i in materials_data: mat = bpy.data.materials.new(materials_data[mat_i][0]) mat.scs_props.mat_effect_name = materials_data[mat_i][1] materials_data[mat_i].append(materials_data[mat_i][0]) materials_data[mat_i][0] = mat.name lprint("I Created material %r...", (mat.name, )) lprint("I ---------------------------------") # PREPARE VERTEX GROUPS FOR SKINNING object_skinning = {} if scs_globals.import_pim_file and scs_globals.import_pis_file and bones: if skin_streams: # global skinning section for skin_stream in skin_streams: for stream_i, stream in enumerate(skin_stream): for data in stream[ 5]: # index 5 is data block, see _get_skin_stream # print(' ORIGIN - data: %s' % str(data)) for rec in data['clones']: obj = objects_data[rec[0]][1] # piece name if obj not in object_skinning: object_skinning[obj] = {} vertex = rec[1] for weight in data['weights']: vg = bones[weight[0]] if vg not in object_skinning[obj]: object_skinning[obj][vg] = {} vw = weight[1] object_skinning[obj][vg][vertex] = vw elif piece_skin_data: # or skinning per piece for piece_idx, piece_skin_streams in piece_skin_data.items(): obj = objects_data[piece_idx][1] # piece name for skin_stream in piece_skin_streams: for stream_i, stream in enumerate(skin_stream): for data in stream[ 5]: # index 5 is data block, see _get_skin_stream # print(' ORIGIN - data: %s' % str(data)) for vertex_idx in data['vertex_indices']: if obj not in object_skinning: object_skinning[obj] = {} for weight in data['weights']: vg = bones[weight[0]] if vg not in object_skinning[obj]: object_skinning[obj][vg] = {} vw = weight[1] object_skinning[obj][vg][vertex_idx] = vw # CREATE OBJECTS lprint("\nI ------ Creating mesh objects: -------") objects = [] skinned_objects = [] for obj_i in objects_data: # PARTS - search part first so preview model can possibly ignore objects with prescribed variant part_name = None for part in parts_data: if parts_data[part][0] is not None and obj_i in parts_data[part][0]: part_name = part.lower() if preview_model: # ignore pieces with "coll" parts if match(r'^coll([0-9]?|_.*)$', part_name): lprint( "I Ignoring piece with part collision part name %r for preview model!", (part_name, )) continue # ignore pieces with shadow and none material effects used_mat_effect = materials_data[objects_data[obj_i][2]][1] if ".shadowonly" in used_mat_effect or ".fakeshadow" in used_mat_effect or used_mat_effect.startswith( "eut2.none"): lprint( "I Ignoring piece with material having shadow or none effect for preview model!" ) continue # print('objects_data[obj_i]: %s' % str(objects_data[obj_i])) obj = _create_piece( objects_data[obj_i][0], # context preview_model, objects_data[obj_i][1], # piece_name objects_data[obj_i][2], # ob_material objects_data[obj_i][3], # mesh_vertices objects_data[obj_i][4], # mesh_normals objects_data[obj_i][5], # mesh_tangents objects_data[obj_i][6], # mesh_rgb objects_data[obj_i][7], # mesh_rgba objects_data[obj_i][8], # mesh_scalars object_skinning, objects_data[obj_i][9], # mesh_uv objects_data[obj_i][10], # mesh_tuv objects_data[obj_i][11], # mesh_triangles materials_data, objects_data[obj_i][12], # points_to_weld_list terrain_points_trans, ) piece_name = objects_data[obj_i][1] if obj: # make sure that objects are using Z depth calculation # comes handy when we have any kind of transparent materials. # Moreover as this property doesn't do any change on # none transparent materials we can easily set this to all imported objects obj.show_transparent = True if piece_name in object_skinning: skinned_objects.append(obj) else: objects.append(obj) lprint("I Created object %r (%s/%s)...", (obj.name, obj_i, len(objects_data))) # PARTS if part_name: obj.scs_props.scs_part = part_name else: lprint("E %r - Object creation FAILED!", piece_name) lprint("I -------------------------------------") if preview_model: # abort loading if no meshes inside imported model if len(objects) == 0 and len(skinned_objects) == 0: return None # get active object for joining meshes into it active_object = objects[0] if len(objects) > 0 else skinned_objects[0] override = context.copy() override["active_object"] = active_object override["selected_editable_objects"] = objects + skinned_objects bpy.ops.object.join(override) return active_object # CREATE MODEL LOCATORS locators = [] if scs_globals.import_pim_file and not preview_model: lprint("\nI ------ Creating model locators: ------") for loc_i in locators_data: # print('locators_data[loc_i]: %s' % str(locators_data[loc_i])) loc = _object_utils.create_locator_empty( locators_data[loc_i][0], # loc_name locators_data[loc_i][2], # loc_position locators_data[loc_i][3], # loc_rotation locators_data[loc_i][4], # loc_scale 1.0, # loc_size 'Model', # loc_type locators_data[loc_i][1], # loc_hookup ) # loc = create_locator( # locators_data[loc_i][0], # loc_name # locators_data[loc_i][1], # loc_hookup # locators_data[loc_i][2], # loc_position # locators_data[loc_i][3], # loc_rotation # locators_data[loc_i][4], # loc_scale # 'Model', ## loc_type # ) locator_name = locators_data[loc_i][0] if loc: lprint("I Created locator %r...", (locator_name, )) locators.append(loc) for part in parts_data: # print('parts_data[part]: %s' % str(parts_data[part])) if parts_data[part][1] is not None: if loc_i in parts_data[part][1]: # print(' loc_i: %s - part: %s - parts_data[part][1]: %s' % (loc_i, part, parts_data[part][1])) loc.scs_props.scs_part = part.lower() else: lprint("E %r - Locator creation FAILED!", (locator_name, )) lprint("I --------------------------------------") # CREATE SKELETON (ARMATURE) armature = None if scs_globals.import_pis_file and bones: bpy.ops.object.add(type='ARMATURE') bpy.ops.object.editmode_toggle() for bone in bones: bpy.ops.armature.bone_primitive_add(name=bone) bpy.ops.object.editmode_toggle() # bpy.context.object.data.show_names = True armature = bpy.context.object # ADD ARMATURE MODIFIERS TO SKINNED OBJECTS for obj in skinned_objects: # print('...adding Armature modifier to %r...' % str(obj.name)) bpy.context.view_layer.objects.active = obj bpy.ops.object.modifier_add(type='ARMATURE') arm_modifier = None for modifier in obj.modifiers: if modifier.type == 'ARMATURE': arm_modifier = modifier break if arm_modifier: arm_modifier.object = armature obj.parent = armature # WARNING PRINTOUTS if piece_count < 0: lprint("W More Pieces found than were declared!") if piece_count > 0: lprint("W Some Pieces not found, but were declared!") if piece_skin_count > 0: lprint("W More PieceSkins found than were declared!") if piece_skin_count < 0: lprint("W Some PieceSkins not found, but were declared!") return {'FINISHED' }, objects, locators, armature, skeleton, materials_data.values()
def load(filepath): scs_globals = _get_scs_globals() print("\n************************************") print("** SCS PIC Importer **") print("** (c)2014 SCS Software **") print("************************************\n") ind = ' ' pic_container = _pix_container.get_data_from_file(filepath, ind) # TEST PRINTOUTS # ind = ' ' # for section in pic_container: # print('SEC.: "%s"' % section.type) # for prop in section.props: # print('%sProp: %s' % (ind, prop)) # for data in section.data: # print('%sdata: %s' % (ind, data)) # for sec in section.sections: # print_section(sec, ind) # print('\nTEST - Source: "%s"' % pic_container[0].props[1][1]) # print('') # TEST EXPORT # path, file = os.path.splitext(filepath) # export_filepath = str(path + '_reex' + file) # result = pix_write.write_data(pic_container, export_filepath, ind) # if result == {'FINISHED'}: # Print(dump_level, '\nI Test export succesful! The new file:\n "%s"', export_filepath) # else: # Print(dump_level, '\nE Test export failed! File:\n "%s"', export_filepath) # LOAD HEADER ''' NOTE: skipped for now as no data needs to be readed format_version, source, f_type, f_name, source_filename, author = _get_header(pic_container) ''' # LOAD GLOBALS ''' NOTE: skipped for now as no data needs to be readed vertex_count, triangle_count, material_count, piece_count, part_count, locator_count = _get_global(pic_container) ''' # LOAD MATERIALS if 0: # NOTE: NO MATERIALS USED FOR COLLIDERS AT A MOMENT! loaded_materials = [] for section in pic_container: if section.type == 'Material': material_alias, material_effect = _get_material(section) lprint('I Adding a Material Alias: "%s"', material_alias) loaded_materials.append(material_alias) # PRINT "MATERIAL SETTINGS" TO CONSOLE... if 0: import pprint pp = pprint.PrettyPrinter(indent=1) print("=== MATERIAL SETTINGS ==========================") pp.pprint(material_effect) print("==================================================") # LOAD PARTS parts = [] for section in pic_container: if section.type == "Part": (name, pieces, locators) = _get_part(section) parts.append({"name": name, "pieces": pieces, "locators": locators}) # LOAD (CONVEX) PIECES pieces = [] for section in pic_container: if section.type == 'Piece': pieces.append(_get_piece(section)) # LOAD AND CREATE LOCATORS import_scale = scs_globals.import_scale locators = [] for section in pic_container: if section.type == 'Locator': (locator_name, locator_index, locator_position, locator_rotation, locator_alias, locator_weight, locator_type, locator_parameters, locator_convex_piece) = _get_locator(section) lprint('I Adding a Locator: "%s"', locator_name) locator = _object_utils.create_locator_empty(locator_name, locator_position, locator_rotation, (1, 1, 1), 1.0, 'Collision') locator.scs_props.scs_part = _get_locator_part(parts, locator_index) locator.scs_props.locator_collider_centered = True locator.scs_props.locator_collider_mass = locator_weight locator.scs_props.locator_collider_type = locator_type if locator_type == 'Box': locator.scs_props.locator_collider_box_x = locator_parameters[0] * import_scale locator.scs_props.locator_collider_box_y = locator_parameters[2] * import_scale locator.scs_props.locator_collider_box_z = locator_parameters[1] * import_scale elif locator_type in ('Sphere', 'Capsule', 'Cylinder'): locator.scs_props.locator_collider_dia = locator_parameters[0] * 2 * import_scale locator.scs_props.locator_collider_len = locator_parameters[1] * import_scale elif locator_type == 'Convex': piece_index, piece_material, verts, faces = pieces[locator_convex_piece] if verts and faces: # BOUNDING BOX DATA CREATION AND SPACE CONVERSION min_val = [None, None, None] max_val = [None, None, None] scs_verts = [] for vert in verts: scs_vert = _convert_utils.change_to_scs_xyz_coordinates(vert, import_scale) scs_verts.append(scs_vert) min_val, max_val = _math_utils.evaluate_minmax(scs_vert, min_val, max_val) bbox, bbcenter = _math_utils.get_bb(min_val, max_val) # FACE FLIPPING flipped_faces = _mesh_utils.flip_faceverts(faces) # COLLIDER CREATION geom_data = (scs_verts, flipped_faces, bbox, bbcenter) _object_utils.add_collider_convex_locator(geom_data, {}, locator) locators.append(locator) # DATA BUILDING # WARNING PRINTOUTS # if piece_count < 0: Print(dump_level, '\nW More Pieces found than were declared!') # if piece_count > 0: Print(dump_level, '\nW Some Pieces not found, but were declared!') # if dump_level > 1: print('') print("************************************") return {'FINISHED'}, locators