io_scene_3ds: Added fog and gradient import and export #104811

Merged
Sebastian Sille merged 64 commits from :main into main 2023-08-01 16:21:54 +02:00
2 changed files with 44 additions and 38 deletions
Showing only changes of commit 820c7a6ec0 - Show all commits

View File

@ -37,6 +37,8 @@ USE_SOLIDBGND = 0x1201 # The background color flag
VGRADIENT = 0x1300 # The background gradient colors VGRADIENT = 0x1300 # The background gradient colors
USE_VGRADIENT = 0x1301 # The background gradient flag USE_VGRADIENT = 0x1301 # The background gradient flag
AMBIENTLIGHT = 0x2100 # The color of the ambient light AMBIENTLIGHT = 0x2100 # The color of the ambient light
LAYER_FOG = 0x2302 # The fog atmosphere settings
USE_LAYER_FOG = 0x2303 # The fog atmosphere flag
MATERIAL = 45055 # 0xAFFF // This stored the texture info MATERIAL = 45055 # 0xAFFF // This stored the texture info
OBJECT = 16384 # 0x4000 // This stores the faces, vertices, etc... OBJECT = 16384 # 0x4000 // This stores the faces, vertices, etc...
@ -1567,17 +1569,17 @@ def save(operator, context, filepath="", scale_factor=1.0, apply_unit=False, use
background_color = _3ds_chunk(RGB) background_color = _3ds_chunk(RGB)
background_chunk = _3ds_chunk(SOLIDBACKGND) background_chunk = _3ds_chunk(SOLIDBACKGND)
background_flag = _3ds_chunk(USE_SOLIDBGND) background_flag = _3ds_chunk(USE_SOLIDBGND)
bgcol, bgtex, nworld = 'BACKGROUND', 'TEX_IMAGE', 'OUTPUT_WORLD' amcol, bgcol, bgtex, nworld = 'EMISSION', 'BACKGROUND', 'TEX_ENVIRONMENT', 'OUTPUT_WORLD'
bg_color = next((lk.from_node.inputs[0].default_value[:3] for lk in ntree if lk.to_node.type == nworld), world.color) bg_color = next((lk.from_node.inputs[0].default_value[:3] for lk in ntree if lk.to_node.type == bgcol), world.color)
bg_image = next((lk.from_node.image.name for lk in ntree if lk.from_node.type == bgtex and lk.to_node.type in {bgcol, nworld}), False) bg_image = next((lk.from_node.image.name for lk in ntree if lk.from_node.type == bgtex and lk.to_node.type in {amcol, bgcol}), False)
background_color.add_variable("color", _3ds_float_color(bg_color)) background_color.add_variable("color", _3ds_float_color(bg_color))
background_chunk.add_subchunk(background_color) background_chunk.add_subchunk(background_color)
object_info.add_subchunk(background_chunk)
if bg_image: if bg_image:
background_image = _3ds_chunk(BITMAP) background_image = _3ds_chunk(BITMAP)
background_flag = _3ds_chunk(USE_BITMAP) background_flag = _3ds_chunk(USE_BITMAP)
background_image.add_variable("image", _3ds_string(sane_name(bg_image))) background_image.add_variable("image", _3ds_string(sane_name(bg_image)))
object_info.add_subchunk(background_image) object_info.add_subchunk(background_image)
object_info.add_subchunk(background_chunk)
object_info.add_subchunk(background_flag) object_info.add_subchunk(background_flag)
if write_keyframe and world.animation_data: if write_keyframe and world.animation_data:
kfdata.add_subchunk(make_ambient_node(world)) kfdata.add_subchunk(make_ambient_node(world))

View File

@ -44,6 +44,8 @@ USE_SOLIDBGND = 0x1201 # The background color flag
VGRADIENT = 0x1300 # The background gradient colors VGRADIENT = 0x1300 # The background gradient colors
USE_VGRADIENT = 0x1301 # The background gradient flag USE_VGRADIENT = 0x1301 # The background gradient flag
AMBIENTLIGHT = 0x2100 # The color of the ambient light AMBIENTLIGHT = 0x2100 # The color of the ambient light
LAYER_FOG = 0x2302 # The fog atmosphere settings
USE_LAYER_FOG = 0x2303 # The fog atmosphere flag
MATERIAL = 0xAFFF # This stored the texture info MATERIAL = 0xAFFF # This stored the texture info
OBJECT = 0x4000 # This stores the faces, vertices, etc... OBJECT = 0x4000 # This stores the faces, vertices, etc...
@ -335,6 +337,7 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
FILTER, IMAGE_SEARCH, WORLD_MATRIX, KEYFRAME, CONVERSE, MEASURE): FILTER, IMAGE_SEARCH, WORLD_MATRIX, KEYFRAME, CONVERSE, MEASURE):
contextObName = None contextObName = None
contextWorld = None
contextLamp = None contextLamp = None
contextCamera = None contextCamera = None
contextMaterial = None contextMaterial = None
@ -680,50 +683,50 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
elif CreateWorld and new_chunk.ID == AMBIENTLIGHT: elif CreateWorld and new_chunk.ID == AMBIENTLIGHT:
path, filename = os.path.split(file.name) path, filename = os.path.split(file.name)
realname, ext = os.path.splitext(filename) realname, ext = os.path.splitext(filename)
world = bpy.data.worlds.new("Ambient: " + realname) contextWorld = bpy.data.worlds.new("Ambient: " + realname)
context.scene.world = world context.scene.world = contextWorld
read_chunk(file, temp_chunk) read_chunk(file, temp_chunk)
if temp_chunk.ID == COLOR_F: if temp_chunk.ID == COLOR_F:
context.scene.world.color[:] = read_float_array(temp_chunk) contextWorld.color[:] = read_float_array(temp_chunk)
elif temp_chunk.ID == LIN_COLOR_F: elif temp_chunk.ID == LIN_COLOR_F:
context.scene.world.color[:] = read_float_array(temp_chunk) contextWorld.color[:] = read_float_array(temp_chunk)
else: else:
skip_to_end(file, temp_chunk) skip_to_end(file, temp_chunk)
new_chunk.bytes_read += temp_chunk.bytes_read new_chunk.bytes_read += temp_chunk.bytes_read
# If background chunk # If background chunk
elif CreateWorld and new_chunk.ID == SOLIDBACKGND: elif CreateWorld and new_chunk.ID == SOLIDBACKGND:
if context.scene.world is None: if contextWorld is None:
path, filename = os.path.split(file.name) path, filename = os.path.split(file.name)
realname, ext = os.path.splitext(filename) realname, ext = os.path.splitext(filename)
world = bpy.data.worlds.new("Background: " + realname) contextWorld = bpy.data.worlds.new("Background: " + realname)
context.scene.world = world context.scene.world = contextWorld
world = context.scene.world else:
world.use_nodes = True contextWorld.use_nodes = True
read_chunk(file, temp_chunk) read_chunk(file, temp_chunk)
if temp_chunk.ID == RGB: if temp_chunk.ID == RGB:
world.node_tree.nodes['Background'].inputs[0].default_value[:3] = read_float_array(temp_chunk) contextWorld.node_tree.nodes['Background'].inputs[0].default_value[:3] = read_float_array(temp_chunk)
elif temp_chunk.ID == RGBF: elif temp_chunk.ID == RGBF:
world.node_tree.nodes['Background'].inputs[0].default_value[:3] = read_float_array(temp_chunk) contextWorld.node_tree.nodes['Background'].inputs[0].default_value[:3] = read_float_array(temp_chunk)
else: skip_to_end(file, temp_chunk) else: skip_to_end(file, temp_chunk)
new_chunk.bytes_read += temp_chunk.bytes_read new_chunk.bytes_read += temp_chunk.bytes_read
# If bitmap chunk # If bitmap chunk
elif CreateWorld and new_chunk.ID == BITMAP: elif CreateWorld and new_chunk.ID == BITMAP:
bitmap_name, read_str_len = read_string(file) bitmap_name, read_str_len = read_string(file)
bitmap = load_image(bitmap_name, dirname, place_holder=False, recursive=image_search, check_existing=True) if contextWorld is None:
if context.scene.world is None:
path, filename = os.path.split(file.name) path, filename = os.path.split(file.name)
realname, ext = os.path.splitext(filename) realname, ext = os.path.splitext(filename)
world = bpy.data.worlds.new("Bitmap: " + realname) contextWorld = bpy.data.worlds.new("Bitmap: " + realname)
context.scene.world = world context.scene.world = contextWorld
world = context.scene.world else:
world.use_nodes = True contextWorld.use_nodes = True
links = world.node_tree.links links = contextWorld.node_tree.links
nodes = world.node_tree.nodes nodes = contextWorld.node_tree.nodes
bitmapnode = nodes.new(type='ShaderNodeTexImage') bitmapnode = nodes.new(type='ShaderNodeTexEnvironment')
bitmapnode.label = bitmap_name bitmapnode.label = bitmap_name
bitmapnode.location = (-300, 300) bitmapnode.location = (-300, 300)
bitmapnode.image = load_image(bitmap_name, dirname, place_holder=False, recursive=image_search, check_existing=True)
links.new(bitmapnode.outputs['Color'], nodes['Background'].inputs[0]) links.new(bitmapnode.outputs['Color'], nodes['Background'].inputs[0])
new_chunk.bytes_read += read_str_len new_chunk.bytes_read += read_str_len
@ -1091,8 +1094,9 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
mixshade = nodes.new(type='ShaderNodeMixShader') mixshade = nodes.new(type='ShaderNodeMixShader')
ambinode = nodes.new(type='ShaderNodeEmission') ambinode = nodes.new(type='ShaderNodeEmission')
ambinode.inputs[0].default_value[:3] = child.color ambinode.inputs[0].default_value[:3] = child.color
worldout.location = (600, 250) ambinode.location = (10, 150)
mixshade.location = (300, 250) worldout.location = (600, 200)
mixshade.location = (300, 300)
links.new(mixshade.outputs[0], worldout.inputs['Surface']) links.new(mixshade.outputs[0], worldout.inputs['Surface'])
links.new(nodes['Background'].outputs[0], mixshade.inputs[1]) links.new(nodes['Background'].outputs[0], mixshade.inputs[1])
links.new(ambinode.outputs[0], mixshade.inputs[2]) links.new(ambinode.outputs[0], mixshade.inputs[2])
@ -1141,12 +1145,12 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
keyframe_data = {} keyframe_data = {}
default_data = child.color[:] default_data = child.color[:]
child.color = read_track_data(new_chunk)[0] child.color = read_track_data(new_chunk)[0]
child.node_tree.nodes['Background'].inputs[0].default_value[:3] = child.color ambinode.inputs[0].default_value[:3] = child.color
for keydata in keyframe_data.items(): for keydata in keyframe_data.items():
child.color = keydata[1] child.color = keydata[1]
child.keyframe_insert(data_path="color", frame=keydata[0]) child.keyframe_insert(data_path="color", frame=keydata[0])
child.node_tree.nodes['Background'].inputs[0].default_value[:3] = keydata[1] ambinode.inputs[0].default_value[:3] = keydata[1]
child.node_tree.keyframe_insert(data_path="nodes[\"Background\"].inputs[0].default_value", frame=keydata[0]) nodetree.keyframe_insert(data_path="nodes[\"Emission\"].inputs[0].default_value", frame=keydata[0])
contextTrack_flag = False contextTrack_flag = False
elif KEYFRAME and new_chunk.ID == COL_TRACK_TAG and tracking == 'LIGHT': # Color elif KEYFRAME and new_chunk.ID == COL_TRACK_TAG and tracking == 'LIGHT': # Color