Finish UI merge

This commit is contained in:
Lubos Lenco 2017-08-21 12:17:55 +02:00
parent 77350393a2
commit 5dd42f6948
25 changed files with 879 additions and 927 deletions

View file

@ -1243,16 +1243,15 @@ class ArmoryExporter:
if not bobject.cycles_visibility.shadow:
o['visible_shadow'] = False
if bobject.spawn == False:
if bobject.arm_spawn == False:
o['spawn'] = False
if bobject.mobile == False:
if bobject.arm_mobile == False:
o['mobile'] = False
if bobject.dupli_type == 'GROUP' and bobject.dupli_group != None:
o['group_ref'] = bobject.dupli_group.name
# if ArmoryExporter.option_spawn_all_layers == False:
layer_found = False
for l in self.active_layers:
if bobject.layers[l] == True:
@ -1267,17 +1266,17 @@ class ArmoryExporter:
objname = self.asset_name(objref)
# Lods
if bobject.type == 'MESH' and hasattr(objref, 'my_lodlist') and len(objref.my_lodlist) > 0:
if bobject.type == 'MESH' and hasattr(objref, 'arm_lodlist') and len(objref.arm_lodlist) > 0:
o['lods'] = []
for l in objref.my_lodlist:
for l in objref.arm_lodlist:
if l.enabled_prop == False:
continue
lod = {}
lod['object_ref'] = l.name
lod['screen_size'] = l.screen_size_prop
o['lods'].append(lod)
if objref.lod_material:
o['lod_material'] = True
if objref.arm_lod_material:
o['arm_lod_material'] = True
if type == NodeTypeMesh:
if not objref in self.meshArray:
@ -1297,7 +1296,7 @@ class ArmoryExporter:
o['material_refs'] = []
for i in range(len(bobject.material_slots)):
self.export_material_ref(bobject, bobject.material_slots[i].material, i, o)
if bobject.material_slots[i].material != None and bobject.material_slots[i].material.decal:
if bobject.material_slots[i].material != None and bobject.material_slots[i].material.arm_decal:
o['type'] = 'decal_object'
# No material, mimic cycles and assign default
if len(o['material_refs']) == 0:
@ -1311,10 +1310,10 @@ class ArmoryExporter:
o['dimensions'] = [bobject.dimensions[0], bobject.dimensions[1], bobject.dimensions[2]]
# Origin not in geometry center
if hasattr(bobject.data, 'mesh_aabb'):
dx = bobject.data.mesh_aabb[0] * bobject.scale[0]
dy = bobject.data.mesh_aabb[1] * bobject.scale[1]
dz = bobject.data.mesh_aabb[2] * bobject.scale[2]
if hasattr(bobject.data, 'arm_aabb'):
dx = bobject.data.arm_aabb[0] * bobject.scale[0]
dy = bobject.data.arm_aabb[1] * bobject.scale[1]
dz = bobject.data.arm_aabb[2] * bobject.scale[2]
if dx > o['dimensions'][0]:
o['dimensions'][0] = dx
if dy > o['dimensions'][1]:
@ -1399,7 +1398,7 @@ class ArmoryExporter:
bobject.animation_data.action = action
fp = self.get_meshes_file_path('bones_' + armatureid + '_' + action.name, compressed=self.is_compress(bdata))
assets.add(fp)
if bdata.data_cached == False or not os.path.exists(fp):
if bdata.arm_data_cached == False or not os.path.exists(fp):
bones = []
for bone in bdata.bones:
if not bone.parent:
@ -1410,7 +1409,7 @@ class ArmoryExporter:
bones_obj = {}
bones_obj['objects'] = bones
arm.utils.write_arm(fp, bones_obj)
bdata.data_cached = True
bdata.arm_data_cached = True
if parento == None:
self.output['objects'].append(o)
@ -1448,7 +1447,7 @@ class ArmoryExporter:
bone_array = armature.data.bones
bone_count = len(bone_array)
max_bones = bpy.data.worlds['Arm'].generate_gpu_skin_max_bones
max_bones = bpy.data.worlds['Arm'].arm_gpu_skin_max_bones
if bone_count > max_bones:
log.warn(bobject.name + ' - ' + str(bone_count) + ' bones found, exceeds maximum of ' + str(max_bones) + ' bones defined - raise the value in Camera Data - Armory Render Props - Max Bones')
@ -1619,10 +1618,10 @@ class ArmoryExporter:
mesh_obj['mesh_datas'] = [o]
arm.utils.write_arm(fp, mesh_obj)
bobject.data.mesh_cached = True
bobject.data.arm_cached = True
if bobject.type != 'FONT' and bobject.type != 'META':
bobject.data.mesh_cached_verts = len(bobject.data.vertices)
bobject.data.mesh_cached_edges = len(bobject.data.edges)
bobject.data.arm_cached_verts = len(bobject.data.vertices)
bobject.data.arm_cached_edges = len(bobject.data.edges)
else:
self.output['mesh_datas'].append(o)
@ -1772,10 +1771,10 @@ class ArmoryExporter:
if ArmoryExporter.option_mesh_per_file:
fp = self.get_meshes_file_path('mesh_' + oid, compressed=self.is_compress(bobject.data))
assets.add(fp)
if bobject.data.sdfgen:
if hasattr(bobject.data, 'arm_sdfgen') and bobject.data.arm_sdfgen:
sdf_path = fp.replace('/mesh_', '/sdf_')
assets.add(sdf_path)
if self.object_is_mesh_cached(bobject) == True and os.path.exists(fp):
if self.object_is_cached(bobject) == True and os.path.exists(fp):
return
print('Exporting mesh ' + self.asset_name(bobject.data))
@ -1887,8 +1886,8 @@ class ArmoryExporter:
if positions[i + 2] < aabb_min[2]:
aabb_min[2] = positions[i + 2];
i += stride;
if hasattr(bobject.data, 'mesh_aabb'):
bobject.data.mesh_aabb = [abs(aabb_min[0]) + abs(aabb_max[0]), abs(aabb_min[1]) + abs(aabb_max[1]), abs(aabb_min[2]) + abs(aabb_max[2])]
if hasattr(bobject.data, 'arm_aabb'):
bobject.data.arm_aabb = [abs(aabb_min[0]) + abs(aabb_max[0]), abs(aabb_min[1]) + abs(aabb_max[1]), abs(aabb_min[2]) + abs(aabb_max[2])]
break
# Restore the morph state
@ -1906,15 +1905,15 @@ class ArmoryExporter:
o['instance_offsets'] = instance_offsets
# Export usage
if bobject.data.dynamic_usage:
o['dynamic_usage'] = bobject.data.dynamic_usage
if bobject.data.arm_dynamic_usage:
o['dynamic_usage'] = bobject.data.arm_dynamic_usage
if bobject.data.sdfgen:
if hasattr(bobject.data, 'arm_sdfgen') and bobject.data.arm_sdfgen:
o['sdf_ref'] = 'sdf_' + oid
self.write_mesh(bobject, fp, o)
if bobject.data.sdfgen:
if hasattr(bobject.data, 'arm_sdfgen') and bobject.data.arm_sdfgen:
# Copy input
sdk_path = arm.utils.get_sdk_path()
sdfgen_path = sdk_path + '/armory/tools/sdfgen'
@ -2090,10 +2089,10 @@ class ArmoryExporter:
o['type'] = 'sun'
o['cast_shadow'] = objref.cycles.cast_shadow
o['near_plane'] = objref.lamp_clip_start
o['far_plane'] = objref.lamp_clip_end
o['fov'] = objref.lamp_fov
o['shadows_bias'] = objref.lamp_shadows_bias
o['near_plane'] = objref.arm_clip_start
o['far_plane'] = objref.arm_clip_end
o['fov'] = objref.arm_fov
o['shadows_bias'] = objref.arm_shadows_bias
wrd = bpy.data.worlds['Arm']
if wrd.rp_shadowmap == 'None':
o['shadowmap_size'] = 0
@ -2107,7 +2106,7 @@ class ArmoryExporter:
if lamp_size > 1:
o['shadows_bias'] += 0.00001 * lamp_size
o['lamp_size'] = lamp_size * 10 # Match to Cycles
if objtype == 'POINT' and objref.lamp_omni_shadows and not arm.utils.get_gapi().startswith('direct3d'):
if objtype == 'POINT' and objref.arm_omni_shadows and not arm.utils.get_gapi().startswith('direct3d'):
o['fov'] = 1.5708 # 90 deg
o['shadowmap_cube'] = True
o['shadows_bias'] *= 4.0
@ -2165,12 +2164,12 @@ class ArmoryExporter:
else:
o['type'] = 'orthographic'
if objref.is_mirror:
o['is_mirror'] = True
o['mirror_resolution_x'] = int(objref.mirror_resolution_x)
o['mirror_resolution_y'] = int(objref.mirror_resolution_y)
if objref.arm_render_to_texture:
o['render_to_texture'] = True
o['texture_resolution_x'] = int(objref.arm_texture_resolution_x)
o['texture_resolution_y'] = int(objref.arm_texture_resolution_y)
o['frustum_culling'] = objref.frustum_culling
o['frustum_culling'] = objref.arm_frustum_culling
o['render_path'] = wrd.renderpath_path + '/' + wrd.renderpath_path # Same file name and id
if self.scene.world != None and 'Background' in self.scene.world.node_tree.nodes: # TODO: parse node tree
@ -2207,8 +2206,8 @@ class ArmoryExporter:
else:
o['sound'] = ''
o['muted'] = objref.muted
o['loop'] = objref.loop
o['stream'] = objref.stream
o['loop'] = objref.arm_loop
o['stream'] = objref.arm_stream
o['volume'] = objref.volume
o['pitch'] = objref.pitch
o['attenuation'] = objref.attenuation
@ -2229,7 +2228,7 @@ class ArmoryExporter:
make_material.parse(mat, o, mat_users, mat_armusers, ArmoryExporter.renderpath_id)
self.output['material_datas'].append(o)
bpy.data.materials.remove(mat)
if bpy.data.worlds['Arm'].force_no_culling:
if bpy.data.worlds['Arm'].arm_culling == False:
o['override_context'] = {}
o['override_context']['cull_mode'] = 'none'
@ -2254,16 +2253,13 @@ class ArmoryExporter:
o = {}
o['name'] = materialRef[1]["structName"]
if material.skip_context != '':
o['skip_context'] = material.skip_context
if material.two_sided_shading or wrd.force_no_culling:
if material.arm_two_sided or wrd.arm_culling == False:
o['override_context'] = {}
o['override_context']['cull_mode'] = 'none'
elif material.override_cull_mode != 'Clockwise':
elif material.arm_cull_mode != 'Clockwise':
o['override_context'] = {}
o['override_context']['cull_mode'] = material.override_cull_mode
o['override_context']['cull_mode'] = material.arm_cull_mode
o['contexts'] = []
@ -2309,7 +2305,7 @@ class ArmoryExporter:
material.export_tangents = tang_export
mat_users = self.materialToObjectDict[material]
for ob in mat_users:
ob.data.mesh_cached = False
ob.data.arm_cached = False
self.output['material_datas'].append(o)
material.is_cached = True
@ -2372,7 +2368,7 @@ class ArmoryExporter:
def export_grease_pencils(self):
gpRef = self.scene.grease_pencil
if gpRef == None or self.scene.gp_export == False:
if gpRef == None or self.scene.arm_gp_export == False:
return
# ArmoryExporter.option_mesh_per_file # Currently always exports to separate file
@ -2389,17 +2385,17 @@ class ArmoryExporter:
assets.add_shader(arm.utils.build_dir() + '/compiled/Shaders/grease_pencil/grease_pencil_shadows.frag.glsl')
assets.add_shader(arm.utils.build_dir() + '/compiled/Shaders/grease_pencil/grease_pencil_shadows.vert.glsl')
if gpRef.data_cached == True and os.path.exists(fp):
if gpRef.arm_data_cached == True and os.path.exists(fp):
return
gpo = self.post_export_grease_pencil(gpRef)
gp_obj = {}
gp_obj['grease_pencil_datas'] = [gpo]
arm.utils.write_arm(fp, gp_obj)
gpRef.data_cached = True
gpRef.arm_data_cached = True
def is_compress(self, obj):
return ArmoryExporter.compress_enabled and obj.data_compressed
return ArmoryExporter.compress_enabled and obj.arm_compress
def export_objects(self, scene):
if not ArmoryExporter.option_mesh_only:
@ -2486,12 +2482,12 @@ class ArmoryExporter:
# Auto-bones
wrd = bpy.data.worlds['Arm']
if wrd.generate_gpu_skin_max_bones_auto:
if wrd.arm_gpu_skin_max_bones_auto:
max_bones = 8
for armature in bpy.data.armatures:
if max_bones < len(armature.bones):
max_bones = len(armature.bones)
wrd.generate_gpu_skin_max_bones = max_bones
wrd.arm_gpu_skin_max_bones = max_bones
self.output['objects'] = []
for bo in self.scene.objects:
@ -2603,14 +2599,14 @@ class ArmoryExporter:
return {'FINISHED'}
# Callbacks
def object_is_mesh_cached(self, bobject):
def object_is_cached(self, bobject):
if bobject.type == 'FONT' or bobject.type == 'META': # No verts
return bobject.data.mesh_cached
if bobject.data.mesh_cached_verts != len(bobject.data.vertices):
return bobject.data.arm_cached
if bobject.data.arm_cached_verts != len(bobject.data.vertices):
return False
if bobject.data.mesh_cached_edges != len(bobject.data.edges):
if bobject.data.arm_cached_edges != len(bobject.data.edges):
return False
return bobject.data.mesh_cached
return bobject.data.arm_cached
def get_export_tangents(self, mesh):
for m in mesh.materials:
@ -2640,7 +2636,7 @@ class ArmoryExporter:
instance_offsets = [0.0, 0.0, 0.0] # Include parent
for sn in n.children:
# Child hidden
if sn.game_export == False:
if sn.arm_export == False:
continue
# Do not take parent matrix into account
loc = sn.matrix_local.to_translation()
@ -2685,7 +2681,6 @@ class ArmoryExporter:
# Used for material shader export and khafile
ArmoryExporter.renderpath_id = wrd.renderpath_id
ArmoryExporter.renderpath_passes = wrd.renderpath_passes.split('_')
ArmoryExporter.mesh_context = 'mesh'
ArmoryExporter.mesh_context_empty = ''
ArmoryExporter.shadows_context = 'shadowmap'
@ -2696,7 +2691,7 @@ class ArmoryExporter:
export_object = True
# Disabled object
if bobject.game_export == False:
if bobject.arm_export == False:
return False
for m in bobject.modifiers:
@ -2704,9 +2699,9 @@ class ArmoryExporter:
# Do not export ocean mesh, just take specified constants
export_object = False
wrd = bpy.data.worlds['Arm']
wrd.generate_ocean = True
wrd.arm_ocean = True
# Take position and bounds
wrd.generate_ocean_level = 0.0#bobject.location.z
wrd.arm_ocean_level = 0.0#bobject.location.z
return export_object
@ -2727,12 +2722,12 @@ class ArmoryExporter:
x['speeds'] = [1.0]
x['loops'] = [True]
x['reflects'] = [False]
x['max_bones'] = bpy.data.worlds['Arm'].generate_gpu_skin_max_bones
x['max_bones'] = bpy.data.worlds['Arm'].arm_gpu_skin_max_bones
o['animation_setup'] = x
# Export traits
if hasattr(bobject, 'my_traitlist'):
for t in bobject.my_traitlist:
if hasattr(bobject, 'arm_traitlist'):
for t in bobject.arm_traitlist:
if t.enabled_prop == False:
continue
x = {}
@ -2804,13 +2799,13 @@ class ArmoryExporter:
else:
trait_prefix = arm.utils.safestr(bpy.data.worlds['Arm'].arm_project_package) + '.'
x['class_name'] = trait_prefix + t.class_name_prop
if len(t.my_paramstraitlist) > 0:
if len(t.arm_traitparamslist) > 0:
x['parameters'] = []
for pt in t.my_paramstraitlist: # Append parameters
for pt in t.arm_traitparamslist: # Append parameters
x['parameters'].append(pt.name)
if len(t.my_propstraitlist) > 0:
if len(t.arm_traitpropslist) > 0:
x['props'] = []
for pt in t.my_propstraitlist: # Append props
for pt in t.arm_traitpropslist: # Append props
x['props'].append(pt.name)
x['props'].append(pt.value)
o['traits'].append(x)
@ -2873,7 +2868,7 @@ class ArmoryExporter:
bend = soft_mod.settings.bending_stiffness
elif soft_type == 1:
bend = (soft_mod.settings.bend + 1.0) * 10
cloth_trait['parameters'] = [str(soft_type), str(bend), str(soft_mod.settings.mass), str(bobject.soft_body_margin)]
cloth_trait['parameters'] = [str(soft_type), str(bend), str(soft_mod.settings.mass), str(bobject.arm_soft_body_margin)]
o['traits'].append(cloth_trait)
if soft_type == 0 and soft_mod.settings.use_pin_cloth:
self.add_hook_trait(o, bobject, '', soft_mod.settings.vertex_group_mass)
@ -2976,7 +2971,7 @@ class ArmoryExporter:
def post_export_world(self, world, o):
defs = bpy.data.worlds['Arm'].world_defs + bpy.data.worlds['Arm'].rp_defs
bgcol = world.world_envtex_color
bgcol = world.arm_envtex_color
if '_LDR' in defs: # No compositor used
for i in range(0, 3):
bgcol[i] = pow(bgcol[i], 1.0 / 2.2)
@ -2986,29 +2981,29 @@ class ArmoryExporter:
o['material_ref'] = wmat_name + '/' + wmat_name + '/world'
o['probes'] = []
# Main probe
world_generate_radiance = False
generate_irradiance = True #'_EnvTex' in defs or '_EnvSky' in defs or '_EnvCon' in defs
disable_hdr = world.world_envtex_name.endswith('.jpg')
radtex = world.world_envtex_name.rsplit('.', 1)[0]
irrsharmonics = world.world_envtex_irr_name
world_arm_radiance = False
arm_irradiance = True #'_EnvTex' in defs or '_EnvSky' in defs or '_EnvCon' in defs
disable_hdr = world.arm_envtex_name.endswith('.jpg')
radtex = world.arm_envtex_name.rsplit('.', 1)[0]
irrsharmonics = world.arm_envtex_irr_name
# Radiance
if '_EnvTex' in defs:
world_generate_radiance = bpy.data.worlds['Arm'].generate_radiance
elif '_EnvSky' in defs and bpy.data.worlds['Arm'].generate_radiance_sky:
world_generate_radiance = bpy.data.worlds['Arm'].generate_radiance
world_arm_radiance = bpy.data.worlds['Arm'].arm_radiance
elif '_EnvSky' in defs and bpy.data.worlds['Arm'].arm_radiance_sky:
world_arm_radiance = bpy.data.worlds['Arm'].arm_radiance
radtex = 'hosek'
num_mips = world.world_envtex_num_mips
strength = world.world_envtex_strength
po = self.make_probe(world.name, irrsharmonics, radtex, num_mips, strength, 1.0, [0, 0, 0], [0, 0, 0], world_generate_radiance, generate_irradiance, disable_hdr)
num_mips = world.arm_envtex_num_mips
strength = world.arm_envtex_strength
po = self.make_probe(world.name, irrsharmonics, radtex, num_mips, strength, 1.0, [0, 0, 0], [0, 0, 0], world_arm_radiance, arm_irradiance, disable_hdr)
o['probes'].append(po)
if '_EnvSky' in defs:
# Sky data for probe
po['sun_direction'] = list(world.world_envtex_sun_direction)
po['turbidity'] = world.world_envtex_turbidity
po['ground_albedo'] = world.world_envtex_ground_albedo
po['sun_direction'] = list(world.arm_envtex_sun_direction)
po['turbidity'] = world.arm_envtex_turbidity
po['ground_albedo'] = world.arm_envtex_ground_albedo
def post_export_grease_pencil(self, gp):
o = {}
@ -3113,17 +3108,17 @@ class ArmoryExporter:
co['fill_alpha'] = color.fill_alpha
return co
def make_probe(self, id, irrsharmonics, radtex, mipmaps, strength, blending, volume, volume_center, generate_radiance, generate_irradiance, disable_hdr):
def make_probe(self, id, irrsharmonics, radtex, mipmaps, strength, blending, volume, volume_center, arm_radiance, arm_irradiance, disable_hdr):
po = {}
po['name'] = id
if generate_radiance:
if arm_radiance:
po['radiance'] = radtex + '_radiance'
if disable_hdr:
po['radiance'] += '.jpg'
else:
po['radiance'] += '.hdr'
po['radiance_mipmaps'] = mipmaps
if generate_irradiance:
if arm_irradiance:
po['irradiance'] = irrsharmonics + '_irradiance'
else:
po['irradiance'] = '' # No irradiance data, fallback to default at runtime

View file

@ -200,9 +200,9 @@ def on_scene_update_post(context):
def recache(edit_obj):
if edit_obj.type == 'MESH':
edit_obj.data.mesh_cached = False
edit_obj.data.arm_cached = False
elif edit_obj.type == 'ARMATURE':
edit_obj.data.data_cached = False
edit_obj.data.arm_data_cached = False
def op_changed(op, obj):
# Recache mesh data
@ -211,7 +211,7 @@ def op_changed(op, obj):
op.bl_idname == 'OBJECT_OT_transform_apply' or \
op.bl_idname == 'OBJECT_OT_shade_smooth' or \
op.bl_idname == 'OBJECT_OT_shade_flat':
obj.data.mesh_cached = False
obj.data.arm_cached = False
appended_py_paths = []
@persistent

View file

@ -77,7 +77,7 @@ def export_data(fp, sdk_path, is_play=False, is_publish=False, in_viewport=False
make_logic.build_node_trees()
active_worlds = set()
for scene in bpy.data.scenes:
if scene.game_export and scene.world != None:
if scene.arm_export and scene.world != None:
active_worlds.add(scene.world)
world_outputs = make_world.build_node_trees(active_worlds)
make_renderpath.build_node_trees(assets_path)
@ -92,8 +92,8 @@ def export_data(fp, sdk_path, is_play=False, is_publish=False, in_viewport=False
ArmoryExporter.compress_enabled = is_publish and wrd.arm_asset_compression
ArmoryExporter.in_viewport = in_viewport
for scene in bpy.data.scenes:
if scene.game_export:
ext = '.zip' if (scene.data_compressed and is_publish) else '.arm'
if scene.arm_export:
ext = '.zip' if (scene.arm_compress and is_publish) else '.arm'
asset_path = arm.utils.build_dir() + '/compiled/Assets/' + arm.utils.safestr(scene.name) + ext
exporter.execute(bpy.context, asset_path, scene=scene)
if ArmoryExporter.export_physics:

View file

@ -1,6 +1,7 @@
import bpy
import arm.nodes_renderpath as nodes_renderpath
import arm.utils
import arm.assets as assets
group = None
nodes = None
@ -17,15 +18,14 @@ def set_preset(self, context, preset):
if preset == 'Low':
wrd.rp_renderer = 'Forward'
wrd.material_model = 'PBR'
wrd.arm_material_model = 'PBR'
wrd.rp_shadowmap = '1024'
wrd.rp_meshes = True
wrd.rp_translucency_state = 'Off'
wrd.rp_overlays_state = 'Off'
wrd.rp_decals_state = 'Off'
wrd.rp_sss_state = 'Off'
wrd.rp_hdr = False
wrd.rp_worldnodes = False
wrd.rp_world = False
wrd.rp_clearbackground = True
wrd.rp_stereo = False
wrd.rp_greasepencil = False
@ -46,15 +46,14 @@ def set_preset(self, context, preset):
wrd.rp_motionblur = 'None'
elif preset == 'Forward':
wrd.rp_renderer = 'Forward'
wrd.material_model = 'PBR'
wrd.arm_material_model = 'PBR'
wrd.rp_shadowmap = '2048'
wrd.rp_meshes = True
wrd.rp_translucency_state = 'Auto'
wrd.rp_overlays_state = 'Auto'
wrd.rp_decals_state = 'Auto'
wrd.rp_sss_state = 'Auto'
wrd.rp_hdr = True
wrd.rp_worldnodes = True
wrd.rp_world = True
wrd.rp_clearbackground = False
wrd.rp_stereo = False
wrd.rp_greasepencil = False
@ -75,15 +74,14 @@ def set_preset(self, context, preset):
wrd.rp_motionblur = 'None'
elif preset == 'Deferred':
wrd.rp_renderer = 'Deferred'
wrd.material_model = 'PBR'
wrd.arm_material_model = 'PBR'
wrd.rp_shadowmap = '2048'
wrd.rp_meshes = True
wrd.rp_translucency_state = 'Auto'
wrd.rp_overlays_state = 'Auto'
wrd.rp_decals_state = 'Auto'
wrd.rp_sss_state = 'Auto'
wrd.rp_hdr = True
wrd.rp_worldnodes = True
wrd.rp_world = True
wrd.rp_clearbackground = False
wrd.rp_stereo = False
wrd.rp_greasepencil = False
@ -104,15 +102,14 @@ def set_preset(self, context, preset):
wrd.rp_motionblur = 'None'
elif preset == 'Max':
wrd.rp_renderer = 'Deferred'
wrd.material_model = 'PBR'
wrd.arm_material_model = 'PBR'
wrd.rp_shadowmap = '4096'
wrd.rp_meshes = True
wrd.rp_translucency_state = 'Auto'
wrd.rp_overlays_state = 'Auto'
wrd.rp_decals_state = 'Auto'
wrd.rp_sss_state = 'Auto'
wrd.rp_hdr = True
wrd.rp_worldnodes = True
wrd.rp_world = True
wrd.rp_clearbackground = False
wrd.rp_stereo = False
wrd.rp_greasepencil = False
@ -134,13 +131,12 @@ def set_preset(self, context, preset):
elif preset == 'Render Capture':
wrd.rp_renderer = 'Deferred'
wrd.rp_shadowmap = '8192'
wrd.rp_meshes = True
wrd.rp_translucency_state = 'Auto'
wrd.rp_overlays_state = 'Auto'
wrd.rp_decals_state = 'Auto'
wrd.rp_sss_state = 'Auto'
wrd.rp_hdr = True
wrd.rp_worldnodes = True
wrd.rp_world = True
wrd.rp_clearbackground = False
wrd.rp_stereo = False
wrd.rp_greasepencil = False
@ -161,19 +157,18 @@ def set_preset(self, context, preset):
wrd.rp_rendercapture = True
wrd.rp_rendercapture_format = '8bit'
wrd.rp_motionblur = 'None'
wrd.material_model = 'Cycles'
wrd.generate_pcss_state = 'On'
wrd.arm_material_model = 'Cycles'
wrd.arm_pcss_state = 'On'
elif preset == 'Deferred Plus':
wrd.rp_renderer = 'Deferred Plus'
wrd.material_model = 'PBR'
wrd.arm_material_model = 'PBR'
wrd.rp_shadowmap = '4096'
wrd.rp_meshes = True
wrd.rp_translucency_state = 'Auto'
wrd.rp_overlays_state = 'Auto'
wrd.rp_decals_state = 'Auto'
wrd.rp_sss_state = 'Auto'
wrd.rp_hdr = True
wrd.rp_worldnodes = True
wrd.rp_world = True
wrd.rp_clearbackground = False
wrd.rp_stereo = False
wrd.rp_greasepencil = False
@ -194,15 +189,14 @@ def set_preset(self, context, preset):
wrd.rp_motionblur = 'None'
elif preset == 'VR Low':
wrd.rp_renderer = 'Forward'
wrd.material_model = 'Restricted'
wrd.arm_material_model = 'Restricted'
wrd.rp_shadowmap = '1024'
wrd.rp_meshes = True
wrd.rp_translucency_state = 'Off'
wrd.rp_overlays_state = 'Off'
wrd.rp_decals_state = 'Off'
wrd.rp_sss_state = 'Off'
wrd.rp_hdr = False
wrd.rp_worldnodes = False
wrd.rp_world = False
wrd.rp_clearbackground = True
wrd.rp_stereo = True
wrd.rp_greasepencil = False
@ -223,15 +217,14 @@ def set_preset(self, context, preset):
wrd.rp_motionblur = 'None'
elif preset == 'Mobile Low':
wrd.rp_renderer = 'Forward'
wrd.material_model = 'Restricted'
wrd.arm_material_model = 'Restricted'
wrd.rp_shadowmap = '1024'
wrd.rp_meshes = True
wrd.rp_translucency_state = 'Off'
wrd.rp_overlays_state = 'Off'
wrd.rp_decals_state = 'Off'
wrd.rp_sss_state = 'Off'
wrd.rp_hdr = False
wrd.rp_worldnodes = False
wrd.rp_world = False
wrd.rp_clearbackground = True
wrd.rp_stereo = False
wrd.rp_greasepencil = False
@ -252,15 +245,14 @@ def set_preset(self, context, preset):
wrd.rp_motionblur = 'None'
elif preset == 'Grease Pencil':
wrd.rp_renderer = 'Forward'
wrd.material_model = 'Restricted'
wrd.arm_material_model = 'Restricted'
wrd.rp_shadowmap = 'None'
wrd.rp_meshes = False
wrd.rp_translucency_state = 'Off'
wrd.rp_overlays_state = 'Off'
wrd.rp_decals_state = 'Off'
wrd.rp_sss_state = 'Off'
wrd.rp_hdr = False
wrd.rp_worldnodes = False
wrd.rp_world = False
wrd.rp_clearbackground = True
wrd.rp_stereo = False
wrd.rp_greasepencil = True
@ -288,7 +280,7 @@ def set_renderpath(self, context):
return
# assets.invalidate_compiled_data(self, context)
assets.invalidate_shader_cache(self, context)
make_renderer.make_renderer(bpy.data.worlds['Arm'])
make_renderer(bpy.data.worlds['Arm'])
bpy.data.worlds['Arm'].renderpath_path = 'armory_default'
def make_renderer(wrd):
@ -354,19 +346,16 @@ def make_forward(wrd):
links.new(nodes['Clear Target Mesh'].outputs[0], nodes['Draw Grease Pencil'].inputs[0])
links.new(nodes['Draw Grease Pencil'].outputs[0], nodes['Draw Meshes Mesh'].inputs[0])
if not wrd.rp_meshes:
relink('Draw Meshes Mesh', 'Draw World')
if not wrd.rp_worldnodes:
if not wrd.rp_world:
relink('Draw World', 'Set Target Accum')
if wrd.rp_clearbackground:
nodes['Clear Target Mesh'].inputs[1].default_value = True
if not wrd.rp_render_to_texture:
links.new(nodes['Framebuffer'].outputs[0], nodes['Set Target Mesh'].inputs[1])
if wrd.rp_worldnodes:
if wrd.rp_world:
l = nodes['Draw World'].outputs[0].links[0]
elif wrd.rp_greasepencil and not wrd.rp_meshes:
elif wrd.rp_greasepencil:
l = nodes['Draw Grease Pencil'].outputs[0].links[0]
else:
l = nodes['Draw Meshes Mesh'].outputs[0].links[0]
@ -409,7 +398,7 @@ def make_deferred(wrd):
n.inputs[2].default_value = res
links.new(nodes['Image 3D Voxels'].outputs[0], nodes['Deferred Indirect'].inputs[4])
wrd = bpy.data.worlds['Arm']
if wrd.voxelgi_shadows or wrd.voxelgi_refraction:
if wrd.arm_voxelgi_shadows or wrd.arm_voxelgi_refraction:
links.new(nodes['Image 3D Voxels'].outputs[0], nodes['Deferred Light'].inputs[4])
links.new(nodes['Image 3D Voxels'].outputs[0], nodes['Deferred Light.001'].inputs[4])
@ -437,7 +426,7 @@ def make_deferred(wrd):
l = nodes['Deferred Indirect'].inputs[3].links[0]
links.remove(l)
if not wrd.rp_worldnodes:
if not wrd.rp_world:
relink('Draw World', 'Water')
if wrd.rp_clearbackground:
nodes['Clear Target Mesh'].inputs[1].default_value = True
@ -457,7 +446,7 @@ def make_deferred(wrd):
if not wrd.rp_ssr:
relink('SSR', 'Draw Compositor')
if bpy.data.worlds['Arm'].generate_ssr_half_res:
if bpy.data.worlds['Arm'].arm_ssr_half_res:
links.new(nodes['ssra'].outputs[0], nodes['SSR'].inputs[2])
links.new(nodes['ssrb'].outputs[0], nodes['SSR'].inputs[3])

View file

@ -24,7 +24,7 @@ def build_node_trees(assets_path):
os.makedirs(arm.utils.build_dir() + '/compiled/Assets/renderpaths')
build_node_trees.assets_path = assets_path
if wrd.material_model != 'Restricted':
if wrd.arm_material_model != 'Restricted':
# Always include
assets.add(assets_path + 'brdf.png')
assets.add_embedded_data('brdf.png')
@ -136,7 +136,7 @@ def make_draw_meshes(stage, node_group, node):
context = node.inputs[1].default_value
# Store shadowmap size
if context == 'shadowmap':
bpy.data.worlds['Arm'].shadowmap_size = buildNode.last_set_target_w
bpy.data.worlds['Arm'].arm_shadowmap_size_cache = buildNode.last_set_target_w
stage['params'].append(context)
# Order
order = node.inputs[2].default_value
@ -236,19 +236,19 @@ def make_draw_compositor(stage, node_group, node, with_fxaa=False):
wrd = bpy.data.worlds['Arm']
world_defs = wrd.world_defs + wrd.rp_defs
compositor_defs = make_compositor.parse_defs(bpy.data.scenes[0].node_tree) # Thrown in scene 0 for now
compositor_defs += '_CTone' + wrd.generate_tonemap
compositor_defs += '_CTone' + wrd.arm_tonemap
# Additional compositor flags
compo_depth = False # Read depth
# compo_pos = False # Construct position from depth
if with_fxaa: # FXAA directly in compositor, useful for forward path
compositor_defs += '_CFXAA'
if wrd.generate_letterbox:
if wrd.arm_letterbox:
compositor_defs += '_CLetterbox'
if wrd.generate_grain:
if wrd.arm_grain:
compositor_defs += '_CGrain'
if bpy.data.scenes[0].cycles.film_exposure != 1.0:
compositor_defs += '_CExposure'
if wrd.generate_fog:
if wrd.arm_fog:
compositor_defs += '_CFog'
# compo_pos = True
if bpy.data.cameras[0].dof_distance > 0.0:
@ -260,14 +260,14 @@ def make_draw_compositor(stage, node_group, node, with_fxaa=False):
if compo_depth:
compositor_defs += '_CDepth'
if wrd.generate_lens_texture != '':
if wrd.arm_lens_texture != '':
compositor_defs += '_CLensTex'
assets.add_embedded_data('lenstexture.jpg')
if wrd.generate_fisheye:
if wrd.arm_fisheye:
compositor_defs += '_CFishEye'
if wrd.generate_vignette:
if wrd.arm_vignette:
compositor_defs += '_CVignette'
wrd.compo_defs = compositor_defs
@ -351,7 +351,7 @@ def make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices
stages.append(stage)
def make_ssao_pass(stages, node_group, node):
sc = 0.5 if bpy.data.worlds['Arm'].generate_ssao_half_res else 1.0
sc = 0.5 if bpy.data.worlds['Arm'].arm_ssao_half_res else 1.0
make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[3, 4], bind_target_constants=['gbufferD', 'gbuffer0'], shader_context='ssao_pass/ssao_pass/ssao_pass', viewport_scale=sc)
make_quad_pass(stages, node_group, node, target_index=2, bind_target_indices=[1, 4], bind_target_constants=['tex', 'gbuffer0'], shader_context='blur_edge_pass/blur_edge_pass/blur_edge_pass_x', viewport_scale=sc)
make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[2, 4], bind_target_constants=['tex', 'gbuffer0'], shader_context='blur_edge_pass/blur_edge_pass/blur_edge_pass_y')
@ -458,7 +458,7 @@ def make_water_pass(stages, node_group, node):
def make_deferred_light_pass(stages, node_group, node):
wrd = bpy.data.worlds['Arm']
if wrd.voxelgi_shadows or wrd.voxelgi_refraction:
if wrd.arm_voxelgi_shadows or wrd.arm_voxelgi_refraction:
make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[2, 3, 4], bind_target_constants=['gbuffer', 'shadowMap', 'voxels'], shader_context='', with_draw_quad=False)
else:
make_quad_pass(stages, node_group, node, target_index=1, bind_target_indices=[2, 3], bind_target_constants=['gbuffer', 'shadowMap'], shader_context='', with_draw_quad=False)
@ -752,14 +752,8 @@ def get_root_node(node_group):
if n.bl_idname == 'BeginNodeType':
# Store contexts
build_node_tree.wrd.renderpath_id = n.inputs[0].default_value
# TODO: deprecated
if len(n.inputs) > 5:
if n.inputs[5].default_value == False:
bpy.data.worlds['Arm'].rp_defs += '_LDR'
else:
if n.inputs[1].default_value == False:
bpy.data.worlds['Arm'].rp_defs += '_LDR'
if n.inputs[1].default_value == False:
bpy.data.worlds['Arm'].rp_defs += '_LDR'
rn = nodes.find_node_by_link_from(node_group, n, n.outputs[0])
break
return rn
@ -772,17 +766,10 @@ def preprocess_renderpath(root_node, node_group):
render_targets3D = []
depth_buffers = []
preprocess_renderpath.velocity_def_added = False
build_node_tree.wrd.renderpath_passes = ''
traverse_renderpath(root_node, node_group, render_targets, depth_buffers)
return render_targets, depth_buffers
def traverse_renderpath(node, node_group, render_targets, depth_buffers):
# Gather linked draw geometry contexts
if node.bl_idname == 'DrawMeshesNodeType':
if build_node_tree.wrd.renderpath_passes != '':
build_node_tree.wrd.renderpath_passes += '_' # Separator
build_node_tree.wrd.renderpath_passes += node.inputs[1].default_value
# Gather defs from linked nodes
if node.bl_idname == 'TAAPassNodeType' or node.bl_idname == 'MotionBlurVelocityPassNodeType' or node.bl_idname == 'SSAOReprojectPassNodeType':
if preprocess_renderpath.velocity_def_added == False:
@ -802,7 +789,7 @@ def traverse_renderpath(node, node_group, render_targets, depth_buffers):
bpy.data.worlds['Arm'].rp_defs += '_Hist'
elif node.bl_idname == 'SSAOPassNodeType' or node.bl_idname == 'ApplySSAOPassNodeType' or node.bl_idname == 'SSAOReprojectPassNodeType':
if bpy.data.worlds['Arm'].generate_ssao: # SSAO enabled
if bpy.data.worlds['Arm'].arm_ssao: # SSAO enabled
bpy.data.worlds['Arm'].rp_defs += '_SSAO'
elif node.bl_idname == 'DrawStereoNodeType':

View file

@ -53,37 +53,37 @@ def build_node_tree(world):
wrd.world_defs += '_EnvCol'
# Irradiance json file name
world.world_envtex_name = wname
world.world_envtex_irr_name = wname
write_probes.write_color_irradiance(wname, world.world_envtex_color)
world.arm_envtex_name = wname
world.arm_envtex_irr_name = wname
write_probes.write_color_irradiance(wname, world.arm_envtex_color)
# Clouds enabled
if wrd.generate_clouds:
if wrd.arm_clouds:
wrd.world_defs += '_EnvClouds'
# Percentage closer soft shadows
if wrd.generate_pcss_state == 'On':
if wrd.arm_pcss_state == 'On':
wrd.world_defs += '_PCSS'
sdk_path = arm.utils.get_sdk_path()
assets.add(sdk_path + 'armory/Assets/noise64.png')
assets.add_embedded_data('noise64.png')
# Screen-space ray-traced shadows
if wrd.generate_ssrs:
if wrd.arm_ssrs:
wrd.world_defs += '_SSRS'
if wrd.generate_two_sided_area_lamp:
if wrd.arm_two_sided_area_lamp:
wrd.world_defs += '_TwoSidedAreaLamp'
# Alternative models
if wrd.material_model == 'Cycles':
if wrd.arm_material_model == 'Cycles':
wrd.world_defs += '_Cycles'
# TODO: Lamp texture test..
if wrd.generate_lamp_texture != '':
if wrd.arm_lamp_texture != '':
bpy.data.worlds['Arm'].world_defs += '_LampColTex'
if wrd.generate_lamp_ies_texture != '':
if wrd.arm_lamp_ies_texture != '':
bpy.data.worlds['Arm'].world_defs += '_LampIES'
assets.add_embedded_data('iestexture.png')
@ -109,16 +109,16 @@ def build_node_tree(world):
if voxelgi:
assets.add_khafile_def('arm_voxelgi')
if wrd.voxelgi_revoxelize:
if wrd.arm_voxelgi_revoxelize:
assets.add_khafile_def('arm_voxelgi_revox')
if wrd.voxelgi_multibounce:
if wrd.arm_voxelgi_multibounce:
wrd.world_defs += '_VoxelGIMulti'
if wrd.voxelgi_camera:
if wrd.arm_voxelgi_camera:
wrd.world_defs += '_VoxelGICam'
if wrd.voxelgi_shadows:
if wrd.arm_voxelgi_shadows:
wrd.world_defs += '_VoxelGIDirect'
wrd.world_defs += '_VoxelGIShadow'
if wrd.voxelgi_refraction:
if wrd.arm_voxelgi_refraction:
wrd.world_defs += '_VoxelGIDirect'
wrd.world_defs += '_VoxelGIRefract'
wrd.world_defs += '_VoxelGI'
@ -167,7 +167,7 @@ def parse_surface(world, node, context):
if node.type == 'BACKGROUND':
# Append irradiance define
if wrd.generate_irradiance:
if wrd.arm_irradiance:
bpy.data.worlds['Arm'].world_defs += '_Irr'
# Strength
@ -182,8 +182,8 @@ def parse_surface(world, node, context):
parse_color(world, color_node, context, envmap_strength_const)
# Cache results
world.world_envtex_color = node.inputs[0].default_value
world.world_envtex_strength = envmap_strength_const['float']
world.arm_envtex_color = node.inputs[0].default_value
world.arm_envtex_strength = envmap_strength_const['float']
def parse_color(world, node, context, envmap_strength_const):
wrd = bpy.data.worlds['Arm']
@ -252,14 +252,14 @@ def parse_color(world, node, context, envmap_strength_const):
assets.add(arm.utils.asset_path(image.filepath))
# Generate prefiltered envmaps
world.world_envtex_name = tex['file']
world.world_envtex_irr_name = tex['file'].rsplit('.', 1)[0]
world.arm_envtex_name = tex['file']
world.arm_envtex_irr_name = tex['file'].rsplit('.', 1)[0]
disable_hdr = target_format == 'JPEG'
mip_count = world.world_envtex_num_mips
mip_count = write_probes.write_probes(filepath, disable_hdr, mip_count, generate_radiance=wrd.generate_radiance)
mip_count = world.arm_envtex_num_mips
mip_count = write_probes.write_probes(filepath, disable_hdr, mip_count, arm_radiance=wrd.arm_radiance)
world.world_envtex_num_mips = mip_count
world.arm_envtex_num_mips = mip_count
# Append envtex define
bpy.data.worlds['Arm'].world_defs += '_EnvTex'
@ -267,7 +267,7 @@ def parse_color(world, node, context, envmap_strength_const):
if disable_hdr:
bpy.data.worlds['Arm'].world_defs += '_EnvLDR'
# Append radiance define
if wrd.generate_irradiance and wrd.generate_radiance:
if wrd.arm_irradiance and wrd.arm_radiance:
bpy.data.worlds['Arm'].world_defs += '_Rad'
# Static image background
@ -316,20 +316,20 @@ def parse_color(world, node, context, envmap_strength_const):
const['vec3'] = list(sun_direction)
context['bind_constants'].append(const)
world.world_envtex_sun_direction = sun_direction
world.world_envtex_turbidity = node.turbidity
world.world_envtex_ground_albedo = node.ground_albedo
world.arm_envtex_sun_direction = sun_direction
world.arm_envtex_turbidity = node.turbidity
world.arm_envtex_ground_albedo = node.ground_albedo
# Irradiance json file name
wname = arm.utils.safestr(world.name)
world.world_envtex_irr_name = wname
world.arm_envtex_irr_name = wname
write_probes.write_sky_irradiance(wname)
# Radiance
if wrd.generate_radiance_sky and wrd.generate_radiance and wrd.generate_irradiance:
if wrd.arm_radiance_sky and wrd.arm_radiance and wrd.arm_irradiance:
bpy.data.worlds['Arm'].world_defs += '_Rad'
if wrd.generate_radiance_sky_type == 'Hosek':
if wrd.arm_radiance_sky_type == 'Hosek':
hosek_path = 'armory/Assets/hosek/'
else:
hosek_path = 'armory/Assets/hosek_fake/'
@ -340,5 +340,5 @@ def parse_color(world, node, context, envmap_strength_const):
for i in range(0, 8):
assets.add(sdk_path + hosek_path + 'hosek_radiance_' + str(i) + '.hdr')
world.world_envtex_name = 'hosek'
world.world_envtex_num_mips = 8
world.arm_envtex_name = 'hosek'
world.arm_envtex_num_mips = 8

View file

@ -915,7 +915,7 @@ def parse_normal_map_color_input(inp):
frag.write_pre = True
parse_teximage_vector = False # Force texCoord for normal map image vector
defplus = c_state.get_rp_renderer() == 'Deferred Plus'
if not c_state.get_arm_export_tangents() or defplus or c_state.mat_get_material().decal: # Compute TBN matrix
if not c_state.get_arm_export_tangents() or defplus or c_state.mat_get_material().arm_decal: # Compute TBN matrix
frag.write('vec3 texn = ({0}) * 2.0 - 1.0;'.format(parse_vector_input(inp)))
frag.add_include('../../Shaders/std/normals.glsl')
if defplus:

View file

@ -42,7 +42,7 @@ def parse(material, mat_data, mat_users, mat_armusers, rid):
if rp == 'mesh':
const = {}
const['name'] = 'receiveShadow'
const['bool'] = material.receive_shadow
const['bool'] = material.arm_receive_shadow
c['bind_constants'].append(const)
if bpy.data.worlds['Arm'].rp_sss_state == 'On':
@ -90,7 +90,7 @@ def parse(material, mat_data, mat_users, mat_armusers, rid):
elif rp == 'translucent':
const = {}
const['name'] = 'receiveShadow'
const['bool'] = material.receive_shadow
const['bool'] = material.arm_receive_shadow
c['bind_constants'].append(const)
mat_data['shader'] = shader_data_name + '/' + shader_data_name

View file

@ -16,7 +16,7 @@ def make(context_id, rid):
con_mesh = mat_state.data.add_context({ 'name': context_id, 'depth_write': True, 'compare_mode': 'less', 'cull_mode': 'clockwise' })
if rid == 'forward':
if bpy.data.worlds['Arm'].material_model != 'Restricted':
if bpy.data.worlds['Arm'].arm_material_model != 'Restricted':
make_forward(con_mesh)
else:
make_forward_restricted(con_mesh)
@ -101,7 +101,7 @@ def make_base(con_mesh, parse_opacity):
const = {}
const['name'] = 'tessLevel'
const['vec2'] = [mat_state.material.height_tess_inner, mat_state.material.height_tess_outer]
const['vec2'] = [mat_state.material.arm_tess_inner, mat_state.material.arm_tess_outer]
mat_state.bind_constants.append(const)
tesc.add_uniform('vec2 tessLevel')
make_tess.tesc_levels(tesc)
@ -205,8 +205,8 @@ def write_norpos(con_mesh, vert, declare=False):
def make_deferred(con_mesh):
wrd = bpy.data.worlds['Arm']
discard_transparent = mat_state.material.discard_transparent
parse_opacity = discard_transparent or wrd.voxelgi_refraction
arm_discard = mat_state.material.arm_discard
parse_opacity = arm_discard or wrd.arm_voxelgi_refraction
make_base(con_mesh, parse_opacity=parse_opacity)
@ -214,8 +214,8 @@ def make_deferred(con_mesh):
vert = con_mesh.vert
tese = con_mesh.tese
if discard_transparent:
opac = mat_state.material.discard_transparent_opacity
if arm_discard:
opac = mat_state.material.arm_discard_transpa
frag.write('if (opacity < {0}) discard;'.format(opac))
gapi = arm.utils.get_gapi()
@ -247,7 +247,7 @@ def make_deferred(con_mesh):
# Pack gbuffer
frag.add_include('../../Shaders/std/gbuffer.glsl')
if mat_state.material.two_sided_shading:
if mat_state.material.arm_two_sided:
frag.add_uniform('vec3 v', link='_cameraLook')
frag.write('if (dot(n, v) > 0.0) n = -n;')
@ -261,7 +261,7 @@ def make_deferred(con_mesh):
if '_SSS' in wrd.rp_defs:
frag.add_uniform('int materialID')
frag.write('fragColor[1] = vec4(basecol.rgb, materialID + clamp(occlusion, 0.0, 1.0 - 0.001));')
elif wrd.voxelgi_refraction:
elif wrd.arm_voxelgi_refraction:
frag.write('fragColor[1] = vec4(basecol.rgb, opacity);')
else:
frag.write('fragColor[1] = vec4(basecol.rgb, occlusion);')

View file

@ -9,7 +9,7 @@ import arm.utils
def make(context_id, rpasses):
is_disp = mat_utils.disp_linked(mat_state.output_node) and mat_state.material.height_tess_shadows
is_disp = mat_utils.disp_linked(mat_state.output_node) and mat_state.material.arm_tess_shadows
vs = [{'name': 'pos', 'size': 3}]
if is_disp:
@ -28,7 +28,7 @@ def make(context_id, rpasses):
frag.add_out('vec4 fragColor') # Definition requred for d3d9 - pixel shader must minimally write all four components of COLOR0
vert.write_main_header('vec4 spos = vec4(pos, 1.0);')
parse_opacity = 'translucent' in rpasses or mat_state.material.discard_transparent
parse_opacity = 'translucent' in rpasses or mat_state.material.arm_discard
if parse_opacity:
frag.write('vec3 n;') # Discard at compile time
frag.write('float dotNV;')
@ -56,7 +56,7 @@ def make(context_id, rpasses):
const = {}
const['name'] = 'tessLevel'
const['vec2'] = [mat_state.material.height_tess_shadows_inner, mat_state.material.height_tess_shadows_outer]
const['vec2'] = [mat_state.material.arm_tess_shadows_inner, mat_state.material.arm_tess_shadows_outer]
mat_state.bind_constants.append(const)
tesc.add_uniform('vec2 tessLevel')
make_tess.tesc_levels(tesc)
@ -124,7 +124,7 @@ def make(context_id, rpasses):
vert.write('vec2 t2 = tex; // TODO: Temp for d3d')
if parse_opacity:
opac = mat_state.material.discard_transparent_opacity_shadows
opac = mat_state.material.arm_discard_opacity_shadows
frag.write('if (opacity < {0}) discard;'.format(opac))
# frag.write('fragColor = vec4(0.0);')

View file

@ -87,7 +87,7 @@ def make(image_node, tex_name, matname=None):
# tex['format'] = image_format
interpolation = image_node.interpolation
texfilter = wrd.texture_filtering_state
texfilter = wrd.arm_texture_filter
if texfilter == 'Anisotropic':
interpolation = 'Smart'
elif texfilter == 'Linear':

View file

@ -60,7 +60,7 @@ def make(context_id):
frag.write('float roughness;') #
frag.write('float metallic;') #
frag.write('float occlusion;') #
parse_opacity = wrd.voxelgi_refraction
parse_opacity = wrd.arm_voxelgi_refraction
if parse_opacity:
frag.write('float opacity;')
frag.write_pre = True
@ -75,7 +75,7 @@ def make(context_id):
frag.write('vec3 n;')
frag.write_pre = False
if wrd.voxelgi_camera:
if wrd.arm_voxelgi_camera:
vert.add_uniform('vec3 eye', '_cameraPosition')
vert.add_uniform('mat4 W', '_worldMatrix')
vert.add_uniform('mat3 N', '_normalMatrix')
@ -89,7 +89,7 @@ def make(context_id):
vert.add_out('vec2 texCoordGeom')
vert.write('texCoordGeom = tex;')
if wrd.voxelgi_camera:
if wrd.arm_voxelgi_camera:
vert.write('const float step = voxelgiDimensions / voxelgiResolution;') # TODO: Pass as uniform
vert.write('vec3 eyeSnap = ivec3(eye / step) * step;') # TODO: Pass as uniform
vert.write('wpositionGeom = (vec3(W * vec4(pos, 1.0)) - eyeSnap) / voxelgiDimensions;')
@ -139,7 +139,7 @@ def make(context_id):
frag.write('vec3 color = basecol * visibility * lightColor * dotNL * attenuate(distance(wposition * voxelgiDimensions, lightPos));')
frag.write('vec3 voxel = wposition * 0.5 + vec3(0.5);')
if wrd.material_model == 'Cycles':
if wrd.arm_material_model == 'Cycles':
frag.write('color = min(color * 0.9, vec3(0.9)) + min(color / 200.0, 0.1);') # Higher range to allow emission
# if bpy.data.worlds['Arm'].rp_voxelgi_hdr:

View file

@ -25,12 +25,11 @@ def get_signature(mat):
if output_node != None:
sign = traverse_tree(output_node, '')
# Append flags
sign += '1' if mat.cast_shadow else '0'
sign += '1' if mat.overlay else '0'
sign += '1' if mat.override_cull_mode == 'Clockwise' else '0'
sign += '1' if mat.height_tess else '0'
sign += '1' if mat.height_tess_shadows else '0'
sign += '1' if mat.transluc_shadows else '0'
sign += '1' if mat.arm_cast_shadow else '0'
sign += '1' if mat.arm_overlay else '0'
sign += '1' if mat.arm_cull_mode == 'Clockwise' else '0'
sign += '1' if mat.arm_tess else '0'
sign += '1' if mat.arm_tess_shadows else '0'
return sign
def traverse_tree2(node, ar):

View file

@ -27,13 +27,13 @@ def get_rpasses(material):
# ar.append('depth')
wrd = bpy.data.worlds['Arm']
vgirefract = wrd.rp_voxelgi and wrd.voxelgi_refraction
vgirefract = wrd.rp_voxelgi and wrd.arm_voxelgi_refraction
if material.decal:
ar.append('decal')
elif material.overlay:
ar.append('overlay')
elif is_transluc(material) and not material.discard_transparent and not vgirefract:
if material.arm_decal:
ar.append('arm_decal')
elif material.arm_overlay:
ar.append('arm_overlay')
elif is_transluc(material) and not material.arm_discard and not vgirefract:
ar.append('translucent')
else:
ar.append('mesh')
@ -41,7 +41,7 @@ def get_rpasses(material):
ar.append(con)
if wrd.rp_voxelgi:
ar.append('voxel')
if wrd.voxelgi_multibounce:
if wrd.arm_voxelgi_multibounce:
ar.append('voxelbounce')
if wrd.rp_renderer == 'Deferred Plus':
ar.append('rect')
@ -53,7 +53,7 @@ def get_rpasses(material):
shadows_enabled = True
# break
if material.cast_shadow and shadows_enabled and ('mesh' in ar or 'translucent' in ar):
if material.arm_cast_shadow and shadows_enabled and ('mesh' in ar or 'translucent' in ar):
ar.append('shadowmap')
return ar

View file

@ -2,7 +2,7 @@ import bpy
from bpy.props import *
import os
import shutil
from arm.props_traits_library import *
from arm.props_library import *
import arm.props_ui as props_ui
import arm.assets as assets
import arm.log as log
@ -15,7 +15,7 @@ except ImportError:
pass
# Armory version
arm_version = '17.08'
arm_version = '17.08.1'
def update_preset(self, context):
make_renderer.set_preset(self, context, self.rp_preset)
@ -66,7 +66,7 @@ def update_sss_state(self, context):
def invalidate_mesh_cache(self, context):
if context.object == None or context.object.data == None:
return
context.object.data.mesh_cached = False
context.object.data.arm_cached = False
def invalidate_instance_cache(self, context):
if context.object == None or context.object.data == None:
@ -139,8 +139,6 @@ def init_properties():
name="Target", default='html5', description='Build paltform')
bpy.types.World.arm_project_name = StringProperty(name="Name", description="Exported project name", default="")
bpy.types.World.arm_project_package = StringProperty(name="Package", description="Package name for scripts", default="arm")
bpy.types.World.arm_librarylist = bpy.props.CollectionProperty(type=ListLibraryTraitItem)
bpy.types.World.arm_librarylist_index = bpy.props.IntProperty(name="Library index", default=0)
bpy.types.World.arm_play_active_scene = BoolProperty(name="Play Active Scene", description="Load currently edited scene when launching player", default=True)
bpy.types.World.arm_project_scene = StringProperty(name="Scene", description="Scene to load when launching player")
bpy.types.World.arm_samples_per_pixel = EnumProperty(
@ -187,7 +185,8 @@ def init_properties():
bpy.types.World.arm_play_camera = EnumProperty(
items=[('Scene', 'Scene', 'Scene'),
('Viewport', 'Viewport', 'Viewport'),
('Viewport Shared', 'Viewport Shared', 'Viewport Shared')],
# ('Viewport Shared', 'Viewport Shared', 'Viewport Shared')
],
name="Camera", description="Viewport camera", default='Scene')
bpy.types.World.arm_play_console = BoolProperty(name="Debug Console", description="Show inspector in player", default=False)
bpy.types.World.arm_play_runtime = EnumProperty(
@ -255,45 +254,43 @@ def init_properties():
# bpy.types.Object.arm_instanced_scale_x = bpy.props.BoolProperty(name="X", default=False)
# bpy.types.Object.arm_instanced_scale_y = bpy.props.BoolProperty(name="Y", default=False)
# bpy.types.Object.arm_instanced_scale_z = bpy.props.BoolProperty(name="Z", default=False)
bpy.types.Object.game_export = bpy.props.BoolProperty(name="Export", description="Export object data", default=True)
bpy.types.Object.spawn = bpy.props.BoolProperty(name="Spawn", description="Auto-add this object when creating scene", default=True)
bpy.types.Object.mobile = bpy.props.BoolProperty(name="Mobile", description="Object moves during gameplay", default=True)
bpy.types.Object.soft_body_margin = bpy.props.FloatProperty(name="Soft Body Margin", description="Collision margin", default=0.04)
bpy.types.Object.bone_animation_enabled = bpy.props.BoolProperty(name="Animation", description="Enable skinning", default=True)
bpy.types.Object.object_animation_enabled = bpy.props.BoolProperty(name="Animation", description="Enable timeline animation", default=True)
bpy.types.Object.arm_export = bpy.props.BoolProperty(name="Export", description="Export object data", default=True)
bpy.types.Object.arm_spawn = bpy.props.BoolProperty(name="Spawn", description="Auto-add this object when creating scene", default=True)
bpy.types.Object.arm_mobile = bpy.props.BoolProperty(name="Mobile", description="Object moves during gameplay", default=True)
bpy.types.Object.arm_soft_body_margin = bpy.props.FloatProperty(name="Soft Body Margin", description="Collision margin", default=0.04)
bpy.types.Object.arm_animation_enabled = bpy.props.BoolProperty(name="Animation", description="Enable skinning & timeline animation", default=True)
# For speakers
bpy.types.Speaker.loop = bpy.props.BoolProperty(name="Loop", description="Loop this sound", default=False)
bpy.types.Speaker.stream = bpy.props.BoolProperty(name="Stream", description="Stream this sound", default=False)
bpy.types.Speaker.arm_loop = bpy.props.BoolProperty(name="Loop", description="Loop this sound", default=False)
bpy.types.Speaker.arm_stream = bpy.props.BoolProperty(name="Stream", description="Stream this sound", default=False)
# For mesh
bpy.types.Mesh.mesh_cached = bpy.props.BoolProperty(name="Mesh Cached", description="No need to reexport mesh data", default=False)
bpy.types.Mesh.mesh_cached_verts = bpy.props.IntProperty(name="Last Verts", description="Number of vertices in last export", default=0)
bpy.types.Mesh.mesh_cached_edges = bpy.props.IntProperty(name="Last Edges", description="Number of edges in last export", default=0)
bpy.types.Mesh.mesh_aabb = bpy.props.FloatVectorProperty(name="AABB", size=3, default=[0,0,0])
bpy.types.Mesh.dynamic_usage = bpy.props.BoolProperty(name="Dynamic Usage", description="Mesh data can change at runtime", default=False)
bpy.types.Mesh.data_compressed = bpy.props.BoolProperty(name="Compress Data", description="Pack data into zip file", default=False)
bpy.types.Mesh.sdfgen = bpy.props.BoolProperty(name="Generate SDF", description="Make signed distance field data", default=False, update=invalidate_mesh_cache)
bpy.types.Curve.mesh_cached = bpy.props.BoolProperty(name="Mesh Cached", description="No need to reexport curve data", default=False)
bpy.types.Curve.data_compressed = bpy.props.BoolProperty(name="Compress Data", description="Pack data into zip file", default=False)
bpy.types.Curve.dynamic_usage = bpy.props.BoolProperty(name="Dynamic Data Usage", description="Curve data can change at runtime", default=False)
bpy.types.MetaBall.mesh_cached = bpy.props.BoolProperty(name="Mesh Cached", description="No need to reexport metaball data", default=False)
bpy.types.MetaBall.data_compressed = bpy.props.BoolProperty(name="Compress Data", description="Pack data into zip file", default=False)
bpy.types.MetaBall.dynamic_usage = bpy.props.BoolProperty(name="Dynamic Data Usage", description="Metaball data can change at runtime", default=False)
bpy.types.Mesh.arm_cached = bpy.props.BoolProperty(name="Mesh Cached", description="No need to reexport mesh data", default=False)
bpy.types.Mesh.arm_cached_verts = bpy.props.IntProperty(name="Last Verts", description="Number of vertices in last export", default=0)
bpy.types.Mesh.arm_cached_edges = bpy.props.IntProperty(name="Last Edges", description="Number of edges in last export", default=0)
bpy.types.Mesh.arm_aabb = bpy.props.FloatVectorProperty(name="AABB", size=3, default=[0,0,0])
bpy.types.Mesh.arm_dynamic_usage = bpy.props.BoolProperty(name="Dynamic Usage", description="Mesh data can change at runtime", default=False)
bpy.types.Mesh.arm_compress = bpy.props.BoolProperty(name="Compress", description="Pack data into zip file", default=False)
bpy.types.Mesh.arm_sdfgen = bpy.props.BoolProperty(name="Generate SDF", description="Make signed distance field data", default=False, update=invalidate_mesh_cache)
bpy.types.Curve.arm_cached = bpy.props.BoolProperty(name="Mesh Cached", description="No need to reexport curve data", default=False)
bpy.types.Curve.arm_compress = bpy.props.BoolProperty(name="Compress", description="Pack data into zip file", default=False)
bpy.types.Curve.arm_dynamic_usage = bpy.props.BoolProperty(name="Dynamic Data Usage", description="Curve data can change at runtime", default=False)
bpy.types.MetaBall.arm_cached = bpy.props.BoolProperty(name="Mesh Cached", description="No need to reexport metaball data", default=False)
bpy.types.MetaBall.arm_compress = bpy.props.BoolProperty(name="Compress", description="Pack data into zip file", default=False)
bpy.types.MetaBall.arm_dynamic_usage = bpy.props.BoolProperty(name="Dynamic Data Usage", description="Metaball data can change at runtime", default=False)
# For grease pencil
bpy.types.GreasePencil.data_cached = bpy.props.BoolProperty(name="GP Cached", description="No need to reexport grease pencil data", default=False)
bpy.types.GreasePencil.data_compressed = bpy.props.BoolProperty(name="Compress Data", description="Pack data into zip file", default=True)
bpy.types.GreasePencil.arm_data_cached = bpy.props.BoolProperty(name="GP Cached", description="No need to reexport grease pencil data", default=False)
bpy.types.GreasePencil.arm_compress = bpy.props.BoolProperty(name="Compress", description="Pack data into zip file", default=True)
# For armature
bpy.types.Armature.data_cached = bpy.props.BoolProperty(name="Armature Cached", description="No need to reexport armature data", default=False)
bpy.types.Armature.data_compressed = bpy.props.BoolProperty(name="Compress Data", description="Pack data into zip file", default=False)
bpy.types.Armature.arm_data_cached = bpy.props.BoolProperty(name="Armature Cached", description="No need to reexport armature data", default=False)
bpy.types.Armature.arm_compress = bpy.props.BoolProperty(name="Compress", description="Pack data into zip file", default=False)
# For camera
bpy.types.Camera.frustum_culling = bpy.props.BoolProperty(name="Frustum Culling", description="Perform frustum culling for this camera", default=True)
bpy.types.Camera.is_mirror = bpy.props.BoolProperty(name="Mirror", description="Render this camera into texture", default=False)
bpy.types.Camera.mirror_resolution_x = bpy.props.FloatProperty(name="X", default=512.0)
bpy.types.Camera.mirror_resolution_y = bpy.props.FloatProperty(name="Y", default=256.0)
bpy.types.Camera.arm_frustum_culling = bpy.props.BoolProperty(name="Frustum Culling", description="Perform frustum culling for this camera", default=True)
bpy.types.Camera.arm_render_to_texture = bpy.props.BoolProperty(name="Render to Texture", description="Render this camera into texture", default=False)
bpy.types.Camera.arm_texture_resolution_x = bpy.props.FloatProperty(name="X", default=512.0)
bpy.types.Camera.arm_texture_resolution_y = bpy.props.FloatProperty(name="Y", default=256.0)
bpy.types.World.renderpath_path = bpy.props.StringProperty(name="Render Path", description="Render path nodes", default="armory_default", update=assets.invalidate_shader_cache)
bpy.types.World.renderpath_id = bpy.props.StringProperty(name="Render Path ID", description="Asset ID", default="deferred")
bpy.types.World.renderpath_passes = bpy.props.StringProperty(name="Render Path Passes", description="Referenced render passes", default="")
# Render path generator
bpy.types.World.rp_preset = EnumProperty(
items=[('Low', 'Low', 'Low'),
@ -314,12 +311,11 @@ def init_properties():
],
name="Renderer", description="Renderer type", default='Deferred', update=update_renderpath)
bpy.types.World.rp_depthprepass = bpy.props.BoolProperty(name="Depth Prepass", description="Depth Prepass for mesh context", default=False, update=update_renderpath)
bpy.types.World.rp_meshes = bpy.props.BoolProperty(name="Meshes", description="Render mesh objects", default=True, update=update_renderpath)
bpy.types.World.rp_hdr = bpy.props.BoolProperty(name="HDR", description="Render in HDR Space", default=True, update=update_renderpath)
bpy.types.World.rp_render_to_texture = bpy.props.BoolProperty(name="Post Process", description="Render scene to texture for further processing", default=True, update=update_renderpath)
bpy.types.World.rp_worldnodes = bpy.props.BoolProperty(name="World Nodes", description="Draw world nodes", default=True, update=update_renderpath)
bpy.types.World.rp_clearbackground = bpy.props.BoolProperty(name="Clear Background", description="Clear background with solid color", default=False, update=update_renderpath)
bpy.types.World.rp_compositornodes = bpy.props.BoolProperty(name="Compositor Nodes", description="Draw compositor nodes", default=True, update=update_renderpath)
bpy.types.World.rp_world = bpy.props.BoolProperty(name="World", description="Draw world nodes", default=True, update=update_renderpath)
bpy.types.World.rp_clearbackground = bpy.props.BoolProperty(name="Clear", description="Clear background with solid color", default=False, update=update_renderpath)
bpy.types.World.rp_compositornodes = bpy.props.BoolProperty(name="Compositor", description="Draw compositor nodes", default=True, update=update_renderpath)
bpy.types.World.rp_shadowmap = EnumProperty(
items=[('None', 'None', 'None'),
('512', '512', '512'),
@ -394,195 +390,179 @@ def init_properties():
('512', '512', '512')],
name="Resolution", description="3D texture resolution", default='128', update=update_renderpath)
bpy.types.World.rp_voxelgi_hdr = bpy.props.BoolProperty(name="HDR", description="Store voxels in RGBA64 instead of RGBA32", default=False, update=update_renderpath)
bpy.types.World.generate_voxelgi_dimensions = bpy.props.FloatProperty(name="Dimensions", description="Voxelization bounds",default=16, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_revoxelize = bpy.props.BoolProperty(name="Revoxelize", description="Revoxelize scene each frame", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_multibounce = bpy.props.BoolProperty(name="Multi-bounce", description="Accumulate multiple light bounces", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_camera = bpy.props.BoolProperty(name="Camera", description="Use camera as voxelization origin", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_anisotropic = bpy.props.BoolProperty(name="Anisotropic", description="Use anisotropic voxels", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_shadows = bpy.props.BoolProperty(name="Shadows", description="Use voxels to render shadows", default=False, update=update_renderpath)
bpy.types.World.voxelgi_refraction = bpy.props.BoolProperty(name="Refraction", description="Use voxels to render refraction", default=False, update=update_renderpath)
bpy.types.World.voxelgi_diff = bpy.props.FloatProperty(name="Diffuse", description="", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_spec = bpy.props.FloatProperty(name="Specular", description="", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_occ = bpy.props.FloatProperty(name="Occlussion", description="", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_env = bpy.props.FloatProperty(name="Env Map", description="Contribute light from environment map", default=0.0, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_step = bpy.props.FloatProperty(name="Step", description="Step size", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.voxelgi_range = bpy.props.FloatProperty(name="Range", description="Maximum range", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.sss_width = bpy.props.FloatProperty(name="SSS Width", description="SSS blur strength", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_voxelgi_dimensions = bpy.props.FloatProperty(name="Dimensions", description="Voxelization bounds",default=16, update=assets.invalidate_shader_cache)
bpy.types.World.arm_voxelgi_revoxelize = bpy.props.BoolProperty(name="Revoxelize", description="Revoxelize scene each frame", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.arm_voxelgi_multibounce = bpy.props.BoolProperty(name="Multi-bounce", description="Accumulate multiple light bounces", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.arm_voxelgi_camera = bpy.props.BoolProperty(name="Camera", description="Use camera as voxelization origin", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.arm_voxelgi_anisotropic = bpy.props.BoolProperty(name="Anisotropic", description="Use anisotropic voxels", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.arm_voxelgi_shadows = bpy.props.BoolProperty(name="Shadows", description="Use voxels to render shadows", default=False, update=update_renderpath)
bpy.types.World.arm_voxelgi_refraction = bpy.props.BoolProperty(name="Refraction", description="Use voxels to render refraction", default=False, update=update_renderpath)
bpy.types.World.arm_voxelgi_diff = bpy.props.FloatProperty(name="Diffuse", description="", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_voxelgi_spec = bpy.props.FloatProperty(name="Specular", description="", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_voxelgi_occ = bpy.props.FloatProperty(name="Occlussion", description="", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_voxelgi_env = bpy.props.FloatProperty(name="Env Map", description="Contribute light from environment map", default=0.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_voxelgi_step = bpy.props.FloatProperty(name="Step", description="Step size", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_voxelgi_range = bpy.props.FloatProperty(name="Range", description="Maximum range", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_sss_width = bpy.props.FloatProperty(name="SSS Width", description="SSS blur strength", default=1.0, update=assets.invalidate_shader_cache)
# For world
bpy.types.World.world_envtex_name = bpy.props.StringProperty(name="Environment Texture", default='')
bpy.types.World.world_envtex_irr_name = bpy.props.StringProperty(name="Environment Irradiance", default='')
bpy.types.World.world_envtex_num_mips = bpy.props.IntProperty(name="Number of mips", default=0)
bpy.types.World.world_envtex_color = bpy.props.FloatVectorProperty(name="Environment Color", size=4, default=[0,0,0,1])
bpy.types.World.world_envtex_strength = bpy.props.FloatProperty(name="Environment Strength", default=1.0)
bpy.types.World.world_envtex_sun_direction = bpy.props.FloatVectorProperty(name="Sun Direction", size=3, default=[0,0,0])
bpy.types.World.world_envtex_turbidity = bpy.props.FloatProperty(name="Turbidity", default=1.0)
bpy.types.World.world_envtex_ground_albedo = bpy.props.FloatProperty(name="Ground Albedo", default=0.0)
bpy.types.World.world_defs = bpy.props.StringProperty(name="World Shader Defs", default='')
bpy.types.World.rp_defs = bpy.props.StringProperty(name="Render Path Shader Defs", default='')
bpy.types.World.compo_defs = bpy.props.StringProperty(name="Compositor Shader Defs", default='')
bpy.types.World.generate_irradiance = bpy.props.BoolProperty(name="Irradiance", description="Generate spherical harmonics", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.generate_radiance = bpy.props.BoolProperty(name="Radiance", description="Generate radiance textures", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.generate_radiance_size = EnumProperty(
bpy.types.World.arm_envtex_name = bpy.props.StringProperty(name="Environment Texture", default='')
bpy.types.World.arm_envtex_irr_name = bpy.props.StringProperty(name="Environment Irradiance", default='')
bpy.types.World.arm_envtex_num_mips = bpy.props.IntProperty(name="Number of mips", default=0)
bpy.types.World.arm_envtex_color = bpy.props.FloatVectorProperty(name="Environment Color", size=4, default=[0,0,0,1])
bpy.types.World.arm_envtex_strength = bpy.props.FloatProperty(name="Environment Strength", default=1.0)
bpy.types.World.arm_envtex_sun_direction = bpy.props.FloatVectorProperty(name="Sun Direction", size=3, default=[0,0,0])
bpy.types.World.arm_envtex_turbidity = bpy.props.FloatProperty(name="Turbidity", default=1.0)
bpy.types.World.arm_envtex_ground_albedo = bpy.props.FloatProperty(name="Ground Albedo", default=0.0)
bpy.types.World.arm_irradiance = bpy.props.BoolProperty(name="Irradiance", description="Generate spherical harmonics", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.arm_radiance = bpy.props.BoolProperty(name="Radiance", description="Generate radiance textures", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.arm_radiance_size = EnumProperty(
items=[('512', '512', '512'),
('1024', '1024', '1024'),
('2048', '2048', '2048')],
name="", description="Prefiltered map size", default='1024', update=assets.invalidate_envmap_data)
bpy.types.World.generate_radiance_sky = bpy.props.BoolProperty(name="Sky Radiance", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.generate_radiance_sky_type = EnumProperty(
bpy.types.World.arm_radiance_sky = bpy.props.BoolProperty(name="Sky Radiance", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.arm_radiance_sky_type = EnumProperty(
items=[('Fake', 'Fake', 'Fake'),
('Hosek', 'Hosek', 'Hosek')],
name="", description="Prefiltered maps to be used for radiance", default='Hosek', update=assets.invalidate_envmap_data)
bpy.types.World.generate_clouds = bpy.props.BoolProperty(name="Clouds", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.generate_clouds_density = bpy.props.FloatProperty(name="Density", default=0.5, min=0.0, max=10.0, update=assets.invalidate_shader_cache)
bpy.types.World.generate_clouds_size = bpy.props.FloatProperty(name="Size", default=1.0, min=0.0, max=10.0, update=assets.invalidate_shader_cache)
bpy.types.World.generate_clouds_lower = bpy.props.FloatProperty(name="Lower", default=2.0, min=1.0, max=10.0, update=assets.invalidate_shader_cache)
bpy.types.World.generate_clouds_upper = bpy.props.FloatProperty(name="Upper", default=3.5, min=1.0, max=10.0, update=assets.invalidate_shader_cache)
bpy.types.World.generate_clouds_wind = bpy.props.FloatVectorProperty(name="Wind", default=[0.2, 0.06], size=2, update=assets.invalidate_shader_cache)
bpy.types.World.generate_clouds_secondary = bpy.props.FloatProperty(name="Secondary", default=0.0, min=0.0, max=10.0, update=assets.invalidate_shader_cache)
bpy.types.World.generate_clouds_precipitation = bpy.props.FloatProperty(name="Precipitation", default=1.0, min=0.0, max=2.0, update=assets.invalidate_shader_cache)
bpy.types.World.generate_clouds_eccentricity = bpy.props.FloatProperty(name="Eccentricity", default=0.6, min=0.0, max=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.shadowmap_size = bpy.props.IntProperty(name="Shadowmap Size", default=0, update=assets.invalidate_shader_cache)
bpy.types.World.scripts_list = bpy.props.CollectionProperty(type=bpy.types.PropertyGroup)
bpy.types.World.bundled_scripts_list = bpy.props.CollectionProperty(type=bpy.types.PropertyGroup)
bpy.types.World.canvas_list = bpy.props.CollectionProperty(type=bpy.types.PropertyGroup)
bpy.types.World.generate_ocean = bpy.props.BoolProperty(name="Ocean", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ocean_base_color = bpy.props.FloatVectorProperty(name="Base Color", size=3, default=[0.1, 0.19, 0.37], subtype='COLOR', min=0, max=1, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ocean_water_color = bpy.props.FloatVectorProperty(name="Water Color", size=3, default=[0.6, 0.7, 0.9], subtype='COLOR', min=0, max=1, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ocean_level = bpy.props.FloatProperty(name="Level", default=0.0, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ocean_amplitude = bpy.props.FloatProperty(name="Amplitude", default=2.5, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ocean_height = bpy.props.FloatProperty(name="Height", default=0.6, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ocean_choppy = bpy.props.FloatProperty(name="Choppy", default=4.0, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ocean_speed = bpy.props.FloatProperty(name="Speed", default=1.5, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ocean_freq = bpy.props.FloatProperty(name="Freq", default=0.16, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ocean_fade = bpy.props.FloatProperty(name="Fade", default=1.8, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ssao = bpy.props.BoolProperty(name="SSAO", description="Screen-Space Ambient Occlusion", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ssao_size = bpy.props.FloatProperty(name="Size", default=0.12, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ssao_strength = bpy.props.FloatProperty(name="Strength", default=0.1, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ssao_half_res = bpy.props.BoolProperty(name="Half Res", description="Trace in half resolution", default=False, update=assets.invalidate_shader_cache) # TODO: Refactor as quality enum
bpy.types.World.generate_bloom = bpy.props.BoolProperty(name="Bloom", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.generate_bloom_threshold = bpy.props.FloatProperty(name="Threshold", default=5.0, update=assets.invalidate_shader_cache)
bpy.types.World.generate_bloom_strength = bpy.props.FloatProperty(name="Strength", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.generate_bloom_radius = bpy.props.FloatProperty(name="Radius", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.generate_motion_blur = bpy.props.BoolProperty(name="Motion Blur", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.generate_motion_blur_intensity = bpy.props.FloatProperty(name="Intensity", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ssr = bpy.props.BoolProperty(name="SSR", description="Screen-Space Reflections", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ssr_ray_step = bpy.props.FloatProperty(name="Ray Step", default=0.04, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ssr_min_ray_step = bpy.props.FloatProperty(name="Ray Step Min", default=0.05, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ssr_search_dist = bpy.props.FloatProperty(name="Search Dist", default=5.0, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ssr_falloff_exp = bpy.props.FloatProperty(name="Falloff Exp", default=5.0, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ssr_jitter = bpy.props.FloatProperty(name="Jitter", default=0.6, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ssr_half_res = bpy.props.BoolProperty(name="Half Res", description="Trace in half resolution", default=True, update=update_renderpath) # TODO: Refactor as quality enum
bpy.types.World.generate_volumetric_light = bpy.props.BoolProperty(name="Volumetric Light", description="", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.generate_volumetric_light_air_turbidity = bpy.props.FloatProperty(name="Air Turbidity", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.generate_volumetric_light_air_color = bpy.props.FloatVectorProperty(name="Air Color", size=3, default=[1.0, 1.0, 1.0], subtype='COLOR', min=0, max=1, update=assets.invalidate_shader_cache)
bpy.types.World.generate_pcss_state = EnumProperty(
bpy.types.World.arm_clouds = bpy.props.BoolProperty(name="Clouds", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.arm_clouds_density = bpy.props.FloatProperty(name="Density", default=0.5, min=0.0, max=10.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_clouds_size = bpy.props.FloatProperty(name="Size", default=1.0, min=0.0, max=10.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_clouds_lower = bpy.props.FloatProperty(name="Lower", default=2.0, min=1.0, max=10.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_clouds_upper = bpy.props.FloatProperty(name="Upper", default=3.5, min=1.0, max=10.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_clouds_wind = bpy.props.FloatVectorProperty(name="Wind", default=[0.2, 0.06], size=2, update=assets.invalidate_shader_cache)
bpy.types.World.arm_clouds_secondary = bpy.props.FloatProperty(name="Secondary", default=0.0, min=0.0, max=10.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_clouds_precipitation = bpy.props.FloatProperty(name="Precipitation", default=1.0, min=0.0, max=2.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_clouds_eccentricity = bpy.props.FloatProperty(name="Eccentricity", default=0.6, min=0.0, max=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ocean = bpy.props.BoolProperty(name="Ocean", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ocean_base_color = bpy.props.FloatVectorProperty(name="Base Color", size=3, default=[0.1, 0.19, 0.37], subtype='COLOR', min=0, max=1, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ocean_water_color = bpy.props.FloatVectorProperty(name="Water Color", size=3, default=[0.6, 0.7, 0.9], subtype='COLOR', min=0, max=1, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ocean_level = bpy.props.FloatProperty(name="Level", default=0.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ocean_amplitude = bpy.props.FloatProperty(name="Amplitude", default=2.5, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ocean_height = bpy.props.FloatProperty(name="Height", default=0.6, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ocean_choppy = bpy.props.FloatProperty(name="Choppy", default=4.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ocean_speed = bpy.props.FloatProperty(name="Speed", default=1.5, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ocean_freq = bpy.props.FloatProperty(name="Freq", default=0.16, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ocean_fade = bpy.props.FloatProperty(name="Fade", default=1.8, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ssao = bpy.props.BoolProperty(name="SSAO", description="Screen-Space Ambient Occlusion", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ssao_size = bpy.props.FloatProperty(name="Size", default=0.12, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ssao_strength = bpy.props.FloatProperty(name="Strength", default=0.1, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ssao_half_res = bpy.props.BoolProperty(name="Half Res", description="Trace in half resolution", default=False, update=assets.invalidate_shader_cache) # TODO: Refactor as quality enum
bpy.types.World.arm_bloom = bpy.props.BoolProperty(name="Bloom", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.arm_bloom_threshold = bpy.props.FloatProperty(name="Threshold", default=5.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_bloom_strength = bpy.props.FloatProperty(name="Strength", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_bloom_radius = bpy.props.FloatProperty(name="Radius", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_motion_blur = bpy.props.BoolProperty(name="Motion Blur", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.arm_motion_blur_intensity = bpy.props.FloatProperty(name="Intensity", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ssr = bpy.props.BoolProperty(name="SSR", description="Screen-Space Reflections", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ssr_ray_step = bpy.props.FloatProperty(name="Ray Step", default=0.04, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ssr_min_ray_step = bpy.props.FloatProperty(name="Ray Step Min", default=0.05, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ssr_search_dist = bpy.props.FloatProperty(name="Search Dist", default=5.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ssr_falloff_exp = bpy.props.FloatProperty(name="Falloff Exp", default=5.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ssr_jitter = bpy.props.FloatProperty(name="Jitter", default=0.6, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ssr_half_res = bpy.props.BoolProperty(name="Half Res", description="Trace in half resolution", default=True, update=update_renderpath) # TODO: Refactor as quality enum
bpy.types.World.arm_volumetric_light = bpy.props.BoolProperty(name="Volumetric Light", description="", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.arm_volumetric_light_air_turbidity = bpy.props.FloatProperty(name="Air Turbidity", default=1.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_volumetric_light_air_color = bpy.props.FloatVectorProperty(name="Air Color", size=3, default=[1.0, 1.0, 1.0], subtype='COLOR', min=0, max=1, update=assets.invalidate_shader_cache)
bpy.types.World.arm_pcss_state = EnumProperty(
items=[('On', 'On', 'On'),
('Off', 'Off', 'Off'),
('Auto', 'Auto', 'Auto')],
name="Soft Shadows", description="Percentage Closer Soft Shadows", default='Off', update=assets.invalidate_shader_cache)
bpy.types.World.generate_pcss_rings = bpy.props.IntProperty(name="Rings", description="", default=20, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ssrs = bpy.props.BoolProperty(name="SSRS", description="Screen-space ray-traced shadows", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.generate_ssrs_ray_step = bpy.props.FloatProperty(name="Ray Step", default=0.01, update=assets.invalidate_shader_cache)
bpy.types.World.arm_pcss_rings = bpy.props.IntProperty(name="Rings", description="", default=20, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ssrs = bpy.props.BoolProperty(name="SSRS", description="Screen-space ray-traced shadows", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.arm_ssrs_ray_step = bpy.props.FloatProperty(name="Ray Step", default=0.01, update=assets.invalidate_shader_cache)
# Compositor
bpy.types.World.generate_letterbox = bpy.props.BoolProperty(name="Letterbox", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.generate_letterbox_size = bpy.props.FloatProperty(name="Size", default=0.1, update=assets.invalidate_shader_cache)
bpy.types.World.generate_grain = bpy.props.BoolProperty(name="Film Grain", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.generate_grain_strength = bpy.props.FloatProperty(name="Strength", default=2.0, update=assets.invalidate_shader_cache)
bpy.types.World.generate_fog = bpy.props.BoolProperty(name="Volumetric Fog", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.generate_fog_color = bpy.props.FloatVectorProperty(name="Color", size=3, subtype='COLOR', default=[0.5, 0.6, 0.7], min=0, max=1, update=assets.invalidate_shader_cache)
bpy.types.World.generate_fog_amounta = bpy.props.FloatProperty(name="Amount A", default=0.25, update=assets.invalidate_shader_cache)
bpy.types.World.generate_fog_amountb = bpy.props.FloatProperty(name="Amount B", default=0.5, update=assets.invalidate_shader_cache)
bpy.types.World.generate_tonemap = EnumProperty(
bpy.types.World.arm_letterbox = bpy.props.BoolProperty(name="Letterbox", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.arm_letterbox_size = bpy.props.FloatProperty(name="Size", default=0.1, update=assets.invalidate_shader_cache)
bpy.types.World.arm_grain = bpy.props.BoolProperty(name="Film Grain", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.arm_grain_strength = bpy.props.FloatProperty(name="Strength", default=2.0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_fog = bpy.props.BoolProperty(name="Volumetric Fog", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.arm_fog_color = bpy.props.FloatVectorProperty(name="Color", size=3, subtype='COLOR', default=[0.5, 0.6, 0.7], min=0, max=1, update=assets.invalidate_shader_cache)
bpy.types.World.arm_fog_amounta = bpy.props.FloatProperty(name="Amount A", default=0.25, update=assets.invalidate_shader_cache)
bpy.types.World.arm_fog_amountb = bpy.props.FloatProperty(name="Amount B", default=0.5, update=assets.invalidate_shader_cache)
bpy.types.World.arm_tonemap = EnumProperty(
items=[('None', 'None', 'None'),
('Filmic', 'Filmic', 'Filmic'),
('Filmic2', 'Filmic2', 'Filmic2'),
('Reinhard', 'Reinhard', 'Reinhard'),
('Uncharted', 'Uncharted', 'Uncharted')],
name='Tonemap', description='Tonemapping operator', default='Filmic', update=assets.invalidate_shader_cache)
bpy.types.World.generate_lamp_texture = bpy.props.StringProperty(name="Mask Texture", default="")
bpy.types.World.generate_lamp_ies_texture = bpy.props.StringProperty(name="IES Texture", default="")
bpy.types.World.generate_lens_texture = bpy.props.StringProperty(name="Lens Texture", default="")
bpy.types.World.generate_fisheye = bpy.props.BoolProperty(name="Fish Eye", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.generate_vignette = bpy.props.BoolProperty(name="Vignette", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.arm_lamp_texture = bpy.props.StringProperty(name="Mask Texture", default="")
bpy.types.World.arm_lamp_ies_texture = bpy.props.StringProperty(name="IES Texture", default="")
bpy.types.World.arm_lens_texture = bpy.props.StringProperty(name="Lens Texture", default="")
bpy.types.World.arm_fisheye = bpy.props.BoolProperty(name="Fish Eye", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.arm_vignette = bpy.props.BoolProperty(name="Vignette", default=False, update=assets.invalidate_shader_cache)
# Skin
bpy.types.World.generate_gpu_skin = bpy.props.BoolProperty(name="GPU Skinning", description="Calculate skinning on GPU", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.generate_gpu_skin_max_bones_auto = bpy.props.BoolProperty(name="Auto Bones", description="Calculate amount of maximum bones based on armatures", default=True, update=assets.invalidate_compiled_data)
bpy.types.World.generate_gpu_skin_max_bones = bpy.props.IntProperty(name="Max Bones", default=50, min=1, max=3000, update=assets.invalidate_shader_cache)
bpy.types.World.arm_gpu_skin = bpy.props.BoolProperty(name="GPU Skinning", description="Calculate skinning on GPU", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.arm_gpu_skin_max_bones_auto = bpy.props.BoolProperty(name="Auto Bones", description="Calculate amount of maximum bones based on armatures", default=True, update=assets.invalidate_compiled_data)
bpy.types.World.arm_gpu_skin_max_bones = bpy.props.IntProperty(name="Max Bones", default=50, min=1, max=3000, update=assets.invalidate_shader_cache)
# Material override flags
bpy.types.World.texture_filtering_state = EnumProperty(
bpy.types.World.arm_texture_filter = EnumProperty(
items=[('Anisotropic', 'Anisotropic', 'Anisotropic'),
('Linear', 'Linear', 'Linear'),
('Point', 'Point', 'Point'),
('Manual', 'Manual', 'Manual')],
name="Texture Filtering", description="Set Manual to honor interpolation setting on Image Texture node", default='Anisotropic')
bpy.types.World.force_no_culling = bpy.props.BoolProperty(name="Force No Culling", default=False)
bpy.types.World.generate_two_sided_area_lamp = bpy.props.BoolProperty(name="Two-Sided Area Lamps", description="Emit light from both faces of area lamp", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.tessellation_enabled = bpy.props.BoolProperty(name="Tessellation", description="Enable tessellation for height maps on supported targets", default=True, update=assets.invalidate_shader_cache)
bpy.types.World.arm_culling = bpy.props.BoolProperty(name="Culling", default=True)
bpy.types.World.arm_two_sided_area_lamp = bpy.props.BoolProperty(name="Two-Sided Area Lamps", description="Emit light from both faces of area lamp", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.arm_tessellation = bpy.props.BoolProperty(name="Tessellation", description="Enable tessellation for height maps on supported targets", default=True, update=assets.invalidate_shader_cache)
# Material builder flags
bpy.types.World.material_model = EnumProperty(
bpy.types.World.arm_material_model = EnumProperty(
items=[('PBR', 'PBR', 'PBR'),
('Cycles', 'Cycles', 'Cycles'),
('Restricted', 'Restricted', 'Restricted'),
],
name="Materials", description="Material builder", default='PBR', update=update_material_model)
# For material
bpy.types.Material.arm_cast_shadow = bpy.props.BoolProperty(name="Cast Shadow", default=True)
bpy.types.Material.arm_receive_shadow = bpy.props.BoolProperty(name="Receive Shadow", default=True)
bpy.types.Material.arm_overlay = bpy.props.BoolProperty(name="Overlay", default=False)
bpy.types.Material.arm_decal = bpy.props.BoolProperty(name="Decal", default=False)
bpy.types.Material.arm_two_sided = bpy.props.BoolProperty(name="Two-Sided", default=False)
bpy.types.Material.arm_cull_mode = EnumProperty(
items=[('none', 'Both', 'None'),
('clockwise', 'Front', 'Clockwise'),
('counter_clockwise', 'Back', 'Counter-Clockwise')],
name="", default='clockwise', description="Draw geometry faces")
bpy.types.Material.arm_discard = bpy.props.BoolProperty(name="Discard", default=False)
bpy.types.Material.arm_discard_opacity = bpy.props.FloatProperty(name="Mesh Opacity", default=0.2, min=0, max=1)
bpy.types.Material.arm_discard_opacity_shadows = bpy.props.FloatProperty(name="Shadows Opacity", default=0.1, min=0, max=1)
bpy.types.Material.arm_tess = bpy.props.BoolProperty(name="Tess Displacement", description="Use tessellation shaders to subdivide and displace surface", default=True)
bpy.types.Material.arm_tess_inner = bpy.props.IntProperty(name="Inner", description="Inner tessellation level for mesh", default=14)
bpy.types.Material.arm_tess_outer = bpy.props.IntProperty(name="Outer", description="Outer tessellation level for mesh", default=14)
bpy.types.Material.arm_tess_shadows = bpy.props.BoolProperty(name="Tess Shadows", description="Use tessellation shaders when rendering shadow maps", default=True)
bpy.types.Material.arm_tess_shadows_inner = bpy.props.IntProperty(name="Inner", description="Inner tessellation level for shadows", default=7)
bpy.types.Material.arm_tess_shadows_outer = bpy.props.IntProperty(name="Outer", description="Outer tessellation level for shadows", default=7)
# For scene
bpy.types.Scene.arm_export = bpy.props.BoolProperty(name="Export", description="Export scene data", default=True)
bpy.types.Scene.arm_gp_export = bpy.props.BoolProperty(name="Export GP", description="Export grease pencil data", default=True)
bpy.types.Scene.arm_compress = bpy.props.BoolProperty(name="Compress", description="Pack data into zip file", default=False)
# For lamp
bpy.types.Lamp.arm_clip_start = bpy.props.FloatProperty(name="Clip Start", default=0.1)
bpy.types.Lamp.arm_clip_end = bpy.props.FloatProperty(name="Clip End", default=50.0)
bpy.types.Lamp.arm_fov = bpy.props.FloatProperty(name="Field of View", default=0.84)
bpy.types.Lamp.arm_shadows_bias = bpy.props.FloatProperty(name="Bias", description="Depth offset for shadow acne", default=0.0001)
bpy.types.Lamp.arm_omni_shadows = bpy.props.BoolProperty(name="Omni-Shadows", description="Draw shadows to all faces of the cube map", default=True)
bpy.types.World.arm_pcfsize = bpy.props.FloatProperty(name="PCF Size", description="Filter size", default=0.001)
bpy.types.World.arm_shadowmap_size_cache = bpy.props.IntProperty(name="Shadowmap Size", default=0, update=assets.invalidate_shader_cache)
bpy.types.World.arm_scripts_list = bpy.props.CollectionProperty(type=bpy.types.PropertyGroup)
bpy.types.World.arm_bundled_scripts_list = bpy.props.CollectionProperty(type=bpy.types.PropertyGroup)
bpy.types.World.arm_canvas_list = bpy.props.CollectionProperty(type=bpy.types.PropertyGroup)
bpy.types.World.world_defs = bpy.props.StringProperty(name="World Shader Defs", default='')
bpy.types.World.rp_defs = bpy.props.StringProperty(name="Render Path Shader Defs", default='')
bpy.types.World.compo_defs = bpy.props.StringProperty(name="Compositor Shader Defs", default='')
bpy.types.Material.export_uvs = bpy.props.BoolProperty(name="Export UVs", default=False)
bpy.types.Material.export_vcols = bpy.props.BoolProperty(name="Export VCols", default=False)
bpy.types.Material.export_tangents = bpy.props.BoolProperty(name="Export Tangents", default=False)
bpy.types.Material.vertex_structure = bpy.props.StringProperty(name="Vertex Structure", default='')
bpy.types.NodeSocket.is_uniform = bpy.props.BoolProperty(name="Is Uniform", description="Mark node sockets to be processed as material uniforms", default=False)
bpy.types.NodeTree.is_cached = bpy.props.BoolProperty(name="Node Tree Cached", description="No need to reexport node tree", default=False)
bpy.types.Material.signature = bpy.props.StringProperty(name="Signature", description="Unique string generated from material nodes", default="")
bpy.types.Material.is_cached = bpy.props.BoolProperty(name="Material Cached", description="No need to reexport material data", default=False, update=update_mat_cache)
bpy.types.Material.lock_cache = bpy.props.BoolProperty(name="Lock Material Cache", description="Prevent is_cached from updating", default=False)
bpy.types.Material.cast_shadow = bpy.props.BoolProperty(name="Cast Shadow", default=True)
bpy.types.Material.receive_shadow = bpy.props.BoolProperty(name="Receive Shadow", default=True)
bpy.types.Material.override_shader = bpy.props.BoolProperty(name="Override Shader", default=False)
bpy.types.Material.override_shader_name = bpy.props.StringProperty(name="", default='')
bpy.types.Material.override_shader_context = bpy.props.BoolProperty(name="Override Context", default=False)
bpy.types.Material.override_shader_context_name = bpy.props.StringProperty(name="", default='')
bpy.types.Material.stencil_mask = bpy.props.IntProperty(name="Stencil Mask", default=0)
bpy.types.Material.export_uvs = bpy.props.BoolProperty(name="Export UVs", default=False)
bpy.types.Material.export_vcols = bpy.props.BoolProperty(name="Export VCols", default=False)
bpy.types.Material.export_tangents = bpy.props.BoolProperty(name="Export Tangents", default=False)
bpy.types.Material.vertex_structure = bpy.props.StringProperty(name="Vertex Structure", default='')
bpy.types.Material.skip_context = bpy.props.StringProperty(name="Skip Context", default='')
bpy.types.Material.overlay = bpy.props.BoolProperty(name="Overlay", default=False)
bpy.types.Material.decal = bpy.props.BoolProperty(name="Decal", default=False)
bpy.types.Material.two_sided_shading = bpy.props.BoolProperty(name="Two-Sided", default=False)
bpy.types.Material.override_cull_mode = EnumProperty(
items=[('none', 'Both', 'None'),
('clockwise', 'Front', 'Clockwise'),
('counter_clockwise', 'Back', 'Counter-Clockwise')],
name="", default='clockwise', description="Draw geometry faces")
bpy.types.Material.discard_transparent = bpy.props.BoolProperty(name="Discard", default=False)
bpy.types.Material.discard_transparent_opacity = bpy.props.FloatProperty(name="Mesh Opacity", default=0.2, min=0, max=1)
bpy.types.Material.discard_transparent_opacity_shadows = bpy.props.FloatProperty(name="Shadows Opacity", default=0.1, min=0, max=1)
bpy.types.Material.override_compare = bpy.props.BoolProperty(name="Override Compare-Mode", default=False)
bpy.types.Material.override_compare_mode = EnumProperty(
items = [('Always', 'Always', 'Always'),
('Less', 'Less', 'Less')],
name = "Compare-Mode", default='Less')
bpy.types.Material.override_depthwrite = bpy.props.BoolProperty(name="Override Depth-Write", default=False)
bpy.types.Material.override_depthwrite_mode = EnumProperty(
items = [('True', 'True', 'True'),
('False', 'False', 'False')],
name = "Depth-Write", default='True')
bpy.types.Material.height_tess = bpy.props.BoolProperty(name="Tess Displacement", description="Use tessellation shaders to subdivide and displace surface", default=True)
bpy.types.Material.height_tess_inner = bpy.props.IntProperty(name="Inner", description="Inner tessellation level for mesh", default=14)
bpy.types.Material.height_tess_outer = bpy.props.IntProperty(name="Outer", description="Outer tessellation level for mesh", default=14)
bpy.types.Material.height_tess_shadows = bpy.props.BoolProperty(name="Tess Shadows", description="Use tessellation shaders when rendering shadow maps", default=True)
bpy.types.Material.height_tess_shadows_inner = bpy.props.IntProperty(name="Inner", description="Inner tessellation level for shadows", default=7)
bpy.types.Material.height_tess_shadows_outer = bpy.props.IntProperty(name="Outer", description="Outer tessellation level for shadows", default=7)
bpy.types.Material.transluc_shadows = bpy.props.BoolProperty(name="Translucent Shadows", description="Cast shadows for translucent surfaces", default=True)
# For scene
bpy.types.Scene.game_export = bpy.props.BoolProperty(name="Export", description="Export scene data", default=True)
bpy.types.Scene.gp_export = bpy.props.BoolProperty(name="Export Grease Pencil", description="Export grease pencil data", default=True)
bpy.types.Scene.data_compressed = bpy.props.BoolProperty(name="Compress Data", description="Pack data into zip file", default=False)
# For lamp
bpy.types.Lamp.lamp_clip_start = bpy.props.FloatProperty(name="Clip Start", default=0.1)
bpy.types.Lamp.lamp_clip_end = bpy.props.FloatProperty(name="Clip End", default=50.0)
bpy.types.Lamp.lamp_fov = bpy.props.FloatProperty(name="Field of View", default=0.84)
bpy.types.Lamp.lamp_shadows_bias = bpy.props.FloatProperty(name="Bias", description="Depth offset for shadow acne", default=0.0001)
bpy.types.Lamp.lamp_omni_shadows = bpy.props.BoolProperty(name="Omni-Shadows", description="Draw shadows to all faces of the cube map", default=True)
bpy.types.World.lamp_omni_shadows_pcfsize = bpy.props.FloatProperty(name="PCF Size", description="Filter size", default=0.001)
if not 'Arm' in bpy.data.worlds:
wrd = bpy.data.worlds.new('Arm')
@ -625,6 +605,19 @@ def init_properties_on_load():
wrd.arm_version = arm_version
arm.make.clean_project()
make_renderer.make_renderer(bpy.data.worlds['Arm'])
# Deprecated: migrate traits
for bobject in bpy.data.objects:
if not hasattr(bobject, 'my_traitlist'):
continue
for trait in bobject.my_traitlist:
t = bobject.arm_traitlist.add()
t.name = trait.name
t.enabled_prop = trait.enabled_prop
t.type_prop = trait.type_prop
t.class_name_prop = trait.class_name_prop
t.canvas_name_prop = trait.canvas_name_prop
t.jsscript_prop = trait.jsscript_prop
t.nodes_name_prop = trait.nodes_name_prop
# Set url for embedded player
if arm.utils.with_krom():
barmory.set_files_location(arm.utils.get_fp_build() + '/krom')

View file

@ -5,7 +5,7 @@ import json
from bpy.types import Menu, Panel, UIList
from bpy.props import *
class ListLibraryTraitItem(bpy.types.PropertyGroup):
class ArmLibraryListItem(bpy.types.PropertyGroup):
name = bpy.props.StringProperty(
name="Name",
description="A name for this item",
@ -16,7 +16,7 @@ class ListLibraryTraitItem(bpy.types.PropertyGroup):
description="A name for this item",
default=True)
class MY_UL_LibraryTraitList(bpy.types.UIList):
class ArmLibraryList(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# We could write some code to decide which icon to use here...
custom_icon = 'OBJECT_DATAMODE'
@ -31,7 +31,7 @@ class MY_UL_LibraryTraitList(bpy.types.UIList):
layout.alignment = 'CENTER'
layout.label("", icon = custom_icon)
class LIST_OT_LibraryTraitNewItem(bpy.types.Operator):
class ArmLibraryListNewItem(bpy.types.Operator):
# Add a new item to the list
bl_idname = "arm_librarylist.new_item"
bl_label = "Add a new item"
@ -43,7 +43,7 @@ class LIST_OT_LibraryTraitNewItem(bpy.types.Operator):
return{'FINISHED'}
class LIST_OT_LibraryTraitDeleteItem(bpy.types.Operator):
class ArmLibraryListDeleteItem(bpy.types.Operator):
# Delete the selected item from the list
bl_idname = "arm_librarylist.delete_item"
bl_label = "Deletes an item"
@ -68,7 +68,7 @@ class LIST_OT_LibraryTraitDeleteItem(bpy.types.Operator):
return{'FINISHED'}
class LIST_OT_LibraryTraitMoveItem(bpy.types.Operator):
class ArmLibraryListMoveItem(bpy.types.Operator):
# Move an item in the list
bl_idname = "arm_librarylist.move_item"
bl_label = "Move an item in the list"
@ -119,15 +119,18 @@ class LIST_OT_LibraryTraitMoveItem(bpy.types.Operator):
return{'FINISHED'}
def register():
bpy.utils.register_class(ListLibraryTraitItem)
bpy.utils.register_class(MY_UL_LibraryTraitList)
bpy.utils.register_class(LIST_OT_LibraryTraitNewItem)
bpy.utils.register_class(LIST_OT_LibraryTraitDeleteItem)
bpy.utils.register_class(LIST_OT_LibraryTraitMoveItem)
bpy.utils.register_class(ArmLibraryListItem)
bpy.utils.register_class(ArmLibraryList)
bpy.utils.register_class(ArmLibraryListNewItem)
bpy.utils.register_class(ArmLibraryListDeleteItem)
bpy.utils.register_class(ArmLibraryListMoveItem)
bpy.types.World.arm_librarylist = bpy.props.CollectionProperty(type=ArmLibraryListItem)
bpy.types.World.arm_librarylist_index = bpy.props.IntProperty(name="Library index", default=0)
def unregister():
bpy.utils.unregister_class(ListLibraryTraitItem)
bpy.utils.unregister_class(MY_UL_LibraryTraitList)
bpy.utils.unregister_class(LIST_OT_LibraryTraitNewItem)
bpy.utils.unregister_class(LIST_OT_LibraryTraitDeleteItem)
bpy.utils.unregister_class(LIST_OT_LibraryTraitMoveItem)
bpy.utils.unregister_class(ArmLibraryListItem)
bpy.utils.unregister_class(ArmLibraryList)
bpy.utils.unregister_class(ArmLibraryListNewItem)
bpy.utils.unregister_class(ArmLibraryListDeleteItem)
bpy.utils.unregister_class(ArmLibraryListMoveItem)

View file

@ -6,13 +6,13 @@ def update_size_prop(self, context):
if context.object == None:
return
mdata = context.object.data
i = mdata.lodlist_index
ar = mdata.my_lodlist
i = mdata.arm_lodlist_index
ar = mdata.arm_lodlist
# Clamp screen size to not exceed previous entry
if i > 0 and ar[i - 1].screen_size_prop < self.screen_size_prop:
self.screen_size_prop = ar[i - 1].screen_size_prop
class ListLodItem(bpy.types.PropertyGroup):
class ArmLodListItem(bpy.types.PropertyGroup):
# Group of properties representing an item in the list
name = bpy.props.StringProperty(
name="Name",
@ -32,7 +32,7 @@ class ListLodItem(bpy.types.PropertyGroup):
default=0.0,
update=update_size_prop)
class MY_UL_LodList(bpy.types.UIList):
class ArmLodList(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# We could write some code to decide which icon to use here...
custom_icon = 'OBJECT_DATAMODE'
@ -52,50 +52,54 @@ class MY_UL_LodList(bpy.types.UIList):
layout.alignment = 'CENTER'
layout.label("", icon = custom_icon)
class LIST_OT_LodNewItem(bpy.types.Operator):
class ArmLodListNewItem(bpy.types.Operator):
# Add a new item to the list
bl_idname = "my_lodlist.new_item"
bl_idname = "arm_lodlist.new_item"
bl_label = "Add a new item"
def execute(self, context):
mdata = bpy.context.object.data
mdata.my_lodlist.add()
mdata.lodlist_index = len(mdata.my_lodlist) - 1
mdata.arm_lodlist.add()
mdata.arm_lodlist_index = len(mdata.arm_lodlist) - 1
return{'FINISHED'}
class LIST_OT_LodDeleteItem(bpy.types.Operator):
class ArmLodListDeleteItem(bpy.types.Operator):
# Delete the selected item from the list
bl_idname = "my_lodlist.delete_item"
bl_idname = "arm_lodlist.delete_item"
bl_label = "Deletes an item"
@classmethod
def poll(self, context):
""" Enable if there's something in the list """
mdata = bpy.context.object.data
return len(mdata.my_lodlist) > 0
return len(mdata.arm_lodlist) > 0
def execute(self, context):
mdata = bpy.context.object.data
list = mdata.my_lodlist
index = mdata.lodlist_index
list = mdata.arm_lodlist
index = mdata.arm_lodlist_index
list.remove(index)
if index > 0:
index = index - 1
mdata.lodlist_index = index
mdata.arm_lodlist_index = index
return{'FINISHED'}
def register():
bpy.utils.register_class(ListLodItem)
bpy.utils.register_class(MY_UL_LodList)
bpy.utils.register_class(LIST_OT_LodNewItem)
bpy.utils.register_class(LIST_OT_LodDeleteItem)
bpy.utils.register_class(ArmLodListItem)
bpy.utils.register_class(ArmLodList)
bpy.utils.register_class(ArmLodListNewItem)
bpy.utils.register_class(ArmLodListDeleteItem)
bpy.types.Mesh.arm_lodlist = bpy.props.CollectionProperty(type=ArmLodListItem)
bpy.types.Mesh.arm_lodlist_index = bpy.props.IntProperty(name="Index for my_list", default=0)
bpy.types.Mesh.arm_lod_material = bpy.props.BoolProperty(name="Material Lod", description="Use materials of lod objects", default=False)
def unregister():
bpy.utils.unregister_class(ListLodItem)
bpy.utils.unregister_class(MY_UL_LodList)
bpy.utils.unregister_class(LIST_OT_LodNewItem)
bpy.utils.unregister_class(LIST_OT_LodDeleteItem)
bpy.utils.unregister_class(ArmLodListItem)
bpy.utils.unregister_class(ArmLodList)
bpy.utils.unregister_class(ArmLodListNewItem)
bpy.utils.unregister_class(ArmLodListDeleteItem)

View file

@ -2,7 +2,6 @@ import shutil
import bpy
import subprocess
import os
import json
from bpy.types import Menu, Panel, UIList
from bpy.props import *
from arm.props_traits_params import *
@ -51,13 +50,54 @@ class ListTraitItem(bpy.types.PropertyGroup):
description="A name for this item",
default="")
my_paramstraitlist = bpy.props.CollectionProperty(type=ListParamsTraitItem)
paramstraitlist_index = bpy.props.IntProperty(name="Index for my_list", default=0)
class ArmTraitListItem(bpy.types.PropertyGroup):
# Group of properties representing an item in the list
name = bpy.props.StringProperty(
name="Name",
description="A name for this item",
default="")
enabled_prop = bpy.props.BoolProperty(
name="",
description="A name for this item",
default=True)
my_propstraitlist = bpy.props.CollectionProperty(type=ListPropsTraitItem)
propstraitlist_index = bpy.props.IntProperty(name="Index for my_list", default=0)
type_prop = bpy.props.EnumProperty(
items = [('Haxe Script', 'Haxe Script', 'Haxe Script'),
('JS Script', 'JS Script', 'JS Script'),
('UI Canvas', 'UI Canvas', 'UI Canvas'),
('Bundled Script', 'Bundled Script', 'Bundled Script'),
('Logic Nodes', 'Logic Nodes', 'Logic Nodes')
],
name = "Type")
class MY_UL_TraitList(bpy.types.UIList):
class_name_prop = bpy.props.StringProperty(
name="Class",
description="A name for this item",
default="")
canvas_name_prop = bpy.props.StringProperty(
name="Canvas",
description="A name for this item",
default="")
jsscript_prop = bpy.props.StringProperty(
name="Text",
description="A name for this item",
default="")
nodes_name_prop = bpy.props.StringProperty(
name="Nodes",
description="A name for this item",
default="")
arm_traitparamslist = bpy.props.CollectionProperty(type=ArmTraitParamListItem)
arm_traitparamslist_index = bpy.props.IntProperty(name="Index for my_list", default=0)
arm_traitpropslist = bpy.props.CollectionProperty(type=ArmTraitPropListItem)
arm_traitpropslist_index = bpy.props.IntProperty(name="Index for my_list", default=0)
class ArmTraitList(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# We could write some code to decide which icon to use here...
custom_icon = 'OBJECT_DATAMODE'
@ -71,48 +111,43 @@ class MY_UL_TraitList(bpy.types.UIList):
layout.alignment = 'CENTER'
layout.label("", icon = custom_icon)
def initObjectProperties():
bpy.types.Object.my_traitlist = bpy.props.CollectionProperty(type=ListTraitItem)
bpy.types.Object.traitlist_index = bpy.props.IntProperty(name="Index for my_list", default=0)
class LIST_OT_TraitNewItem(bpy.types.Operator):
class ArmTraitListNewItem(bpy.types.Operator):
# Add a new item to the list
bl_idname = "my_traitlist.new_item"
bl_idname = "arm_traitlist.new_item"
bl_label = "Add a new item"
def execute(self, context):
trait = bpy.context.object.my_traitlist.add()
bpy.context.object.traitlist_index = len(bpy.context.object.my_traitlist) - 1
trait = bpy.context.object.arm_traitlist.add()
bpy.context.object.arm_traitlist_index = len(bpy.context.object.arm_traitlist) - 1
return{'FINISHED'}
class LIST_OT_TraitDeleteItem(bpy.types.Operator):
class ArmTraitListDeleteItem(bpy.types.Operator):
# Delete the selected item from the list
bl_idname = "my_traitlist.delete_item"
bl_idname = "arm_traitlist.delete_item"
bl_label = "Deletes an item"
@classmethod
def poll(self, context):
""" Enable if there's something in the list """
return len(bpy.context.object.my_traitlist) > 0
return len(bpy.context.object.arm_traitlist) > 0
def execute(self, context):
list = bpy.context.object.my_traitlist
index = bpy.context.object.traitlist_index
list = bpy.context.object.arm_traitlist
index = bpy.context.object.arm_traitlist_index
list.remove(index)
if index > 0:
index = index - 1
bpy.context.object.traitlist_index = index
bpy.context.object.arm_traitlist_index = index
return{'FINISHED'}
class LIST_OT_TraitMoveItem(bpy.types.Operator):
class ArmTraitListMoveItem(bpy.types.Operator):
# Move an item in the list
bl_idname = "my_traitlist.move_item"
bl_idname = "arm_traitlist.move_item"
bl_label = "Move an item in the list"
direction = bpy.props.EnumProperty(
items=(
@ -122,13 +157,13 @@ class LIST_OT_TraitMoveItem(bpy.types.Operator):
@classmethod
def poll(self, context):
""" Enable if there's something in the list. """
return len(bpy.context.object.my_traitlist) > 0
return len(bpy.context.object.arm_traitlist) > 0
def move_index(self):
# Move index of an item render queue while clamping it
index = bpy.context.object.traitlist_index
list_length = len(bpy.context.object.my_traitlist) - 1
index = bpy.context.object.arm_traitlist_index
list_length = len(bpy.context.object.arm_traitlist) - 1
new_index = 0
if self.direction == 'UP':
@ -141,8 +176,8 @@ class LIST_OT_TraitMoveItem(bpy.types.Operator):
def execute(self, context):
list = bpy.context.object.my_traitlist
index = bpy.context.object.traitlist_index
list = bpy.context.object.arm_traitlist
index = bpy.context.object.arm_traitlist_index
if self.direction == 'DOWN':
neighbor = index + 1
@ -157,14 +192,14 @@ class LIST_OT_TraitMoveItem(bpy.types.Operator):
return{'CANCELLED'}
return{'FINISHED'}
class ArmoryEditScriptButton(bpy.types.Operator):
class ArmEditScriptButton(bpy.types.Operator):
'''Edit script in Kode Studio'''
bl_idname = 'arm.edit_script'
bl_label = 'Edit Script'
def execute(self, context):
project_path = arm.utils.get_fp()
item = context.object.my_traitlist[context.object.traitlist_index]
item = context.object.arm_traitlist[context.object.arm_traitlist_index]
pkg = arm.utils.safestr(bpy.data.worlds['Arm'].arm_project_package)
hx_path = project_path + '/Sources/' + pkg + '/' + item.class_name_prop + '.hx'
@ -181,7 +216,7 @@ class ArmoryEditScriptButton(bpy.types.Operator):
return{'FINISHED'}
class ArmoryEditBundledScriptButton(bpy.types.Operator):
class ArmEditBundledScriptButton(bpy.types.Operator):
'''Copy script to project and edit in Kode Studio'''
bl_idname = 'arm.edit_bundled_script'
bl_label = 'Edit Script'
@ -190,7 +225,7 @@ class ArmoryEditBundledScriptButton(bpy.types.Operator):
sdk_path = arm.utils.get_sdk_path()
project_path = arm.utils.get_fp()
pkg = arm.utils.safestr(bpy.data.worlds['Arm'].arm_project_package)
item = context.object.my_traitlist[context.object.traitlist_index]
item = context.object.arm_traitlist[context.object.arm_traitlist_index]
source_hx_path = sdk_path + '/armory/Sources/armory/trait/' + item.class_name_prop + '.hx'
target_hx_path = project_path + '/Sources/' + pkg + '/' + item.class_name_prop + '.hx'
@ -213,14 +248,14 @@ class ArmoryEditBundledScriptButton(bpy.types.Operator):
return{'FINISHED'}
class ArmoryEditCanvasButton(bpy.types.Operator):
class ArmEditCanvasButton(bpy.types.Operator):
'''Edit ui canvas'''
bl_idname = 'arm.edit_canvas'
bl_label = 'Edit Canvas'
def execute(self, context):
project_path = arm.utils.get_fp()
item = context.object.my_traitlist[context.object.traitlist_index]
item = context.object.arm_traitlist[context.object.arm_traitlist_index]
canvas_path = project_path + '/Bundled/canvas/' + item.canvas_name_prop + '.json'
write_data.write_canvasprefs(canvas_path)
@ -231,7 +266,7 @@ class ArmoryEditCanvasButton(bpy.types.Operator):
subprocess.Popen([krom_path, armorui_path, armorui_path, '--nosound'])
return{'FINISHED'}
class ArmoryNewScriptDialog(bpy.types.Operator):
class ArmNewScriptDialog(bpy.types.Operator):
'''Create blank script'''
bl_idname = "arm.new_script"
bl_label = "New Script"
@ -243,7 +278,7 @@ class ArmoryNewScriptDialog(bpy.types.Operator):
write_data.write_traithx(self.class_name)
arm.utils.fetch_script_names()
obj = context.object
item = obj.my_traitlist[obj.traitlist_index]
item = obj.arm_traitlist[obj.arm_traitlist_index]
item.class_name_prop = self.class_name
return {'FINISHED'}
@ -253,7 +288,7 @@ class ArmoryNewScriptDialog(bpy.types.Operator):
self.class_name = 'MyTrait'
return context.window_manager.invoke_props_dialog(self)
class ArmoryNewCanvasDialog(bpy.types.Operator):
class ArmNewCanvasDialog(bpy.types.Operator):
'''Create blank canvas'''
bl_idname = "arm.new_canvas"
bl_label = "New Canvas"
@ -265,7 +300,7 @@ class ArmoryNewCanvasDialog(bpy.types.Operator):
write_data.write_canvasjson(self.canvas_name)
arm.utils.fetch_script_names()
obj = context.object
item = obj.my_traitlist[obj.traitlist_index]
item = obj.arm_traitlist[obj.arm_traitlist_index]
item.canvas_name_prop = self.canvas_name
return {'FINISHED'}
@ -275,7 +310,7 @@ class ArmoryNewCanvasDialog(bpy.types.Operator):
self.canvas_name = 'MyCanvas'
return context.window_manager.invoke_props_dialog(self)
class ArmoryRefreshScriptsButton(bpy.types.Operator):
class ArmRefreshScriptsButton(bpy.types.Operator):
'''Fetch all script names'''
bl_idname = 'arm.refresh_scripts'
bl_label = 'Refresh'
@ -286,7 +321,7 @@ class ArmoryRefreshScriptsButton(bpy.types.Operator):
arm.utils.fetch_trait_props()
return{'FINISHED'}
class ArmoryRefreshCanvasListButton(bpy.types.Operator):
class ArmRefreshCanvasListButton(bpy.types.Operator):
'''Fetch all canvas names'''
bl_idname = 'arm.refresh_canvas_list'
bl_label = 'Refresh'
@ -308,23 +343,23 @@ class ArmTraitsPanel(bpy.types.Panel):
obj = bpy.context.object
rows = 2
if len(obj.my_traitlist) > 1:
if len(obj.arm_traitlist) > 1:
rows = 4
row = layout.row()
row.template_list("MY_UL_TraitList", "The_List", obj, "my_traitlist", obj, "traitlist_index", rows=rows)
row.template_list("ArmTraitList", "The_List", obj, "arm_traitlist", obj, "arm_traitlist_index", rows=rows)
col = row.column(align=True)
col.operator("my_traitlist.new_item", icon='ZOOMIN', text="")
col.operator("my_traitlist.delete_item", icon='ZOOMOUT', text="")#.all = False
col.operator("arm_traitlist.new_item", icon='ZOOMIN', text="")
col.operator("arm_traitlist.delete_item", icon='ZOOMOUT', text="")#.all = False
if len(obj.my_traitlist) > 1:
if len(obj.arm_traitlist) > 1:
col.separator()
col.operator("my_traitlist.move_item", icon='TRIA_UP', text="").direction = 'UP'
col.operator("my_traitlist.move_item", icon='TRIA_DOWN', text="").direction = 'DOWN'
col.operator("arm_traitlist.move_item", icon='TRIA_UP', text="").direction = 'UP'
col.operator("arm_traitlist.move_item", icon='TRIA_DOWN', text="").direction = 'DOWN'
if obj.traitlist_index >= 0 and len(obj.my_traitlist) > 0:
item = obj.my_traitlist[obj.traitlist_index]
if obj.arm_traitlist_index >= 0 and len(obj.arm_traitlist) > 0:
item = obj.arm_traitlist[obj.arm_traitlist_index]
# Default props
row = layout.row()
row.prop(item, "type_prop")
@ -335,44 +370,40 @@ class ArmTraitsPanel(bpy.types.Panel):
row = layout.row()
# row.prop(item, "class_name_prop")
if item.type_prop == 'Haxe Script':
row.prop_search(item, "class_name_prop", bpy.data.worlds['Arm'], "scripts_list", "Class")
row.prop_search(item, "class_name_prop", bpy.data.worlds['Arm'], "arm_scripts_list", "Class")
else:
row.prop_search(item, "class_name_prop", bpy.data.worlds['Arm'], "bundled_scripts_list", "Class")
row.prop_search(item, "class_name_prop", bpy.data.worlds['Arm'], "arm_bundled_scripts_list", "Class")
# Props
if len(item.my_propstraitlist) > 0:
if len(item.arm_traitpropslist) > 0:
propsrow = layout.row()
propsrows = 2
if len(item.my_propstraitlist) > 2:
if len(item.arm_traitpropslist) > 2:
propsrows = 4
row = layout.row()
row.template_list("MY_UL_PropsTraitList", "The_List", item, "my_propstraitlist", item, "propstraitlist_index", rows=propsrows)
row.template_list("ArmTraitPropList", "The_List", item, "arm_traitpropslist", item, "arm_traitpropslist_index", rows=propsrows)
# Params
layout.label("Parameters")
paramsrow = layout.row()
paramsrows = 2
if len(item.my_paramstraitlist) > 1:
if len(item.arm_traitparamslist) > 1:
paramsrows = 4
row = layout.row()
row.template_list("MY_UL_ParamsTraitList", "The_List", item, "my_paramstraitlist", item, "paramstraitlist_index", rows=paramsrows)
row.template_list("ArmTraitParamList", "The_List", item, "arm_traitparamslist", item, "arm_traitparamslist_index", rows=paramsrows)
col = row.column(align=True)
col.operator("my_paramstraitlist.new_item", icon='ZOOMIN', text="")
col.operator("my_paramstraitlist.delete_item", icon='ZOOMOUT', text="")
col.operator("arm_traitparamslist.new_item", icon='ZOOMIN', text="")
col.operator("arm_traitparamslist.delete_item", icon='ZOOMOUT', text="")
if len(item.my_paramstraitlist) > 1:
if len(item.arm_traitparamslist) > 1:
col.separator()
col.operator("my_paramstraitlist.move_item", icon='TRIA_UP', text="").direction = 'UP'
col.operator("my_paramstraitlist.move_item", icon='TRIA_DOWN', text="").direction = 'DOWN'
col.operator("arm_traitparamslist.move_item", icon='TRIA_UP', text="").direction = 'UP'
col.operator("arm_traitparamslist.move_item", icon='TRIA_DOWN', text="").direction = 'DOWN'
if item.paramstraitlist_index >= 0 and len(item.my_paramstraitlist) > 0:
paramitem = item.my_paramstraitlist[item.paramstraitlist_index]
# Picker
layout.label('Pickers')
layout.prop_search(paramitem, 'object_picker', bpy.context.scene, "objects", "Object")
layout.prop(paramitem, 'color_picker')
if item.arm_traitparamslist_index >= 0 and len(item.arm_traitparamslist) > 0:
paramitem = item.arm_traitparamslist[item.arm_traitparamslist_index]
if item.type_prop == 'Haxe Script':
row = layout.row(align=True)
@ -397,7 +428,7 @@ class ArmTraitsPanel(bpy.types.Panel):
elif item.type_prop == 'UI Canvas':
item.name = item.canvas_name_prop
row = layout.row()
row.prop_search(item, "canvas_name_prop", bpy.data.worlds['Arm'], "canvas_list", "Canvas")
row.prop_search(item, "canvas_name_prop", bpy.data.worlds['Arm'], "arm_canvas_list", "Canvas")
row = layout.row(align=True)
row.alignment = 'EXPAND'
@ -416,33 +447,40 @@ class ArmTraitsPanel(bpy.types.Panel):
row.prop_search(item, "nodes_name_prop", bpy.data, "node_groups", "Tree")
def register():
bpy.utils.register_class(ListTraitItem)
bpy.utils.register_class(MY_UL_TraitList)
bpy.utils.register_class(LIST_OT_TraitNewItem)
bpy.utils.register_class(LIST_OT_TraitDeleteItem)
bpy.utils.register_class(LIST_OT_TraitMoveItem)
bpy.utils.register_class(ArmoryEditScriptButton)
bpy.utils.register_class(ArmoryEditBundledScriptButton)
bpy.utils.register_class(ArmoryEditCanvasButton)
bpy.utils.register_class(ArmoryNewScriptDialog)
bpy.utils.register_class(ArmoryNewCanvasDialog)
bpy.utils.register_class(ArmoryRefreshScriptsButton)
bpy.utils.register_class(ArmoryRefreshCanvasListButton)
bpy.utils.register_class(ArmTraitListItem)
bpy.utils.register_class(ArmTraitList)
bpy.utils.register_class(ArmTraitListNewItem)
bpy.utils.register_class(ArmTraitListDeleteItem)
bpy.utils.register_class(ArmTraitListMoveItem)
bpy.utils.register_class(ArmEditScriptButton)
bpy.utils.register_class(ArmEditBundledScriptButton)
bpy.utils.register_class(ArmEditCanvasButton)
bpy.utils.register_class(ArmNewScriptDialog)
bpy.utils.register_class(ArmNewCanvasDialog)
bpy.utils.register_class(ArmRefreshScriptsButton)
bpy.utils.register_class(ArmRefreshCanvasListButton)
bpy.utils.register_class(ArmTraitsPanel)
bpy.types.Object.arm_traitlist = bpy.props.CollectionProperty(type=ArmTraitListItem)
bpy.types.Object.arm_traitlist_index = bpy.props.IntProperty(name="Index for my_list", default=0)
initObjectProperties()
# Deprecated
bpy.utils.register_class(ListTraitItem)
bpy.types.Object.my_traitlist = bpy.props.CollectionProperty(type=ListTraitItem)
def unregister():
bpy.utils.unregister_class(ListTraitItem)
bpy.utils.unregister_class(MY_UL_TraitList)
bpy.utils.unregister_class(LIST_OT_TraitNewItem)
bpy.utils.unregister_class(LIST_OT_TraitDeleteItem)
bpy.utils.unregister_class(LIST_OT_TraitMoveItem)
bpy.utils.unregister_class(ArmoryEditScriptButton)
bpy.utils.unregister_class(ArmoryEditBundledScriptButton)
bpy.utils.unregister_class(ArmoryEditCanvasButton)
bpy.utils.unregister_class(ArmoryNewScriptDialog)
bpy.utils.unregister_class(ArmoryNewCanvasDialog)
bpy.utils.unregister_class(ArmoryRefreshScriptsButton)
bpy.utils.unregister_class(ArmoryRefreshCanvasListButton)
bpy.utils.unregister_class(ArmTraitListItem)
bpy.utils.unregister_class(ArmTraitList)
bpy.utils.unregister_class(ArmTraitListNewItem)
bpy.utils.unregister_class(ArmTraitListDeleteItem)
bpy.utils.unregister_class(ArmTraitListMoveItem)
bpy.utils.unregister_class(ArmEditScriptButton)
bpy.utils.unregister_class(ArmEditBundledScriptButton)
bpy.utils.unregister_class(ArmEditCanvasButton)
bpy.utils.unregister_class(ArmNewScriptDialog)
bpy.utils.unregister_class(ArmNewCanvasDialog)
bpy.utils.unregister_class(ArmRefreshScriptsButton)
bpy.utils.unregister_class(ArmRefreshCanvasListButton)
bpy.utils.unregister_class(ArmTraitsPanel)
# Deprecated
bpy.utils.unregister_class(ListTraitItem)

View file

@ -1,46 +1,15 @@
import shutil
import bpy
import os
import json
from bpy.types import Menu, Panel, UIList
from bpy.props import *
from arm.utils import to_hex
def object_picker_update(self, context):
o = context.object
tl = o.my_traitlist[o.traitlist_index]
pl = tl.my_paramstraitlist[tl.paramstraitlist_index]
pl.name = "'" + pl.object_picker + "'"
def color_picker_update(self, context):
o = context.object
tl = o.my_traitlist[o.traitlist_index]
pl = tl.my_paramstraitlist[tl.paramstraitlist_index]
col = pl.color_picker
pl.name = str(to_hex(col))
class ListParamsTraitItem(bpy.types.PropertyGroup):
class ArmTraitParamListItem(bpy.types.PropertyGroup):
# Group of properties representing an item in the list
name = bpy.props.StringProperty(
name="Name",
description="A name for this item",
default="Untitled")
object_picker = bpy.props.StringProperty(
name="Object",
description="A name for this item",
default="",
update=object_picker_update)
color_picker = bpy.props.FloatVectorProperty(
name="Color",
description="A name for this item",
size=4,
subtype='COLOR',
default=[1, 1, 1, 1],
update=color_picker_update)
class MY_UL_ParamsTraitList(bpy.types.UIList):
class ArmTraitParamList(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# We could write some code to decide which icon to use here...
custom_icon = 'OBJECT_DATAMODE'
@ -55,52 +24,52 @@ class MY_UL_ParamsTraitList(bpy.types.UIList):
layout.alignment = 'CENTER'
layout.label("", icon = custom_icon)
class LIST_OT_ParamsTraitNewItem(bpy.types.Operator):
class ArmTraitParamListNewItem(bpy.types.Operator):
# Add a new item to the list
bl_idname = "my_paramstraitlist.new_item"
bl_idname = "arm_traitparamslist.new_item"
bl_label = "Add a new item"
def execute(self, context):
if len(context.object.my_traitlist) == 0:
if len(context.object.arm_traitlist) == 0:
return
trait = context.object.my_traitlist[context.object.traitlist_index]
trait.my_paramstraitlist.add()
trait.paramstraitlist_index = len(trait.my_paramstraitlist) - 1
trait = context.object.arm_traitlist[context.object.arm_traitlist_index]
trait.arm_traitparamslist.add()
trait.arm_traitparamslist_index = len(trait.arm_traitparamslist) - 1
return{'FINISHED'}
class LIST_OT_ParamsTraitDeleteItem(bpy.types.Operator):
class ArmTraitParamListDeleteItem(bpy.types.Operator):
# Delete the selected item from the list
bl_idname = "my_paramstraitlist.delete_item"
bl_idname = "arm_traitparamslist.delete_item"
bl_label = "Deletes an item"
@classmethod
def poll(self, context):
""" Enable if there's something in the list """
if len(context.object.my_traitlist) == 0:
if len(context.object.arm_traitlist) == 0:
return False
trait = context.object.my_traitlist[context.object.traitlist_index]
return len(trait.my_paramstraitlist) > 0
trait = context.object.arm_traitlist[context.object.arm_traitlist_index]
return len(trait.arm_traitparamslist) > 0
def execute(self, context):
if len(context.object.my_traitlist) == 0:
if len(context.object.arm_traitlist) == 0:
return
trait = context.object.my_traitlist[context.object.traitlist_index]
list = trait.my_paramstraitlist
index = trait.paramstraitlist_index
trait = context.object.arm_traitlist[context.object.arm_traitlist_index]
list = trait.arm_traitparamslist
index = trait.arm_traitparamslist_index
list.remove(index)
if index > 0:
index = index - 1
trait.paramstraitlist_index = index
trait.arm_traitparamslist_index = index
return{'FINISHED'}
class LIST_OT_ParamsTraitMoveItem(bpy.types.Operator):
class ArmTraitParamListMoveItem(bpy.types.Operator):
# Move an item in the list
bl_idname = "my_paramstraitlist.move_item"
bl_idname = "arm_traitparamslist.move_item"
bl_label = "Move an item in the list"
direction = bpy.props.EnumProperty(
items=(
@ -110,19 +79,19 @@ class LIST_OT_ParamsTraitMoveItem(bpy.types.Operator):
@classmethod
def poll(self, context):
""" Enable if there's something in the list. """
if len(context.object.my_traitlist) == 0:
if len(context.object.arm_traitlist) == 0:
return False
trait = context.object.my_traitlist[context.object.traitlist_index]
return len(trait.my_paramstraitlist) > 0
trait = context.object.arm_traitlist[context.object.arm_traitlist_index]
return len(trait.arm_traitparamslist) > 0
def move_index(self):
# Move index of an item render queue while clamping it
if len(context.object.my_traitlist) == 0:
if len(context.object.arm_traitlist) == 0:
return
trait = context.object.my_traitlist[context.object.traitlist_index]
index = trait.paramstraitlist_index
list_length = len(trait.my_paramstraitlist) - 1
trait = context.object.arm_traitlist[context.object.arm_traitlist_index]
index = trait.arm_traitparamslist_index
list_length = len(trait.arm_traitparamslist) - 1
new_index = 0
if self.direction == 'UP':
@ -135,11 +104,11 @@ class LIST_OT_ParamsTraitMoveItem(bpy.types.Operator):
def execute(self, context):
if len(context.object.my_traitlist) == 0:
if len(context.object.arm_traitlist) == 0:
return
trait = context.object.my_traitlist[context.object.traitlist_index]
list = trait.my_paramstraitlist
index = trait.paramstraitlist_index
trait = context.object.arm_traitlist[context.object.arm_traitlist_index]
list = trait.arm_traitparamslist
index = trait.arm_traitparamslist_index
if self.direction == 'DOWN':
neighbor = index + 1
@ -155,15 +124,15 @@ class LIST_OT_ParamsTraitMoveItem(bpy.types.Operator):
return{'FINISHED'}
def register():
bpy.utils.register_class(ListParamsTraitItem)
bpy.utils.register_class(MY_UL_ParamsTraitList)
bpy.utils.register_class(LIST_OT_ParamsTraitNewItem)
bpy.utils.register_class(LIST_OT_ParamsTraitDeleteItem)
bpy.utils.register_class(LIST_OT_ParamsTraitMoveItem)
bpy.utils.register_class(ArmTraitParamListItem)
bpy.utils.register_class(ArmTraitParamList)
bpy.utils.register_class(ArmTraitParamListNewItem)
bpy.utils.register_class(ArmTraitParamListDeleteItem)
bpy.utils.register_class(ArmTraitParamListMoveItem)
def unregister():
bpy.utils.unregister_class(ListParamsTraitItem)
bpy.utils.unregister_class(MY_UL_ParamsTraitList)
bpy.utils.unregister_class(LIST_OT_ParamsTraitNewItem)
bpy.utils.unregister_class(LIST_OT_ParamsTraitDeleteItem)
bpy.utils.unregister_class(LIST_OT_ParamsTraitMoveItem)
bpy.utils.unregister_class(ArmTraitParamListItem)
bpy.utils.unregister_class(ArmTraitParamList)
bpy.utils.unregister_class(ArmTraitParamListNewItem)
bpy.utils.unregister_class(ArmTraitParamListDeleteItem)
bpy.utils.unregister_class(ArmTraitParamListMoveItem)

View file

@ -6,7 +6,7 @@ from bpy.types import Menu, Panel, UIList
from bpy.props import *
from arm.utils import to_hex
class ListPropsTraitItem(bpy.types.PropertyGroup):
class ArmTraitPropListItem(bpy.types.PropertyGroup):
# Group of properties representing an item in the list
name = bpy.props.StringProperty(
name="Name",
@ -18,7 +18,7 @@ class ListPropsTraitItem(bpy.types.PropertyGroup):
description="A name for this item",
default="")
class MY_UL_PropsTraitList(bpy.types.UIList):
class ArmTraitPropList(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# We could write some code to decide which icon to use here...
custom_icon = 'OBJECT_DATAMODE'
@ -35,9 +35,9 @@ class MY_UL_PropsTraitList(bpy.types.UIList):
layout.label("", icon = custom_icon)
def register():
bpy.utils.register_class(ListPropsTraitItem)
bpy.utils.register_class(MY_UL_PropsTraitList)
bpy.utils.register_class(ArmTraitPropListItem)
bpy.utils.register_class(ArmTraitPropList)
def unregister():
bpy.utils.unregister_class(ListPropsTraitItem)
bpy.utils.unregister_class(MY_UL_PropsTraitList)
bpy.utils.unregister_class(ArmTraitPropListItem)
bpy.utils.unregister_class(ArmTraitPropList)

View file

@ -27,36 +27,33 @@ class ObjectPropsPanel(bpy.types.Panel):
wrd = bpy.data.worlds['Arm']
row = layout.row()
row.prop(obj, 'game_export')
if not obj.game_export:
row.prop(obj, 'arm_export')
if not obj.arm_export:
return
row.prop(obj, 'spawn')
row.prop(obj, 'arm_spawn')
row = layout.row()
row.prop(obj, 'mobile')
if obj.type == 'ARMATURE':
row.prop(obj, 'bone_animation_enabled')
else:
row.prop(obj, 'object_animation_enabled')
row.prop(obj, 'arm_mobile')
row.prop(obj, 'arm_animation_enabled')
if obj.type == 'MESH':
layout.prop(obj, 'arm_instanced')
if obj.arm_instanced:
layout.label('Location')
column = layout.column()
column.prop(obj, 'arm_instanced_child')
column.prop(obj, 'arm_instanced_child')
column.prop(obj, 'arm_instanced_child')
column.prop(obj, 'arm_instanced_loc_x')
column.prop(obj, 'arm_instanced_loc_y')
column.prop(obj, 'arm_instanced_loc_z')
# layout.label('Rotation')
# row = layout.row()
# row.prop(obj, 'arm_instanced_child')
# row.prop(obj, 'arm_instanced_child')
# row.prop(obj, 'arm_instanced_child')
# row.prop(obj, 'arm_instanced')
# row.prop(obj, 'arm_instanced')
# row.prop(obj, 'arm_instanced')
# layout.label('Scale')
# row = layout.row()
# row.prop(obj, 'arm_instanced_childre')
# row.prop(obj, 'arm_instanced_childre')
# row.prop(obj, 'arm_instanced_childre')
# row.prop(obj, 'arm_instanced')
# row.prop(obj, 'arm_instanced')
# row.prop(obj, 'arm_instanced')
class ModifiersPropsPanel(bpy.types.Panel):
bl_label = "Armory Props"
@ -74,15 +71,15 @@ class ModifiersPropsPanel(bpy.types.Panel):
# Assume as first modifier
if len(obj.modifiers) > 0 and obj.modifiers[0].type == 'OCEAN':
layout.prop(bpy.data.worlds['Arm'], 'generate_ocean_base_color')
layout.prop(bpy.data.worlds['Arm'], 'generate_ocean_water_color')
layout.prop(bpy.data.worlds['Arm'], 'generate_ocean_fade')
layout.prop(bpy.data.worlds['Arm'], 'generate_ocean_amplitude')
layout.prop(bpy.data.worlds['Arm'], 'generate_ocean_height')
layout.prop(bpy.data.worlds['Arm'], 'generate_ocean_choppy')
layout.prop(bpy.data.worlds['Arm'], 'generate_ocean_speed')
layout.prop(bpy.data.worlds['Arm'], 'generate_ocean_freq')
layout.prop(bpy.data.worlds['Arm'], 'generate_ocean_fade')
layout.prop(bpy.data.worlds['Arm'], 'arm_ocean_base_color')
layout.prop(bpy.data.worlds['Arm'], 'arm_ocean_water_color')
layout.prop(bpy.data.worlds['Arm'], 'arm_ocean_fade')
layout.prop(bpy.data.worlds['Arm'], 'arm_ocean_amplitude')
layout.prop(bpy.data.worlds['Arm'], 'arm_ocean_height')
layout.prop(bpy.data.worlds['Arm'], 'arm_ocean_choppy')
layout.prop(bpy.data.worlds['Arm'], 'arm_ocean_speed')
layout.prop(bpy.data.worlds['Arm'], 'arm_ocean_freq')
layout.prop(bpy.data.worlds['Arm'], 'arm_ocean_fade')
class PhysicsPropsPanel(bpy.types.Panel):
bl_label = "Armory Props"
@ -96,7 +93,7 @@ class PhysicsPropsPanel(bpy.types.Panel):
if obj == None:
return
layout.prop(obj, 'soft_body_margin')
layout.prop(obj, 'arm_soft_body_margin')
# Menu in data region
class DataPropsPanel(bpy.types.Panel):
@ -113,42 +110,42 @@ class DataPropsPanel(bpy.types.Panel):
wrd = bpy.data.worlds['Arm']
if obj.type == 'CAMERA':
layout.prop_search(obj.data, "renderpath_path", bpy.data, "node_groups")
layout.prop(obj.data, 'frustum_culling')
layout.prop(obj.data, 'is_mirror')
layout.prop_search(wrd, "renderpath_path", bpy.data, "node_groups")
layout.prop(obj.data, 'arm_frustum_culling')
layout.prop(obj.data, 'arm_render_to_texture')
col = layout.column()
col.enabled = obj.data.is_mirror
col.enabled = obj.data.arm_render_to_texture
row = col.row(align=True)
row.label('Resolution')
row.prop(obj.data, 'mirror_resolution_x')
row.prop(obj.data, 'mirror_resolution_y')
row.prop(obj.data, 'arm_texture_resolution_x')
row.prop(obj.data, 'arm_texture_resolution_y')
elif obj.type == 'MESH' or obj.type == 'FONT' or obj.type == 'META':
row = layout.row(align=True)
row.prop(obj.data, 'dynamic_usage')
row.prop(obj.data, 'data_compressed')
row.prop(obj.data, 'arm_dynamic_usage')
row.prop(obj.data, 'arm_compress')
if obj.type == 'MESH':
layout.prop(obj.data, 'sdfgen')
layout.prop(obj.data, 'arm_sdfgen')
layout.operator("arm.invalidate_cache")
elif obj.type == 'LAMP':
row = layout.row(align=True)
col = row.column()
col.prop(obj.data, 'lamp_clip_start')
col.prop(obj.data, 'lamp_clip_end')
col.prop(obj.data, 'arm_clip_start')
col.prop(obj.data, 'arm_clip_end')
col = row.column()
col.prop(obj.data, 'lamp_fov')
col.prop(obj.data, 'lamp_shadows_bias')
col.prop(obj.data, 'arm_fov')
col.prop(obj.data, 'arm_shadows_bias')
if obj.data.type == 'POINT':
layout.prop(obj.data, 'lamp_omni_shadows')
layout.prop(obj.data, 'arm_omni_shadows')
col = layout.column()
col.enabled = obj.data.lamp_omni_shadows
col.prop(wrd, 'lamp_omni_shadows_pcfsize')
layout.prop(wrd, 'generate_lamp_texture')
layout.prop(wrd, 'generate_lamp_ies_texture')
col.enabled = obj.data.arm_omni_shadows
col.prop(wrd, 'arm_pcfsize')
layout.prop(wrd, 'arm_lamp_texture')
layout.prop(wrd, 'arm_lamp_ies_texture')
elif obj.type == 'SPEAKER':
layout.prop(obj.data, 'loop')
layout.prop(obj.data, 'stream')
elif obj.type == 'ARMATURE':
layout.prop(obj.data, 'data_compressed')
layout.prop(obj.data, 'arm_compress')
class ScenePropsPanel(bpy.types.Panel):
bl_label = "Armory Props"
@ -163,12 +160,12 @@ class ScenePropsPanel(bpy.types.Panel):
return
row = layout.row()
column = row.column()
column.prop(scene, 'game_export')
column.prop(scene, 'data_compressed')
column.prop(scene, 'arm_export')
column.prop(scene, 'arm_compress')
column = row.column()
column.prop(scene, 'gp_export')
column.prop(scene, 'arm_gp_export')
columnb = column.column()
columnb.enabled = scene.gp_export
columnb.enabled = scene.arm_gp_export
columnb.operator('arm.invalidate_gp_cache')
class InvalidateCacheButton(bpy.types.Operator):
@ -177,7 +174,7 @@ class InvalidateCacheButton(bpy.types.Operator):
bl_label = "Invalidate Cache"
def execute(self, context):
context.object.data.mesh_cached = False
context.object.data.arm_cached = False
return{'FINISHED'}
class InvalidateMaterialCacheButton(bpy.types.Operator):
@ -196,7 +193,7 @@ class InvalidateGPCacheButton(bpy.types.Operator):
def execute(self, context):
if context.scene.grease_pencil != None:
context.scene.grease_pencil.data_cached = False
context.scene.grease_pencil.arm_data_cached = False
return{'FINISHED'}
class MaterialPropsPanel(bpy.types.Panel):
@ -213,58 +210,40 @@ class MaterialPropsPanel(bpy.types.Panel):
row = layout.row()
column = row.column()
column.prop(mat, 'cast_shadow')
column.prop(mat, 'receive_shadow')
column.prop(mat, 'arm_cast_shadow')
column.prop(mat, 'arm_receive_shadow')
column.separator()
column.prop(mat, 'two_sided_shading')
column.prop(mat, 'arm_two_sided')
columnb = column.column()
columnb.enabled = not mat.two_sided_shading
columnb.prop(mat, 'override_cull_mode')
columnb.enabled = not mat.arm_two_sided
columnb.prop(mat, 'arm_cull_mode')
column = row.column()
column.prop(mat, 'overlay')
column.prop(mat, 'decal')
column.prop(mat, 'arm_overlay')
column.prop(mat, 'arm_decal')
column.separator()
column.prop(mat, 'discard_transparent')
column.prop(mat, 'arm_discard')
columnb = column.column()
columnb.enabled = mat.discard_transparent
columnb.prop(mat, 'discard_transparent_opacity')
columnb.prop(mat, 'discard_transparent_opacity_shadows')
# row = layout.row()
# column = row.column()
# column.prop(mat, 'override_shader')
# columnb = column.column()
# columnb.enabled = mat.override_shader
# columnb.prop(mat, 'override_shader_name')
# column = row.column()
# column.prop(mat, 'override_shader_context')
# columnb = column.column()
# columnb.enabled = mat.override_shader_context
# columnb.prop(mat, 'override_shader_context_name')
# row = layout.row()
# row.prop(mat, 'stencil_mask')
# row.prop(mat, 'skip_context')
columnb.enabled = mat.arm_discard
columnb.prop(mat, 'arm_discard_opacity')
columnb.prop(mat, 'arm_discard_opacity_shadows')
layout.separator()
row = layout.row()
column = row.column()
column.prop(mat, 'height_tess')
column.prop(mat, 'arm_tess')
columnb = column.column()
columnb.enabled = mat.height_tess
columnb.prop(mat, 'height_tess_inner')
columnb.prop(mat, 'height_tess_outer')
columnb.enabled = mat.arm_tess
columnb.prop(mat, 'arm_tess_inner')
columnb.prop(mat, 'arm_tess_outer')
column = row.column()
column.prop(mat, 'height_tess_shadows')
column.prop(mat, 'arm_tess_shadows')
columnb = column.column()
columnb.enabled = mat.height_tess_shadows
columnb.prop(mat, 'height_tess_shadows_inner')
columnb.prop(mat, 'height_tess_shadows_outer')
layout.prop(mat, 'transluc_shadows')
columnb.enabled = mat.arm_tess_shadows
columnb.prop(mat, 'arm_tess_shadows_inner')
columnb.prop(mat, 'arm_tess_shadows_outer')
layout.operator("arm.invalidate_material_cache")
@ -279,15 +258,19 @@ class WorldPropsPanel(bpy.types.Panel):
# wrd = bpy.context.world
wrd = bpy.data.worlds['Arm']
layout.prop(wrd, 'generate_irradiance')
layout.prop(wrd, 'arm_irradiance')
row = layout.row()
row.enabled = wrd.generate_irradiance
row.enabled = wrd.arm_irradiance
column = row.column()
column.prop(wrd, 'generate_radiance')
column.prop(wrd, 'generate_radiance_size')
column.prop(wrd, 'arm_radiance')
columnb = column.column()
columnb.enabled = wrd.arm_radiance
columnb.prop(wrd, 'arm_radiance_size')
column = row.column()
column.prop(wrd, 'generate_radiance_sky')
column.prop(wrd, 'generate_radiance_sky_type')
column.prop(wrd, 'arm_radiance_sky')
columnb = column.column()
columnb.enabled = wrd.arm_radiance_sky
columnb.prop(wrd, 'arm_radiance_sky_type')
class ArmoryPlayerPanel(bpy.types.Panel):
bl_label = "Armory Player"
@ -431,7 +414,7 @@ class ArmoryProjectPanel(bpy.types.Panel):
rows = 4
row = layout.row()
row.template_list("MY_UL_LibraryTraitList", "The_List", wrd, "arm_librarylist", wrd, "arm_librarylist_index", rows=rows)
row.template_list("ArmLibraryList", "The_List", wrd, "arm_librarylist", wrd, "arm_librarylist_index", rows=rows)
col = row.column(align=True)
col.operator("arm_librarylist.new_item", icon='ZOOMIN', text="")
@ -494,15 +477,15 @@ class ArmoryGenerateNavmeshButton(bpy.types.Operator):
# TODO: build tilecache here
# Navmesh trait
obj.my_traitlist.add()
obj.my_traitlist[-1].type_prop = 'Bundled Script'
obj.my_traitlist[-1].class_name_prop = 'NavMesh'
obj.arm_traitlist.add()
obj.arm_traitlist[-1].type_prop = 'Bundled Script'
obj.arm_traitlist[-1].class_name_prop = 'NavMesh'
# For visualization
bpy.ops.mesh.navmesh_make('EXEC_DEFAULT')
obj = context.active_object
obj.hide_render = True
obj.game_export = False
obj.arm_export = False
return{'FINISHED'}
@ -813,44 +796,20 @@ class ArmRenderPathPanel(bpy.types.Panel):
layout.prop(dat, "rp_preset")
layout.separator()
layout.prop(dat, "rp_renderer")
layout.prop(wrd, 'material_model')
layout.prop(wrd, "arm_material_model")
layout.prop(dat, "rp_shadowmap")
layout.prop(dat, "rp_meshes")
layout.prop(dat, "rp_translucency_state")
layout.prop(dat, "rp_overlays_state")
layout.prop(dat, "rp_decals_state")
layout.prop(dat, "rp_sss_state")
if dat.rp_sss_state != 'Off':
layout.prop(wrd, 'sss_width')
layout.prop(dat, "rp_hdr")
layout.prop(dat, "rp_worldnodes")
if not dat.rp_worldnodes:
layout.prop(dat, "rp_clearbackground")
layout.prop(dat, "rp_world")
col = layout.column()
col.enabled = not dat.rp_world
col.prop(dat, "rp_clearbackground")
layout.prop(dat, "rp_stereo")
layout.prop(dat, "rp_greasepencil")
layout.prop(dat, 'rp_voxelgi')
if dat.rp_voxelgi:
layout.prop(dat, 'rp_voxelgi_resolution')
layout.prop(wrd, 'generate_voxelgi_dimensions')
row = layout.row()
row.prop(wrd, 'voxelgi_diff')
row.prop(wrd, 'voxelgi_spec')
row = layout.row()
row.prop(wrd, 'voxelgi_occ')
row.prop(wrd, 'voxelgi_env')
row = layout.row()
row.prop(wrd, 'voxelgi_step')
row.prop(wrd, 'voxelgi_range')
row = layout.row()
row.prop(wrd, 'voxelgi_revoxelize')
row.prop(wrd, 'voxelgi_multibounce')
row = layout.row()
row.prop(wrd, 'voxelgi_camera')
row.prop(wrd, 'voxelgi_anisotropic')
row = layout.row()
row.prop(wrd, 'voxelgi_shadows')
row.prop(wrd, 'voxelgi_refraction')
layout.prop(dat, 'rp_voxelgi_hdr')
layout.separator()
layout.prop(dat, "rp_render_to_texture")
@ -870,6 +829,23 @@ class ArmRenderPathPanel(bpy.types.Panel):
layout.prop(dat, "rp_rendercapture")
layout.prop(dat, "rp_ocean")
layout.prop(wrd, 'arm_pcss_state')
layout.prop(wrd, 'arm_ssrs')
layout.prop(wrd, 'arm_samples_per_pixel')
row = layout.row()
row.prop(wrd, 'arm_gpu_skin')
if wrd.arm_gpu_skin:
row.prop(wrd, 'arm_gpu_skin_max_bones_auto')
if not wrd.arm_gpu_skin_max_bones_auto:
layout.prop(wrd, 'arm_gpu_skin_max_bones')
layout.prop(wrd, 'arm_texture_filter')
layout.prop(wrd, 'arm_tessellation')
layout.prop(wrd, 'arm_culling')
layout.prop(wrd, 'arm_two_sided_area_lamp')
layout.prop(wrd, 'arm_clouds')
layout.prop(wrd, 'arm_tonemap')
class ArmRenderPropsPanel(bpy.types.Panel):
bl_label = "Armory Render Props"
bl_space_type = "PROPERTIES"
@ -880,88 +856,87 @@ class ArmRenderPropsPanel(bpy.types.Panel):
def draw(self, context):
layout = self.layout
wrd = bpy.data.worlds['Arm']
dat = bpy.data.worlds['Arm']
layout.prop(wrd, 'generate_pcss_state')
if wrd.generate_pcss_state == 'On' or wrd.generate_pcss_state == 'Auto':
layout.prop(wrd, 'generate_pcss_rings')
layout.prop(wrd, 'generate_ssrs')
layout.label('PCSS')
layout.prop(wrd, 'arm_pcss_rings')
layout.label('Clouds')
layout.prop(wrd, 'arm_clouds_density')
layout.prop(wrd, 'arm_clouds_size')
layout.prop(wrd, 'arm_clouds_lower')
layout.prop(wrd, 'arm_clouds_upper')
layout.prop(wrd, 'arm_clouds_wind')
layout.prop(wrd, 'arm_clouds_secondary')
layout.prop(wrd, 'arm_clouds_precipitation')
layout.prop(wrd, 'arm_clouds_eccentricity')
layout.prop(wrd, 'arm_samples_per_pixel')
layout.label('Voxel GI')
layout.prop(dat, 'rp_voxelgi_resolution')
layout.prop(wrd, 'arm_voxelgi_dimensions')
row = layout.row()
row.prop(wrd, 'generate_gpu_skin')
if wrd.generate_gpu_skin:
row.prop(wrd, 'generate_gpu_skin_max_bones_auto')
if not wrd.generate_gpu_skin_max_bones_auto:
layout.prop(wrd, 'generate_gpu_skin_max_bones')
layout.prop(wrd, 'texture_filtering_state')
layout.prop(wrd, 'tessellation_enabled')
layout.prop(wrd, 'force_no_culling')
layout.prop(wrd, 'generate_two_sided_area_lamp')
row.prop(wrd, 'arm_voxelgi_diff')
row.prop(wrd, 'arm_voxelgi_spec')
row = layout.row()
row.prop(wrd, 'arm_voxelgi_occ')
row.prop(wrd, 'arm_voxelgi_env')
row = layout.row()
row.prop(wrd, 'arm_voxelgi_step')
row.prop(wrd, 'arm_voxelgi_range')
row = layout.row()
row.prop(wrd, 'arm_voxelgi_revoxelize')
row.prop(wrd, 'arm_voxelgi_multibounce')
row = layout.row()
row.prop(wrd, 'arm_voxelgi_camera')
row.prop(wrd, 'arm_voxelgi_anisotropic')
row = layout.row()
row.prop(wrd, 'arm_voxelgi_shadows')
row.prop(wrd, 'arm_voxelgi_refraction')
layout.prop(dat, 'rp_voxelgi_hdr')
layout.prop(wrd, 'generate_clouds')
if wrd.generate_clouds:
layout.prop(wrd, 'generate_clouds_density')
layout.prop(wrd, 'generate_clouds_size')
layout.prop(wrd, 'generate_clouds_lower')
layout.prop(wrd, 'generate_clouds_upper')
layout.prop(wrd, 'generate_clouds_wind')
layout.prop(wrd, 'generate_clouds_secondary')
layout.prop(wrd, 'generate_clouds_precipitation')
layout.prop(wrd, 'generate_clouds_eccentricity')
layout.label('SSAO')
# layout.prop(wrd, 'generate_ssao')
# if wrd.generate_ssao:
layout.prop(wrd, 'generate_ssao_size')
layout.prop(wrd, 'generate_ssao_strength')
layout.prop(wrd, 'generate_ssao_half_res')
layout.prop(wrd, 'arm_ssao_size')
layout.prop(wrd, 'arm_ssao_strength')
layout.prop(wrd, 'arm_ssao_half_res')
layout.label('Bloom')
# layout.prop(wrd, 'generate_bloom')
# if wrd.generate_bloom:
layout.prop(wrd, 'generate_bloom_threshold')
layout.prop(wrd, 'generate_bloom_strength')
layout.prop(wrd, 'generate_bloom_radius')
layout.prop(wrd, 'arm_bloom_threshold')
layout.prop(wrd, 'arm_bloom_strength')
layout.prop(wrd, 'arm_bloom_radius')
layout.label('Motion Blur')
# layout.prop(wrd, 'generate_motion_blur')
# if wrd.generate_motion_blur:
layout.prop(wrd, 'generate_motion_blur_intensity')
layout.prop(wrd, 'arm_motion_blur_intensity')
layout.label('SSR')
# layout.prop(wrd, 'generate_ssr')
# if wrd.generate_ssr:
layout.prop(wrd, 'generate_ssr_ray_step')
layout.prop(wrd, 'generate_ssr_min_ray_step')
layout.prop(wrd, 'generate_ssr_search_dist')
layout.prop(wrd, 'generate_ssr_falloff_exp')
layout.prop(wrd, 'generate_ssr_jitter')
layout.prop(wrd, 'generate_ssr_half_res')
layout.prop(wrd, 'arm_ssr_ray_step')
layout.prop(wrd, 'arm_ssr_min_ray_step')
layout.prop(wrd, 'arm_ssr_search_dist')
layout.prop(wrd, 'arm_ssr_falloff_exp')
layout.prop(wrd, 'arm_ssr_jitter')
layout.prop(wrd, 'arm_ssr_half_res')
layout.label('SSS')
layout.prop(wrd, 'arm_sss_width')
layout.label('SSRS')
layout.prop(wrd, 'generate_ssrs_ray_step')
layout.prop(wrd, 'arm_ssrs_ray_step')
layout.label('Volumetric Light')
# layout.prop(wrd, 'generate_volumetric_light')
# if wrd.generate_volumetric_light:
layout.prop(wrd, 'generate_volumetric_light_air_turbidity')
layout.prop(wrd, 'generate_volumetric_light_air_color')
layout.prop(wrd, 'arm_volumetric_light_air_turbidity')
layout.prop(wrd, 'arm_volumetric_light_air_color')
layout.prop(wrd, 'generate_tonemap')
layout.prop(wrd, 'generate_letterbox')
if wrd.generate_letterbox:
layout.prop(wrd, 'generate_letterbox_size')
layout.prop(wrd, 'generate_grain')
if wrd.generate_grain:
layout.prop(wrd, 'generate_grain_strength')
layout.prop(wrd, 'generate_fog')
if wrd.generate_fog:
layout.prop(wrd, 'generate_fog_color')
layout.prop(wrd, 'generate_fog_amounta')
layout.prop(wrd, 'generate_fog_amountb')
layout.prop(wrd, 'generate_fisheye')
layout.prop(wrd, 'generate_vignette')
layout.prop(wrd, 'generate_lens_texture')
layout.label('Compositor')
layout.prop(wrd, 'arm_letterbox')
layout.prop(wrd, 'arm_letterbox_size')
layout.prop(wrd, 'arm_grain')
layout.prop(wrd, 'arm_grain_strength')
layout.prop(wrd, 'arm_fog')
layout.prop(wrd, 'arm_fog_color')
layout.prop(wrd, 'arm_fog_amounta')
layout.prop(wrd, 'arm_fog_amountb')
layout.prop(wrd, 'arm_fisheye')
layout.prop(wrd, 'arm_vignette')
layout.prop(wrd, 'arm_lens_texture')
class ArmGenLodButton(bpy.types.Operator):
'''Automatically generate LoD levels'''
@ -978,8 +953,8 @@ class ArmGenLodButton(bpy.types.Operator):
# Clear
mdata = context.object.data
mdata.lodlist_index = 0
mdata.my_lodlist.clear()
mdata.arm_lodlist_index = 0
mdata.arm_lodlist.clear()
# Lod levels
wrd = bpy.data.worlds['Arm']
@ -1003,9 +978,9 @@ class ArmGenLodButton(bpy.types.Operator):
# Screen sizes
for level in range(0, num_levels):
mdata.my_lodlist.add()
mdata.my_lodlist[-1].name = self.lod_name(obj.name, level)
mdata.my_lodlist[-1].screen_size_prop = (1 - (1 / (num_levels + 1)) * level) - (1 / (num_levels + 1))
mdata.arm_lodlist.add()
mdata.arm_lodlist[-1].name = self.lod_name(obj.name, level)
mdata.arm_lodlist[-1].screen_size_prop = (1 - (1 / (num_levels + 1)) * level) - (1 / (num_levels + 1))
return{'FINISHED'}
@ -1027,17 +1002,17 @@ class ArmLodPanel(bpy.types.Panel):
mdata = obj.data
rows = 2
if len(mdata.my_lodlist) > 1:
if len(mdata.arm_lodlist) > 1:
rows = 4
row = layout.row()
row.template_list("MY_UL_LodList", "The_List", mdata, "my_lodlist", mdata, "lodlist_index", rows=rows)
row.template_list("ArmLodList", "The_List", mdata, "arm_lodlist", mdata, "arm_lodlist_index", rows=rows)
col = row.column(align=True)
col.operator("my_lodlist.new_item", icon='ZOOMIN', text="")
col.operator("my_lodlist.delete_item", icon='ZOOMOUT', text="")
col.operator("arm_lodlist.new_item", icon='ZOOMIN', text="")
col.operator("arm_lodlist.delete_item", icon='ZOOMOUT', text="")
if mdata.lodlist_index >= 0 and len(mdata.my_lodlist) > 0:
item = mdata.my_lodlist[mdata.lodlist_index]
if mdata.arm_lodlist_index >= 0 and len(mdata.arm_lodlist) > 0:
item = mdata.arm_lodlist[mdata.arm_lodlist_index]
row = layout.row()
row.prop_search(item, "name", bpy.data, "objects", "Object")
row = layout.row()
@ -1052,7 +1027,7 @@ class ArmLodPanel(bpy.types.Panel):
row.prop(wrd, 'arm_lod_gen_levels')
row.prop(wrd, 'arm_lod_gen_ratio')
layout.prop(mdata, "lod_material")
layout.prop(mdata, "arm_lod_material")
def register():
bpy.utils.register_class(ObjectPropsPanel)

View file

@ -141,10 +141,10 @@ def krom_paths():
def fetch_bundled_script_names():
wrd = bpy.data.worlds['Arm']
wrd.bundled_scripts_list.clear()
wrd.arm_bundled_scripts_list.clear()
os.chdir(get_sdk_path() + '/armory/Sources/armory/trait')
for file in glob.glob('*.hx'):
wrd.bundled_scripts_list.add().name = file.rsplit('.')[0]
wrd.arm_bundled_scripts_list.add().name = file.rsplit('.')[0]
script_props = {}
script_props_defaults = {}
@ -184,46 +184,46 @@ def fetch_script_names():
return
wrd = bpy.data.worlds['Arm']
# Sources
wrd.scripts_list.clear()
wrd.arm_scripts_list.clear()
sources_path = get_fp() + '/Sources/' + safestr(wrd.arm_project_package)
if os.path.isdir(sources_path):
os.chdir(sources_path)
for file in glob.glob('*.hx'):
name = file.rsplit('.')[0]
wrd.scripts_list.add().name = name
wrd.arm_scripts_list.add().name = name
fetch_script_props(file)
# Canvas
wrd.canvas_list.clear()
wrd.arm_canvas_list.clear()
canvas_path = get_fp() + '/Bundled/canvas'
if os.path.isdir(canvas_path):
os.chdir(canvas_path)
for file in glob.glob('*.json'):
wrd.canvas_list.add().name = file.rsplit('.')[0]
wrd.arm_canvas_list.add().name = file.rsplit('.')[0]
os.chdir(get_fp())
def fetch_trait_props():
for o in bpy.data.objects:
for item in o.my_traitlist:
for item in o.arm_traitlist:
if item.name not in script_props:
continue
props = script_props[item.name]
defaults = script_props_defaults[item.name]
# Remove old props
for i in range(len(item.my_propstraitlist) - 1, -1, -1):
ip = item.my_propstraitlist[i]
for i in range(len(item.arm_traitpropslist) - 1, -1, -1):
ip = item.arm_traitpropslist[i]
if ip.name not in props:
item.my_propstraitlist.remove(i)
item.arm_traitpropslist.remove(i)
# Add new props
for i in range(0, len(props)):
p = props[i]
found = False
for ip in item.my_propstraitlist:
for ip in item.arm_traitpropslist:
if ip.name == p:
found = True
break
if not found:
prop = item.my_propstraitlist.add()
prop = item.arm_traitpropslist.add()
prop.name = p
prop.value = defaults[i]
@ -321,11 +321,11 @@ def check_engine(self):
return True
def tess_enabled(target):
return (target == 'krom' or target == 'native') and bpy.data.worlds['Arm'].tessellation_enabled
return (target == 'krom' or target == 'native') and bpy.data.worlds['Arm'].arm_tessellation
def is_object_animation_enabled(bobject):
# Checks if animation is present and enabled
if bobject.object_animation_enabled == False or bobject.type == 'BONE' or bobject.type == 'ARMATURE':
if bobject.arm_animation_enabled == False or bobject.type == 'BONE' or bobject.type == 'ARMATURE':
return False
if bobject.animation_data and bobject.animation_data.action:
return True
@ -334,14 +334,14 @@ def is_object_animation_enabled(bobject):
def is_bone_animation_enabled(bobject):
# Checks if animation is present and enabled for parented armature
if bobject.parent and bobject.parent.type == 'ARMATURE':
if bobject.parent.bone_animation_enabled == False:
if bobject.parent.arm_animation_enabled == False:
return False
if bobject.parent.animation_data and bobject.parent.animation_data.action:
return True
return False
def export_bone_data(bobject):
return bobject.find_armature() and is_bone_animation_enabled(bobject) and bpy.data.worlds['Arm'].generate_gpu_skin == True
return bobject.find_armature() and is_bone_animation_enabled(bobject) and bpy.data.worlds['Arm'].arm_gpu_skin == True
def register():
global krom_found

View file

@ -163,7 +163,7 @@ project.addSources('Sources');
if wrd.arm_stream_scene:
assets.add_khafile_def('arm_stream')
if wrd.generate_gpu_skin == False:
if wrd.arm_gpu_skin == False:
assets.add_khafile_def('arm_cpu_skin')
for d in assets.khafile_defs:
@ -179,7 +179,7 @@ project.addSources('Sources');
def write_main(resx, resy, is_play, in_viewport, is_publish):
wrd = bpy.data.worlds['Arm']
scene_name = arm.utils.get_project_scene_name()
scene_ext = '.zip' if (bpy.data.scenes[scene_name].data_compressed and is_publish) else ''
scene_ext = '.zip' if (bpy.data.scenes[scene_name].arm_compress and is_publish) else ''
#if not os.path.isfile('Sources/Main.hx'):
with open('Sources/Main.hx', 'w') as f:
f.write(
@ -280,7 +280,7 @@ def write_indexhtml(w, h):
def write_compiledglsl():
clip_start = bpy.data.cameras[0].clip_start # Same clip values for all cameras for now
clip_end = bpy.data.cameras[0].clip_end
shadowmap_size = bpy.data.worlds['Arm'].shadowmap_size
shadowmap_size = bpy.data.worlds['Arm'].arm_shadowmap_size_cache
wrd = bpy.data.worlds['Arm']
with open(arm.utils.build_dir() + '/compiled/Shaders/compiled.glsl', 'w') as f:
f.write(
@ -290,82 +290,82 @@ const float PI = 3.1415926535;
const float PI2 = PI * 2.0;
const vec2 cameraPlane = vec2(""" + str(round(clip_start * 100) / 100) + """, """ + str(round(clip_end * 100) / 100) + """);
const vec2 shadowmapSize = vec2(""" + str(shadowmap_size) + """, """ + str(shadowmap_size) + """);
const float shadowmapCubePcfSize = """ + str(round(wrd.lamp_omni_shadows_pcfsize * 10000) / 10000) + """;
const float shadowmapCubePcfSize = """ + str(round(wrd.arm_pcfsize * 10000) / 10000) + """;
""")
if wrd.generate_clouds:
if wrd.arm_clouds:
f.write(
"""const float cloudsDensity = """ + str(round(wrd.generate_clouds_density * 100) / 100) + """;
const float cloudsSize = """ + str(round(wrd.generate_clouds_size * 100) / 100) + """;
const float cloudsLower = """ + str(round(wrd.generate_clouds_lower * 1000)) + """;
const float cloudsUpper = """ + str(round(wrd.generate_clouds_upper * 1000)) + """;
const vec2 cloudsWind = vec2(""" + str(round(wrd.generate_clouds_wind[0] * 1000) / 1000) + """, """ + str(round(wrd.generate_clouds_wind[1] * 1000) / 1000) + """);
const float cloudsSecondary = """ + str(round(wrd.generate_clouds_secondary * 100) / 100) + """;
const float cloudsPrecipitation = """ + str(round(wrd.generate_clouds_precipitation * 100) / 100) + """;
const float cloudsEccentricity = """ + str(round(wrd.generate_clouds_eccentricity * 100) / 100) + """;
"""const float cloudsDensity = """ + str(round(wrd.arm_clouds_density * 100) / 100) + """;
const float cloudsSize = """ + str(round(wrd.arm_clouds_size * 100) / 100) + """;
const float cloudsLower = """ + str(round(wrd.arm_clouds_lower * 1000)) + """;
const float cloudsUpper = """ + str(round(wrd.arm_clouds_upper * 1000)) + """;
const vec2 cloudsWind = vec2(""" + str(round(wrd.arm_clouds_wind[0] * 1000) / 1000) + """, """ + str(round(wrd.arm_clouds_wind[1] * 1000) / 1000) + """);
const float cloudsSecondary = """ + str(round(wrd.arm_clouds_secondary * 100) / 100) + """;
const float cloudsPrecipitation = """ + str(round(wrd.arm_clouds_precipitation * 100) / 100) + """;
const float cloudsEccentricity = """ + str(round(wrd.arm_clouds_eccentricity * 100) / 100) + """;
""")
if wrd.generate_ocean:
if wrd.arm_ocean:
f.write(
"""const float seaLevel = """ + str(round(wrd.generate_ocean_level * 100) / 100) + """;
const float seaMaxAmplitude = """ + str(round(wrd.generate_ocean_amplitude * 100) / 100) + """;
const float seaHeight = """ + str(round(wrd.generate_ocean_height * 100) / 100) + """;
const float seaChoppy = """ + str(round(wrd.generate_ocean_choppy * 100) / 100) + """;
const float seaSpeed = """ + str(round(wrd.generate_ocean_speed * 100) / 100) + """;
const float seaFreq = """ + str(round(wrd.generate_ocean_freq * 100) / 100) + """;
const vec3 seaBaseColor = vec3(""" + str(round(wrd.generate_ocean_base_color[0] * 100) / 100) + """, """ + str(round(wrd.generate_ocean_base_color[1] * 100) / 100) + """, """ + str(round(wrd.generate_ocean_base_color[2] * 100) / 100) + """);
const vec3 seaWaterColor = vec3(""" + str(round(wrd.generate_ocean_water_color[0] * 100) / 100) + """, """ + str(round(wrd.generate_ocean_water_color[1] * 100) / 100) + """, """ + str(round(wrd.generate_ocean_water_color[2] * 100) / 100) + """);
const float seaFade = """ + str(round(wrd.generate_ocean_fade * 100) / 100) + """;
"""const float seaLevel = """ + str(round(wrd.arm_ocean_level * 100) / 100) + """;
const float seaMaxAmplitude = """ + str(round(wrd.arm_ocean_amplitude * 100) / 100) + """;
const float seaHeight = """ + str(round(wrd.arm_ocean_height * 100) / 100) + """;
const float seaChoppy = """ + str(round(wrd.arm_ocean_choppy * 100) / 100) + """;
const float seaSpeed = """ + str(round(wrd.arm_ocean_speed * 100) / 100) + """;
const float seaFreq = """ + str(round(wrd.arm_ocean_freq * 100) / 100) + """;
const vec3 seaBaseColor = vec3(""" + str(round(wrd.arm_ocean_base_color[0] * 100) / 100) + """, """ + str(round(wrd.arm_ocean_base_color[1] * 100) / 100) + """, """ + str(round(wrd.arm_ocean_base_color[2] * 100) / 100) + """);
const vec3 seaWaterColor = vec3(""" + str(round(wrd.arm_ocean_water_color[0] * 100) / 100) + """, """ + str(round(wrd.arm_ocean_water_color[1] * 100) / 100) + """, """ + str(round(wrd.arm_ocean_water_color[2] * 100) / 100) + """);
const float seaFade = """ + str(round(wrd.arm_ocean_fade * 100) / 100) + """;
""")
if wrd.generate_ssao:
scale = 0.5 if wrd.generate_ssao_half_res else 1.0
if wrd.arm_ssao:
scale = 0.5 if wrd.arm_ssao_half_res else 1.0
f.write(
"""const float ssaoSize = """ + str(round(wrd.generate_ssao_size * 100) / 100) + """;
const float ssaoStrength = """ + str(round(wrd.generate_ssao_strength * 100) / 100) + """;
"""const float ssaoSize = """ + str(round(wrd.arm_ssao_size * 100) / 100) + """;
const float ssaoStrength = """ + str(round(wrd.arm_ssao_strength * 100) / 100) + """;
const float ssaoTextureScale = """ + str(scale) + """;
""")
if wrd.generate_bloom:
if wrd.arm_bloom:
f.write(
"""const float bloomThreshold = """ + str(round(wrd.generate_bloom_threshold * 100) / 100) + """;
const float bloomStrength = """ + str(round(wrd.generate_bloom_strength * 100) / 100) + """;
const float bloomRadius = """ + str(round(wrd.generate_bloom_radius * 100) / 100) + """;
"""const float bloomThreshold = """ + str(round(wrd.arm_bloom_threshold * 100) / 100) + """;
const float bloomStrength = """ + str(round(wrd.arm_bloom_strength * 100) / 100) + """;
const float bloomRadius = """ + str(round(wrd.arm_bloom_radius * 100) / 100) + """;
""")
if wrd.generate_motion_blur:
if wrd.arm_motion_blur:
f.write(
"""const float motionBlurIntensity = """ + str(round(wrd.generate_motion_blur_intensity * 100) / 100) + """;
"""const float motionBlurIntensity = """ + str(round(wrd.arm_motion_blur_intensity * 100) / 100) + """;
""")
if wrd.generate_ssr:
if wrd.arm_ssr:
f.write(
"""const float ssrRayStep = """ + str(round(wrd.generate_ssr_ray_step * 100) / 100) + """;
const float ssrMinRayStep = """ + str(round(wrd.generate_ssr_min_ray_step * 100) / 100) + """;
const float ssrSearchDist = """ + str(round(wrd.generate_ssr_search_dist * 100) / 100) + """;
const float ssrFalloffExp = """ + str(round(wrd.generate_ssr_falloff_exp * 100) / 100) + """;
const float ssrJitter = """ + str(round(wrd.generate_ssr_jitter * 100) / 100) + """;
"""const float ssrRayStep = """ + str(round(wrd.arm_ssr_ray_step * 100) / 100) + """;
const float ssrMinRayStep = """ + str(round(wrd.arm_ssr_min_ray_step * 100) / 100) + """;
const float ssrSearchDist = """ + str(round(wrd.arm_ssr_search_dist * 100) / 100) + """;
const float ssrFalloffExp = """ + str(round(wrd.arm_ssr_falloff_exp * 100) / 100) + """;
const float ssrJitter = """ + str(round(wrd.arm_ssr_jitter * 100) / 100) + """;
""")
if wrd.generate_ssrs:
if wrd.arm_ssrs:
f.write(
"""const float ssrsRayStep = """ + str(round(wrd.generate_ssrs_ray_step * 100) / 100) + """;
"""const float ssrsRayStep = """ + str(round(wrd.arm_ssrs_ray_step * 100) / 100) + """;
""")
if wrd.generate_volumetric_light:
if wrd.arm_volumetric_light:
f.write(
"""const float volumAirTurbidity = """ + str(round(wrd.generate_volumetric_light_air_turbidity * 100) / 100) + """;
const vec3 volumAirColor = vec3(""" + str(round(wrd.generate_volumetric_light_air_color[0] * 100) / 100) + """, """ + str(round(wrd.generate_volumetric_light_air_color[1] * 100) / 100) + """, """ + str(round(wrd.generate_volumetric_light_air_color[2] * 100) / 100) + """);
"""const float volumAirTurbidity = """ + str(round(wrd.arm_volumetric_light_air_turbidity * 100) / 100) + """;
const vec3 volumAirColor = vec3(""" + str(round(wrd.arm_volumetric_light_air_color[0] * 100) / 100) + """, """ + str(round(wrd.arm_volumetric_light_air_color[1] * 100) / 100) + """, """ + str(round(wrd.arm_volumetric_light_air_color[2] * 100) / 100) + """);
""")
if wrd.generate_pcss_state == 'On':
if wrd.arm_pcss_state == 'On':
f.write(
"""const int pcssRings = """ + str(wrd.generate_pcss_rings) + """;
"""const int pcssRings = """ + str(wrd.arm_pcss_rings) + """;
""")
# Compositor
if wrd.generate_letterbox:
if wrd.arm_letterbox:
f.write(
"""const float compoLetterboxSize = """ + str(round(wrd.generate_letterbox_size * 100) / 100) + """;
"""const float compoLetterboxSize = """ + str(round(wrd.arm_letterbox_size * 100) / 100) + """;
""")
if wrd.generate_grain:
if wrd.arm_grain:
f.write(
"""const float compoGrainStrength = """ + str(round(wrd.generate_grain_strength * 100) / 100) + """;
"""const float compoGrainStrength = """ + str(round(wrd.arm_grain_strength * 100) / 100) + """;
""")
if bpy.data.scenes[0].cycles.film_exposure != 1.0:
@ -373,11 +373,11 @@ const vec3 volumAirColor = vec3(""" + str(round(wrd.generate_volumetric_light_ai
"""const float compoExposureStrength = """ + str(round(bpy.data.scenes[0].cycles.film_exposure * 100) / 100) + """;
""")
if wrd.generate_fog:
if wrd.arm_fog:
f.write(
"""const float compoFogAmountA = """ + str(round(wrd.generate_fog_amounta * 100) / 100) + """;
const float compoFogAmountB = """ + str(round(wrd.generate_fog_amountb * 100) / 100) + """;
const vec3 compoFogColor = vec3(""" + str(round(wrd.generate_fog_color[0] * 100) / 100) + """, """ + str(round(wrd.generate_fog_color[1] * 100) / 100) + """, """ + str(round(wrd.generate_fog_color[2] * 100) / 100) + """);
"""const float compoFogAmountA = """ + str(round(wrd.arm_fog_amounta * 100) / 100) + """;
const float compoFogAmountB = """ + str(round(wrd.arm_fog_amountb * 100) / 100) + """;
const vec3 compoFogColor = vec3(""" + str(round(wrd.arm_fog_color[0] * 100) / 100) + """, """ + str(round(wrd.arm_fog_color[1] * 100) / 100) + """, """ + str(round(wrd.arm_fog_color[2] * 100) / 100) + """);
""")
if bpy.data.cameras[0].dof_distance > 0.0:
@ -390,24 +390,24 @@ const float compoDOFLength = 160.0;
if bpy.data.worlds['Arm'].rp_voxelgi:
f.write(
"""const float voxelgiResolution = """ + str(bpy.data.worlds['Arm'].rp_voxelgi_resolution) + """;
const float voxelgiDimensions = """ + str(round(wrd.generate_voxelgi_dimensions)) + """;
const float voxelgiDiff = """ + str(round(wrd.voxelgi_diff * 100) / 100) + """;
const float voxelgiSpec = """ + str(round(wrd.voxelgi_spec * 100) / 100) + """;
const float voxelgiOcc = """ + str(round(wrd.voxelgi_occ * 100) / 100) + """;
const float voxelgiEnv = """ + str(round(wrd.voxelgi_env * 100) / 100) + """;
const float voxelgiStep = """ + str(round(wrd.voxelgi_step * 100) / 100) + """;
const float voxelgiRange = """ + str(round(wrd.voxelgi_range * 100) / 100) + """;
const float voxelgiDimensions = """ + str(round(wrd.arm_voxelgi_dimensions)) + """;
const float voxelgiDiff = """ + str(round(wrd.arm_voxelgi_diff * 100) / 100) + """;
const float voxelgiSpec = """ + str(round(wrd.arm_voxelgi_spec * 100) / 100) + """;
const float voxelgiOcc = """ + str(round(wrd.arm_voxelgi_occ * 100) / 100) + """;
const float voxelgiEnv = """ + str(round(wrd.arm_voxelgi_env * 100) / 100) + """;
const float voxelgiStep = """ + str(round(wrd.arm_voxelgi_step * 100) / 100) + """;
const float voxelgiRange = """ + str(round(wrd.arm_voxelgi_range * 100) / 100) + """;
""")
if bpy.data.worlds['Arm'].rp_sss_state == 'On':
f.write(
"""const float sssWidth = """ + str(wrd.sss_width / 10.0) + """;
"""const float sssWidth = """ + str(wrd.arm_sss_width / 10.0) + """;
""")
# Skinning
if wrd.generate_gpu_skin:
if wrd.arm_gpu_skin:
f.write(
"""const int skinMaxBones = """ + str(wrd.generate_gpu_skin_max_bones) + """;
"""const int skinMaxBones = """ + str(wrd.arm_gpu_skin_max_bones) + """;
""")
f.write("""#endif // _COMPILED_GLSL_

View file

@ -16,7 +16,7 @@ def add_rad_assets(output_file_rad, rad_format, num_mips):
assets.add(output_file_rad + '_' + str(i) + '.' + rad_format)
# Generate probes from environment map
def write_probes(image_filepath, disable_hdr, cached_num_mips, generate_radiance=True):
def write_probes(image_filepath, disable_hdr, cached_num_mips, arm_radiance=True):
envpath = arm.utils.build_dir() + '/compiled/Assets/envmaps'
if not os.path.exists(envpath):
@ -26,16 +26,16 @@ def write_probes(image_filepath, disable_hdr, cached_num_mips, generate_radiance
# Assets to be generated
output_file_irr = envpath + '/' + base_name + '_irradiance'
if generate_radiance:
if arm_radiance:
output_file_rad = envpath + '/' + base_name + '_radiance'
rad_format = 'jpg' if disable_hdr else 'hdr'
# Radiance & irradiance exists, keep cache
basep = envpath + '/' + base_name
if os.path.exists(basep + '_irradiance.arm'):
if not generate_radiance or os.path.exists(basep + '_radiance_0.' + rad_format):
if not arm_radiance or os.path.exists(basep + '_radiance_0.' + rad_format):
add_irr_assets(output_file_irr)
if generate_radiance:
if arm_radiance:
add_rad_assets(output_file_rad, rad_format, cached_num_mips)
return cached_num_mips
@ -57,7 +57,7 @@ def write_probes(image_filepath, disable_hdr, cached_num_mips, generate_radiance
# Scale map
wrd = bpy.data.worlds['Arm']
target_w = int(wrd.generate_radiance_size)
target_w = int(wrd.arm_radiance_size)
target_h = int(target_w / 2)
scaled_file = output_file_rad + '.' + rad_format
@ -109,7 +109,7 @@ def write_probes(image_filepath, disable_hdr, cached_num_mips, generate_radiance
add_irr_assets(output_file_irr)
# Mip-mapped radiance
if generate_radiance == False:
if arm_radiance == False:
return cached_num_mips
# 4096 = 256 face
@ -267,7 +267,7 @@ def parse_band_floats(irradiance_floats, band_line):
def write_sky_irradiance(base_name):
wrd = bpy.data.worlds['Arm']
if wrd.generate_radiance_sky_type == 'Hosek':
if wrd.arm_radiance_sky_type == 'Hosek':
# Hosek spherical harmonics
irradiance_floats = [1.5519331988822218,2.3352207154503266,2.997277451988076,0.2673894962434794,0.4305630474135794,0.11331825259716752,-0.04453633521758638,-0.038753175134160295,-0.021302768541875794,0.00055858020486499,0.000371654770334503,0.000126606145406403,-0.000135708721978705,-0.000787399554583089,-0.001550090690860059,0.021947399048903773,0.05453650591711572,0.08783641266630278,0.17053593578630663,0.14734127083304463,0.07775404698816404,-2.6924363189795e-05,-7.9350169701934e-05,-7.559914435231e-05,0.27035455385870993,0.23122918445556914,0.12158817295211832]
for i in range(0, len(irradiance_floats)):

View file

@ -1,7 +1,7 @@
import arm.nodes_logic
import arm.nodes_renderpath
import arm.make_renderer
import arm.props_traits_library
import arm.props_library
import arm.props_traits_params
import arm.props_traits_props
import arm.props_traits
@ -19,16 +19,16 @@ def register():
global registered
registered = True
arm.utils.register()
arm.props_traits_library.register()
arm.props_traits_params.register()
arm.props_traits_props.register()
arm.props_traits.register()
arm.props_lod.register()
arm.props_library.register()
arm.props.register()
arm.props_ui.register()
arm.nodes_logic.register()
arm.nodes_renderpath.register()
arm.make_renderer.register()
arm.props_traits_params.register()
arm.props_traits_props.register()
arm.props_traits.register()
arm.props_lod.register()
arm.space_armory.register()
arm.keymap.register()
arm.handlers.register()
@ -41,12 +41,12 @@ def unregister():
arm.nodes_logic.unregister()
arm.make_renderer.unregister()
arm.nodes_renderpath.unregister()
arm.handlers.unregister()
arm.props_ui.unregister()
arm.props.unregister()
arm.props_library.unregister()
arm.props_traits_params.unregister()
arm.props_traits_props.unregister()
arm.props_traits.unregister()
arm.props_lod.unregister()
arm.handlers.unregister()
arm.props_ui.unregister()
arm.props.unregister()
arm.props_traits_library.unregister()
arm.space_armory.unregister()