X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=blender_export.py;h=73d17059d19fded822a9af16c95c818104bae03d;hb=223e75026f958029f9664380ed20a5daa3ee2ae7;hp=a7698e9bf2fa6f33334d1d2d31de574286b6c873;hpb=1b522daa02f28128498b04def4d60b63e590d1f3;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/blender_export.py b/blender_export.py index a7698e9..73d1705 100644 --- a/blender_export.py +++ b/blender_export.py @@ -30,6 +30,8 @@ sr_entity_list = [ ('ent_font', 'Font', '', 9 ), ('ent_font_variant', 'Font:Variant', '', 10 ), ('ent_traffic', 'Traffic Model', '', 11 ), + ('ent_skateshop', 'Skate Shop', '', 12 ), + ('ent_camera', 'Camera', '', 13 ) ] def get_entity_enum_id( alias ): @@ -68,7 +70,8 @@ class mdl_submesh(Structure): ("vertex_start",c_uint32), ("vertex_count",c_uint32), ("bbx",(c_float*3)*2), - ("material_id",c_uint32)] # index into the material array + ("material_id",c_uint16), # index into the material array + ("flags",c_uint16)] #} class mdl_material(Structure): @@ -270,19 +273,13 @@ class volume_union(Union): ("particles",volume_particles)] #} -class ent_index(Structure): -#{ - _fields_ = [("type",c_uint32), - ("index",c_uint32)] -#} - class ent_volume(Structure): #{ _fields_ = [("transform",mdl_transform), ("to_world",(c_float*3)*4), ("to_local",(c_float*3)*4), ("type",c_uint32), - ("target",ent_index), + ("target",c_uint32), ("_anon",volume_union)] #} @@ -329,10 +326,38 @@ class ent_font(Structure): ("glyph_utf32_base",c_uint32)] #} +class ent_traffic(Structure): +#{ + _fields_ = [("transform",mdl_transform), + ("submesh_start",c_uint32), + ("submesh_count",c_uint32), + ("start_node",c_uint32), + ("node_count",c_uint32), + ("speed",c_float), + ("t",c_float), + ("index",c_uint32)] +#} + +class ent_skateshop(Structure): +#{ + _fields_ = [("transform",mdl_transform), + ("id_display",c_uint32), + ("id_info",c_uint32), + ("id_rack",c_uint32), + ("id_camera",c_uint32)] +#} + +class ent_camera(Structure): +#{ + _fields_ = [("transform",mdl_transform), + ("fov",c_float)] +#} + def obj_ent_type( obj ): #{ if obj.type == 'ARMATURE': return 'mdl_armature' elif obj.type == 'LIGHT': return 'ent_light' + elif obj.type == 'CAMERA': return 'ent_camera' else: return obj.SR_data.ent_type #} @@ -442,6 +467,10 @@ cxr_graph_mapping = \ "Color": material_tex_image("tex_normal") } } + }, + "Emission": + { + "Color": material_tex_image("tex_diffuse") } } @@ -664,25 +693,24 @@ def sr_armature_bones( armature ): yield from _recurse_bone( b ) #} -def sr_compile_mesh( obj ): +def sr_entity_id( obj ): #{ - node=mdl_mesh() - compile_obj_transform(obj, node.transform) - node.pstr_name = sr_compile_string(obj.name) - ent_type = obj_ent_type( obj ) + tipo = get_entity_enum_id( obj_ent_type(obj) ) + index = sr_compile.entity_ids[ obj.name ] - node.entity_id = 0 - - if ent_type != 'none':#{ - ent_id_lwr = sr_compile.entity_ids[obj.name] - ent_id_upr = get_entity_enum_id( obj_ent_type(obj) ) - node.entity_id = (ent_id_upr << 16) | ent_id_lwr - #} - print( node.entity_id ) + return (tipo&0xffff)<<16 | (index&0xffff) +#} +# Returns submesh_start,count and armature_id +def sr_compile_mesh_internal( obj ): +#{ can_use_cache = True armature = None + submesh_start = 0 + submesh_count = 0 + armature_id = 0 + for mod in obj.modifiers:#{ if mod.type == 'DATA_TRANSFER' or mod.type == 'SHRINKWRAP' or \ mod.type == 'BOOLEAN' or mod.type == 'CURVE' or \ @@ -695,7 +723,7 @@ def sr_compile_mesh( obj ): armature = mod.object rig_weight_groups = \ ['0 [ROOT]']+[_.name for _ in sr_armature_bones(mod.object)] - node.armature_id = sr_compile.entity_ids[armature.name] + armature_id = sr_compile.entity_ids[armature.name] POSE_OR_REST_CACHE = armature.data.pose_position armature.data.pose_position = 'REST' @@ -706,16 +734,15 @@ def sr_compile_mesh( obj ): # if can_use_cache and (obj.data.name in sr_compile.mesh_cache):#{ ref = sr_compile.mesh_cache[obj.data.name] - node.submesh_start = ref[0] - node.submesh_count = ref[1] - sr_compile.mesh_data.extend(bytearray(node)) - return + submesh_start = ref[0] + submesh_count = ref[1] + return (submesh_start,submesh_count,armature_id) #} # Compile a whole new mesh # - node.submesh_start = len(sr_compile.submesh_data)//sizeof(mdl_submesh) - node.submesh_count = 0 + submesh_start = len(sr_compile.submesh_data)//sizeof(mdl_submesh) + submesh_count = 0 dgraph = bpy.context.evaluated_depsgraph_get() data = obj.evaluated_get(dgraph).data @@ -899,16 +926,37 @@ def sr_compile_mesh( obj ): # Add submesh to encoder # sr_compile.submesh_data.extend( bytearray(sm) ) - node.submesh_count += 1 + submesh_count += 1 #} if armature:#{ armature.data.pose_position = POSE_OR_REST_CACHE #} - # Save a reference to this node since we want to reuse the submesh indices + # Save a reference to this mesh since we want to reuse the submesh indices # later. - sr_compile.mesh_cache[obj.data.name]=(node.submesh_start,node.submesh_count) + sr_compile.mesh_cache[obj.data.name]=(submesh_start,submesh_count) + return (submesh_start,submesh_count,armature_id) +#} + +def sr_compile_mesh( obj ): +#{ + node=mdl_mesh() + compile_obj_transform(obj, node.transform) + node.pstr_name = sr_compile_string(obj.name) + ent_type = obj_ent_type( obj ) + + node.entity_id = 0 + + if ent_type != 'none':#{ + ent_id_lwr = sr_compile.entity_ids[obj.name] + ent_id_upr = get_entity_enum_id( obj_ent_type(obj) ) + node.entity_id = (ent_id_upr << 16) | ent_id_lwr + #} + + node.submesh_start, node.submesh_count, node.armature_id = \ + sr_compile_mesh_internal( obj ) + sr_compile.mesh_data.extend(bytearray(node)) #} @@ -931,7 +979,7 @@ def sr_compile_fonts( collection ): font.glyph_start = glyph_count glyph_base = data.glyphs[0].utf32 - glyph_range = data.glyphs[-1].utf32 - glyph_base + glyph_range = data.glyphs[-1].utf32+1 - glyph_base font.glyph_utf32_base = glyph_base font.glyph_count = glyph_range @@ -1274,7 +1322,9 @@ def sr_compile( collection ): mesh_count = 0 for obj in collection.all_objects: #{ - if obj.type == 'MESH': mesh_count += 1 + if obj.type == 'MESH':#{ + mesh_count += 1 + #} ent_type = obj_ent_type( obj ) if ent_type == 'none': continue @@ -1289,6 +1339,16 @@ def sr_compile( collection ): for obj in collection.all_objects:#{ if obj.type == 'MESH':#{ i+=1 + + ent_type = obj_ent_type( obj ) + + # entity ignore mesh list + # + if ent_type == 'ent_traffic': continue + if ent_type == 'ent_font': continue + if ent_type == 'ent_font_variant': continue + #-------------------------- + print( F'[SR] {i: 3}/{mesh_count} {obj.name:<40}', end='\r' ) sr_compile_mesh( obj ) #} @@ -1323,6 +1383,12 @@ def sr_compile( collection ): light.colour[3] = obj.data.energy sr_ent_push( light ) #} + elif ent_type == 'ent_camera': #{ + cam = ent_camera() + compile_obj_transform( obj, cam.transform ) + cam.fov = obj.data.angle + sr_ent_push(cam) + #} elif ent_type == 'ent_gate': #{ gate = ent_gate() obj_data = obj.SR_data.ent_gate[0] @@ -1434,9 +1500,7 @@ def sr_compile( collection ): compile_obj_transform( obj, volume.transform ) if obj_data.target:#{ - target = obj_data.target - volume.target.type = get_entity_enum_id( obj_ent_type(target) ) - volume.target.index = sr_compile.entity_ids[ target.name ] + volume.target = sr_entity_id( obj_data.target ) #} sr_ent_push(volume) @@ -1447,6 +1511,16 @@ def sr_compile( collection ): compile_obj_transform( obj, marker.transform ) sr_ent_push(marker) #} + elif ent_type == 'ent_skateshop':#{ + skateshop = ent_skateshop() + obj_data = obj.SR_data.ent_skateshop[0] + skateshop.id_display = sr_entity_id( obj_data.mark_display ) + skateshop.id_info = sr_entity_id( obj_data.mark_info ) + skateshop.id_rack = sr_entity_id( obj_data.mark_rack ) + skateshop.id_camera = sr_entity_id( obj_data.cam ) + compile_obj_transform( obj, skateshop.transform ) + sr_ent_push(skateshop) + #} #} #} @@ -1468,6 +1542,7 @@ def sr_compile( collection ): route_gates = [] route_curves = [] routes = [] + traffics = [] for obj in col.objects:#{ if obj.type == 'ARMATURE': pass @@ -1483,6 +1558,8 @@ def sr_compile( collection ): #} elif ent_type == 'ent_route': routes += [obj] + elif ent_type == 'ent_traffic': + traffics += [obj] #} #} @@ -1541,6 +1618,52 @@ def sr_compile( collection ): sr_ent_push( route ) #} + for obj in traffics:#{ + traffic = ent_traffic() + compile_obj_transform( obj, traffic.transform ) + traffic.submesh_start, traffic.submesh_count, _ = \ + sr_compile_mesh_internal( obj ) + + # find best subsection + + graph_keys = list(dij.graph) + min_dist = 100.0 + best_point = 0 + + for j in range(len(dij.points)):#{ + point = dij.points[j] + dist = (point-obj.location).magnitude + + if dist < min_dist:#{ + min_dist = dist + best_point = j + #} + #} + + # scan to each edge + best_begin = best_point + best_end = best_point + + while True:#{ + map0 = dij.subsections[best_begin] + if map0[1] == -1: break + best_begin = map0[1] + #} + while True:#{ + map1 = dij.subsections[best_end] + if map1[2] == -1: break + best_end = map1[2] + #} + + traffic.start_node = routenode_count + best_begin + traffic.node_count = best_end - best_begin + traffic.index = best_point - best_begin + traffic.speed = obj.SR_data.ent_traffic[0].speed + traffic.t = 0.0 + + sr_ent_push(traffic) + #} + for point in dij.points:#{ rn = ent_route_node() rn.co[0] = point[0] @@ -1552,7 +1675,6 @@ def sr_compile( collection ): routenode_count += len(dij.points) #} - print( F"[SR] Writing file" ) file_array_instructions = {} @@ -1595,7 +1717,7 @@ def sr_compile( collection ): fp = open( path, "wb" ) header = mdl_header() - header.version = 40 + header.version = 100 sr_array_title( header.arrays, \ 'index', len(file_array_instructions), \ sizeof(mdl_array), header_size ) @@ -2291,7 +2413,8 @@ class SR_UL_FONT_GLYPH_LIST(bpy.types.UIList): s1 = c.split(factor=0.3) c = s1.column() row = c.row() - lbl = chr(item.utf32) if item.utf32 >= 32 and item.utf32 <= 126 else 'ERR' + lbl = chr(item.utf32) if item.utf32 >= 32 and item.utf32 <= 126 else \ + f'x{item.utf32:x}' row.label(text=lbl) c = s1.column() c.prop( item, 'utf32', text='', emboss=True ) @@ -2344,7 +2467,8 @@ class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup): target: bpy.props.PointerProperty( \ type=bpy.types.Object, name="Target", \ - poll=lambda self,obj: sr_filter_ent_type(obj,['ent_audio'])) + poll=lambda self,obj: sr_filter_ent_type(obj,\ + ['ent_audio','ent_skateshop'])) @staticmethod def sr_inspector( layout, data ): @@ -2492,9 +2616,23 @@ class SR_OBJECT_ENT_FONT(bpy.types.PropertyGroup): class SR_OBJECT_ENT_TRAFFIC(bpy.types.PropertyGroup): #{ - track: bpy.props.PointerProperty(\ - type=bpy.types.Object, name='track', \ - poll=lambda self,obj: sr_filter_ent_type(obj,['ent_route_node'])) + speed: bpy.props.FloatProperty(default=1.0) +#} + +class SR_OBJECT_ENT_SKATESHOP(bpy.types.PropertyGroup): +#{ + mark_rack: bpy.props.PointerProperty( \ + type=bpy.types.Object, name="Board Rack", \ + poll=lambda self,obj: sr_filter_ent_type(obj,['ent_marker'])) + mark_display: bpy.props.PointerProperty( \ + type=bpy.types.Object, name="Selected Board Display", \ + poll=lambda self,obj: sr_filter_ent_type(obj,['ent_marker'])) + mark_info: bpy.props.PointerProperty( \ + type=bpy.types.Object, name="Selected Board Info", \ + poll=lambda self,obj: sr_filter_ent_type(obj,['ent_marker'])) + cam: bpy.props.PointerProperty( \ + type=bpy.types.Object, name="Viewpoint", \ + poll=lambda self,obj: sr_filter_ent_type(obj,['ent_camera'])) #} class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup): @@ -2508,6 +2646,7 @@ class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup): ent_glyph: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_GLYPH) ent_font: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_FONT) ent_traffic: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_TRAFFIC) + ent_skateshop: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_SKATESHOP) ent_type: bpy.props.EnumProperty( name="Type", items=sr_entity_list, @@ -3458,6 +3597,30 @@ def cv_draw(): #} #} #} + elif ent_type == 'ent_skateshop':#{ + cc = (0.0,0.9,0.6) + cc1 = (0.4,0.9,0.2) + cc2 = (0.9,0.6,0.1) + + data = obj.SR_data.ent_skateshop[0] + display = data.mark_display + info = data.mark_info + rack = data.mark_rack + + rack_cu = Vector((3.15,2.0,0.1))*0.5 + rack_co = Vector((0.0,0.0,0.0)) + display_cu = Vector((0.3,1.2,0.1))*0.5 + display_co = Vector((0.0,0.0,0.1))*0.5 + info_cu = Vector((1.2,0.01,0.3))*0.5 + info_co = Vector((0.0,0.0,0.0))*0.5 + + if rack: + cv_draw_ucube( rack.matrix_world, cc, rack_cu, rack_co ) + if display: + cv_draw_ucube( display.matrix_world, cc1, display_cu, display_co) + if info: + cv_draw_ucube( info.matrix_world, cc2, info_cu, info_co ) + #} #} #} @@ -3491,7 +3654,7 @@ classes = [ SR_INTERFACE, SR_MATERIAL_PANEL,\ SR_OBJECT_ENT_FONT_VARIANT, SR_OBJECT_ENT_GLYPH_ENTRY,\ SR_UL_FONT_VARIANT_LIST,SR_UL_FONT_GLYPH_LIST,\ - SR_OBJECT_ENT_FONT,SR_OBJECT_ENT_TRAFFIC,\ + SR_OBJECT_ENT_FONT,SR_OBJECT_ENT_TRAFFIC,SR_OBJECT_ENT_SKATESHOP,\ \ SR_OBJECT_PROPERTIES, SR_LIGHT_PROPERTIES, SR_BONE_PROPERTIES, SR_MESH_PROPERTIES, SR_MATERIAL_PROPERTIES \