diff --git a/io_scene_3ds/export_3ds.py b/io_scene_3ds/export_3ds.py index c9a67702c..3cced15fa 100644 --- a/io_scene_3ds/export_3ds.py +++ b/io_scene_3ds/export_3ds.py @@ -1455,7 +1455,34 @@ def make_ambient_node(world): amb_node_header_chunk.add_variable("parent", _3ds_ushort(ROOT_OBJECT)) amb_node.add_subchunk(amb_node_header_chunk) - if world.animation_data.action: + if world.use_nodes and world.node_tree.animation_data.action: + action = world.node_tree.animation_data.action + ambinode = next((nd for nd in world.node_tree.nodes if nd.type in {'RGB', 'EMISSION'}), False) + if ambinode and action.fcurves: + fcurves = action.fcurves + fcurves.update() + kframes = [kf.co[0] for kf in [fc for fc in fcurves if fc is not None][0].keyframe_points] + ambipath = ('nodes[\"RGB\"].outputs[0].default_value' if ambinode.type == 'RGB' else + 'nodes[\"Emission\"].inputs[0].default_value') + nkeys = len(kframes) + if not 0 in kframes: + kframes.append(0) + nkeys = nkeys + 1 + kframes = sorted(set(kframes)) + track_chunk.add_variable("track_flags", _3ds_ushort(0x40)) + track_chunk.add_variable("frame_start", _3ds_uint(int(action.frame_start))) + track_chunk.add_variable("frame_total", _3ds_uint(int(action.frame_end))) + track_chunk.add_variable("nkeys", _3ds_uint(nkeys)) + + for i, frame in enumerate(kframes): + ambient = [fc.evaluate(frame) for fc in fcurves if fc is not None and fc.data_path == ambipath] + if not ambient: + ambient.append(world.color) + track_chunk.add_variable("tcb_frame", _3ds_uint(int(frame))) + track_chunk.add_variable("tcb_flags", _3ds_ushort()) + track_chunk.add_variable("color", _3ds_float_color(ambient[:3])) + + elif world.animation_data.action: action = world.animation_data.action if action.fcurves: fcurves = action.fcurves diff --git a/io_scene_3ds/import_3ds.py b/io_scene_3ds/import_3ds.py index 5f0971d18..2cce3b0c7 100644 --- a/io_scene_3ds/import_3ds.py +++ b/io_scene_3ds/import_3ds.py @@ -709,19 +709,26 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI # If background chunk elif CreateWorld and new_chunk.ID == SOLIDBACKGND: + backgroundcolor = mathutils.Color((0.1, 0.1, 0.1)) if contextWorld is None: path, filename = os.path.split(file.name) realname, ext = os.path.splitext(filename) contextWorld = bpy.data.worlds.new("Background: " + realname) context.scene.world = contextWorld contextWorld.use_nodes = True + worldnodes = contextWorld.node_tree.nodes + backgroundnode = worldnodes['Background'] read_chunk(file, temp_chunk) if temp_chunk.ID == COLOR_F: - contextWorld.node_tree.nodes['Background'].inputs[0].default_value[:3] = read_float_array(temp_chunk) + backgroundcolor = read_float_array(temp_chunk) elif temp_chunk.ID == LIN_COLOR_F: - contextWorld.node_tree.nodes['Background'].inputs[0].default_value[:3] = read_float_array(temp_chunk) + backgroundcolor = read_float_array(temp_chunk) else: skip_to_end(file, temp_chunk) + backgroundmix = next((wn for wn in worldnodes if wn.type in {'MIX', 'MIX_RGB'}), False) + backgroundnode.inputs[0].default_value[:3] = backgroundcolor + if backgroundmix: + backgroundmix.inputs[2].default_value[:3] = backgroundcolor new_chunk.bytes_read += temp_chunk.bytes_read # If bitmap chunk @@ -738,9 +745,9 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI bitmap_mix = nodes.new(type='ShaderNodeMixRGB') bitmapnode = nodes.new(type='ShaderNodeTexEnvironment') bitmap_mix.label = "Solid Color" - bitmapnode.label = bitmap_name - bitmap_mix.location = (-250, 300) - bitmapnode.location = (-300, 300) + bitmapnode.label = "Bitmap: " + bitmap_name + bitmap_mix.location = (-250, 360) + bitmapnode.location = (-600, 300) bitmap_mix.inputs[2].default_value = nodes['Background'].inputs[0].default_value bitmapnode.image = load_image(bitmap_name, dirname, place_holder=False, recursive=IMAGE_SEARCH, check_existing=True) bitmap_mix.inputs[0].default_value = 0.0 if bitmapnode.image is not None else 1.0 @@ -1143,13 +1150,17 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI worldout = nodes['World Output'] mixshade = nodes.new(type='ShaderNodeMixShader') ambinode = nodes.new(type='ShaderNodeEmission') + ambilite = nodes.new(type='ShaderNodeRGB') + ambilite.label = "Ambient Color" ambinode.inputs[0].default_value[:3] = child.color ambinode.location = (10, 150) worldout.location = (600, 200) mixshade.location = (300, 300) + ambilite.location = (-250, 150) links.new(mixshade.outputs[0], worldout.inputs['Surface']) links.new(nodes['Background'].outputs[0], mixshade.inputs[1]) links.new(ambinode.outputs[0], mixshade.inputs[2]) + links.new(ambilite.outputs[0], ambinode.inputs[0]) ambinode.label = object_name if object_name != '$AMBIENT$' else "Ambient" elif CreateEmpty and tracking == 'OBJECT' and object_name == '$$$DUMMY': child = bpy.data.objects.new(object_name, None) # Create an empty object @@ -1195,11 +1206,13 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI keyframe_data = {} default_data = child.color[:] child.color = read_track_data(new_chunk)[0] - ambinode.inputs[0].default_value[:3] = child.color + ambilite.color = child.color + ambinode.inputs[0].default_value[:3] = ambilite.color for keydata in keyframe_data.items(): - child.color = keydata[1] - child.keyframe_insert(data_path="color", frame=keydata[0]) ambinode.inputs[0].default_value[:3] = keydata[1] + child.color = ambilite.outputs[0].default_value[:3] = keydata[1] + child.keyframe_insert(data_path="color", frame=keydata[0]) + nodetree.keyframe_insert(data_path="nodes[\"RGB\"].outputs[0].default_value", frame=keydata[0]) nodetree.keyframe_insert(data_path="nodes[\"Emission\"].inputs[0].default_value", frame=keydata[0]) contextTrack_flag = False