X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=blender_export.py;h=820c49ac05e6f721af4ca38ab7f02e200bb5e616;hb=7eba38b8178c82040618a518634d8ff4813e2ff2;hp=7117b4ca25c79d3f2c894f6bb77ea945fc3e6f9f;hpb=02e009ae6e20938675277e9ce2f467e17b170cc7;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/blender_export.py b/blender_export.py index 7117b4c..820c49a 100644 --- a/blender_export.py +++ b/blender_export.py @@ -35,7 +35,8 @@ sr_entity_list = [ ('ent_swspreview', 'Workshop Preview', '', 14 ), ('ent_menuitem', 'Menu Item', '', 15 ), ('ent_worldinfo', 'World Info', '', 16 ), - ('ent_ccmd', 'CCmd', '', 17 ) + ('ent_ccmd', 'CCmd', '', 17 ), + ('ent_challenge', 'Challenge', '', 18 ) ] def get_entity_enum_id( alias ): @@ -445,6 +446,17 @@ class ent_ccmd(Structure): _fields_ = [("pstr_command",c_uint32)] #} +class ent_challenge(Structure):#{ + _fields_ = [("transform",mdl_transform), + ("submesh_start",c_uint32), ("submesh_count",c_uint32), + ("id_next",c_uint32), + ("filter",c_uint32), + ("time_limit",c_float)] + + sr_functions = { 0: 'trigger', + 1: 'start_challenge' } +#} + def obj_ent_type( obj ): #{ if obj.type == 'ARMATURE': return 'mdl_armature' @@ -468,6 +480,31 @@ def sr_filter_ent_type( obj, ent_types ): return False #} +def v4_dot( a, b ):#{ + return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3] +#} + +def q_identity( q ):#{ + q[0] = 0.0 + q[1] = 0.0 + q[2] = 0.0 + q[3] = 1.0 +#} + +def q_normalize( q ):#{ + l2 = v4_dot(q,q) + if( l2 < 0.00001 ):#{ + q_identity( q ) + #} + else:#{ + s = 1.0/math.sqrt(l2) + q[0] *= s + q[1] *= s + q[2] *= s + q[3] *= s + #} +#} + def compile_obj_transform( obj, transform ): #{ co = obj.matrix_world @ Vector((0,0,0)) @@ -475,6 +512,7 @@ def compile_obj_transform( obj, transform ): # This was changed from matrix_local on 09.05.23 q = obj.matrix_world.to_quaternion() s = obj.scale + q_normalize( q ) # Setup transform # @@ -760,14 +798,18 @@ def sr_compile_material( mat ): if mat.SR_data.shader == 'boundary':#{ m.shader = 6 #} + + if mat.SR_data.shader == 'fxglow':#{ + m.shader = 7 + #} inf = material_info( mat ) if mat.SR_data.shader == 'standard' or \ mat.SR_data.shader == 'standard_cutout' or \ mat.SR_data.shader == 'terrain_blend' or \ - mat.SR_data.shader == 'vertex_blend': - #{ + mat.SR_data.shader == 'vertex_blend' or \ + mat.SR_data.shader == 'fxglow': #{ if 'tex_diffuse' in inf: m.tex_diffuse = sr_compile_texture(inf['tex_diffuse']) #} @@ -789,8 +831,9 @@ def sr_armature_bones( armature ): yield from _recurse_bone( b ) #} -def sr_entity_id( obj ): -#{ +def sr_entity_id( obj ):#{ + if not obj: return 0 + tipo = get_entity_enum_id( obj_ent_type(obj) ) index = sr_compile.entity_ids[ obj.name ] @@ -1384,6 +1427,7 @@ def sr_compile_armature( obj ): lc_m = smtx.inverted() @ lc_m #} rq = lc_m.to_quaternion() + q_normalize( rq ) kf = mdl_transform() kf.co[0] = loc[0] @@ -1527,6 +1571,7 @@ def sr_compile( collection ): if ent_type == 'ent_font': continue if ent_type == 'ent_font_variant': continue if ent_type == 'ent_menuitem': continue + if ent_type == 'ent_challenge': continue #-------------------------- print( F'[SR] {i: 3}/{mesh_count} {obj.name:<40}', end='\r' ) @@ -1682,6 +1727,7 @@ def sr_compile( collection ): if obj_data.target:#{ volume.target = sr_entity_id( obj_data.target ) + volume._anon.trigger.event = obj_data.event #} sr_ent_push(volume) @@ -1739,6 +1785,19 @@ def sr_compile( collection ): ccmd.pstr_command = sr_compile_string( obj_data.command ) sr_ent_push( ccmd ) #} + elif ent_type == 'ent_challenge':#{ + challenge = ent_challenge() + obj_data = obj.SR_data.ent_challenge[0] + challenge.id_next = sr_entity_id( obj_data.proxima ) + challenge.filter = 0 + challenge.time_limit = obj_data.time_limit + + compile_obj_transform( obj, challenge.transform ) + challenge.submesh_start, challenge.submesh_count, _ = \ + sr_compile_mesh_internal( obj ) + + sr_ent_push( challenge ) + #} #} #} @@ -2678,8 +2737,7 @@ class SR_OBJECT_ENT_ROUTE(bpy.types.PropertyGroup): #} #} -class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup): -#{ +class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup):#{ subtype: bpy.props.EnumProperty( name="Subtype", items=[('0','Trigger',''), @@ -2689,14 +2747,33 @@ 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','ent_skateshop','ent_ccmd'])) + ['ent_audio','ent_skateshop','ent_ccmd',\ + 'ent_challenge'])) + + event: bpy.props.IntProperty( name="Event/Method" ) @staticmethod - def sr_inspector( layout, data ): - #{ - data = data[0] - layout.prop( data, 'subtype' ) - layout.prop( data, 'target' ) + def sr_inspector( layout, data ):#{ + layout.prop( data[0], 'subtype' ) + layout.prop( data[0], 'target' ) + + row = layout.row() + row.prop( data[0], 'event' ) + + if data[0].target:#{ + tipo = data[0].target.SR_data.ent_type + cls = globals()[ tipo ] + + table = getattr( cls, 'sr_functions', None ) + if table:#{ + if data[0].event in table:#{ + row.label( text=table[data[0].event] ) + #} + else:#{ + row.label( text="undefined function" ) + #} + #} + #} #} #} @@ -2978,6 +3055,18 @@ class SR_OBJECT_ENT_CCMD(bpy.types.PropertyGroup): command: bpy.props.StringProperty(name="Command Line") #} +class SR_OBJECT_ENT_CHALLENGE(bpy.types.PropertyGroup):#{ + proxima: bpy.props.PointerProperty( \ + type=bpy.types.Object, name="Next", \ + poll=lambda self,obj: sr_filter_ent_type(obj,['ent_challenge'])) + target: bpy.props.PointerProperty( \ + type=bpy.types.Object, name="Target", \ + poll=lambda self,obj: sr_filter_ent_type(obj,\ + ['ent_audio','ent_ccmd'])) + event: bpy.props.IntProperty( name="Event/Method" ) + time_limit: bpy.props.FloatProperty( name="Time Limit", default=1.0 ) +#} + class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup): #{ ent_gate: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_GATE) @@ -2995,6 +3084,7 @@ class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup): ent_menuitem: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_MENU_ITEM) ent_worldinfo: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_WORLD_INFO) ent_ccmd: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_CCMD) + ent_challenge: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_CHALLENGE) ent_type: bpy.props.EnumProperty( name="Type", @@ -3069,7 +3159,8 @@ class SR_MATERIAL_PROPERTIES(bpy.types.PropertyGroup): ('vertex_blend', "vertex_blend", ''), ('water',"water",''), ('invisible','Invisible',''), - ('boundary','Boundary','') + ('boundary','Boundary',''), + ('fxglow','FX Glow',''), ]) surface_prop: bpy.props.EnumProperty( @@ -3639,14 +3730,14 @@ def cv_ent_volume( obj ): cv_draw_ucube( obj.matrix_world, (0,1,0) ) if data.target:#{ - cv_draw_line( obj.location, data.target.location, (0,1,0) ) + cv_draw_arrow( obj.location, data.target.location, (0,1,0) ) #} #} elif data.subtype == '1':#{ cv_draw_ucube( obj.matrix_world, (1,1,0) ) if data.target:#{ - cv_draw_line( obj.location, data.target.location, (1,1,0) ) + cv_draw_arrow( obj.location, data.target.location, (1,1,0) ) #} #} #} @@ -3925,6 +4016,12 @@ def cv_draw(): elif ent_type == 'ent_volume':#{ cv_ent_volume( obj ) #} + elif ent_type == 'ent_challenge':#{ + data = obj.SR_data.ent_challenge[0] + if data.proxima:#{ + cv_draw_arrow( obj.location, data.proxima.location, (0,0.2,1.0) ) + #} + #} elif ent_type == 'ent_audio':#{ if obj.SR_data.ent_audio[0].flag_3d: cv_draw_sphere( obj.location, obj.scale[0], (1,1,0) ) @@ -4116,6 +4213,7 @@ classes = [ SR_INTERFACE, SR_MATERIAL_PANEL,\ SR_OBJECT_ENT_FONT,SR_OBJECT_ENT_TRAFFIC,SR_OBJECT_ENT_SKATESHOP,\ SR_OBJECT_ENT_WORKSHOP_PREVIEW,SR_OBJECT_ENT_MENU_ITEM,\ SR_OBJECT_ENT_WORLD_INFO,SR_OBJECT_ENT_CCMD,\ + SR_OBJECT_ENT_CHALLENGE,\ \ SR_OBJECT_PROPERTIES, SR_LIGHT_PROPERTIES, SR_BONE_PROPERTIES, SR_MESH_PROPERTIES, SR_MATERIAL_PROPERTIES \