Advertisement
Guest User

OWM EEVEE Lights

a guest
Jul 19th, 2021
30
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 13.99 KB | None | 0 0
  1. import os
  2.  
  3. from . import read_owmap
  4. from . import import_owmdl
  5. from . import import_owmat
  6. from . import import_owentity
  7. from . import bpyhelper
  8. from . import owm_types
  9. from mathutils import *
  10. import math
  11. import bpy, bpy_extras, mathutils
  12.  
  13. sets = None
  14.  
  15. acm = bpy_extras.io_utils.axis_conversion(from_forward='-Z', from_up='Y').to_4x4()
  16.  
  17.  
  18. def pos_matrix(pos):
  19.     global acm
  20.     posMtx = mathutils.Matrix.Translation(pos)
  21.     mtx = acm @ posMtx
  22.     return mtx.to_translation()
  23.  
  24.  
  25. link_queue = []
  26.  
  27. parents = {}
  28. children = {}
  29.  
  30. def buildRelationships():
  31.     for obj in bpy.context.scene.objects:
  32.         if obj.name not in parents:
  33.             if obj.parent is None: continue
  34.             parents[obj.name] = obj.parent.name
  35.     for obj in parents:
  36.         if parents[obj] not in children:
  37.             children[parents[obj]] = []
  38.         children[parents[obj]].append(obj)
  39.  
  40. def destroyRelationships():
  41.     global parents, children
  42.     parents = {}
  43.     children = {}
  44.  
  45. def copy(obj, parent):
  46.     if obj is None: return None
  47.     new_obj = obj.copy()
  48.     if obj.data is not None:
  49.         new_obj.data = obj.data.copy()
  50.         if 'OWM Skeleton' in new_obj.modifiers:
  51.             mod = new_obj.modifiers['OWM Skeleton']
  52.             mod.object = parent
  53.     new_obj.parent = parent
  54.     link_queue.append(new_obj)
  55.     try:
  56.         for child in children[obj.name]:
  57.             copy(bpy.data.objects[child], new_obj)
  58.     except KeyError:
  59.         pass # screw that
  60.     return new_obj
  61.  
  62.  
  63. def remove(obj):
  64.     if obj.name in children:
  65.         for child in children[obj.name]:
  66.             remove(bpy.data.objects[child])
  67.         del children[obj.name]
  68.     try:
  69.         bpyhelper.scene_unlink(obj)
  70.     except Exception as e:
  71.         print('[import_owmap]: error removing object: {}'.format(bpyhelper.format_exc(e)))
  72.  
  73.  
  74. def xpzy(vec):
  75.     return vec[0], vec[2], vec[1]
  76.  
  77.  
  78. def wxzy(vec):
  79.     return vec[3], vec[0], -vec[2], vec[1]
  80.  
  81.  
  82. def progress_update(total, progress, nextFile):
  83.     if owm_types.LOG_ALOT:
  84.         print('%d/%d (%d%%) %s' % (progress, total, progress / total * 100, nextFile))
  85.     bpy.context.window_manager.progress_update(progress)
  86.  
  87. def hide_recursive(obj):
  88.     obj.hide_viewport = obj.hide_render = True
  89.     for child in obj.children:
  90.         hide_recursive(child)
  91.  
  92. def import_mdl(mdls):
  93.     try:
  94.         obj = None
  95.         if mdls.filename.endswith(".owentity"):
  96.             mdls.importEmpties = True
  97.             mdls.importSkeleton = True
  98.             obj = import_owentity.read(mdls, True)
  99.             #     0         1            2       3          4
  100.             #     root,    armature,  meshes,    empties,   data
  101.             obj = (obj[0], obj[2][1], obj[2][2], obj[2][3], obj[2][4])
  102.             if obj[1] is None:
  103.                 obj[0].rotation_euler = (math.radians(90), 0, 0) # reeee
  104.                 if len(obj[3]) > 0 and obj[3][0] is not None:
  105.                     obj[3][0].rotation_euler = (0, 0, 0) # :ahh:
  106.         else:
  107.             obj = import_owmdl.read(mdls, None)
  108.             obj[0].rotation_euler = (math.radians(90), 0, 0)
  109.         wrapObj = bpy.data.objects.new(obj[0].name + '_WRAP', None)
  110.         wrapObj.hide_viewport = True
  111.         obj[0].parent = wrapObj
  112.         bpyhelper.scene_link(wrapObj)
  113.         return wrapObj, obj
  114.     except Exception as e:
  115.         print('[import_owmap]: error importing map object: {}'.format(bpyhelper.format_exc(e)))
  116.         return None, None
  117.  
  118.  
  119. def import_mat(path, prefix):
  120.     try:
  121.         return import_owmat.read(path, prefix)
  122.     except Exception as e:
  123.         print('[import_owmap]: error importing map: {}'.format(bpyhelper.format_exc(e)))
  124.         return None
  125.  
  126.  
  127. def read(settings, importObjects=False, importDetails=True, importPhysics=False, light_settings=owm_types.OWLightSettings(), removeCollision=True, importSound=True):
  128.     global sets, link_queue
  129.     bpyhelper.LOCK_UPDATE = True
  130.     sets = settings
  131.  
  132.     root, file = os.path.split(settings.filename)
  133.  
  134.     data = read_owmap.read(settings.filename)
  135.     if not data: return None
  136.  
  137.     name = data.header.name
  138.     if len(name) == 0:
  139.         name = os.path.splitext(file)[0]
  140.     rootObj = bpy.data.objects.new(name, None)
  141.     rootObj.hide_viewport = True
  142.     bpyhelper.scene_link(rootObj)
  143.  
  144.     wm = bpy.context.window_manager
  145.     prog = 0
  146.     total = 0
  147.     if importPhysics: total += 1
  148.     if importObjects:
  149.         for ob in data.objects:
  150.             total += len(ob.entities)
  151.             for ent in ob.entities:
  152.                 total += len(ent.records)
  153.     if importDetails:
  154.         total += len(data.details) * 3
  155.     if light_settings.enabled:
  156.         total += len(data.lights)
  157.     if importSound:
  158.         total += len(data.sounds)
  159.     wm.progress_begin(prog, total)
  160.  
  161.     matCache = {}
  162.  
  163.     if importObjects:
  164.         globObj = bpy.data.objects.new(name + '_OBJECTS', None)
  165.         globObj.hide_viewport = True
  166.         globObj.parent = rootObj
  167.         bpyhelper.scene_link(globObj)
  168.         for ob in data.objects:
  169.             obpath = ob.model
  170.             if not os.path.isabs(obpath):
  171.                 obpath = bpyhelper.normpath('%s/%s' % (root, obpath))
  172.             if not os.path.isfile(obpath): continue
  173.             progress_update(total, prog, obpath)
  174.  
  175.             obn = os.path.splitext(os.path.basename(obpath))[0]
  176.  
  177.             mutated = settings.mutate(obpath)
  178.             mutated.importMaterial = False
  179.  
  180.             obj, internal_obj = import_mdl(mutated)
  181.             if obj is None:
  182.                 continue
  183.  
  184.             obnObj = bpy.data.objects.new(obn + '_COLLECTION', None)
  185.             obnObj.hide_viewport = True
  186.             obnObj.parent = globObj
  187.             bpyhelper.scene_link(obnObj)
  188.             buildRelationships()
  189.  
  190.             for idx, ent in enumerate(ob.entities):
  191.                 matpath = ent.material
  192.                 if not os.path.isabs(matpath):
  193.                     matpath = bpyhelper.normpath('%s/%s' % (root, matpath))
  194.  
  195.                 mat = None
  196.                 hideModel = False
  197.                 if settings.importMaterial and bpyhelper.valid_path(ent.material):
  198.                     if matpath not in matCache:
  199.                         mat = import_owmat.read(matpath, '%s:%X_' % (name, idx))
  200.                         matCache[matpath] = mat
  201.                     else:
  202.                         mat = matCache[matpath]
  203.                 if mat != None and removeCollision:
  204.                     for tex_name, tex in mat[0].items():
  205.                         if tex_name == '000000001B8D' or tex_name == '000000001BA4':
  206.                             hideModel = True
  207.  
  208.                 prog += 1
  209.  
  210.                 matObj = bpy.data.objects.new(os.path.splitext(os.path.basename(matpath))[0], None)
  211.                 matObj.hide_viewport = True
  212.                 matObj.parent = obnObj
  213.                 bpyhelper.scene_link(matObj)
  214.  
  215.                 import_owmdl.bindMaterialsUniq(internal_obj[2], internal_obj[4], mat)
  216.                 # eobj = copy(obj, None)
  217.  
  218.                 for idx2, rec in enumerate(ent.records):
  219.                     progress_update(total, prog, obpath)
  220.                     nobj = copy(obj, matObj)
  221.                     nobj.location = pos_matrix(rec.position)
  222.                     nobj.rotation_euler = Quaternion(wxzy(rec.rotation)).to_euler('XYZ')
  223.                     nobj.scale = xpzy(rec.scale)
  224.                     if hideModel:
  225.                         hide_recursive(nobj)
  226.                     prog += 1
  227.             remove(obj)
  228.  
  229.     if importDetails:
  230.         globDet = bpy.data.objects.new(name + '_DETAILS', None)
  231.         globDet.hide_viewport = True
  232.         globDet.parent = rootObj
  233.         bpyhelper.scene_link(globDet)
  234.         objCache = {}
  235.         for idx, ob in enumerate(data.details):
  236.             obpath = ob.model
  237.             prog += 1
  238.             if not os.path.isabs(obpath):
  239.                 obpath = bpyhelper.normpath('%s/%s' % (root, obpath))
  240.             if not os.path.isfile(obpath):
  241.                 continue
  242.             progress_update(total, prog, obpath)
  243.             cacheKey = obpath
  244.             if settings.importMaterial and bpyhelper.valid_path(ob.material):
  245.                 cacheKey = cacheKey + ob.material
  246.             if cacheKey in objCache:
  247.                 continue
  248.  
  249.             obn = os.path.splitext(os.path.basename(obpath))[0]
  250.             if not importPhysics and obn == 'physics':
  251.                 continue
  252.  
  253.             mutated = settings.mutate(obpath)
  254.             mutated.importMaterial = False
  255.  
  256.             mdl, internal_obj = import_mdl(mutated)
  257.             if mdl is None:
  258.                 continue
  259.  
  260.             matpath = ob.material
  261.             if not os.path.isabs(matpath):
  262.                 matpath = bpyhelper.normpath('%s/%s' % (root, matpath))
  263.  
  264.             mat = None
  265.             hideModel = False
  266.             if settings.importMaterial and bpyhelper.valid_path(ob.material):
  267.                 if matpath not in matCache:
  268.                     mat = import_owmat.read(matpath, '%s:%X_' % (name, idx))
  269.                     matCache[matpath] = mat
  270.                 else:
  271.                     mat = matCache[matpath]
  272.                 if removeCollision:
  273.                     for tex_name, tex in mat[0].items():
  274.                         if tex_name == '000000001B8D' or tex_name == '000000001BA4':
  275.                             hideModel = True
  276.             if hideModel:
  277.                 hide_recursive(mdl)
  278.  
  279.             import_owmdl.bindMaterialsUniq(internal_obj[2], internal_obj[4], mat)
  280.  
  281.             objCache[cacheKey] = mdl
  282.         buildRelationships()
  283.         for ob in data.details:
  284.             obpath = ob.model
  285.             prog += 1
  286.             if not os.path.isabs(obpath):
  287.                 obpath = bpyhelper.normpath('%s/%s' % (root, obpath))
  288.             cacheKey = obpath
  289.             progress_update(total, prog, obpath)
  290.             if settings.importMaterial and bpyhelper.valid_path(ob.material):
  291.                 cacheKey = cacheKey + ob.material
  292.             if cacheKey not in objCache or objCache[cacheKey] is None:
  293.                 continue
  294.  
  295.             objnode = copy(objCache[cacheKey], globDet)
  296.             objnode.location = pos_matrix(ob.position)
  297.             objnode.rotation_euler = Quaternion(wxzy(ob.rotation)).to_euler('XYZ')
  298.             objnode.scale = xpzy(ob.scale)
  299.  
  300.         for ob in objCache:
  301.             prog += 1
  302.             remove(objCache[ob])
  303.             progress_update(total, prog, ob)
  304.  
  305.     for obj in link_queue:
  306.         bpyhelper.scene_link(obj)
  307.     link_queue = []
  308.     destroyRelationships()
  309.    
  310.     LIGHT_MAP = ['POINT', 'FRUSTUM', 'NONE']
  311.  
  312.     if light_settings.enabled:
  313.         globLight = bpy.data.objects.new(name + '_LIGHTS', None)
  314.         globLight.hide_viewport = True
  315.         globLight.parent = rootObj
  316.         bpyhelper.scene_link(globLight)
  317.         for light in data.lights:
  318.             prog += 1
  319.             is_spot = light.fov > 0
  320.             if light.ex[6] >= 2:
  321.                 print("[owmap] Light is type NONE!?")
  322.             lamp_data = bpy.data.lights.new(name='%s_%s' % (name, LIGHT_MAP[min([2, light.ex[6]])]), type='SPOT' if is_spot else 'POINT')
  323.             lamp_ob = bpy.data.objects.new(name=name, object_data=lamp_data)
  324.             bpyhelper.scene_link(lamp_ob)
  325.             lamp_ob.location = pos_matrix(light.position)
  326.             if light.ex[6] == 1:
  327.                 print("[owmap] warning: importing frustum light at X: %f, Y: %f, Z: %f" % (lamp_ob.location.x, lamp_ob.location.y, lamp_ob.location.z))
  328.             lamp_ob.rotation_euler = Quaternion(wxzy(light.rotation)).to_euler('XYZ')
  329.             lamp_ob.rotation_euler.x -= 1.5708
  330.             light_scale = light.ex[light_settings.sizeIndex % len(light.ex)]
  331.             lamp_ob.scale = (light_scale, light_scale, light_scale)
  332.             lamp_col = Color(light.color)
  333.             lamp_col.v *= light_settings.adjuistValues['VALUE']
  334.             lamp_data.cycles.use_multiple_importance_sampling = light_settings.multipleImportance
  335.             lamp_str = light_settings.adjuistValues['STRENGTH']
  336.             if is_spot:
  337.                 lamp_data.spot_size = math.radians(light.fov)
  338.                 lamp_data.spot_blend = light.ex[light_settings.spotIndex % len(light.ex)]
  339.             if light_settings.useStrength:
  340.                 lamp_str = light_settings.adjuistValues['STRENGTH'] * light.ex[light_settings.index % len(light.ex)]
  341.             lamp_data.use_nodes = True
  342.             lamp_data.shadow_soft_size = light_settings.bias
  343.             enode = lamp_data.node_tree.nodes.get('Emission')
  344.             enode.inputs.get('Color').default_value = (lamp_col.r, lamp_col.g, lamp_col.b, 1.0)
  345.             enode.inputs.get('Strength').default_value = lamp_str
  346.             lamp_ob.parent = globLight
  347.             progress_update(total, prog, "Lamp")
  348.    
  349.     if importSound:
  350.         globSound = bpy.data.objects.new(name + '_SOUNDS', None)
  351.         globSound.hide_viewport = True
  352.         globSound.parent = rootObj
  353.         bpyhelper.scene_link(globSound)
  354.         for sound in data.sounds:
  355.             prog += 1
  356.             soundWrap = bpy.data.objects.new(name = '%s_SPEAKER_WRAP' % (name), object_data = None)
  357.             soundWrap.parent = globSound
  358.             soundWrap.hide_viewport = True
  359.             soundWrap.location = pos_matrix(sound.position)
  360.             bpyhelper.scene_link(soundWrap)
  361.             for soundFile in sound.sounds:
  362.                 print("[import_owmap] %s" % (soundFile))
  363.                 speaker_data = bpy.data.speakers.new(name = '%s_SPEAKER' % (name))
  364.                 speaker_ob = bpy.data.objects.new(name = '%s_SPEAKER' % (name), object_data=speaker_data)
  365.                 speaker_ob.parent = soundWrap
  366.                 speaker_data.sound = bpy.data.sounds.load(soundFile, check_existing=True)
  367.                 speaker_data.volume = 0.7
  368.                 speaker_data.attenuation = 0.3
  369.                 bpyhelper.scene_link(speaker_ob)
  370.             progress_update(total, prog, "Sound")
  371.  
  372.     wm.progress_end()
  373.     bpyhelper.deselect_all()
  374.     print('Finished loading map')
  375.     bpyhelper.LOCK_UPDATE = False
  376.     bpyhelper.scene_update()
  377.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement