unlock rendering
[carveJwlIkooP6JGAAIwe30JlM.git] / blender_export.py
index 54a02e81310a2300b73ab1a3e3038239a1a92229..52f674f73ba4042a0b308ce01822e23daeb42bb5 100644 (file)
@@ -1,9 +1,10 @@
-import bpy, math, gpu, os
+import bpy, blf, math, gpu, os
 import cProfile
 from ctypes import *
 from mathutils import *
 from gpu_extras.batch import batch_for_shader
 from bpy_extras import mesh_utils
+from bpy_extras import view3d_utils
 
 bl_info = {
    "name":"Skaterift .mdl exporter",
@@ -53,6 +54,8 @@ def get_entity_enum_id( alias ):
       #}
    #}
 
+   if alias == 'ent_cubemap': return 21
+
    return 0
 #}
 
@@ -459,18 +462,22 @@ class ent_ccmd(Structure):
 class ent_challenge(Structure):#{
    _fields_ = [("transform",mdl_transform),
                ("submesh_start",c_uint32), ("submesh_count",c_uint32),
+               ("flags",c_uint32),
                ("id_next",c_uint32),
-               ("filter",c_uint32),
+               ("filter",c_uint32),("filter2",c_uint32),
                ("id_win",c_uint32),
                ("win_event",c_uint32),
                ("time_limit",c_float)]
 
    sr_functions = { 0: 'trigger',
-                    1: 'start_challenge' }
+                    1: 'start_challenge',
+                    2: 'show',
+                    3: 'hide' }
 #}
 
 class ent_unlock(Structure):#{
-   _fields_ = [("pstr_alias",c_uint32),
+   _fields_ = [("transform",mdl_transform),
+               ("pstr_alias",c_uint32),
                ("target",c_uint32),
                ("target_event",c_uint32),
                ("status",c_uint32)]
@@ -483,11 +490,23 @@ class ent_relay(Structure):#{
    sr_functions = { 0: 'trigger' }
 #}
 
+class ent_cubemap(Structure):#{
+   _fields_ = [("co",c_float*3),
+               ("resolution",c_uint32), #placeholder
+               ("live",c_uint32),       #placeholder
+               ("texture_id",c_uint32), #engine
+               ("framebuffer_id",c_uint32),#engine
+               ("renderbuffer_id",c_uint32),#engine
+               ("placeholder",c_uint32*2)]
+#}
+
 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'
+   elif obj.type == 'LIGHT_PROBE' and obj.data.type == 'CUBEMAP':
+      return 'ent_cubemap'
    else: return obj.SR_data.ent_type
 #}
 
@@ -752,8 +771,7 @@ def sr_compile_texture( img ):
    return texture_index
 #}
 
-def sr_compile_material( mat ):
-#{
+def sr_compile_material( mat ):#{
    if mat == None: 
       return 0
    if mat.name in sr_compile.material_cache: 
@@ -777,11 +795,13 @@ def sr_compile_material( mat ):
       #}
       if mat.SR_data.shader == 'invisible': flags |= 0x10
       if mat.SR_data.shader == 'boundary': flags |= (0x10|0x20)
+      if mat.SR_data.shader == 'walking': flags |= (0x10|0x80)
    #}
 
    m.flags = flags
 
    m.surface_prop = int(mat.SR_data.surface_prop)
+   inf = material_info( mat )
 
    if mat.SR_data.shader == 'standard': m.shader = 0
    if mat.SR_data.shader == 'standard_cutout': m.shader = 1
@@ -828,14 +848,23 @@ def sr_compile_material( mat ):
    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' or \
-      mat.SR_data.shader == 'fxglow': #{
+   if mat.SR_data.shader == 'cubemap':#{
+      m.shader = 8
+      m.tex_none0 = sr_entity_id( mat.SR_data.cubemap )
+
+      m.colour[0]  = pow( mat.SR_data.tint[0], 1.0/2.2 )
+      m.colour[1]  = pow( mat.SR_data.tint[1], 1.0/2.2 )
+      m.colour[2]  = pow( mat.SR_data.tint[2], 1.0/2.2 )
+      m.colour[3]  = pow( mat.SR_data.tint[3], 1.0/2.2 )
+   #}
+
+   if mat.SR_data.shader == 'walking':#{
+      m.shader = 9
+   #}
+   
+   if mat.SR_data.shader in ['standard', 'standard_cutout', 'terrain_blend', \
+                             'vertex_blend', 'fxglow', 'cubemap' ]: #{
       if 'tex_diffuse' in inf: 
          m.tex_diffuse = sr_compile_texture(inf['tex_diffuse'])
    #}
@@ -1833,7 +1862,8 @@ def sr_compile( collection ):
             challenge.id_next = sr_entity_id( obj_data.proxima )
             challenge.id_win = sr_entity_id( obj_data.target )
             challenge.win_event = obj_data.target_event
-            challenge.filter = 0
+            challenge.filter = int(obj_data.filtrar)
+            challenge.filter2 = 0
             challenge.time_limit = obj_data.time_limit
 
             compile_obj_transform( obj, challenge.transform )
@@ -1845,6 +1875,7 @@ def sr_compile( collection ):
          elif ent_type == 'ent_unlock':#{
             unlock = ent_unlock()
             obj_data = obj.SR_data.ent_unlock[0]
+            compile_obj_transform( obj, unlock.transform )
             unlock.pstr_alias = sr_compile_string( obj_data.alias )
             unlock.target = sr_entity_id( obj_data.target )
             unlock.target_event = obj_data.target_event
@@ -1864,6 +1895,16 @@ def sr_compile( collection ):
             relay.targets[3][1] = obj_data.target3_event
             sr_ent_push( relay )
          #}
+         elif ent_type == 'ent_cubemap':#{
+            cubemap = ent_cubemap()
+            co = obj.matrix_world @ Vector((0,0,0))
+            cubemap.co[0] =  co[0]
+            cubemap.co[1] =  co[2]
+            cubemap.co[2] = -co[1]
+            cubemap.resolution = 0
+            cubemap.live = 60
+            sr_ent_push( cubemap )
+         #}
       #}
    #}
 
@@ -2276,9 +2317,12 @@ class SR_INTERFACE(bpy.types.Panel):
          active_object = context.active_object
          if not active_object: return
 
-         _.layout.operator( 'skaterift.copy_entity_data', \
-               text=F'Copy entity data to {len(context.selected_objects)-1} '+\
-                    F'other objects' )
+         amount = max( 0, len(context.selected_objects)-1 )
+         
+         row = _.layout.row()
+         row.operator( 'skaterift.copy_entity_data', \
+               text=F'Copy entity data to {amount} other objects' )
+         if amount == 0: row.enabled=False
 
          box = _.layout.box()
          row = box.row()
@@ -2286,13 +2330,13 @@ class SR_INTERFACE(bpy.types.Panel):
          row.label( text=active_object.name )
          row.scale_y = 1.5
 
-         def _draw_prop_collection( data ): #{
+         def _draw_prop_collection( source, data ): #{
             nonlocal box
             row = box.row()
             row.alignment = 'CENTER'
             row.enabled = False
             row.scale_y = 1.5
-            row.label( text=F'{data[0]}' )
+            row.label( text=F'{source}' )
             
             if hasattr(type(data[0]),'sr_inspector'):#{
                type(data[0]).sr_inspector( box, data )
@@ -2312,7 +2356,9 @@ class SR_INTERFACE(bpy.types.Panel):
                                  text=F'Mirror attributes to {mb.name}' )
                #}
 
-               _draw_prop_collection( [bones.active.SR_data ] )
+               _draw_prop_collection( \
+                     F'bpy.types.Bone["{bones.active.name}"].SR_data',\
+                     [bones.active.SR_data ] )
             #}
             else: #{
                row = box.row()
@@ -2323,18 +2369,26 @@ class SR_INTERFACE(bpy.types.Panel):
             #}
          #}
          elif active_object.type == 'LIGHT': #{
-            _draw_prop_collection( [active_object.data.SR_data] )
+            _draw_prop_collection( \
+                  F'bpy.types.Light["{active_object.data.name}"].SR_data', \
+                  [active_object.data.SR_data] )
          #}
          elif active_object.type in ['EMPTY','CURVE','MESH']:#{
             box.prop( active_object.SR_data, "ent_type" )
             ent_type = active_object.SR_data.ent_type
             
             col = getattr( active_object.SR_data, ent_type, None )
-            if col != None and len(col)!=0: _draw_prop_collection( col )
+            if col != None and len(col)!=0: 
+               _draw_prop_collection( \
+         F'bpy.types.Object["{active_object.name}"].SR_data.{ent_type}[0]', \
+         col )
 
             if active_object.type == 'MESH':#{
                col = getattr( active_object.data.SR_data, ent_type, None )
-               if col != None and len(col)!=0: _draw_prop_collection( col )
+               if col != None and len(col)!=0: 
+                  _draw_prop_collection( \
+         F'bpy.types.Mesh["{active_object.data.name}"].SR_data.{ent_type}[0]', \
+         col )
             #}
          #}
       #}
@@ -2372,7 +2426,8 @@ class SR_MATERIAL_PANEL(bpy.types.Panel):
          row = box.row()
 
          if (active_mat.SR_data.shader != 'invisible') and \
-            (active_mat.SR_data.shader != 'boundary'):#{
+            (active_mat.SR_data.shader != 'boundary') and \
+            (active_mat.SR_data.shader != 'walking'):#{
             row.prop( active_mat.SR_data, "skate_surface" )
             row.prop( active_mat.SR_data, "grind_surface" )
             row.prop( active_mat.SR_data, "grow_grass" )
@@ -2396,6 +2451,11 @@ class SR_MATERIAL_PANEL(bpy.types.Panel):
          box.prop( active_mat.SR_data, "shore_colour" )
          box.prop( active_mat.SR_data, "ocean_colour" )
       #}
+      elif active_mat.SR_data.shader == "cubemap":#{
+         box = _.layout.box()
+         box.prop( active_mat.SR_data, "cubemap" )
+         box.prop( active_mat.SR_data, "tint" )
+      #}
    #}
 #}
 
@@ -2821,9 +2881,7 @@ 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_challenge']))
+           poll=lambda self,obj: sr_filter_ent_type(obj,SR_TRIGGERABLE))
    target_event: bpy.props.IntProperty( name="Event/Method" )
 
    @staticmethod
@@ -3148,11 +3206,26 @@ class SR_OBJECT_ENT_CHALLENGE(bpy.types.PropertyGroup):#{
            poll=lambda self,obj: sr_filter_ent_type(obj,SR_TRIGGERABLE))
    target_event: bpy.props.IntProperty( name="Event/Method" )
    time_limit: bpy.props.FloatProperty( name="Time Limit", default=1.0 )
+   filtrar: bpy.props.EnumProperty( name='Filter',\
+      items=[('0','none',''),
+             (str(0x1),'trick_shuvit',''),
+             (str(0x2),'trick_kickflip',''),
+             (str(0x4),'trick_treflip',''),
+             (str(0x1|0x2|0x4),'trick_any',''),
+             (str(0x8),'flip_back',''),
+             (str(0x10),'flip_front',''),
+             (str(0x8|0x10),'flip_any',''),
+             (str(0x20),'grind_truck_any',''),
+             (str(0x40),'grind_board_any',''),
+             (str(0x20|0x40),'grind_any',''),
+             (str(0x80),'footplant','')
+             ])
 
    @staticmethod
    def sr_inspector( layout, data ):#{
       layout.prop( data[0], 'proxima' )
       layout.prop( data[0], 'time_limit' )
+      layout.prop( data[0], 'filtrar' )
       SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target' )
    #}
 #}
@@ -3295,6 +3368,8 @@ class SR_MATERIAL_PROPERTIES(bpy.types.PropertyGroup):
       ('invisible','Invisible',''),
       ('boundary','Boundary',''),
       ('fxglow','FX Glow',''),
+      ('cubemap','Cubemap',''),
+      ('walking','Walking','')
       ])
 
    surface_prop: bpy.props.EnumProperty(
@@ -3360,6 +3435,18 @@ class SR_MATERIAL_PROPERTIES(bpy.types.PropertyGroup):
          default=Vector((0.0,0.006,0.03)),\
          description="Water colour in the deep bits"\
    )
+   tint: bpy.props.FloatVectorProperty( \
+         name="Tint",\
+         subtype='COLOR',\
+         min=0.0,max=1.0,\
+         size=4,\
+         default=Vector((1.0,1.0,1.0,1.0)),\
+         description="Reflection tint"\
+   )
+
+   cubemap: bpy.props.PointerProperty( \
+               type=bpy.types.Object, name="cubemap", \
+               poll=lambda self,obj: sr_filter_ent_type(obj,['ent_cubemap']))
 #}
 
 # ---------------------------------------------------------------------------- #
@@ -3369,6 +3456,7 @@ class SR_MATERIAL_PROPERTIES(bpy.types.PropertyGroup):
 # ---------------------------------------------------------------------------- #
 
 cv_view_draw_handler = None
+cv_view_pixel_handler = None
 cv_view_shader = gpu.shader.from_builtin('3D_SMOOTH_COLOR')
 cv_view_verts = []
 cv_view_colours = []
@@ -4106,8 +4194,7 @@ def cv_draw_route( route, dij ):
    #}
 #}
 
-def cv_draw():
-#{
+def cv_draw():#{
    global cv_view_shader
    global cv_view_verts
    global cv_view_colours
@@ -4340,7 +4427,31 @@ def cv_draw():
    #}
 
    cv_draw_lines()
-   return
+#}
+
+def pos3d_to_2d( pos ):#{
+   return view3d_utils.location_3d_to_region_2d( \
+            bpy.context.region, \
+            bpy.context.space_data.region_3d, pos )
+#}
+
+def cv_draw_pixel():#{
+   if not bpy.context.scene.SR_data.gizmos: return
+   blf.size(0,10)
+   blf.color(0, 1.0,1.0,1.0,0.9)
+   blf.enable(0,blf.SHADOW)
+   blf.shadow(0,3,0.0,0.0,0.0,1.0)
+   for obj in bpy.context.collection.objects:#{
+      ent_type = obj_ent_type( obj )
+      
+      if ent_type != 'none':#{
+         co = pos3d_to_2d( obj.location )
+
+         if not co: continue
+         blf.position(0,co[0],co[1],0)
+         blf.draw(0,ent_type)
+      #}
+   #}
 #}
 
 classes = [ SR_INTERFACE, SR_MATERIAL_PANEL,\
@@ -4392,9 +4503,11 @@ def register():
    bpy.types.Material.SR_data = \
          bpy.props.PointerProperty(type=SR_MATERIAL_PROPERTIES)
 
-   global cv_view_draw_handler
+   global cv_view_draw_handler, cv_view_pixel_handler
    cv_view_draw_handler = bpy.types.SpaceView3D.draw_handler_add(\
       cv_draw,(),'WINDOW','POST_VIEW')
+   cv_view_pixel_handler = bpy.types.SpaceView3D.draw_handler_add(\
+      cv_draw_pixel,(),'WINDOW','POST_PIXEL')
 #}
 
 def unregister():
@@ -4402,8 +4515,9 @@ def unregister():
    for c in classes:
       bpy.utils.unregister_class(c)
 
-   global cv_view_draw_handler
+   global cv_view_draw_handler, cv_view_pixel_handler
    bpy.types.SpaceView3D.draw_handler_remove(cv_view_draw_handler,'WINDOW')
+   bpy.types.SpaceView3D.draw_handler_remove(cv_view_pixel_handler,'WINDOW')
 #}
 
 # ---------------------------------------------------------------------------- #