def _default_material(alias): """Return 'default material' data section.""" # DEFAULT PROPERTIES material_export_data = _SectionData("Material") material_export_data.props.append(("Alias", alias)) # material_export_data.props.append(("Effect", "eut2.none")) material_export_data.props.append(("Effect", "eut2.dif")) material_export_data.props.append(("Flags", 0)) attribute_data = [ ('FLOAT3', "diffuse", (1.0, 1.0, 1.0)), ('FLOAT3', "specular", (0.0, 0.0, 0.0)), ('FLOAT', "shininess", (5.0, )), ('FLOAT', "add_ambient", (0.0, )), ('FLOAT', "reflection", (0.0, )), ] texture_data = [ ('texture[0]:texture_base', ""), ] material_export_data.props.append(("AttributeCount", len(attribute_data))) material_export_data.props.append(("TextureCount", len(texture_data))) # DEFAULT ATTRIBUTES AND TEXTURE for attribute in attribute_data: attribute_section = _SectionData("Attribute") attribute_section.props.append(("Format", attribute[0])) attribute_section.props.append(("Tag", attribute[1])) attribute_section.props.append(("Value", ["i", attribute[2]])) material_export_data.sections.append(attribute_section) for texture in texture_data: texture_section = _SectionData("Texture") texture_section.props.append(("Tag", texture[0])) texture_section.props.append(("Value", texture[1])) material_export_data.sections.append(texture_section) return material_export_data
def _fill_bones_sections(bones, export_scale): """Creates "Bones" section.""" section = _SectionData("Bones") for bone_i, bone in enumerate(bones): bone_mat = (Matrix.Scale(export_scale, 4) * _convert_utils.scs_to_blend_matrix().inverted() * bone.matrix_local).transposed() section.data.append(("__bone__", bone.name, bone.parent, bone_mat)) return section
def update_item_in_file(item_pointer, new_value): """Resaves config file with updated given item to a new value. The "item_pointer" variable must be in form of 'SectionName.PropertyName', example: 'Paths.ProjectPath'.""" if _get_scs_globals().config_update_lock: return False else: filepath = get_config_filepath() ind = ' ' config_container = _pix.get_data_from_file(filepath, ind) new_settings_container = [] if config_container: new_value_changed = False item_pointer_split = item_pointer.split('.', 1) for section in config_container: new_section = _SectionData(section.type) for prop in section.props: if section.type == item_pointer_split[0] and prop[0] == item_pointer_split[1]: new_section.props.append((prop[0], new_value)) new_value_changed = True else: new_section.props.append((prop[0], prop[1])) # append new properties if they are not yet there if not new_value_changed and section.type == item_pointer_split[0]: new_section.props.append((item_pointer_split[1], new_value)) new_settings_container.append(new_section) write_file(new_settings_container, filepath, ind) return True
def make_vertex_stream(stream_raw, name=''): """ Takes a raw stream and returns a valid stream data ("section_data" data type). If a name is provided, it is written to the stream. :param stream_raw: :param name: :return: """ stream = _SectionData("Stream") # print('\nstream_raw:\n %s' % str(stream_raw)) # print('stream_raw[1]: %s' % stream_raw[1]) if len(stream_raw[1]) > 0: float_cnt = len(stream_raw[1][0]) if float_cnt > 1: float_lenght = str('FLOAT' + str(float_cnt)) else: float_lenght = 'FLOAT' stream.props.append(("Format", float_lenght)) if name != '': stream.props.append(("Name", name)) stream.props.append(("Tag", stream_raw[0])) stream.data = stream_raw[1] else: stream.props.append(("Format", 'NO-DATA')) if name != '': stream.props.append(("Name", name)) stream.props.append(("Tag", stream_raw[0])) stream.data = ((0.0,),) return stream
def _fill_semaphore_sections(data_list, scs_tsem_profile_inventory): """Fills up "Traffic Semaphore" sections.""" sections = [] for item_i, item in enumerate(data_list): # section = data_structures.section_data("TrafficLight") section = _SectionData("Semaphore") loc, qua, sca = _convert_utils.get_scs_transformation_components(item.matrix_world) section.props.append(("Position", ["&&", loc])) section.props.append(("Rotation", ["&&", qua])) section.props.append(("Type", int(item.scs_props.locator_prefab_tsem_type))) if item.scs_props.locator_prefab_tsem_id == 'none': item_id = -1 else: item_id = int(item.scs_props.locator_prefab_tsem_id) section.props.append(("SemaphoreID", item_id)) if item.scs_props.locator_prefab_tsem_type == '6': section.props.append(("Intervals", ["&&", ( item.scs_props.locator_prefab_tsem_gm, item.scs_props.locator_prefab_tsem_om1, item.scs_props.locator_prefab_tsem_rm, item.scs_props.locator_prefab_tsem_om1)])) else: section.props.append(("Intervals", ["&&", ( item.scs_props.locator_prefab_tsem_gs, item.scs_props.locator_prefab_tsem_os1, item.scs_props.locator_prefab_tsem_rs, item.scs_props.locator_prefab_tsem_os2)])) section.props.append(("Cycle", ["&", (item.scs_props.locator_prefab_tsem_cyc_delay, )])) # section.props.append(("Model", item.scs_props.locator_prefab_tsem_model)) # section.props.append(("Profile", item.scs_props.locator_prefab_tsem_profile)) if item.scs_props.locator_prefab_tsem_profile: profile = scs_tsem_profile_inventory[item.scs_props.locator_prefab_tsem_profile].item_id else: profile = "" section.props.append(("Profile", profile)) sections.append(section) return sections
def _fill_nav_curve_intersections_sections(nav_curve_sections): # for nav_curve_section in nav_curve_sections: # print(' > nav_curve_sections: %s' % str(nav_curve_section)) curve_dict = _curve_utils.compute_curve_intersections(nav_curve_sections) sections = [] for data_dict in curve_dict: # if dict == 'START': # if dict == 'END': # if dict == 'CROSS': for rec in curve_dict[data_dict]: name = "__name__" index = None nav_curve_section = rec[0] ''' NOTE: skipped because currently not supported curve_to_test = rec[1] ''' curve_intersect = rec[2] # print('%r - curve_to_test: %s - curve_intersect: %s' % (dict, str(curve_to_test), str(curve_intersect))) for prop in nav_curve_section.props: # print(' prop: %r - val: %s' % (str(prop[0]), str(prop[1]))) if prop[0] == "": pass elif prop[0] == "Name": name = prop[1] elif prop[0] == "Index": index = prop[1] section = _SectionData("Intersection") section.props.append(("#", str("Curve '" + name + "'"))) section.props.append(("InterCurveID", index)) section.props.append(("InterPosition", float(curve_intersect))) section.props.append(("InterRadius", float(0))) section.props.append(("Flags", 0)) sections.append(section) return sections
def _fill_atr_section(atr): """Creates "Attribute" section.""" section = _SectionData("Attribute") section.props.append(("Format", atr[0])) section.props.append(("Tag", atr[1])) section.props.append(("Value", ["&&", (atr[2], )])) return section
def _fill_part_sections(locator_list, used_parts): """Fills up "Parts" sections. :param locator_list: list of Blender Objects - only 'Empty' typs, set as 'SCS Model Locators' :type locator_list: list :param used_parts: parts transitional structure for storing used parts inside this PIC export :type used_parts: io_scs_tools.exp.transition_structs.parts.PartsTrans :return: list of 'part_sections' :rtype: list """ parts = [] locator_parts = {} for locator_i, locator in enumerate(locator_list): scs_part = locator.scs_props.scs_part if scs_part not in locator_parts: locator_parts[scs_part] = [locator_i] else: locator_parts[scs_part].append(locator_i) if scs_part not in parts: parts.append(scs_part) # PART SECTIONS ordered_part_sections = [] for part_name in used_parts.get_as_list(): piece_count = 0 pieces = None locator_count = 0 locators = None # fill up part data from PIC data if part_name in parts: # PIECE COUNT piece_count = 0 # PIECES pieces = None # LOCATOR COUNT if part_name in locator_parts: locator_count = len(locator_parts[part_name]) # LOCATORS locators = None if part_name in locator_parts: if locator_parts[part_name]: locators = locator_parts[part_name] # MAKE SECTION part_section = _SectionData("Part") part_section.props.append(("Name", part_name)) part_section.props.append(("PieceCount", piece_count)) part_section.props.append(("LocatorCount", locator_count)) part_section.props.append(("Pieces", pieces)) part_section.props.append(("Locators", locators)) ordered_part_sections.append(part_section) return ordered_part_sections
def _fill_material_sections(used_materials): """ Fills up "Material" sections. :param used_materials: :return: """ material_sections = [] for material_i, material in enumerate(used_materials): if material is not None: material_section = _SectionData("Material") if isinstance(material, str): # mat_alias = "_empty_material_" mat_alias = str(material + "-_default_settings_") lprint('I "%s" material has been used to replace all unspecified materials.', (mat_alias,)) # effect_name = "eut2.none" effect_name = "eut2.dif" else: shader_data = material.get("scs_shader_attributes", {}) mat_alias = material.name effect_name = shader_data.get('effect', None) if not effect_name: mat_alias = str("_" + material.name + "_-_default_settings_") # effect_name = "eut2.none" effect_name = "eut2.dif" material_section.props.append(("Alias", mat_alias)) material_section.props.append(("Effect", effect_name)) # print('material %i: "%s"' % (material_i, mat_alias)) material_sections.append(material_section) return material_sections
def _fill_global_section(file_name, vertex_cnt, face_cnt, edge_cnt, material_cnt, piece_cnt, part_cnt, bone_cnt, locator_cnt, output_type): """ Fills up "Global" section. :param vertex_cnt: :param face_cnt: :param edge_cnt: :param material_cnt: :param piece_cnt: :param part_cnt: :param bone_cnt: :param locator_cnt: :return: """ global_section = _SectionData("Global") global_section.props.append(("VertexCount", vertex_cnt)) if output_type.startswith('def'): global_section.props.append(("FaceCount", face_cnt)) global_section.props.append(("EdgeCount", edge_cnt)) else: global_section.props.append(("TriangleCount", face_cnt)) global_section.props.append(("MaterialCount", material_cnt)) global_section.props.append(("PieceCount", piece_cnt)) global_section.props.append(("PartCount", part_cnt)) global_section.props.append(("BoneCount", bone_cnt)) global_section.props.append(("LocatorCount", locator_cnt)) global_section.props.append(("Skeleton", str(file_name + ".pis"))) return global_section
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 * Matrix.Translation((0.0, -item.scs_props.locator_collider_box_y / 2, 0.0)) * (Matrix.Scale(item.scs_props.locator_collider_box_x, 4, (1.0, 0.0, 0.0)) * Matrix.Scale(item.scs_props.locator_collider_box_y, 4, (0.0, 1.0, 0.0)) * Matrix.Scale(item.scs_props.locator_collider_box_z, 4, (0.0, 0.0, 1.0)))) elif item.scs_props.locator_collider_type == 'Sphere': offset_matrix = (item.matrix_world * Matrix.Translation((0.0, -item.scs_props.locator_collider_dia / 2, 0.0)) * Matrix.Scale(item.scs_props.locator_collider_dia, 4)) elif item.scs_props.locator_collider_type in ('Capsule', 'Cylinder'): offset_matrix = (item.matrix_world * Matrix.Translation((0.0, -item.scs_props.locator_collider_len / 2, 0.0)) * Matrix.Scale(item.scs_props.locator_collider_dia, 4)) else: offset_matrix = item.matrix_world 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(scs_root.matrix_world.inverted() * item.matrix_world) section = _SectionData("Locator") section.props.append(("Name", _name_utils.tokenize_name(item.name))) section.props.append(("Index", index)) section.props.append(("Position", ["&&", loc])) section.props.append(("Rotation", ["&&", qua])) section.props.append(("Alias", "")) section.props.append(("Weight", ["&", (item.scs_props.locator_collider_mass,)])) section.props.append(("Type", col_type)) return section
def _fill_node_sections(data_list, offset_matrix): """Fills up "Node" sections.""" sections = [] for item in data_list: section = _SectionData("Node") section.props.append(("Index", int(item.scs_props.locator_prefab_con_node_index))) loc = _convert_utils.convert_location_to_scs(item.location, offset_matrix) section.props.append(("Position", ["&&", loc])) direction = _convert_utils.scs_to_blend_matrix().inverted() * (item.matrix_world.to_quaternion() * Vector((0, 1, 0))) section.props.append(("Direction", ["&&", direction])) # print('p_locator_lanes: %s' % item.scs_props.p_locator_lanes) # lane_input_values = [] # lane_output_values = [] # for lane_num in range(item.scs_props.p_locator_lanes): # if lane_num: # lane_input_values.append(lane_num) # lane_output_values.append(lane_num) # else: # lane_input_values.append(-1) # lane_output_values.append(-1) section.props.append(("InputLanes", ["ii", (-1, -1, -1, -1, -1, -1, -1, -1)])) # section.props.append(("InputLanes", lane_input_values)) section.props.append(("OutputLanes", ["ii", (-1, -1, -1, -1, -1, -1, -1, -1)])) # section.props.append(("OutputLanes", lane_output_values)) section.props.append(("TerrainPointCount", 0)) section.props.append(("StreamCount", 0)) section.props.append(("", "")) # section.props.append(("__EMPTY_LINE__", 0)) sections.append(section) return sections
def _fill_global_section(looks, variants, parts, materials): """Fills up "Global" section.""" section = _SectionData("Global") section.props.append(("LookCount", looks)) section.props.append(("VariantCount", variants)) section.props.append(("PartCount", parts)) section.props.append(("MaterialCount", materials)) return section
def _fill_global_section(skeleton_file, total_time, bone_channel_cnt, custom_channel_cnt): """Fills up "Global" section.""" section = _SectionData("Global") section.props.append(("Skeleton", skeleton_file)) section.props.append(("TotalTime", total_time)) # section.props.append(("#", "...in seconds")) section.props.append(("BoneChannelCount", bone_channel_cnt)) section.props.append(("CustomChannelCount", custom_channel_cnt)) return section
def _fill_part_section(part): """Creates "Part" section.""" section = _SectionData("Part") section.props.append(("Name", part[0])) section.props.append(("AttributeCount", len(part[1]))) for atr in part[1]: atr_section = _fill_atr_section(atr) section.sections.append(atr_section) return section
def get_as_section(self): """Gets piece represented with SectionData structure class. :return: packed piece as section data :rtype: io_scs_tools.internals.structure.SectionData """ # UPDATE COUNTERS self._vertex_count = self._streams[Stream.Types.POSITION].get_size() self._triangle_count = len(self._triangles) self._stream_count = len(self._streams) section = _SectionData("Piece") section.props.append(("Index", self._index)) if not self._material or self._material.get_index() == -1: lprint("W Piece with index %s doesn't have data about material, expect errors in game!", (self._index,)) section.props.append(("Material", -1)) else: section.props.append(("Material", self._material.get_index())) section.props.append(("VertexCount", self._vertex_count)) section.props.append(("TriangleCount", self._triangle_count)) section.props.append(("StreamCount", self._stream_count)) stream_size = None for stream_tag in self._streams: stream = self._streams[stream_tag] # CHECK SYNC OF STREAMS if not stream_size: stream_size = stream.get_size() elif stream_size != stream.get_size(): lprint("W Piece with index %s has desynced stream sizes, expect errors in game!", (self._index,)) break # APPEND STREAMS section.sections.append(stream.get_as_section()) # APPEND TRIANGLES triangle_section = _SectionData("Triangles") for triangle in self._triangles: triangle_section.data.append(triangle) section.sections.append(triangle_section) return section
def _read_section(file, section_ids, pix_container): """This function reads the nested sections. It recursively calls itself to read all levels of data hierarchy.""" data_type = "" props = [] data = [] data_index = 0 section_type = "" while data_type != "SE_E": data_type, line = next_line(file) if data_type in ("EOF", "ERR"): break # print('%s =-> "%s"' % (type, line)) if data_type == "Prop": # print(' -++- line: %s' % line) prop = _get_prop(line) # print('prop: %s' % prop) if prop is not None: props.append(prop) elif data_type == "data": # print('line: "%s"' % line) dat_index, dat = _get_data(file, line) if dat_index == data_index: # print('dat: %s' % dat) data_index += 1 if dat != []: data.append(dat) else: print('WARNING - Inconsistent data indexing in line: "%s"! Skipping...' % line) elif data_type == "empty_line": props.append(("", "")) elif data_type == "line_C": comment = line.strip() props.append(("#", comment[2:])) elif data_type == "SE_C": # comment_section = data_structures.section_data("#comment") print('comment section: "%s"' % line) elif data_type == "SE_S": # section_type = re.split(r'[ ]+', line)[0] type_line = re.split(r"[ ]+", line) for rec in type_line: if rec != "": try: section_type = re.split(r"[ ]+", line)[1] except: section_type = "" print('WARNING - Unknown data in line: "%s"! Skipping...' % line) break new_section_ids = _SectionData(section_type) new_section, pix_container = _read_section(file, new_section_ids, pix_container) section_ids.sections.append(new_section) # pix_container.append(new_section) if data_type != "SE_E": section_ids.props = props section_ids.data = data return section_ids, pix_container
def _fill_look_sections(data_list): """Fills up "Look" sections.""" sections = [] for item_i, item in enumerate(data_list): section = _SectionData("Look") section.props.append(("Name", item['name'])) for material_section in item['material_sections']: section.sections.append(material_section) sections.append(section) return sections
def _fill_global_section(vertices, triangles, materials, pieces, parts, locators): """Fills up "Global" section.""" section = _SectionData("Global") section.props.append(("VertexCount", vertices)) section.props.append(("TriangleCount", triangles)) section.props.append(("MaterialCount", materials)) section.props.append(("PieceCount", pieces)) section.props.append(("PartCount", parts)) section.props.append(("LocatorCount", locators)) return section
def fill_global_display_section(): """Fills up "GlobalDisplay" section.""" section = _SectionData("GlobalDisplay") section.props.append(("DisplayLocators", int(_property.get_default(bpy.types.SceneSCSProps.display_locators)))) section.props.append(("LocatorSize", _property.get_default(bpy.types.SceneSCSProps.locator_size))) section.props.append(("LocatorEmptySize", _property.get_default(bpy.types.SceneSCSProps.locator_empty_size))) section.props.append(("DisplayConnections", int(_property.get_default(bpy.types.SceneSCSProps.display_connections)))) section.props.append(("CurveSegments", _property.get_default(bpy.types.SceneSCSProps.curve_segments))) section.props.append(("DisplayTextInfo", _property.get_default(bpy.types.SceneSCSProps.display_info))) return section
def _fill_bones_section(bone_list): """ Fills up "Bones" section. :param bone_list: :return: """ section = _SectionData("Bones") for bone in bone_list: section.data.append(("__string__", bone.name)) return section
def _fill_variant_sections(data_list): """Fills up "Variant" sections.""" sections = [] for item_i, item in enumerate(data_list): section = _SectionData("Variant") section.props.append(("Name", item[0])) for part in item[1]: part_section = _fill_part_section(part) section.sections.append(part_section) sections.append(section) return sections
def _fill_skin_section(skin_list, skin_weights_cnt, skin_clones_cnt): """ Fills up "Bones" section. :param skin_list: :param skin_weights_cnt: :param skin_clones_cnt: :return: """ section = _SectionData("Skin") section.props.append(("StreamCount", 1)) # NOTE: Multiple streams are currently not supported in the game engine. stream_section = _SectionData("SkinStream") stream_section.props.append(("Format", "FLOAT3")) # NOTE: Nonsense - an old relict. stream_section.props.append(("Tag", "_POSITION")) # NOTE: Nonsense - an old relict. stream_section.props.append(("ItemCount", len(skin_list))) stream_section.props.append(("TotalWeightCount", skin_weights_cnt)) stream_section.props.append(("TotalCloneCount", skin_clones_cnt)) for skin in skin_list: stream_section.data.append(("__skin__", skin)) section.sections.append(stream_section) return section
def get_as_section(self): """Gets material represented with SectionData structure class. :return: packed material as section data :rtype: io_scs_tools.internals.structure.SectionData """ section = _SectionData("Material") section.props.append(("Alias", self.__alias)) section.props.append(("Effect", self.__effect)) return section
def make_triangle_stream(stream_raw): """ Takes a raw triangle list and returns valid "Triangle" data ("section_data" data type). :param stream_raw: :return: """ stream = _SectionData("Triangles") for item in stream_raw: stream.data.append(item) return stream
def fill_global_colors_section(): """Fills up "GlobalColors" section.""" section = _SectionData("GlobalColors") section.props.append(("PrefabLocatorsWire", tuple(_property.get_default(bpy.types.SceneSCSProps.locator_prefab_wire_color)))) section.props.append(("ModelLocatorsWire", tuple(_property.get_default(bpy.types.SceneSCSProps.locator_model_wire_color)))) section.props.append(("ColliderLocatorsWire", tuple(_property.get_default(bpy.types.SceneSCSProps.locator_coll_wire_color)))) section.props.append(("ColliderLocatorsFace", tuple(_property.get_default(bpy.types.SceneSCSProps.locator_coll_face_color)))) section.props.append(("NavigationCurveBase", tuple(_property.get_default(bpy.types.SceneSCSProps.np_connection_base_color)))) section.props.append(("MapLineBase", tuple(_property.get_default(bpy.types.SceneSCSProps.mp_connection_base_color)))) section.props.append(("TriggerLineBase", tuple(_property.get_default(bpy.types.SceneSCSProps.tp_connection_base_color)))) section.props.append(("InfoText", tuple(_property.get_default(bpy.types.SceneSCSProps.info_text_color)))) return section
def get_as_section(self): """Get Bezier information represented with SectionData structure class. :return: packed Bezier as section data :rtype: io_scs_tools.internals.structure.SectionData """ section = _SectionData("Bezier") section.sections.append(self.__start.get_as_section()) section.sections.append(self.__end.get_as_section()) return section
def get_as_section(self): """Get Bezier point information represented with SectionData structure class. :return: packed Bezier point as section data :rtype: io_scs_tools.internals.structure.SectionData """ section = _SectionData(self.__type) section.props.append(("Position", ["&&", tuple(self.__position)])) section.props.append(("Rotation", ["&&", tuple(self.__rotation)])) return section
def fill_header_section(): """Fills up "Header" section.""" section = _SectionData("Header") section.props.append(("FormatVersion", 1)) section.props.append(("Source", get_combined_ver_str())) section.props.append(("Type", "Configuration")) section.props.append(("Note", "User settings of SCS Blender Tools")) author = bpy.context.user_preferences.system.author if author: section.props.append(("Author", str(author))) section.props.append(("DumpLevel", _property.get_default(bpy.types.GlobalSCSProps.dump_level))) return section
def _fill_comment_header_section(look_list, variant_list): """Fills up comment section (before Header).""" section = _SectionData("#comment") section.props.append(("#", "# Look Names:")) for look in look_list: section.props.append(("#", "#\t" + look['name'])) section.props.append(("#", "#")) section.props.append(("#", "# Variant Names:")) for variant in variant_list: section.props.append(("#", "#\t" + variant[0])) section.props.append(("#", "#")) return section
def _make_common_part(item, index, col_type): if not item.scs_props.locator_collider_centered: if item.scs_props.locator_collider_type == 'Box': offset_matrix = ( item.matrix_world * Matrix.Translation( (0.0, -item.scs_props.locator_collider_box_y / 2, 0.0)) * (Matrix.Scale(item.scs_props.locator_collider_box_x, 4, (1.0, 0.0, 0.0)) * Matrix.Scale(item.scs_props.locator_collider_box_y, 4, (0.0, 1.0, 0.0)) * Matrix.Scale(item.scs_props.locator_collider_box_z, 4, (0.0, 0.0, 1.0)))) elif item.scs_props.locator_collider_type == 'Sphere': offset_matrix = ( item.matrix_world * Matrix.Translation( (0.0, -item.scs_props.locator_collider_dia / 2, 0.0)) * Matrix.Scale(item.scs_props.locator_collider_dia, 4)) elif item.scs_props.locator_collider_type in ('Capsule', 'Cylinder'): offset_matrix = ( item.matrix_world * Matrix.Translation( (0.0, -item.scs_props.locator_collider_len / 2, 0.0)) * Matrix.Scale(item.scs_props.locator_collider_dia, 4)) else: offset_matrix = item.matrix_world loc, qua, sca = _convert_utils.get_scs_transformation_components( offset_matrix) else: loc, qua, sca = _convert_utils.get_scs_transformation_components( item.matrix_world) section = _SectionData("Locator") section.props.append(("Name", _name_utils.tokenize_name(item.name))) section.props.append(("Index", index)) section.props.append(("Position", ["&&", loc])) section.props.append(("Rotation", ["&&", qua])) section.props.append(("Alias", "")) section.props.append( ("Weight", ["&", (item.scs_props.locator_collider_mass, )])) section.props.append(("Type", col_type)) return section
def get_as_section(self): """Get node information represented with SectionData structure class. :return: packed node as section data :rtype: io_scs_tools.internals.structure.SectionData """ # prepare streams for section representation self.__prepare_streams__() # update counters if Stream.Types.POSITION in self.__tp_streams: self.__terrain_point_count = self.__tp_streams[ Stream.Types.POSITION].get_size() if Stream.Types.VARIANT_BLOCK in self.__tp_streams: self.__terrain_point_variant_count = self.__tp_streams[ Stream.Types.VARIANT_BLOCK].get_size() self.__stream_count = len(self.__tp_streams) section = _SectionData("Node") section.props.append(("Index", self.__index)) section.props.append(("Position", ["&&", self.__position])) section.props.append(("Direction", ["&&", self.__direction])) section.props.append(("InputLanes", ["ii", tuple(self.__input_lanes)])) section.props.append( ("OutputLanes", ["ii", tuple(self.__output_lanes)])) section.props.append(("", "")) # empty line section.props.append(("TerrainPointCount", self.__terrain_point_count)) if Stream.Types.VARIANT_BLOCK in self.__tp_streams: section.props.append(("TerrainPointVariantCount", self.__terrain_point_variant_count)) section.props.append(("StreamCount", self.__stream_count)) for stream in self.__tp_streams.values(): section.sections.append(stream.get_as_section()) return section
def fill_export_section(): """Fills up "Export" section.""" section = _SectionData("Export") section.props.append(("ContentType", _property_utils.get_default(bpy.types.GlobalSCSProps.content_type))) section.props.append(("ExportScale", _property_utils.get_default(bpy.types.GlobalSCSProps.export_scale))) section.props.append(("ApplyModifiers", int(_property_utils.get_default(bpy.types.GlobalSCSProps.apply_modifiers)))) section.props.append(("ExcludeEdgesplit", int(_property_utils.get_default(bpy.types.GlobalSCSProps.exclude_edgesplit)))) section.props.append(("IncludeEdgesplit", int(_property_utils.get_default(bpy.types.GlobalSCSProps.include_edgesplit)))) section.props.append(("ActiveUVOnly", int(_property_utils.get_default(bpy.types.GlobalSCSProps.active_uv_only)))) section.props.append(("ExportVertexGroups", int(_property_utils.get_default(bpy.types.GlobalSCSProps.export_vertex_groups)))) section.props.append(("ExportVertexColor", int(_property_utils.get_default(bpy.types.GlobalSCSProps.export_vertex_color)))) section.props.append(("ExportVertexColorType", _property_utils.get_default(bpy.types.GlobalSCSProps.export_vertex_color_type))) section.props.append(("ExportVertexColorType7", _property_utils.get_default(bpy.types.GlobalSCSProps.export_vertex_color_type_7))) # section.props.append(("ExportAnimFile", info.get_default_prop_value(bpy.types.GlobalSCSProps.export_anim_file))) section.props.append(("ExportPimFile", int(_property_utils.get_default(bpy.types.GlobalSCSProps.export_pim_file)))) section.props.append(("OutputType", _property_utils.get_default(bpy.types.GlobalSCSProps.output_type))) section.props.append(("ExportPitFile", int(_property_utils.get_default(bpy.types.GlobalSCSProps.export_pit_file)))) section.props.append(("ExportPicFile", int(_property_utils.get_default(bpy.types.GlobalSCSProps.export_pic_file)))) section.props.append(("ExportPipFile", int(_property_utils.get_default(bpy.types.GlobalSCSProps.export_pip_file)))) section.props.append(("SignExport", int(_property_utils.get_default(bpy.types.GlobalSCSProps.sign_export)))) return section
def get_as_section(self): """Gets skin stream represented with SectionData structure class. :return: packed skin stream as section data :rtype: io_scs_tools.internals.structure.SectionData """ self.__item_count = len(self._data) section = _SectionData("PieceSkinStream") section.props.append(("Format", self.__format)) section.props.append(("Tag", self.__tag)) section.props.append(("ItemCount", self.__item_count)) section.props.append(("TotalWeightCount", self.__total_weight_count)) section.props.append( ("TotalVertexIndexCount", self.__total_vertex_index_count)) for skin_entry in self._data.values(): section.data.append(("__skin__", skin_entry.get_section_repr())) return section
def _fill_trigger_point_sections(tp_locators, offset_matrix): """Fills up "Trigger Point" sections.""" sections = [] for loc_index, loc_obj in enumerate(tp_locators): section = _SectionData("TriggerPoint") section.props.append(("TriggerID", loc_index)) section.props.append( ("TriggerAction", loc_obj.scs_props.locator_prefab_tp_action)) section.props.append( ("TriggerRange", loc_obj.scs_props.locator_prefab_tp_range)) section.props.append(("TriggerResetDelay", loc_obj.scs_props.locator_prefab_tp_reset_delay)) section.props.append(("TriggerResetDist", 0.0)) # constant section.props.append(("Flags", 0)) loc = _convert_utils.convert_location_to_scs(loc_obj.location, offset_matrix) section.props.append(("Position", ["&&", loc])) section.props.append( ("Neighbours", ["ii", _get_tp_neigbours(tp_locators, loc_obj)])) sections.append(section) return sections
def get_as_section(self): """Gets global model information represented with SectionData structure class. :return: packed globals as section data :rtype: io_scs_tools.internals.structure.SectionData """ section = _SectionData("Global") section.props.append(("VertexCount", Piece.get_global_vertex_count())) section.props.append( ("TriangleCount", Piece.get_global_triangle_count())) section.props.append( ("MaterialCount", Material.get_global_material_count())) section.props.append(("PieceCount", Piece.get_global_piece_count())) section.props.append(("PartCount", self.__part_count)) section.props.append(("BoneCount", Bones.get_global_bones_count())) section.props.append( ("LocatorCount", Locator.get_global_locator_count())) section.props.append(("Skeleton", self.__skeleton)) section.props.append( ("PieceSkinCount", PieceSkin.get_global_piece_skin_count())) return section
def update_item_in_file(item_pointer, new_value): """Resaves config file with updated given item to a new value. The "item_pointer" variable must be in form of 'SectionName.PropertyName', example: 'Paths.ProjectPath'.""" if _get_scs_globals().config_update_lock: return False else: filepath = get_config_filepath() ind = ' ' config_container = _pix.get_data_from_file(filepath, ind) new_settings_container = [] if config_container: new_value_changed = False item_pointer_split = item_pointer.split('.', 1) for section in config_container: new_section = _SectionData(section.type) for prop in section.props: if section.type == item_pointer_split[0] and prop[ 0] == item_pointer_split[1]: new_section.props.append((prop[0], new_value)) new_value_changed = True else: new_section.props.append((prop[0], prop[1])) # append new properties if they are not yet there if not new_value_changed and section.type == item_pointer_split[ 0]: new_section.props.append( (item_pointer_split[1], new_value)) new_settings_container.append(new_section) write_file(new_settings_container, filepath, ind) return True
def get_as_section(self): """Gets stream represented with SectionData structure class. :return: packed stream as section data :rtype: io_scs_tools.internals.structure.SectionData """ section = _SectionData("Stream") section.props.append(("Format", self.format)) if -1 < self.tag_index < 10: section.props.append(("Tag", self.tag + str(self.tag_index))) else: section.props.append(("Tag", self.tag)) if len(self.aliases) > 0: aliases = sorted(self.aliases.keys()) section.props.append(("AliasCount", len(aliases))) section.props.append(("Aliases", aliases)) section.data = self.data return section
def get_as_section(self): """Get curve information represented with SectionData structure class. :return: packed curve as section data :rtype: io_scs_tools.internals.structure.SectionData """ __EMPTY_LINE__ = ("", "") section = _SectionData("Curve") section.props.append(("Index", self.__index)) section.props.append(("#", "start locator: %r" % self.__tmp_ui_name)) section.props.append(("Name", self.__name)) section.props.append(__EMPTY_LINE__) section.props.append(("Flags", self.__flags)) section.props.append(__EMPTY_LINE__) section.props.append(("LeadsToNodes", self.__leads_to_nodes)) if self.__traffic_rule is not None and self.__traffic_rule != "": section.props.append(__EMPTY_LINE__) section.props.append(("TrafficRule", self.__traffic_rule)) if self.__sempahore_id is not None and self.__sempahore_id != -1: section.props.append(__EMPTY_LINE__) section.props.append(("SemaphoreID", self.__sempahore_id)) section.props.append(__EMPTY_LINE__) section.props.append(("NextCurves", ["ii", tuple(self.__next_curves)])) section.props.append(("PrevCurves", ["ii", tuple(self.__prev_curves)])) section.props.append(__EMPTY_LINE__) section.props.append(("Length", ["&", (self.__length, )])) section.props.append(__EMPTY_LINE__) section.sections.append(self.__bezier.get_as_section()) return section
def get_as_section(self): """Gets part represented with SectionData structure class. :return: packed part as section data :rtype: io_scs_tools.internals.structure.SectionData """ # update counters first self.__piece_count = len(self.__pieces) self.__locator_count = len(self.__locators) section = _SectionData("Part") section.props.append(("Name", self.__name)) section.props.append(("PieceCount", self.__piece_count)) section.props.append(("LocatorCount", self.__locator_count)) if self.__piece_count == 0: section.props.append(("Pieces", None)) else: section.props.append(("Pieces", list(self.__pieces.keys()))) if self.__locator_count == 0: section.props.append(("Locators", None)) else: section.props.append(("Locators", list(self.__locators.keys()))) return section
def _fill_node_sections(data_list, offset_matrix): """Fills up "Node" sections.""" sections = [] for item in data_list: section = _SectionData("Node") section.props.append( ("Index", int(item.scs_props.locator_prefab_con_node_index))) loc = _convert_utils.convert_location_to_scs(item.location, offset_matrix) section.props.append(("Position", ["&&", loc])) direction = _convert_utils.scs_to_blend_matrix().inverted() * ( item.matrix_world.to_quaternion() * Vector((0, 1, 0))) section.props.append(("Direction", ["&&", direction])) # print('p_locator_lanes: %s' % item.scs_props.p_locator_lanes) # lane_input_values = [] # lane_output_values = [] # for lane_num in range(item.scs_props.p_locator_lanes): # if lane_num: # lane_input_values.append(lane_num) # lane_output_values.append(lane_num) # else: # lane_input_values.append(-1) # lane_output_values.append(-1) section.props.append( ("InputLanes", ["ii", (-1, -1, -1, -1, -1, -1, -1, -1)])) # section.props.append(("InputLanes", lane_input_values)) section.props.append( ("OutputLanes", ["ii", (-1, -1, -1, -1, -1, -1, -1, -1)])) # section.props.append(("OutputLanes", lane_output_values)) section.props.append(("TerrainPointCount", 0)) section.props.append(("StreamCount", 0)) section.props.append(("", "")) # section.props.append(("__EMPTY_LINE__", 0)) sections.append(section) return sections
def make_stream_section(data, data_tag, aliases): """Takes data and their tag returns a stream section. :param data: Section data :type data: list :param data_tag: Tag (name) for the Section :type data_tag: str :param aliases: tuple of strings (aliases) :type aliases: tuple :return: 'Stream' Section data :rtype: SectionData """ # print('data: %s type: %s' % (str(data[0]), str(type(data[0])))) if type(data[0]) is Vector: data_type = 'NIC' if type(data[0][0]) is type(0.0): data_type = 'FLOAT' elif type(data[0][0]) is type(0): data_type = 'INT' data_format = str(data_type + str(len(data[0]))) elif data[0][0] == "__matrix__": data_format = 'FLOAT4x4' elif data[0][0] == "__time__": data_format = 'FLOAT' else: data_format = 'UNKNOWN_FORMAT' # print(' format: %r' % format) stream_section = _SectionData("Stream") stream_section.props.append(("Format", data_format)) stream_section.props.append(("Tag", data_tag)) if aliases: stream_section.props.append(("AliasCount", len(aliases))) for alias in aliases: stream_section.props.append(("Aliases", alias)) stream_section.data = data return stream_section
def _fill_coll_material_section(): """Fills up "Material" section for convex colliders.""" section = _SectionData("Material") section.props.append(("Alias", "convex")) # Static value section.props.append(("Effect", "dry.void")) # Static value return section
def export(root_object, filepath, name_suffix, used_parts, used_materials): """Export PIT. :param root_object: SCS root object :type root_object: bpy.types.Object :param filepath: PIT file path :type filepath: str :param name_suffix: file name suffix :type name_suffix: str :param used_parts: parts transitional structure for accessing stored parts from PIM, PIC and PIP :type used_parts: io_scs_tools.exp.transition_structs.parts.PartsTrans :param used_materials: materials transitional structure for accessing stored materials from PIM :type used_materials: io_scs_tools.exp.transition_structs.materials.MaterialsTrans :return: True if successful; False otherwise; :rtype: bool """ scs_globals = _get_scs_globals() file_name = root_object.name print("\n************************************") print("** SCS PIT Exporter **") print("** (c)2014 SCS Software **") print("************************************\n") # DATA GATHERING look_list = [] variant_list = [] saved_active_look = root_object.scs_props.active_scs_look looks_inventory = root_object.scs_object_look_inventory looks_count = len(looks_inventory) if looks_count <= 0: looks_count = 1 used_materials_pairs = used_materials.get_as_pairs() for i in range(0, looks_count): # apply each look from inventory first if len(looks_inventory) > 0: root_object.scs_props.active_scs_look = i # set index for curret look _looks.apply_active_look( root_object ) # apply look manually, as active look setter method works only when user sets index from UI curr_look_name = looks_inventory[i].name else: # if no looks create default curr_look_name = "default" material_dict = {} material_list = [] # get materials data for material_name, material in used_materials_pairs: if material is None: material_name = str("_default_material_-_default_settings_") # DEFAULT MATERIAL material_export_data = default_material(material_name) material_list.append(material_name) else: # print('material name: %r' % material.name) material_list.append(material) # MATERIAL EFFECT effect_name = material.scs_props.mat_effect_name # PRESET SHADERS flags = 0 attribute_cnt = texture_cnt = 0 attribute_sections = [] texture_sections = [] active_shader_preset_name = material.scs_props.active_shader_preset_name # SUBSTANCE substance_value = material.scs_props.substance # only write substance to material if it's assigned if substance_value != "None" and substance_value != "": substance_data = _SectionData("Attribute") substance_data.props.append(("Format", "STRING")) substance_data.props.append(("Tag", "substance")) substance_data.props.append( ("Value", ["i", (substance_value, )])) attribute_sections.append(substance_data) attribute_cnt += 1 if _shader_presets.has_preset( active_shader_preset_name ) and active_shader_preset_name != "<none>": preset = _shader_presets.get_preset( active_shader_preset_name) flavors_str = effect_name[len(preset.effect):] section = _shader_presets.get_section( active_shader_preset_name, flavors_str) # FLAGS for prop in section.props: if prop[0] == "Flags": flags = int(not material.scs_props.enable_aliasing) break # COLLECT ATTRIBUTES AND TEXTURES for item in section.sections: # if attribute is hidden in shader preset ignore it on export # this is useful for flavor hiding some attributes from original material # eg: airbrush on "truckpaint" hides R G B aux attributes which are not present # when using airbrush flavor hidden = item.get_prop_value("Hide") if hidden and hidden == "True": continue preview_only = item.get_prop_value("PreviewOnly") if preview_only and preview_only == "True": continue # ATTRIBUTES if item.type == "Attribute": # print(' Attribute:') attribute_data = _SectionData("Attribute") for rec in item.props: # print(' rec: %r' % str(rec)) if rec[0] == "Format": attribute_data.props.append( (rec[0], rec[1])) elif rec[0] == "Tag": # tag_prop = rec[1].replace("[", "").replace("]", "") # attribute_data.props.append((rec[0], tag_prop)) attribute_data.props.append( (rec[0], rec[1])) elif rec[0] == "Value": format_prop = item.get_prop("Format")[1] tag_prop = item.get_prop("Tag")[1] tag_prop = tag_prop.replace("[", "").replace( "]", "") # print(' format_prop: %r' % str(format_prop)) # print(' tag_prop: %r' % str(tag_prop)) if "aux" in tag_prop: aux_props = getattr( material.scs_props, "shader_attribute_" + tag_prop) value = [] for aux_prop in aux_props: value.append(aux_prop.value) # extract list if there is only one value inside and tagged as FLOAT # otherwise it gets saved as: "Value: ( [0.0] )" instead of: "Value: ( 0.0 )" if len( value ) == 1 and format_prop == "FLOAT": value = value[0] else: value = getattr( material.scs_props, "shader_attribute_" + tag_prop, "NO TAG") # print(' value: %s' % str(value)) if format_prop == 'FLOAT': attribute_data.props.append( (rec[0], ["&&", (value, )])) elif format_prop == 'INT': attribute_data.props.append( (rec[0], ["ii", (value, )])) else: attribute_data.props.append( (rec[0], ["i", tuple(value)])) attribute_sections.append(attribute_data) attribute_cnt += 1 # TEXTURES elif item.type == "Texture": # print(' Texture:') texture_data = _SectionData("Texture") for rec in item.props: # print(' rec: %r' % str(rec)) if rec[0] == "Tag": tag_prop = rec[1].split(":")[1] tag = str("texture[" + str(texture_cnt) + "]:" + tag_prop) texture_data.props.append((rec[0], tag)) elif rec[0] == "Value": tag_prop = item.get_prop("Tag")[1].split( ":")[1] # print(' tag_prop: %r' % str(tag_prop)) # create and get path to tobj tobj_rel_path = get_texture_path_from_material( material, tag_prop, os.path.dirname(filepath)) texture_data.props.append( (rec[0], tobj_rel_path)) texture_sections.append(texture_data) texture_cnt += 1 material_export_data = _SectionData("Material") material_export_data.props.append(("Alias", material.name)) material_export_data.props.append(("Effect", effect_name)) material_export_data.props.append(("Flags", flags)) material_export_data.props.append( ("AttributeCount", attribute_cnt)) material_export_data.props.append( ("TextureCount", texture_cnt)) for attribute in attribute_sections: material_export_data.sections.append(attribute) for texture in texture_sections: material_export_data.sections.append(texture) elif active_shader_preset_name == "<imported>": material_attributes = material['scs_shader_attributes'][ 'attributes'].to_dict().values() material_textures = material['scs_shader_attributes'][ 'textures'].to_dict().values() material_export_data = _SectionData("Material") material_export_data.props.append(("Alias", material.name)) material_export_data.props.append(("Effect", effect_name)) material_export_data.props.append( ("Flags", int(not material.scs_props.enable_aliasing))) material_export_data.props.append( ("AttributeCount", len(material_attributes))) material_export_data.props.append( ("TextureCount", len(material_textures))) for attribute_dict in material_attributes: attribute_section = _SectionData("Attribute") format_value = "" for attr_prop in sorted(attribute_dict.keys()): # get the format of current attribute (we assume that "Format" attribute is before "Value" attribute in this for loop) if attr_prop == "Format": format_value = attribute_dict[attr_prop] if attr_prop == "Value" and ( "FLOAT" in format_value or "STRING" in format_value or "INT" in format_value): tag_prop = attribute_dict["Tag"].replace( "[", "").replace("]", "") if "aux" in tag_prop: aux_props = getattr( material.scs_props, "shader_attribute_" + tag_prop) value = [] for aux_prop in aux_props: value.append(aux_prop.value) else: value = getattr( material.scs_props, "shader_attribute_" + tag_prop, None) if isinstance(value, float): value = [value] if value is None: attribute_section.props.append( (attr_prop, [ "i", tuple(attribute_dict[attr_prop]) ])) else: attribute_section.props.append( (attr_prop, ["i", tuple(value)])) elif attr_prop == "Tag" and "aux" in attribute_dict[ attr_prop]: attribute_section.props.append( (attr_prop, "aux[" + attribute_dict[attr_prop][3:] + "]")) else: attribute_section.props.append( (attr_prop, attribute_dict[attr_prop])) material_export_data.sections.append(attribute_section) for texture_dict in material_textures: texture_section = _SectionData("Texture") tag_id_string = "" for tex_prop in sorted(texture_dict.keys()): if tex_prop == "Tag": tag_id_string = texture_dict[tex_prop].split( ':')[1] if tex_prop == "Value" and tag_id_string != "": tobj_rel_path = get_texture_path_from_material( material, tag_id_string, os.path.dirname(filepath)) texture_section.props.append( (tex_prop, tobj_rel_path)) else: texture_section.props.append( (tex_prop, texture_dict[tex_prop])) material_export_data.sections.append(texture_section) else: # when user made material presets were there, but there is no preset library at export for some reason lprint( "W Shader preset used on %r not found in Shader Presets Library (Did you set correct path?), " "exporting default material instead!", (material_name, )) material_name = str("_" + material_name + "_-_default_settings_") material_export_data = default_material(material_name) material_dict[material_name] = material_export_data # create materials sections for looks material_sections = fill_material_sections(material_list, material_dict) look_data = { "name": curr_look_name, "material_sections": material_sections } look_list.append(look_data) # restore look applied before export root_object.scs_props.active_scs_look = saved_active_look # set index for curret look _looks.apply_active_look( root_object ) # apply look manually, as active look setter method works only when user sets index from UI # PARTS AND VARIANTS... used_parts_names = used_parts.get_as_list() if len(root_object.scs_object_variant_inventory) == 0: # If there is no Variant, add the Default one... part_list = fill_part_list(root_object.scs_object_part_inventory, used_parts_names, all_parts=True) variant_list.append((_VARIANT_consts.default_name, part_list), ) else: for variant in root_object.scs_object_variant_inventory: part_list = fill_part_list(variant.parts, used_parts_names) variant_list.append((variant.name, part_list), ) # DATA CREATION header_section = fill_header_section(1, file_name, scs_globals.export_write_signature) look_section = fill_look_sections(look_list) # part_sections = fill_part_section(part_list) variant_section = fill_variant_sections(variant_list) comment_header_section = fill_comment_header_section( look_list, variant_list) global_section = fill_global_section(len(look_list), len(variant_list), used_parts.count(), len(used_materials_pairs)) # DATA ASSEMBLING pit_container = [comment_header_section, header_section, global_section] for section in look_section: pit_container.append(section) for section in variant_section: pit_container.append(section) # FILE EXPORT ind = " " pit_filepath = str(filepath + ".pit" + name_suffix) result = _pix_container.write_data_to_file(pit_container, pit_filepath, ind) # print("************************************") return result
def _fill_piece_sections_5(root_object, object_list, bone_list, scene, used_materials, offset_matrix, scs_globals): """Fills up "Piece" sections for file version 5. :param root_object: SCS Root Object :type root_object: bpy.types.Object :param object_list: Object for export :type object_list: list of Objects :param bone_list: Bones for export :type bone_list: list :param scene: Blender Scene to operate on :type scene: bpy.types.Scene :param used_materials: All Materials used in 'SCS Game Object' :type used_materials: list :param offset_matrix: Matrix for specifying of pivot point :type offset_matrix: Matrix :param scs_globals: SCS Tools Globals :type scs_globals: GlobalSCSProps :return: list of parameters :rtype: list """ handle_unused_arg(__file__, _fill_piece_sections_5.__name__, "used_materials", used_materials) apply_modifiers = scs_globals.apply_modifiers exclude_edgesplit = scs_globals.exclude_edgesplit include_edgesplit = scs_globals.include_edgesplit piece_sections = [] piece_index_obj = {} piece_index = global_vertex_count = global_face_count = 0 # ----- START: SOLVE THIS! skin_list = [] skin_weights_cnt = skin_clones_cnt = 0 # ----- END: SOLVE THIS! print_info = False if print_info: print('used_materials: %s\n' % str(used_materials)) print('object_list: %s\n' % str(object_list)) # For each object... for obj_i, obj in enumerate(object_list): piece_index_obj[obj_i] = obj # Get all Materials from Object as they're set in material slots... object_materials = _object_utils.get_object_materials(obj) if print_info: print(' object_materials: %s' % str(object_materials)) # Make Material dictionary (needed for getting rid of Material duplicities)... material_dict = _make_material_dict(object_materials) if print_info: for item in material_dict: print(' "%s" = %s' % (str(item), str(material_dict[item]))) print('') # Get Object's Mesh data and list of temporarily disabled "Edge Split" Modifiers... mesh = _object_utils.get_mesh(obj) # SORT GEOMETRY piece_dict, skin_list, skin_weights_cnt, skin_clones_cnt = _get_geometry_dict( root_object, obj, mesh, offset_matrix, material_dict, used_materials, bone_list, scs_globals) # DUMP if 0: for piece in piece_dict: print('Pm: %r' % piece) for data in piece_dict[piece]: print(' Da: %r' % str(data)) if data == 'hash_dict': if len(piece_dict[piece][data]) > 0: for val in piece_dict[piece][data]: print(' HD: %s:%s' % (str(val), str(piece_dict[piece][data][val]))) else: print(' NO "hash_dict" Data!') elif data == 'verts': if len(piece_dict[piece][data]) > 0: for val in piece_dict[piece][data]: print(' Ve: %s' % str(val)) else: print(' NO "verts" Data!') elif data == 'faces': if len(piece_dict[piece][data]) > 0: for val in piece_dict[piece][data]: print(' Fa: %s' % str(val)) else: print(' NO "faces" Data!') print('') print('') # CREATE SECTIONS for piece in piece_dict: vertex_count = len(piece_dict[piece]['verts']) global_vertex_count += vertex_count face_count = len(piece_dict[piece]['faces']) global_face_count += face_count stream_sections = [] # VERTEX STREAMS verts_data = {} for val in piece_dict[piece]['verts']: facevert_common_data, facevert_unique_data = val for data_key in facevert_common_data: # print(' data_key: %s' % str(data_key)) if data_key == '_VG': pass else: if data_key not in verts_data: verts_data[data_key] = [] verts_data[data_key].append( facevert_common_data[data_key]) for data_key in facevert_unique_data: # print(' data_key: %s' % str(data_key)) if data_key == '_UV': for layer_i, layer in enumerate( facevert_unique_data[data_key]): layer_data_key = str(data_key + str(layer_i)) if layer_data_key not in verts_data: verts_data[layer_data_key] = [] verts_data[layer_data_key].append( facevert_unique_data[data_key][layer]) if data_key == '_RGBA': for layer_i, layer in enumerate( facevert_unique_data[data_key]): if len(facevert_unique_data[data_key]) > 1: layer_data_key = str(data_key + str(layer_i)) else: layer_data_key = data_key if layer_data_key not in verts_data: verts_data[layer_data_key] = [] verts_data[layer_data_key].append( facevert_unique_data[data_key][layer]) lprint('S verts_data: %s', (str(verts_data), )) data_types = ('_POSITION', '_NORMAL', '_UV', '_UV0', '_UV1', '_UV2', '_UV3', '_UV4', '_UV5', '_UV6', '_UV7', '_UV8', '_UV9', '_RGBA', '_RGBA0', '_RGBA1', '_RGBA2', '_RGBA3', '_RGBA4', '_RGBA5', '_RGBA6', '_RGBA7', '_RGBA8', '_RGBA9', '_VG') add_uv = True add_rgba = False for data_type in data_types: if '_RGBA' not in verts_data: add_rgba = True if data_type in verts_data: if data_type.startswith('_UV'): add_uv = False stream_sections.append( _pix_container.make_stream_section( verts_data[data_type], data_type, (data_type, ))) else: stream_sections.append( _pix_container.make_stream_section( verts_data[data_type], data_type, ())) # ADD DEFAULT UV LAYER if add_uv: lprint('I Adding default UV layer.') uv_dummy_data = [] for vert in range(len(piece_dict[piece]['verts'])): uv_dummy_data.append(Vector((0.0, 0.0))) stream_sections.append( _pix_container.make_stream_section(uv_dummy_data, '_UV0', ('_UV0', ))) # ADD DEFAULT RGBA LAYER if add_rgba: lprint('I Adding default RGBA (vertex color) layer.') rgba_dummy_data = [] for vert in range(len(piece_dict[piece]['verts'])): rgba_dummy_data.append(Vector((1.0, 1.0, 1.0, 1.0))) stream_sections.append( _pix_container.make_stream_section(rgba_dummy_data, '_RGBA', ())) # PIECE PROPERTIES piece_section = _SectionData("Piece") piece_section.props.append(("Index", piece_index)) piece_section.props.append( ("Material", piece_dict[piece]['material_index'])) piece_section.props.append(("VertexCount", vertex_count)) piece_section.props.append(("TriangleCount", face_count)) piece_section.props.append(("StreamCount", len(stream_sections))) piece_section.props.append(("", "")) piece_index += 1 for stream_section in stream_sections: piece_section.sections.append(stream_section) # FACE STREAM stream_section = _SectionData("Triangles") stream_section.data = piece_dict[piece]['faces'] piece_section.sections.append(stream_section) piece_sections.append(piece_section) return piece_sections, global_vertex_count, global_face_count, piece_index_obj, skin_list, skin_weights_cnt, skin_clones_cnt
def export(root_object, used_parts, used_materials, scene, filepath): scs_globals = _get_scs_globals() output_type = scs_globals.output_type file_name = root_object.name print("\n************************************") print("** SCS PIT Exporter **") print("** (c)2014 SCS Software **") print("************************************\n") # DATA GATHERING look_list = [] variant_list = [] saved_active_look = root_object.scs_props.active_scs_look looks_inventory = root_object.scs_object_look_inventory looks_count = len(looks_inventory) if looks_count <= 0: looks_count = 1 for i in range(0, looks_count): # apply each look from inventory first if len(looks_inventory) > 0: root_object.scs_props.active_scs_look = i # actually write values to material because Blender might not refresh data yet _looks.apply_active_look(root_object) curr_look_name = looks_inventory[i].name else: # if no looks create default curr_look_name = "default" material_dict = {} material_list = [] # get materials data for material in used_materials: if material is not None: # if material in ("_empty_slot_", "_empty_material_"): # NOTE: only workaround until module doesn't gets rewritten if material in bpy.data.materials: material = bpy.data.materials[material] if isinstance(material, str): material_name = str(material + "-_default_settings_") # DEFAULT MATERIAL material_export_data = _default_material(material_name) material_list.append(material_name) else: # print('material name: %r' % material.name) material_name = material.name material_list.append(material) # SUBSTANCE if material.scs_props.substance != 'None': lprint( 'D material.name: %r\tmat.scs_props.substance: "%s"', (material.name, str(material.scs_props.substance))) # TODO: Substance Export... # MATERIAL EFFECT # shader_data = material.get("scs_shader_attributes", {}) # effect_name = shader_data.get('effect', "NO EFFECT") effect_name = material.scs_props.mat_effect_name # CgFX SHADERS # print("\n=== GET SHADER EXPORT DATA =======================") ## NOTE: The following code is OBSOLETE!!! # cgfx_export_data = None # print(" cgfx_export_data:\n%s" % str(cgfx_export_data)) # if cgfx_export_data: # print("\nAttributes:") # for attribute in cgfx_export_data['attributes']: # if cgfx_export_data['attributes'][attribute]: # print(" %s:" % str(attribute)) # for rec in cgfx_export_data['attributes'][attribute]: # print(" %s: %s" % (str(rec), str(cgfx_export_data['attributes'][attribute][rec]))) # else: # print("%s:\n %s" % (str(attribute), cgfx_export_data['attributes'][attribute])) # print("\nTextures:") # for attribute in cgfx_export_data['textures']: # if cgfx_export_data['textures'][attribute]: # print(" %s:" % str(attribute)) # for rec in cgfx_export_data['textures'][attribute]: # print(" %s: %s" % (str(rec), str(cgfx_export_data['textures'][attribute][rec]))) # else: # print("%s:\n %s" % (str(attribute), cgfx_export_data['textures'][attribute])) # else: # Print(1, 'E No CgFX data for material %r!' % material.name) # print("==================================================") # PRESET SHADERS preset_found = False alias = "NO SHADER" def_cnt = attribute_cnt = texture_cnt = 0 def_sections = [] attribute_sections = [] texture_sections = [] active_shader_preset_name = material.scs_props.active_shader_preset_name # print(' active_shader_preset_name: %r' % active_shader_preset_name) for preset_i, preset in enumerate( bpy.data.worlds[0].scs_shader_presets_inventory): # print(' preset[%i]: %r' % (preset_i, preset.name)) if preset.name == active_shader_preset_name: # print(' - material %r - %r' % (material.name, preset.name)) # LOAD PRESET shader_presets_abs_path = _path_utils.get_abs_path( scs_globals.shader_presets_filepath) # shader_presets_filepath = _get_scs_globals().shader_presets_filepath # print('shader_presets_filepath: %r' % shader_presets_filepath) # if shader_presets_filepath.startswith(str(os.sep + os.sep)): ## RELATIVE PATH # shader_presets_abs_path = get_abs_path(shader_presets_filepath) # else: # shader_presets_abs_path = shader_presets_filepath if os.path.isfile(shader_presets_abs_path): presets_container = _pix_container.get_data_from_file( shader_presets_abs_path, ' ') # FIND THE PRESET IN FILE if presets_container: for section in presets_container: if section.type == "Shader": section_properties = _get_properties( section) if 'PresetName' in section_properties: preset_name = section_properties[ 'PresetName'] if preset_name == active_shader_preset_name: alias = material.name # print(' + preset name: %r' % preset_name) # COLLECT ATTRIBUTES AND TEXTURES for item in section.sections: # DATA EXCHANGE FORMAT ATRIBUTE if item.type == "DataExchangeFormat": def_data = _SectionData( "DataExchangeFormat" ) for rec in item.props: def_data.props.append( (rec[0], rec[1])) def_sections.append( def_data) def_cnt += 1 # ATTRIBUTES if item.type == "Attribute": # print(' Attribute:') attribute_data = _SectionData( "Attribute") for rec in item.props: # print(' rec: %r' % str(rec)) if rec[0] == "Format": attribute_data.props.append( (rec[ 0], rec[1] )) elif rec[ 0] == "Tag": # tag_prop = rec[1].replace("[", "").replace("]", "") # attribute_data.props.append((rec[0], tag_prop)) attribute_data.props.append( (rec[ 0], rec[1] )) elif rec[ 0] == "Value": format_prop = item.get_prop( "Format" )[1] tag_prop = item.get_prop( "Tag" )[1] tag_prop = tag_prop.replace( "[", "" ).replace( "]", "") # print(' format_prop: %r' % str(format_prop)) # print(' tag_prop: %r' % str(tag_prop)) if "aux" in tag_prop: aux_props = getattr( material . scs_props, "shader_attribute_" + tag_prop ) value = [] for aux_prop in aux_props: value.append( aux_prop . value ) else: value = getattr( material . scs_props, "shader_attribute_" + tag_prop, "NO TAG" ) # print(' value: %s' % str(value)) if format_prop == 'FLOAT': attribute_data.props.append( (rec[ 0], [ "&&", (value, ) ] )) else: attribute_data.props.append( (rec[ 0], [ "i", tuple( value ) ] )) attribute_sections.append( attribute_data) attribute_cnt += 1 # TEXTURES elif item.type == "Texture": # print(' Texture:') texture_data = _SectionData( "Texture") for rec in item.props: # print(' rec: %r' % str(rec)) if rec[0] == "Tag": tag_prop = rec[ 1].split( ":" )[1] tag = str( "texture[" + str(texture_cnt ) + "]:" + tag_prop ) texture_data.props.append( (rec[ 0], tag)) elif rec[ 0] == "Value": tag_prop = item.get_prop( "Tag" )[1].split( ":")[1] # print(' tag_prop: %r' % str(tag_prop)) # create and get path to tobj tobj_rel_path = _get_texture_path_from_material( material, tag_prop, os. path. dirname( filepath )) texture_data.props.append( (rec[ 0], tobj_rel_path )) texture_sections.append( texture_data) texture_cnt += 1 preset_found = True break else: lprint('\nW The file path "%s" is not valid!', (shader_presets_abs_path, )) if preset_found: break if preset_found: material_export_data = _SectionData("Material") material_export_data.props.append(("Alias", alias)) material_export_data.props.append( ("Effect", effect_name)) material_export_data.props.append(("Flags", 0)) if output_type.startswith('def'): material_export_data.props.append( ("DataExchangeFormatCount", def_cnt)) material_export_data.props.append( ("AttributeCount", attribute_cnt)) material_export_data.props.append( ("TextureCount", texture_cnt)) if output_type.startswith('def'): for def_section in def_sections: material_export_data.sections.append( def_section) for attribute in attribute_sections: material_export_data.sections.append(attribute) for texture in texture_sections: material_export_data.sections.append(texture) elif active_shader_preset_name == "<imported>": material_attributes = material[ 'scs_shader_attributes']['attributes'].to_dict( ).values() material_textures = material['scs_shader_attributes'][ 'textures'].to_dict().values() material_export_data = _SectionData("Material") material_export_data.props.append( ("Alias", material.name)) material_export_data.props.append( ("Effect", effect_name)) material_export_data.props.append(("Flags", 0)) material_export_data.props.append( ("AttributeCount", len(material_attributes))) material_export_data.props.append( ("TextureCount", len(material_textures))) for attribute_dict in material_attributes: attribute_section = _SectionData("Attribute") format_value = "" for attr_prop in sorted(attribute_dict.keys()): # get the format of current attribute (we assume that "Format" attribute is before "Value" attribute in this for loop) if attr_prop == "Format": format_value = attribute_dict[attr_prop] if attr_prop == "Value" and ( "FLOAT" in format_value or "STRING" in format_value): attribute_section.props.append( (attr_prop, [ "i", tuple(attribute_dict[attr_prop]) ])) elif attr_prop == "Tag" and "aux" in attribute_dict[ attr_prop]: attribute_section.props.append( (attr_prop, "aux[" + attribute_dict[attr_prop][3:] + "]")) else: attribute_section.props.append( (attr_prop, attribute_dict[attr_prop])) material_export_data.sections.append( attribute_section) for texture_dict in material_textures: texture_section = _SectionData("Texture") tag_id_string = "" for tex_prop in sorted(texture_dict.keys()): if tex_prop == "Tag": tag_id_string = texture_dict[ tex_prop].split(':')[1] if tex_prop == "Value" and tag_id_string != "": tobj_rel_path = _get_texture_path_from_material( material, tag_id_string, os.path.dirname(filepath)) texture_section.props.append( (tex_prop, tobj_rel_path)) else: texture_section.props.append( (tex_prop, texture_dict[tex_prop])) material_export_data.sections.append( texture_section) else: # DEFAULT MATERIAL material_name = str("_" + material_name + "_-_default_settings_") material_export_data = _default_material(material_name) material_dict[material_name] = material_export_data # create materials sections for looks material_sections = _fill_material_sections(material_list, material_dict) look_data = { "name": curr_look_name, "material_sections": material_sections } look_list.append(look_data) # restore look applied before export root_object.scs_props.active_scs_look = saved_active_look # PARTS AND VARIANTS... part_list_cnt = len(used_parts.keys()) if len(root_object.scs_object_variant_inventory) == 0: # If there is no Variant, add the Default one... part_list = _fill_part_list(root_object.scs_object_part_inventory, used_parts, all_parts=True) variant_list.append((_VARIANT_consts.default_name, part_list), ) else: for variant in root_object.scs_object_variant_inventory: part_list = _fill_part_list(variant.parts, used_parts) variant_list.append((variant.name, part_list), ) # DATA CREATION header_section = _fill_header_section(file_name, scs_globals.sign_export) look_section = _fill_look_sections(look_list) # part_sections = fill_part_section(part_list) variant_section = _fill_variant_sections(variant_list) comment_header_section = _fill_comment_header_section( look_list, variant_list) global_section = _fill_global_section(len(look_list), len(variant_list), part_list_cnt, len(used_materials)) # DATA ASSEMBLING pit_container = [comment_header_section, header_section, global_section] for section in look_section: pit_container.append(section) for section in variant_section: pit_container.append(section) # FILE EXPORT ind = " " pit_filepath = str(filepath + ".pit") result = _pix_container.write_data_to_file(pit_container, pit_filepath, ind) # print("************************************") return result
def _fill_global_section(bone_cnt): """Fills up "Global" section.""" section = _SectionData("Global") section.props.append(("BoneCount", bone_cnt)) return section
def fill_import_section(): """Fills up "Import" section.""" section = _SectionData("Import") section.props.append( ("ImportScale", _property.get_default(bpy.types.GlobalSCSProps.import_scale))) section.props.append( ("ImportPimFile", int( _property.get_default( bpy.types.GlobalSCSProps.import_pim_file)))) section.props.append( ("UseWelding", int(_property.get_default(bpy.types.GlobalSCSProps.use_welding)))) section.props.append( ("WeldingPrecision", int( _property.get_default( bpy.types.GlobalSCSProps.welding_precision)))) section.props.append( ("ImportPitFile", int( _property.get_default( bpy.types.GlobalSCSProps.import_pit_file)))) section.props.append( ("LoadTextures", int(_property.get_default( bpy.types.GlobalSCSProps.load_textures)))) section.props.append( ("ImportPicFile", int( _property.get_default( bpy.types.GlobalSCSProps.import_pic_file)))) section.props.append( ("ImportPipFile", int( _property.get_default( bpy.types.GlobalSCSProps.import_pip_file)))) section.props.append( ("ImportPisFile", int( _property.get_default( bpy.types.GlobalSCSProps.import_pis_file)))) section.props.append( ("ConnectedBones", int( _property.get_default( bpy.types.GlobalSCSProps.connected_bones)))) section.props.append(("BoneImportScale", _property.get_default( bpy.types.GlobalSCSProps.bone_import_scale))) section.props.append( ("ImportPiaFile", int( _property.get_default( bpy.types.GlobalSCSProps.import_pia_file)))) section.props.append( ("IncludeSubdirsForPia", int( _property.get_default( bpy.types.GlobalSCSProps.include_subdirs_for_pia)))) section.props.append( ("MeshCreationType", _property.get_default( bpy.types.GlobalSCSProps.mesh_creation_type))) return section
def _fill_part_sections(locator_list, used_parts): """Fills up "Parts" sections. :param locator_list: list of Blender Objects - only 'Empty' typs, set as 'SCS Model Locators' :type locator_list: list :return: list of 'part_sections' :rtype: list """ parts = [] locator_parts = {} for locator_i, locator in enumerate(locator_list): scs_part = locator.scs_props.scs_part if scs_part not in locator_parts: locator_parts[scs_part] = [locator_i] else: locator_parts[scs_part].append(locator_i) if scs_part not in parts: parts.append(scs_part) # PART SECTIONS part_sections = {} for part_name in parts: # PIECE COUNT piece_count = 0 # PIECES pieces = None # LOCATOR COUNT locator_count = 0 if part_name in locator_parts: locator_count = len(locator_parts[part_name]) # LOCATORS locators = None if part_name in locator_parts: if locator_parts[part_name]: locators = locator_parts[part_name] # MAKE SECTION part_section = _SectionData("Part") part_section.props.append(("Name", part_name)) part_section.props.append(("PieceCount", piece_count)) part_section.props.append(("LocatorCount", locator_count)) part_section.props.append(("Pieces", pieces)) part_section.props.append(("Locators", locators)) part_sections[part_name] = part_section # add this part to used parts dictionary if part_name not in used_parts: used_parts[part_name] = 1 # add parts from PIM file which are not yet addded ordered_part_sections = [] for part_name in used_parts.keys(): if part_name in part_sections: ordered_part_sections.append(part_sections[part_name]) else: part_section = _SectionData("Part") part_section.props.append(("Name", part_name)) part_section.props.append(("PieceCount", 0)) part_section.props.append(("LocatorCount", 0)) part_section.props.append(("Pieces", None)) part_section.props.append(("Locators", None)) ordered_part_sections.append(part_section) return ordered_part_sections
def _read_section(file, section_ids, pix_container): """This function reads the nested sections. It recursively calls itself to read all levels of data hierarchy.""" data_type = '' props = [] data = [] data_index = 0 section_type = '' while data_type != 'SE_E': data_type, line = next_line(file) if data_type in ('EOF', 'ERR'): break # print('%s =-> "%s"' % (type, line)) if data_type == 'Prop': # print(' -++- line: %s' % line) prop = _get_prop(line) # print('prop: %s' % prop) if prop is not None: props.append(prop) elif data_type == 'data': # print('line: "%s"' % line) dat_index, dat = _get_data(file, line) if dat_index == data_index: # print('dat: %s' % dat) data_index += 1 if dat != []: data.append(dat) else: print( 'WARNING - Inconsistent data indexing in line: "%s"! Skipping...' % line) elif data_type == 'empty_line': props.append(("", "")) elif data_type == 'line_C': comment = line.strip() props.append(("#", comment[2:])) elif data_type == 'SE_C': # comment_section = data_structures.section_data("#comment") print('comment section: "%s"' % line) elif data_type == 'SE_S': # section_type = re.split(r'[ ]+', line)[0] type_line = re.split(r'[ ]+', line) for rec in type_line: if rec != '': try: section_type = re.split(r'[ ]+', line)[1] except: section_type = '' print( 'WARNING - Unknown data in line: "%s"! Skipping...' % line) break new_section_ids = _SectionData(section_type) new_section, pix_container = _read_section(file, new_section_ids, pix_container) section_ids.sections.append(new_section) # pix_container.append(new_section) if data_type != 'SE_E': section_ids.props = props section_ids.data = data return section_ids, pix_container
def _fill_nav_curve_sections(nav_point_list, offset_matrix): """Fills up (navigation) "Curve" sections.""" _INDEX = "index" _START = "start" _END = "end" _PREV_CURVES = "prev_curves" _NEXT_CURVES = "next_curves" curves_dict = _connections_group_wrapper.get_curves( nav_point_list, _INDEX, _START, _END, _NEXT_CURVES, _PREV_CURVES) # prepare empty sections for curves so it can be later placed directly on right index sections = [_SectionData("Dummy")] * len(curves_dict) for connection_key in curves_dict.keys(): curve = curves_dict[connection_key] start_loc = bpy.data.objects[curve[_START]] end_loc = bpy.data.objects[curve[_END]] section = _SectionData("Curve") section.props.append(("Index", curve[_INDEX])) section.props.append( ("Name", _name_utils.tokenize_name(curve[_START]))) section.props.append(("", "")) section.props.append(("#", "Flags:")) section.props.append(("Flags", _get_np_flags(start_loc, end_loc))) section.props.append(("", "")) section.props.append( ("LeadsToNodes", 0)) # TODO SIMON: make it happen when you know what it means speed_limit = _get_np_speed_limit(start_loc) if speed_limit: section.props.append(("", "")) section.props.append(("SpeedLimit", [ "&", ])) traffic_light = _get_np_traffic_light_id(start_loc) if traffic_light != -1: section.props.append(("", "")) section.props.append(("TrafficLightID", )) section.props.append(("", "")) section.props.append(("NextCurves", [ "ii", _get_np_prev_next_curves(curves_dict, curve[_NEXT_CURVES], _INDEX) ])) section.props.append(("PrevCurves", [ "ii", _get_np_prev_next_curves(curves_dict, curve[_PREV_CURVES], _INDEX) ])) section.props.append(("", "")) section.props.append( ("Length", ["&", (_get_np_length(start_loc, end_loc), )])) section.props.append(("", "")) bezier_section = _SectionData("Bezier") # START NODE start_section = _SectionData("Start") loc = _convert_utils.convert_location_to_scs(start_loc.location, offset_matrix) start_section.props.append(("Position", ["&&", loc])) direction_vector = _convert_utils.scs_to_blend_matrix().inverted() * ( start_loc.matrix_world.to_quaternion() * Vector((0, 1, 0))) start_section.props.append(("Direction", [ "&&", (direction_vector[0], direction_vector[1], direction_vector[2]) ])) # END NODE end_section = _SectionData("End") loc = _convert_utils.convert_location_to_scs(end_loc.location, offset_matrix) end_section.props.append(("Position", ["&&", loc])) direction_vector = _convert_utils.scs_to_blend_matrix().inverted() * ( end_loc.matrix_world.to_quaternion() * Vector((0, 1, 0))) end_section.props.append(("Direction", [ "&&", (direction_vector[0], direction_vector[1], direction_vector[2]) ])) bezier_section.sections.append(start_section) bezier_section.sections.append(end_section) section.sections.append(bezier_section) # make sure that current section is placed on right place sections[curve[_INDEX]] = section return sections
def _fill_piece_sections_7(root_object, object_list, bone_list, scene, vg_list, used_materials, offset_matrix, scs_globals, output_type): """ Fills up "Piece" sections for file version 7 (exchange format). :param object_list: :param bone_list: :param scene: :param vg_list: :param used_materials: :param offset_matrix: :return: """ piece_sections = [] # container for all "Pieces" global_vertex_count = 0 global_face_count = 0 global_edge_count = 0 piece_index_obj = {} skin_list = [] skin_weights_cnt = 0 skin_clones_cnt = 0 for piece_index, obj in enumerate(object_list): mat_world = obj.matrix_world piece_index_obj[piece_index] = obj object_materials = _object_utils.get_object_materials( obj) # get object materials # Get Object's Mesh data and list of temporarily disabled "Edge Split" Modifiers... mesh = _object_utils.get_mesh(obj) # VERTICES # TEMPORAL VERTEX STREAM DATA FORMAT: # example: ('_POSITION', [(0.0, 0.0, 0.0), (0.0, 0.0, 0.0), ...]) # example: ('_SCALAR', [(0.0), (0.0), ...]) stream_pos = ('_POSITION', []) # stream_nor = ('_NORMAL', []) # if scs_globals.export_vertex_groups: vg_layers_for_export, streams_vg = _object_utils.get_stream_vgs( obj) # get Vertex Group layers (SCALARs) vertex_stream_count = 1 vertex_streams = [] stream_vg_container = [] # print('bone_list: %s' % str(bone_list.keys)) for vert_i, vert in enumerate(mesh.vertices): position = offset_matrix.inverted() * mesh.vertices[vert_i].co # scs_position = io_utils.change_to_scs_xyz_coordinates(mat_world * position, scs_globals.export_scale) ## POSITION scs_position = Matrix.Scale( scs_globals.export_scale, 4) * _convert_utils.scs_to_blend_matrix().inverted( ) * mat_world * position # POSITION stream_pos[1].append(scs_position) # stream_nor[1].append(io_utils.get_vertex_normal(mesh, vert_i)) # NORMAL if scs_globals.export_vertex_groups: if streams_vg: vg_i = 0 for vg in vg_layers_for_export: # weights (even unused) all vertices become 0.0 if vg.name in vg_list: vg_weight = (_object_utils.get_vertex_group( vg, vert_i), ) # SCALARs key = str("_SCALAR" + str(vg_i)) if vg_i == len(stream_vg_container) and len( stream_vg_container) != len( vg_layers_for_export): stream_vg_container.append( (vg.name, key, [vg_weight])) else: stream_vg_container[vg_i][2].append(vg_weight) vg_i += 1 # SKINNING (OLD STYLE FOR PIM VER. 7) # if scs_globals.export_anim_file == 'anim': if root_object.scs_props.scs_root_animated == 'anim': skin_vector = scs_position # NOTE: Vertex position - from Maya scaled *10 (old & unused in game engine) skin_weights = [] for group in vert.groups: for vg in vg_layers_for_export: if vg.index == group.group: for bone_i, bone in enumerate(bone_list): if vg.name == bone.name: skin_weights.append((bone_i, group.weight)) skin_weights_cnt += 1 # print('vert: %i - group: %r (%i) - %s' % (vert_i, vg.name, bone_i, str(group.weight))) break break skin_clones = ((piece_index, vert_i), ) skin_clones_cnt += 1 skin_list.append((skin_vector, skin_weights, skin_clones)) # ## vertex_streams.append(stream_pos) # print('\nstream_pos:\n %s' % str(stream_pos)) # vertex_streams.append(stream_nor) # print('\nstream_nor:\n %s' % str(stream_nor)) for vg_stream in stream_vg_container: vertex_stream_count += 1 vertex_streams.append(vg_stream) # print('\nvg_stream:\n %s' % str(vg_stream)) # FACES # TEMPORAL FACE STREAM DATA FORMAT: # faces = [face_data, face_data, ...] # face_data = (material, [vertex indices], [face-vertex streams]) # face_streams = [('_UV0', [(0.0, 0.0), (0.0, 0.0), ...]), ...] # example: [(0, [0, 1, 2], [('_UV0', [(0.0, 0.0), (0.0, 0.0)]), ('_UV0', [(0.0, 0.0), (0.0, 0.0)])]), (), ...] faces = [] face_cnt = 0 uv_layers_exists = 1 rgb_layers_exists = 1 # print('used_materials: %s' % str(used_materials)) for face_i, face in enumerate(mesh.polygons): face_cnt += 1 streams_uv = None streams_vcolor = None if uv_layers_exists: requested_uv_layers, streams_uv = _mesh_utils.get_stream_uvs( mesh, scs_globals.active_uv_only) # get UV layers (UVs) if not streams_uv: uv_layers_exists = 0 if rgb_layers_exists and scs_globals.export_vertex_color: if scs_globals.export_vertex_color_type_7 == 'rgb': rgb_all_layers, streams_vcolor = _mesh_utils.get_stream_rgb( mesh, output_type, False) # get Vertex Color layers (RGB) elif scs_globals.export_vertex_color_type_7 == 'rgbda': rgb_all_layers, streams_vcolor = _mesh_utils.get_stream_rgb( mesh, output_type, True) # get Vertex Color layers ( # RGBdA) else: streams_vcolor = None # TODO: Alpha from another layer if not streams_vcolor: rgb_layers_exists = 0 mat_index = used_materials.index( object_materials[face.material_index]) # print('face-mat_index: %s; object_materials[f-m_i]: %s; used_materials.index(o_m[f-m_i]): %s' % (face.material_index, # object_materials[face.material_index], used_materials.index(object_materials[face.material_index]))) face_verts = [] for vert in face.vertices: face_verts.append(vert) face_verts = face_verts[::-1] # revert vertex order in face # print('face_verts: %s' % str(face_verts)) face_streams = [] stream_fv_nor = ("_NORMAL", []) stream_fv_uv_container = [] stream_fv_rgb_container = [] stream_names = {} for loop_index in range(face.loop_start, face.loop_start + face.loop_total): # edge_index = mesh.loops[loop_index].edge_index vert_index = mesh.loops[loop_index].vertex_index # print('face i.: %s\tloop i.: %s\tedge i.: %s\tvert i.: %s' % (face_i, loop_index, edge_index, vert_index)) # Normals stream_fv_nor[1].append( offset_matrix.inverted() * Vector(_mesh_utils.get_vertex_normal(mesh, vert_index))) # UV Layers if streams_uv: for uv_i, uv_l in enumerate(requested_uv_layers): uv_values = _mesh_utils.get_face_vertex_uv( uv_l.data, loop_index, uv_i) key = str("_UV" + str(uv_i)) if uv_i == len(stream_fv_uv_container ) and len(stream_fv_uv_container ) != len(requested_uv_layers): stream_fv_uv_container.append((key, [uv_values])) stream_names[key] = uv_l.name else: stream_fv_uv_container[uv_i][1].append(uv_values) # Vertex Color Layers (RGB) if scs_globals.export_vertex_color: if streams_vcolor: for rgb_i, rgb_l in enumerate(rgb_all_layers): if scs_globals.export_vertex_color_type_7 == 'rgb': rgb_values = _mesh_utils.get_face_vertex_color( rgb_l.data, loop_index, False, rgb_i) key = str("_RGB" + str(rgb_i)) elif scs_globals.export_vertex_color_type_7 == 'rgbda': rgb_values = _mesh_utils.get_face_vertex_color( rgb_l.data, loop_index, True, rgb_i) key = str("_RGBA" + str(rgb_i)) else: streams_vcolor = None # TODO: Alpha from another layer if rgb_i == len(stream_fv_rgb_container ) and len(stream_fv_rgb_container ) != len(rgb_all_layers): stream_fv_rgb_container.append( (key, [rgb_values])) stream_names[key] = rgb_l.name else: stream_fv_rgb_container[rgb_i][1].append( rgb_values) # Data Assembling face_streams.append(stream_fv_nor) for stream in stream_fv_uv_container: face_streams.append(stream) for stream in stream_fv_rgb_container: face_streams.append(stream) face_data = (mat_index, face_verts, face_streams) faces.append(face_data) # SHARP EDGES sharp_edges = [] for edge in mesh.edges: if edge.use_edge_sharp: sharp_edges.append(edge.vertices[:]) # BUILD FACE SECTION faces_container = _SectionData("Faces") faces_container.props.append(("StreamCount", len(faces[0][2]))) for face_i, face_data in enumerate(faces): face_container = _SectionData("Face") face_container.props.append(("Index", face_i)) face_container.props.append(("Material", face_data[0])) face_container.props.append(("Indices", face_data[1])) for stream in face_data[2]: if stream[0] in stream_names: face_container.sections.append( _pix_container.make_vertex_stream( stream, stream_names[stream[0]])) else: face_container.sections.append( _pix_container.make_vertex_stream(stream)) faces_container.sections.append(face_container) # BUILD PIECE SECTION piece_section = _SectionData("Piece") piece_section.props.append(("Index", piece_index)) global_vertex_count += len(stream_pos[1]) piece_section.props.append(("VertexCount", len(stream_pos[1]))) global_face_count += face_cnt piece_section.props.append(("FaceCount", face_cnt)) global_edge_count += len(sharp_edges) piece_section.props.append(("EdgeCount", len(sharp_edges))) piece_section.props.append(("StreamCount", vertex_stream_count)) piece_section.props.append(("", "")) # vertex streams... for stream in vertex_streams: if len(stream) == 3: # print('\nstream:\n %s' % str(stream)) piece_section.sections.append( _pix_container.make_vertex_stream(stream[1:], stream[0])) else: piece_section.sections.append( _pix_container.make_vertex_stream(stream)) # faces... piece_section.sections.append(faces_container) # BUILD AND STORE EDGE SECTION if sharp_edges: edges_container = _SectionData("Edges") for edge in sharp_edges: edges_container.data.append(edge) piece_section.sections.append(edges_container) # STORE PIECE SECTION piece_sections.append(piece_section) # add a piece return piece_sections, global_vertex_count, global_face_count, global_edge_count, piece_index_obj, skin_list, skin_weights_cnt, skin_clones_cnt