change shader properties to be vg_msg based
[carveJwlIkooP6JGAAIwe30JlM.git] / skaterift_blender / sr_mat.py
diff --git a/skaterift_blender/sr_mat.py b/skaterift_blender/sr_mat.py
new file mode 100644 (file)
index 0000000..cd35614
--- /dev/null
@@ -0,0 +1,244 @@
+print( "sr_mat" )
+
+def material_tex_image(v):
+#{
+    return {
+       "Image Texture":
+       {
+          "image": F"{v}"
+       }
+    }
+#}
+
+cxr_graph_mapping = \
+{
+   # Default shader setup 
+   "Principled BSDF":
+   {
+      "Base Color":
+      {
+         "Image Texture":
+         {
+            "image": "tex_diffuse"
+         },
+         "Mix":
+         {
+            "A": material_tex_image("tex_diffuse"),
+            "B": material_tex_image("tex_decal")
+         },
+      },
+      "Normal":
+      {
+         "Normal Map":
+         {
+            "Color": material_tex_image("tex_normal")
+         }
+      }
+   },
+   "Emission":
+   {
+      "Color": material_tex_image("tex_diffuse")
+   }
+}
+
+# https://harrygodden.com/git/?p=convexer.git;a=blob;f=__init__.py;#l1164
+#
+def material_info(mat):
+#{
+   info = {}
+
+   # Using the cxr_graph_mapping as a reference, go through the shader
+   # graph and gather all $props from it.
+   #
+   def _graph_read( node_def, node=None, depth=0 ):
+   #{
+      nonlocal mat
+      nonlocal info
+      
+      # Find rootnodes
+      #
+      if node == None:
+      #{
+         _graph_read.extracted = []
+
+         done = False
+         for node_idname in node_def:
+         #{
+            for n in mat.node_tree.nodes:
+            #{
+               if n.name == node_idname:
+               #{
+                  node_def = node_def[node_idname]
+                  node = n
+                  done = True
+                  break
+               #}
+            #}
+            if done: break
+         #}
+      #}
+
+      for link in node_def:
+      #{
+         link_def = node_def[link]
+
+         if isinstance( link_def, dict ):
+         #{
+            node_link = None
+            for x in node.inputs:
+            #{
+               if isinstance( x, bpy.types.NodeSocketColor ):
+               #{
+                  if link == x.name:
+                  #{
+                     node_link = x
+                     break
+                  #}
+               #}
+            #}
+
+            if node_link and node_link.is_linked:
+            #{
+               # look for definitions for the connected node type
+               #
+               from_node = node_link.links[0].from_node
+               
+               node_name = from_node.name.split('.')[0]
+               if node_name in link_def:
+               #{
+                  from_node_def = link_def[ node_name ]
+
+                  _graph_read( from_node_def, from_node, depth+1 )
+               #}
+            #}
+            else:
+            #{
+               if "default" in link_def:
+               #{
+                  prop = link_def['default']
+                  info[prop] = node_link.default_value
+               #}
+            #}
+         #}
+         else:
+         #{
+            prop = link_def
+            info[prop] = getattr( node, link )
+         #}
+      #}
+   #}
+
+   _graph_read( cxr_graph_mapping )
+   return info
+#}
+
+def sr_compile_material( mat ):
+#{
+   if mat == None: 
+      return 0
+   if mat.name in sr_compile.material_cache: 
+      return sr_compile.material_cache[mat.name]
+
+   print( F'[SR] Compiling material {mat.name}' )
+
+   index = (len(sr_compile.material_data)//sizeof(mdl_material))+1
+   sr_compile.material_cache[mat.name] = index
+
+   m = mdl_material()
+   m.pstr_name = sr_compile_string( mat.name )
+   
+   flags = 0x00
+   if mat.SR_data.collision:
+   #{
+      flags |= 0x2 # collision flag
+      if (mat.SR_data.shader != 'invisible') and \
+         (mat.SR_data.shader != 'boundary'):
+      #{
+         if mat.SR_data.skate_surface: flags |= 0x1
+         if mat.SR_data.grow_grass: flags |= 0x4
+         if mat.SR_data.grind_surface: flags |= 0x8
+         if mat.SR_data.preview_visibile: flags |= 0x40
+      #}
+      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 )
+
+   msg = vg_msg()
+   buf = (c_uint8 * 512)()
+   sr_lib.vg_msg_init( pointer(msg), buf, 512 )
+
+   if mat.SR_data.tex_diffuse_rt >= 0:
+   #{
+      m.tex_diffuse = 0x80000000 | mat.SR_data.tex_diffuse_rt
+   #}
+   else:
+   #{
+      if 'tex_diffuse' in inf:
+      #{
+         shader_prop_texture( msg, 'tex_diffuse', inf['tex_diffuse'] )
+      #}
+   #}
+
+   if mat.SR_data.shader == 'standard': m.shader = 0
+   if mat.SR_data.shader == 'standard_cutout': m.shader = 1
+   if mat.SR_data.shader == 'foliage': m.shader = 10
+   if mat.SR_data.shader == 'terrain_blend':
+   #{
+      m.shader = 2
+      shader_prop_rgba( msg, "sand_colour", mat.SR_data.sand_colour )
+      shader_prop_f32( msg, "blend_offset", 2, mat.SR_data.blend_offset )
+   #}
+   if mat.SR_data.shader == 'vertex_blend':
+   #{
+      m.shader = 3
+      shader_prop_f32( msg, "blend_offset", 2, mat.SR_data.blend_offset )
+   #}
+   if mat.SR_data.shader == 'water':
+   #{
+      m.shader = 4
+      shader_prop_rgba( msg, 'shore_colour', mat.SR_data.shore_colour )
+      shader_prop_rgba( msg, 'deep_colour', mat.SR_data.ocean_colour )
+      shader_prop_f32( msg, 'fog_scale', 1, (mat.SR_data.water_fog,) )
+      shader_prop_f32( msg, 'fresnel', 1, (mat.SR_data.water_fresnel,) )
+      shader_prop_f32( msg, 'water_scale', 1, (mat.SR_data.water_scale,) )
+      shader_prop_f32( msg, 'wave_speed', 4, mat.SR_data.water_rate )
+   #}
+   if mat.SR_data.shader == 'invisible':
+   #{
+      m.shader = 5
+   #}
+   if mat.SR_data.shader == 'boundary':
+   #{
+      m.shader = 6
+   #}
+   if mat.SR_data.shader == 'fxglow':
+   #{
+      m.shader = 7
+   #}
+   if mat.SR_data.shader == 'cubemap':
+   #{
+      m.shader = 8
+
+      shader_prop_u32( msg, 'cubemap', sr_entity_id( mat.SR_data.cubemap ) )
+      shader_prop_rgba( msg, 'tint', mat.SR_data.tint )
+   #}
+   if mat.SR_data.shader == 'walking':
+   #{
+      m.shader = 9
+   #}
+
+   # sr_lib.vg_msg_print( byref(msg), msg.cur.co )
+
+   m.props.kvs.offset = len( sr_compile.shader_data )
+   m.props.kvs.size = msg.cur.co
+
+   sr_compile.shader_data.extend( bytearray(buf[:msg.cur.co]) )
+   sr_compile.material_data.extend( bytearray(m) )
+   return index
+#}
+