('ent_font', 'Font', '', 9 ),
('ent_font_variant', 'Font:Variant', '', 10 ),
('ent_traffic', 'Traffic Model', '', 11 ),
+ ('ent_skateshop', 'Skate Shop', '', 12 ),
+ ('ent_camera', 'Camera', '', 13 ),
+ ('ent_swspreview', 'Workshop Preview', '', 14 )
]
def get_entity_enum_id( alias ):
("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):
("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)]
#}
("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_swspreview(Structure):
+#{
+ _fields_ = [("id_camera",c_uint32),
+ ("id_display",c_uint32),
+ ("id_display1",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
#}
"Color": material_tex_image("tex_normal")
}
}
+ },
+ "Emission":
+ {
+ "Color": material_tex_image("tex_diffuse")
}
}
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 \
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'
#
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
# 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))
#}
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
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
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 )
#}
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 * 45.0
+ sr_ent_push(cam)
+ #}
elif ent_type == 'ent_gate': #{
gate = ent_gate()
obj_data = obj.SR_data.ent_gate[0]
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)
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)
+ #}
+ elif ent_type == 'ent_swspreview':#{
+ workshop_preview = ent_swspreview()
+ obj_data = obj.SR_data.ent_swspreview[0]
+ workshop_preview.id_display = sr_entity_id( obj_data.mark_display )
+ workshop_preview.id_display1 = sr_entity_id( obj_data.mark_display1)
+ workshop_preview.id_camera = sr_entity_id( obj_data.cam )
+ sr_ent_push( workshop_preview )
+ #}
#}
#}
route_gates = []
route_curves = []
routes = []
+ traffics = []
for obj in col.objects:#{
if obj.type == 'ARMATURE': pass
#}
elif ent_type == 'ent_route':
routes += [obj]
+ elif ent_type == 'ent_traffic':
+ traffics += [obj]
#}
#}
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]
routenode_count += len(dij.points)
#}
-
print( F"[SR] Writing file" )
file_array_instructions = {}
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 )
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 )
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 ):
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_ENT_WORKSHOP_PREVIEW(bpy.types.PropertyGroup):
+#{
+ mark_display: bpy.props.PointerProperty( \
+ type=bpy.types.Object, name="Board Display", \
+ poll=lambda self,obj: sr_filter_ent_type(obj,['ent_marker']))
+ mark_display1: bpy.props.PointerProperty( \
+ type=bpy.types.Object, name="Board Display (other side)", \
+ 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):
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_swspreview: \
+ bpy.props.CollectionProperty(type=SR_OBJECT_ENT_WORKSHOP_PREVIEW)
+
ent_type: bpy.props.EnumProperty(
name="Type",
items=sr_entity_list,
#}
#}
#}
+ 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 )
+ #}
+ elif ent_type == 'ent_swspreview':#{
+ cc1 = (0.4,0.9,0.2)
+ data = obj.SR_data.ent_swspreview[0]
+ display = data.mark_display
+ display1 = data.mark_display1
+ display_cu = Vector((0.3,1.2,0.1))*0.5
+ display_co = Vector((0.0,0.0,0.1))*0.5
+ if display:
+ cv_draw_ucube( display.matrix_world, cc1, display_cu, display_co)
+ if display1:
+ cv_draw_ucube(display1.matrix_world, cc1, display_cu, display_co)
+ #}
#}
#}
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_ENT_WORKSHOP_PREVIEW,\
\
SR_OBJECT_PROPERTIES, SR_LIGHT_PROPERTIES, SR_BONE_PROPERTIES,
SR_MESH_PROPERTIES, SR_MATERIAL_PROPERTIES \