Browse Source

initial commit for blender 2.80 support

Jason0214 7 years ago
parent
commit
3f89937418
100 changed files with 259 additions and 486 deletions
  1. 1 1
      .pylintrc
  2. 6 3
      .travis.yml
  3. 2 2
      Makefile
  4. 4 8
      README.md
  5. 12 15
      io_scene_godot/__init__.py
  6. 1 1
      io_scene_godot/converters/__init__.py
  7. 0 6
      io_scene_godot/converters/animation/action.py
  8. 3 20
      io_scene_godot/converters/animation/animation_data.py
  9. 14 37
      io_scene_godot/converters/animation/constraint_baking.py
  10. 6 6
      io_scene_godot/converters/animation/serializer.py
  11. 1 4
      io_scene_godot/converters/armature.py
  12. 0 6
      io_scene_godot/converters/material.py
  13. 3 11
      io_scene_godot/converters/material_node_tree/node_vistors.py
  14. 2 2
      io_scene_godot/converters/material_node_tree/shaders.py
  15. 56 61
      io_scene_godot/converters/mesh.py
  16. 11 11
      io_scene_godot/converters/physics.py
  17. 4 25
      io_scene_godot/converters/simple_nodes.py
  18. 60 52
      io_scene_godot/export_godot.py
  19. 5 3
      io_scene_godot/structures.py
  20. 1 1
      requirements.txt
  21. 13 3
      tests/install_blender.sh
  22. 0 0
      tests/reference_exports/action_animation/animation_bone_transform.escn
  23. 1 1
      tests/reference_exports/action_animation/physics_animation.escn
  24. 0 0
      tests/reference_exports/action_with_constraint/bone_attachment_ik.escn
  25. 0 0
      tests/reference_exports/action_with_constraint/constraint_external_IK.escn
  26. 0 0
      tests/reference_exports/action_with_constraint/constraint_internal_IK.escn
  27. 0 0
      tests/reference_exports/action_with_constraint/stashed_constraint.escn
  28. 0 0
      tests/reference_exports/armature/armature_bone_attachment.escn
  29. 6 6
      tests/reference_exports/armature/armature_illegal_bone_name.escn
  30. 0 0
      tests/reference_exports/armature/armature_with_mesh.escn
  31. 0 0
      tests/reference_exports/armature/armature_with_non_deform_bone.escn
  32. 0 0
      tests/reference_exports/armature/armature_with_other_vertex_groups.escn
  33. 0 0
      tests/reference_exports/armature/armature_with_physics.escn
  34. 0 0
      tests/reference_exports/armature/armature_with_pose.escn
  35. 4 23
      tests/reference_exports/light/animation_sun.escn
  36. 0 5
      tests/reference_exports/light/animation_various_lights.escn
  37. 0 4
      tests/reference_exports/light/just_point_lights.escn
  38. 0 8
      tests/reference_exports/light/just_spot_lights.escn
  39. 0 1
      tests/reference_exports/material/material_search.escn
  40. 0 20
      tests/reference_exports/material/object_link_material.escn
  41. 0 11
      tests/reference_exports/material/simple_materials.escn
  42. 0 0
      tests/reference_exports/material_cycle/material_anistropy.escn
  43. 2 2
      tests/reference_exports/material_cycle/material_cycle.escn
  44. 23 106
      tests/reference_exports/material_cycle/material_normal.escn
  45. 6 6
      tests/reference_exports/mesh/just_mesh.escn
  46. 2 2
      tests/reference_exports/mesh/parented_meshes.escn
  47. 1 2
      tests/reference_exports/mesh/physics.escn
  48. 0 0
      tests/reference_exports/misc/duplicate_name.escn
  49. 8 0
      tests/reference_exports/misc/invisible_objects.escn
  50. 1 1
      tests/reference_exports/nla_animation/animation_with_empty_strip.escn
  51. 0 0
      tests/reference_exports/nla_animation/nla_with_stashed_action.escn
  52. 0 10
      tests/reference_exports/shape_key/shapekey_with_multi_surface.escn
  53. BIN
      tests/test_scenes/action_animation/animation_bone_transform.blend
  54. BIN
      tests/test_scenes/action_animation/animation_object_transform.blend
  55. BIN
      tests/test_scenes/action_animation/animation_rotation_euler.blend
  56. BIN
      tests/test_scenes/action_animation/animation_shared_action.blend
  57. BIN
      tests/test_scenes/action_animation/physics_animation.blend
  58. BIN
      tests/test_scenes/action_with_constraint/bone_attachment_ik.blend
  59. BIN
      tests/test_scenes/action_with_constraint/constraint_external_IK.blend
  60. BIN
      tests/test_scenes/action_with_constraint/constraint_internal_IK.blend
  61. BIN
      tests/test_scenes/action_with_constraint/stashed_constraint.blend
  62. BIN
      tests/test_scenes/armature/armature_bone_attachment.blend
  63. BIN
      tests/test_scenes/armature/armature_illegal_bone_name.blend
  64. BIN
      tests/test_scenes/armature/armature_with_mesh.blend
  65. BIN
      tests/test_scenes/armature/armature_with_non_deform_bone.blend
  66. BIN
      tests/test_scenes/armature/armature_with_other_vertex_groups.blend
  67. BIN
      tests/test_scenes/armature/armature_with_physics.blend
  68. BIN
      tests/test_scenes/armature/armature_with_pose.blend
  69. BIN
      tests/test_scenes/armature/just_armature.blend
  70. BIN
      tests/test_scenes/camera/animation_camera.blend
  71. BIN
      tests/test_scenes/camera/just_cameras.blend
  72. BIN
      tests/test_scenes/light/animation_sun.blend
  73. BIN
      tests/test_scenes/light/animation_various_lights.blend
  74. BIN
      tests/test_scenes/light/just_point_lights.blend
  75. BIN
      tests/test_scenes/light/just_spot_lights.blend
  76. BIN
      tests/test_scenes/material/material_search.blend
  77. BIN
      tests/test_scenes/material/object_link_material.blend
  78. BIN
      tests/test_scenes/material/simple_materials.blend
  79. BIN
      tests/test_scenes/material_cycle/material_anistropy.blend
  80. BIN
      tests/test_scenes/material_cycle/material_cycle.blend
  81. BIN
      tests/test_scenes/material_cycle/material_normal.blend
  82. BIN
      tests/test_scenes/material_cycle/material_unpack_texture.blend
  83. BIN
      tests/test_scenes/mesh/just_mesh.blend
  84. BIN
      tests/test_scenes/mesh/parented_meshes.blend
  85. BIN
      tests/test_scenes/mesh/physics.blend
  86. BIN
      tests/test_scenes/mesh/single_edge_and_vertex.blend
  87. BIN
      tests/test_scenes/mesh/tangent_test.blend
  88. BIN
      tests/test_scenes/mesh/uv_testing.blend
  89. BIN
      tests/test_scenes/mesh/vertex_color.blend
  90. 0 0
      tests/test_scenes/misc/duplicate_name.blend
  91. BIN
      tests/test_scenes/misc/invisible_objects.blend
  92. BIN
      tests/test_scenes/nla_animation/animation_multi_strip.blend
  93. BIN
      tests/test_scenes/nla_animation/animation_with_empty_strip.blend
  94. BIN
      tests/test_scenes/nla_animation/nla_with_active_action.blend
  95. BIN
      tests/test_scenes/nla_animation/nla_with_no_active_action.blend
  96. BIN
      tests/test_scenes/nla_animation/nla_with_stashed_action.blend
  97. BIN
      tests/test_scenes/scene_animation/animation_parented_objects.blend
  98. BIN
      tests/test_scenes/shape_key/animation_shapekey.blend
  99. BIN
      tests/test_scenes/shape_key/animation_shapekey_with_transform.blend
  100. BIN
      tests/test_scenes/shape_key/just_shapekey.blend

+ 1 - 1
.pylintrc

@@ -165,7 +165,7 @@ expected-line-ending-format=
 [MISCELLANEOUS]
 
 # List of note tags to take in consideration, separated by a comma.
-notes=FIXME,XXX,TODO
+notes=
 
 
 [SIMILARITIES]

+ 6 - 3
.travis.yml

@@ -1,6 +1,7 @@
+dist: xenial
 language: python
 python:
-    - 3.4
+    - 3.6
 
 cache:
     directories:
@@ -8,11 +9,13 @@ cache:
 
 before_install:
     - sudo apt-get update
-    - sudo apt-get install --no-install-recommends -y libsdl1.2debian python3-pip
+    - sudo apt-get install --no-install-recommends -y libsdl1.2debian libglu1 python3-pip
+    - sudo pip3 install --upgrade pip
+    - sudo pip3 install --upgrade setuptools
     - sudo pip3 install -r requirements.txt
 
 install:
-    - tests/install_blender.sh
+    - bash tests/install_blender.sh
     - source .envs
 
 script:

+ 2 - 2
Makefile

@@ -1,5 +1,5 @@
-PYLINT = pylint3
-PEP8 = pep8
+PYLINT = pylint
+PEP8 = pycodestyle 
 BLENDER = blender
 GODOT = godot
 

+ 4 - 8
README.md

@@ -32,14 +32,10 @@ This repository includes a Makefile to assist with development. Running
    be elegible to merge.
 
 
-Due to differences in blender versions creating minor differences in the 
-output files (even with the same blender release number), the regression tests 
-are best run with blender 2.79 downloaded from 
-[this exact url](http://mirror.cs.umn.edu/blender.org/release/Blender2.79/), 
-which is used for the Travis builds. If you think your blender version is 
-adequate, the hash (visble in the upper right of blender's splash screen) 
-should be `5bd8ac9abfa`. The exporter itself should run on all modern versions 
-of blender, but the output may differ slightly.
+Current regression tests use the daily build of blender 2.80 from blender [official
+site](https://builder.blender.org/download/) and runs on ubuntu 16.04. If you run
+on different blender version or different platform, the output may differ slightly 
+mostly causing by different float precision.
 
 
 ## License

+ 12 - 15
io_scene_godot/__init__.py

@@ -27,8 +27,7 @@ from .structures import ValidationError
 bl_info = {  # pylint: disable=invalid-name
     "name": "Godot Engine Exporter",
     "author": "Juan Linietsky",
-    "blender": (2, 5, 8),
-    "api": 38691,
+    "blender": (2, 80, 0),
     "location": "File > Import-Export",
     "description": ("Export Godot Scenes to a format that can be efficiently "
                     "imported. "),
@@ -57,7 +56,7 @@ class ExportGodot(bpy.types.Operator, ExportHelper):
         items=(
             ("EMPTY", "Empty", ""),
             ("CAMERA", "Camera", ""),
-            ("LAMP", "Lamp", ""),
+            ("LIGHT", "LIGHT", ""),
             ("ARMATURE", "Armature", ""),
             ("MESH", "Mesh", ""),
             # ("CURVE", "Curve", ""),
@@ -65,7 +64,7 @@ class ExportGodot(bpy.types.Operator, ExportHelper):
         default={
             "EMPTY",
             "CAMERA",
-            "LAMP",
+            "LIGHT",
             "ARMATURE",
             "MESH",
             # "CURVE"
@@ -79,8 +78,7 @@ class ExportGodot(bpy.types.Operator, ExportHelper):
     )
     use_export_selected = BoolProperty(
         name="Selected Objects",
-        description="Export only selected objects (and visible in active "
-                    "layers if that applies).",
+        description="Export only selected objects",
         default=False,
     )
     use_exclude_ctrl_bone = BoolProperty(
@@ -101,9 +99,10 @@ class ExportGodot(bpy.types.Operator, ExportHelper):
         description="Apply modifiers to mesh objects (on a copy!).",
         default=True,
     )
-    use_active_layers = BoolProperty(
-        name="Active Layers",
-        description="Export only objects on the active layers.",
+    use_visible_objects = BoolProperty(
+        name="Visible Object",
+        description="Export only objects which are in the current view layer "
+                    "and are visible.",
         default=True,
     )
     use_stashed_action = BoolProperty(
@@ -201,16 +200,14 @@ def menu_func(self, context):
 
 def register():
     """Add addon to blender"""
-    bpy.utils.register_module(__name__)
-
-    bpy.types.INFO_MT_file_export.append(menu_func)
+    bpy.utils.register_class(ExportGodot)
+    bpy.types.TOPBAR_MT_file_export.append(menu_func)
 
 
 def unregister():
     """Remove addon from blender"""
-    bpy.utils.unregister_module(__name__)
-
-    bpy.types.INFO_MT_file_export.remove(menu_func)
+    bpy.utils.unregister_class(ExportGodot)
+    bpy.types.TOPBAR_MT_file_export.remove(menu_func)
 
 
 def export(filename, overrides=None):

+ 1 - 1
io_scene_godot/converters/__init__.py

@@ -26,7 +26,7 @@ BLENDER_TYPE_TO_EXPORTER = {
     "MESH": export_mesh_node,
     "ARMATURE": export_armature_node,
     "CAMERA": export_camera_node,
-    "LAMP": export_lamp_node,
+    "LIGHT": export_light_node,
     "EMPTY": export_empty_node
 }
 

+ 0 - 6
io_scene_godot/converters/animation/action.py

@@ -247,12 +247,6 @@ def export_light_action(light_node, animation_player, blender_lamp,
     )
 
     fcurves = action_strip.action.fcurves
-    animation_resource.add_attribute_track(
-        action_strip,
-        fcurves.find('use_negative'),
-        lambda x: x > 0.0,
-        base_node_path.new_copy('light_negative'),
-    )
 
     animation_resource.add_attribute_track(
         action_strip,

+ 3 - 20
io_scene_godot/converters/animation/animation_data.py

@@ -38,8 +38,6 @@ class ObjectAnimationExporter:
         self.action_exporter_func = ACTION_EXPORTER_MAP[action_type]
         self.animation_player = None
 
-        self.has_object_constraint = False
-        self.has_pose_constraint = False
         self.need_baking = False
 
         self.unmute_nla_tracks = []
@@ -56,8 +54,6 @@ class ObjectAnimationExporter:
         self.need_baking = (
             action_type == 'transform' and (has_obj_cst or has_pose_cst)
         )
-        self.has_object_constraint = has_obj_cst
-        self.has_pose_constraint = has_pose_cst
 
     def preprocess_nla_tracks(self, blender_object):
         """Iterative through nla tracks, separately store mute and unmuted
@@ -77,22 +73,9 @@ class ObjectAnimationExporter:
 
         Note that it accept a action to bake (which would not be modified)
         and always return a new created baked actiony"""
-        if self.has_object_constraint and self.has_pose_constraint:
-            tmp = bake_constraint_to_action(
-                self.blender_object, action_to_bake, "OBJECT", False
-            )
-            ret = bake_constraint_to_action(
-                self.blender_object, action_to_bake, "POSE", True
-            )
-        elif self.has_pose_constraint:
-            ret = bake_constraint_to_action(
-                self.blender_object, action_to_bake, "POSE", False
-            )
-        elif self.has_object_constraint:
-            ret = bake_constraint_to_action(
-                self.blender_object, action_to_bake, "OBJECT", False
-            )
-        return ret
+        return bake_constraint_to_action(
+            self.blender_object, action_to_bake, False
+        )
 
     def export_active_action(self, escn_file, active_action):
         """Export the active action, if needed, would call bake.

+ 14 - 37
io_scene_godot/converters/animation/constraint_baking.py

@@ -24,7 +24,7 @@ def action_baking_finalize(action):
 def check_object_constraint(blender_object):
     """Return bool indicate if object has constraint"""
     if isinstance(blender_object, bpy.types.Object):
-        return True if blender_object.constraints else False
+        return bool(blender_object.constraints)
     return False
 
 
@@ -38,14 +38,15 @@ def check_pose_constraint(blender_object):
     return False
 
 
-def bake_constraint_to_action(blender_object, base_action, bake_type,
-                              in_place):
+def bake_constraint_to_action(blender_object, base_action, in_place):
     """Bake pose or object constrainst (e.g. IK) to action"""
     if base_action is not None:
         blender_object.animation_data.action = base_action
-        frame_range = tuple([int(x) for x in base_action.frame_range])
+        frame_range = range(
+            int(base_action.frame_range[0]),
+            int(base_action.frame_range[1]) + 1)
     else:
-        frame_range = (1, 250)  # default, can be improved
+        frame_range = range(1, 251)  # default, can be improved
 
     # if action_bake_into is None, it would create a new one
     # and baked into it
@@ -54,38 +55,14 @@ def bake_constraint_to_action(blender_object, base_action, bake_type,
     else:
         action_bake_into = None
 
-    do_pose = bake_type == "POSE"
-    do_object = not do_pose
-
-    if bpy.app.version <= (2, 79, 0):
-        active_obj_backup = bpy.context.scene.objects.active
-
-        # the object to bake is the current active object
-        bpy.context.scene.objects.active = blender_object
-        baked_action = bpy_extras.anim_utils.bake_action(
-            frame_start=frame_range[0],
-            frame_end=frame_range[1],
-            frame_step=1,
-            only_selected=False,
-            action=action_bake_into,
-            do_pose=do_pose,
-            do_object=do_object,
-            do_visual_keying=True,
-        )
-
-        bpy.context.scene.objects.active = active_obj_backup
-    else:
-        baked_action = bpy_extras.anim_utils.bake_action(
-            obj=blender_object,
-            frame_start=frame_range[0],
-            frame_end=frame_range[1],
-            frame_step=1,
-            only_selected=False,
-            action=action_bake_into,
-            do_pose=do_pose,
-            do_object=do_object,
-            do_visual_keying=True,
-        )
+    baked_action = bpy_extras.anim_utils.bake_action_objects(
+        object_action_pairs=[(blender_object, action_bake_into)],
+        frames=frame_range,
+        only_selected=False,
+        do_pose=True,
+        do_object=True,
+        do_visual_keying=True,
+    )[0]
 
     if in_place:
         return action_bake_into

+ 6 - 6
io_scene_godot/converters/animation/serializer.py

@@ -75,7 +75,7 @@ class TransformFrame:
         """Factory function, create cls from a transform matrix"""
         ret = cls()
         ret.location = trans_mat.to_translation()
-        # fixme: lose negative scale
+        # FIXME: lose negative scale
         ret.scale = trans_mat.to_scale()
 
         # quaternion and euler fcurves may both exist in fcurves
@@ -112,7 +112,7 @@ class TransformFrame:
             (0, self.scale[1], 0),
             (0, 0, self.scale[2]),
         )).to_4x4()
-        return loc_mat * rot_mat * sca_mat
+        return loc_mat @ rot_mat @ sca_mat
 
 
 class Track:
@@ -255,7 +255,7 @@ class TransformTrack(Track):
 
     def blend_frames(self, frame_val1, frame_val2):
         """Blend two transform frames into one"""
-        # fixme: currently only blend with ADD
+        # FIXME: currently only blend with ADD
         new_frame = TransformFrame()
         for frame in (frame_val1, frame_val2):
             if frame.rotation_mode != 'QUATERNION':
@@ -264,7 +264,7 @@ class TransformTrack(Track):
                 )
 
         new_frame.rotation_quaternion = (
-            frame_val1.rotation_quaternion * frame_val2.rotation_quaternion
+            frame_val1.rotation_quaternion @ frame_val2.rotation_quaternion
         )
 
         new_frame.location = frame_val1.location + frame_val2.location
@@ -291,7 +291,7 @@ class TransformTrack(Track):
             if frame < scene_frame_start:
                 continue
 
-            mat = self.parent_trans_inverse * trans_frame.to_matrix()
+            mat = self.parent_trans_inverse @ trans_frame.to_matrix()
             if self.is_directional:
                 mat = fix_directional_transform(mat)
             # convert from z-up to y-up
@@ -326,7 +326,7 @@ class ValueTrack(Track):
         self.interp = interp
 
     def blend_frames(self, frame_val1, frame_val2):
-        # xxx: default use REPLACE
+        # FIXME: default use REPLACE
         return max(frame_val1, frame_val2)
 
     def convert_to_keys_object(self):

+ 1 - 4
io_scene_godot/converters/armature.py

@@ -73,7 +73,7 @@ def export_bone(pose_bone, bl_bones_to_export):
     while ps_bone_ptr is not None and ps_bone_ptr not in bl_bones_to_export:
         ps_bone_ptr = ps_bone_ptr.parent
     if ps_bone_ptr is not None:
-        rest_mat = (ps_bone_ptr.bone.matrix_local.inverted_safe() *
+        rest_mat = (ps_bone_ptr.bone.matrix_local.inverted_safe() @
                     rest_bone.matrix_local)
         parent_bone_name = ps_bone_ptr.name
     else:
@@ -151,9 +151,6 @@ class SkeletonNode(NodeTemplate):
 
 def export_armature_node(escn_file, export_settings, node, parent_gd_node):
     """Export an armature node"""
-    if "ARMATURE" not in export_settings['object_types']:
-        return parent_gd_node
-
     skeleton_node = SkeletonNode(node.name, parent_gd_node)
     skeleton_node['transform'] = node.matrix_local
 

+ 0 - 6
io_scene_godot/converters/material.py

@@ -85,13 +85,7 @@ def generate_material_resource(escn_file, export_settings, material):
 
     if mat is None:
         mat = InternalResource("SpatialMaterial", material_rsc_name)
-
-        mat['flags_unshaded'] = material.use_shadeless
-        mat['flags_vertex_lighting'] = material.use_vertex_color_light
-        mat['flags_transparent'] = material.use_transparency
-        mat['vertex_color_use_as_albedo'] = material.use_vertex_color_paint
         mat['albedo_color'] = gamma_correct(material.diffuse_color)
-        mat['subsurf_scatter_enabled'] = material.subsurface_scattering.use
     return escn_file.add_internal_resource(mat, material)
 
 

+ 3 - 11
io_scene_godot/converters/material_node_tree/node_vistors.py

@@ -440,12 +440,12 @@ def visit_mapping_node(shader, node):
     if node.vector_type == "TEXTURE":
         # Texture: Transform a texture by inverse
         # mapping the texture coordinate
-        transform_mat = (loc_mat * rot_mat * sca_mat).inverted_safe()
+        transform_mat = (loc_mat @ rot_mat @ sca_mat).inverted_safe()
     elif node.vector_type == "POINT":
-        transform_mat = loc_mat * rot_mat * sca_mat
+        transform_mat = loc_mat @ rot_mat @ sca_mat
     else:  # node.vector_type in ("VECTOR", "NORMAL")
         # no translation for vectors
-        transform_mat = rot_mat * sca_mat
+        transform_mat = rot_mat @ sca_mat
 
     mat = Value.create_from_blender_value(transform_mat)
     clamp_min = Value.create_from_blender_value(node.min)
@@ -520,14 +520,6 @@ def visit_tangent_node(shader, node):
 
 def visit_uvmap_node(shader, node):
     """Visit UV Map node"""
-    if node.from_dupli:
-        raise ValidationError(
-            "'{}' from_dupli not supported, at '{}'".format(
-                node.bl_idname,
-                node.name
-            )
-        )
-
     shader.assign_variable_to_socket(
         node.outputs['UV'],
         Value("vec3", ('UV', 0.0)),

+ 2 - 2
io_scene_godot/converters/material_node_tree/shaders.py

@@ -360,7 +360,7 @@ class FragmentShader(BaseShader):
                 self.code_array.append(
                     '{} = {};'.format(name.upper(), str(var))
                 )
-        # xxx: transmission for thick object is not supported in godot
+        # XXX: transmission for thick object is not supported in godot
         # transmission_var = bsdf_output.get_attribute('transmission')
         # if transmission_var is not None:
         #     self.append_code_line(
@@ -407,7 +407,7 @@ class FragmentShader(BaseShader):
 
     def add_bump_displacement(self, displacement_output):
         """Add bump displacement to fragment shader"""
-        # xxx: use tangent space if uv exists?
+        # XXX: use tangent space if uv exists?
         function = find_function_by_name('node_bump')
 
         in_arguments = list()

+ 56 - 61
io_scene_godot/converters/mesh.py

@@ -15,73 +15,71 @@ MAX_BONE_PER_VERTEX = 4
 
 
 # ------------------------------- The Mesh -----------------------------------
-def export_mesh_node(escn_file, export_settings, node, parent_gd_node):
+def export_mesh_node(escn_file, export_settings, obj, parent_gd_node):
     """Exports a MeshInstance. If the mesh is not already exported, it will
     trigger the export of that mesh"""
-    if (node.data is None or
-            "MESH" not in export_settings['object_types']):
-        return parent_gd_node
-
     # If this mesh object has physics properties, we need to export them first
     # because they need to be higher in the scene-tree
-    if physics.has_physics(node):
+
+    if physics.has_physics(obj):
         parent_gd_node = physics.export_physics_properties(
-            escn_file, export_settings, node, parent_gd_node
+            escn_file, export_settings, obj, parent_gd_node
         )
 
-    if (node.hide_render or
-            (physics.has_physics(node) and node.draw_type == "WIRE")):
+    if physics.has_physics(obj) and obj.display_type == "WIRE":
+        # skip wire mesh which is used as collision mesh
         return parent_gd_node
 
-    else:
-        mesh_node = NodeTemplate(node.name, "MeshInstance", parent_gd_node)
-        mesh_exporter = MeshResourceExporter(node)
+    mesh_node = NodeTemplate(obj.name, "MeshInstance", parent_gd_node)
+    mesh_exporter = MeshResourceExporter(obj)
 
-        armature_data = get_modifier_armature_data(node)
-        if ("ARMATURE" in export_settings['object_types'] and
-                armature_data is not None):
-            skeleton_node = armature.find_skeletion_node(parent_gd_node)
+    armature_data = get_modifier_armature_data(obj)
+    if ("ARMATURE" in export_settings['object_types'] and
+            armature_data is not None):
+        skeleton_node = armature.find_skeletion_node(parent_gd_node)
+        if skeleton_node is not None:
             mesh_exporter.init_mesh_bones_data(skeleton_node)
             mesh_node['skeleton'] = NodePath(
                 mesh_node.get_path(), skeleton_node.get_path())
 
-        mesh_id = mesh_exporter.export_mesh(escn_file, export_settings)
+    mesh_id = mesh_exporter.export_mesh(escn_file, export_settings)
 
-        mesh_node['mesh'] = "SubResource({})".format(mesh_id)
-        mesh_node['visible'] = not node.hide
+    mesh_node['mesh'] = "SubResource({})".format(mesh_id)
+    mesh_node['visible'] = obj.visible_get()
 
-        # Transform of rigid mesh is moved up to its collision
-        # shapes.
-        if not physics.has_physics(node):
-            mesh_node['transform'] = node.matrix_local
-        else:
-            mesh_node['transform'] = mathutils.Matrix.Identity(4)
+    # Transform of rigid mesh is moved up to its collision
+    # shapes.
+    if not physics.has_physics(obj):
+        mesh_node['transform'] = obj.matrix_local
+    else:
+        mesh_node['transform'] = mathutils.Matrix.Identity(4)
 
-        escn_file.add_node(mesh_node)
+    escn_file.add_node(mesh_node)
 
-        export_object_link_material(
-            escn_file, export_settings, node, mesh_node
-        )
+    export_object_link_material(
+        escn_file, export_settings, obj, mesh_node
+    )
 
-        # export shape key animation
-        if (export_settings['use_export_shape_key'] and
-                node.data.shape_keys is not None):
-            animation.export_animation_data(
-                escn_file, export_settings, mesh_node,
-                node.data.shape_keys, 'shapekey')
+    # export shape key animation
+    if (export_settings['use_export_shape_key'] and
+            obj.data.shape_keys is not None):
+        animation.export_animation_data(
+            escn_file, export_settings, mesh_node,
+            obj.data.shape_keys, 'shapekey')
 
-        return mesh_node
+    return mesh_node
 
 
 def triangulate_mesh(mesh):
     """Triangulate a mesh"""
     tri_mesh = bmesh.new()
     tri_mesh.from_mesh(mesh)
-    bmesh.ops.triangulate(tri_mesh, faces=tri_mesh.faces, quad_method=2)
+    bmesh.ops.triangulate(
+        tri_mesh, faces=tri_mesh.faces, quad_method="ALTERNATE")
     tri_mesh.to_mesh(mesh)
     tri_mesh.free()
 
-    mesh.update(calc_tessface=True)
+    mesh.update(calc_loop_triangles=True)
 
 
 def fix_vertex(vtx):
@@ -173,24 +171,15 @@ class MeshResourceExporter:
 
     def make_arrays(self, escn_file, export_settings):
         """Generates arrays of positions, normals etc"""
-        armature_data = get_modifier_armature_data(self.object)
-        if armature_data is not None:
-            original_pose_position = armature_data.pose_position
-            armature_data.pose_position = 'REST'
-            bpy.context.scene.update()
-
-        if not export_settings['use_mesh_modifiers']:
-            for modifier in self.object.modifiers:
-                if not isinstance(modifier, bpy.types.ArmatureModifier):
-                    modifier.show_render = False
+        apply_modifiers = export_settings['use_mesh_modifiers']
 
         # set shape key to basis key which would have index 0
         self.object.show_only_shape_key = True
         self.object.active_shape_key_index = 0
 
-        mesh = self.object.to_mesh(bpy.context.scene,
-                                   True,
-                                   "RENDER")
+        mesh = self.object.to_mesh(bpy.context.view_layer.depsgraph,
+                                   apply_modifiers=apply_modifiers,
+                                   calc_undeformed=True)
 
         self.object.show_only_shape_key = False
 
@@ -205,9 +194,9 @@ class MeshResourceExporter:
         triangulate_mesh(mesh)
 
         # godot engine supports two uv channels
-        uv_layer_count = min(len(mesh.uv_textures), 2)
+        uv_layer_count = min(len(mesh.uv_layers), 2)
 
-        if mesh.uv_textures:
+        if mesh.uv_layers:
             self.has_tangents = True
             try:
                 mesh.calc_tangents()
@@ -230,10 +219,6 @@ class MeshResourceExporter:
 
         bpy.data.meshes.remove(mesh)
 
-        if armature_data is not None:
-            armature_data.pose_position = original_pose_position
-            bpy.context.scene.update()
-
     @staticmethod
     def extract_shape_keys(blender_shape_keys):
         """Return a list of (shape_key_index, shape_key_object) each of them
@@ -269,8 +254,10 @@ class MeshResourceExporter:
 
         return surfaces_morph_list
 
+    # pylint: disable-msg=R0914
     def export_morphs(self, export_settings, surfaces):
         """Export shape keys in mesh node and append them to surfaces"""
+        modifier_config_cache = list()
         if export_settings['use_mesh_modifiers']:
             if not self.validate_morph_mesh_modifiers(
                     self.object):
@@ -280,6 +267,10 @@ class MeshResourceExporter:
                     self.object.name
                 )
 
+            for modifier in self.object.modifiers:
+                modifier_config_cache.append(modifier.show_render)
+                modifier.show_render = False
+
         self.mesh_resource["blend_shape/names"] = Array(
             prefix="PoolStringArray(", suffix=')'
         )
@@ -298,9 +289,9 @@ class MeshResourceExporter:
             shape_key.value = 1.0
 
             shape_key_mesh = self.object.to_mesh(
-                bpy.context.scene,
-                True,
-                "RENDER"
+                bpy.context.view_layer.depsgraph,
+                apply_modifiers=True,
+                calc_undeformed=True
             )
 
             self.object.show_only_shape_key = False
@@ -340,6 +331,10 @@ class MeshResourceExporter:
 
             bpy.data.meshes.remove(shape_key_mesh)
 
+        if export_settings['use_mesh_modifiers']:
+            for index, modifier in enumerate(self.object.modifiers):
+                modifier.show_render = modifier_config_cache[index]
+
     def generate_surfaces(self, escn_file, export_settings, mesh):
         """Splits up the mesh into surfaces with a single material each.
         Within this, it creates the Vertex structure to contain all data about
@@ -403,7 +398,7 @@ class MeshResourceExporter:
                 self.object.data.shape_keys):
             self.export_morphs(export_settings, surfaces)
 
-        has_bone = True if self.vgroup_to_bone_mapping else False
+        has_bone = bool(self.vgroup_to_bone_mapping)
         for surface in surfaces:
             surface.vertex_data.has_bone = has_bone
             for vert_array in surface.morph_arrays:

+ 11 - 11
io_scene_godot/converters/physics.py

@@ -64,9 +64,9 @@ def export_collision_shape(escn_file, export_settings, node, parent_gd_node,
     if parent_override is None:
         col_node['transform'] = mathutils.Matrix.Identity(4)
     else:
-        parent_to_world = parent_override.matrix_world.inverted()
-        col_node['transform'] = parent_to_world * node.matrix_world
-    col_node['transform'] *= _AXIS_CORRECT
+        parent_to_world = parent_override.matrix_world.inverted_safe()
+        col_node['transform'] = parent_to_world @ node.matrix_world
+    col_node['transform'] = col_node['transform'] @ _AXIS_CORRECT
 
     rbd = node.rigid_body
 
@@ -121,9 +121,9 @@ def generate_convex_mesh_array(escn_file, export_settings, node):
 
     col_shape = InternalResource("ConvexPolygonShape", mesh.name)
 
-    mesh = node.to_mesh(bpy.context.scene,
-                        export_settings['use_mesh_modifiers'],
-                        "RENDER")
+    mesh = node.to_mesh(bpy.context.view_layer.depsgraph,
+                        apply_modifiers=True,
+                        calc_undeformed=True)
 
     # Triangulate
     triangulated_mesh = bmesh.new()
@@ -156,9 +156,9 @@ def generate_triangle_mesh_array(escn_file, export_settings, node):
 
     col_shape = InternalResource("ConcavePolygonShape", mesh.name)
 
-    mesh = node.to_mesh(bpy.context.scene,
-                        export_settings['use_mesh_modifiers'],
-                        "RENDER")
+    mesh = node.to_mesh(bpy.context.view_layer.depsgraph,
+                        apply_modifiers=True,
+                        calc_undeformed=True)
 
     # Triangulate
     triangulated_mesh = bmesh.new()
@@ -202,8 +202,8 @@ def export_physics_controller(escn_file, export_settings, node,
     phys_obj['bounce'] = rbd.restitution
 
     col_groups = 0
-    for offset, bit in enumerate(rbd.collision_groups):
-        col_groups += bit << offset
+    for offset, flag in enumerate(rbd.collision_collections):
+        col_groups += (1 if flag else 0) << offset
 
     phys_obj['transform'] = node.matrix_local
     phys_obj['collision_layer'] = col_groups

+ 4 - 25
io_scene_godot/converters/simple_nodes.py

@@ -43,10 +43,6 @@ class CameraNode(NodeTemplate):
 
 def export_camera_node(escn_file, export_settings, node, parent_gd_node):
     """Exports a camera"""
-    if (node.data is None or node.hide_render or
-            "CAMERA" not in export_settings['object_types']):
-        return parent_gd_node
-
     cam_node = CameraNode(node.name, parent_gd_node)
     camera = node.data
 
@@ -76,8 +72,7 @@ class LightNode(NodeTemplate):
     """Base class for godot light node"""
     _light_attr_conv = [
         AttributeConvertInfo(
-            'use_specular', 'light_specular', lambda x: 1.0 if x else 0.0
-        ),
+            'specular_factor', 'light_specular', lambda x: x),
         AttributeConvertInfo('energy', 'light_energy', lambda x: x),
         AttributeConvertInfo('color', 'light_color', gamma_correct),
         AttributeConvertInfo('shadow_color', 'shadow_color', gamma_correct),
@@ -106,30 +101,15 @@ class LightNode(NodeTemplate):
         return self._light_attr_conv
 
 
-def export_lamp_node(escn_file, export_settings, node, parent_gd_node):
+def export_light_node(escn_file, export_settings, node, parent_gd_node):
     """Exports lights - well, the ones it knows about. Other light types
     just throw a warning"""
-    if (node.data is None or node.hide_render or
-            "LAMP" not in export_settings['object_types']):
-        return parent_gd_node
-
     light = node.data
 
     if light.type == "POINT":
         light_node = LightNode(node.name, 'OmniLight', parent_gd_node)
-
-        if not light.use_sphere:
-            logging.warning(
-                "Ranged light without sphere enabled: %s", node.name
-            )
-
     elif light.type == "SPOT":
         light_node = LightNode(node.name, 'SpotLight', parent_gd_node)
-        if not light.use_sphere:
-            logging.warning(
-                "Ranged light without sphere enabled: %s", node.name
-            )
-
     elif light.type == "SUN":
         light_node = LightNode(node.name, 'DirectionalLight', parent_gd_node)
     else:
@@ -143,10 +123,9 @@ def export_lamp_node(escn_file, export_settings, node, parent_gd_node):
             bl_attr, gd_attr, converter = item
             light_node[gd_attr] = converter(getattr(light, bl_attr))
 
-        # Properties common to all lights
+        # Properties cannot handled by a converter function
         light_node['transform'] = fix_directional_transform(node.matrix_local)
-        light_node['shadow_enabled'] = light.shadow_method != "NOSHADOW"
-        light_node['light_negative'] = light.use_negative
+        light_node['shadow_enabled'] = light.use_shadow
 
         escn_file.add_node(light_node)
 

+ 60 - 52
io_scene_godot/export_godot.py

@@ -50,7 +50,7 @@ def find_godot_project_dir(export_path):
     last = None
     while not os.path.isfile(os.path.join(project_dir, "project.godot")):
         project_dir = os.path.split(project_dir)[0]
-        if project_dir == "/" or project_dir == last:
+        if project_dir in ("/", last):
             raise structures.ValidationError(
                 "Unable to find godot project file"
             )
@@ -79,54 +79,57 @@ class ExporterLogHandler(logging.Handler):
 class GodotExporter:
     """Handles picking what nodes to export and kicks off the export process"""
 
-    def export_node(self, node, parent_gd_node):
-        """Recursively export a node. It calls the export_node function on
-        all of the nodes children. If you have heirarchies more than 1000 nodes
-        deep, this will fail with a recursion error"""
-        if node not in self.valid_nodes:
+    def export_object(self, obj, parent_gd_node):
+        """Recursively export a object. It calls the export_object function on
+        all of the objects children. If you have heirarchies more than 1000
+        objects deep, this will fail with a recursion error"""
+        if obj not in self.valid_objects:
             return
-        logging.info("Exporting Blender Object: %s", node.name)
 
-        prev_node = bpy.context.scene.objects.active
-        bpy.context.scene.objects.active = node
+        logging.info("Exporting Blender Object: %s", obj.name)
+
+        prev_node = bpy.context.view_layer.objects.active
+        bpy.context.view_layer.objects.active = obj
 
         # Figure out what function will perform the export of this object
-        if node.type in converters.BLENDER_TYPE_TO_EXPORTER:
-            exporter = converters.BLENDER_TYPE_TO_EXPORTER[node.type]
+        if (obj.type in converters.BLENDER_TYPE_TO_EXPORTER and
+                obj in self.exporting_objects):
+            exporter = converters.BLENDER_TYPE_TO_EXPORTER[obj.type]
         else:
             logging.warning(
-                "Unknown object type. Treating as empty: %s", node.name
+                "Unknown object type. Treating as empty: %s", obj.name
             )
             exporter = converters.BLENDER_TYPE_TO_EXPORTER["EMPTY"]
 
         is_bone_attachment = False
         if ("ARMATURE" in self.config['object_types'] and
-                node.parent_bone != ''):
+                obj.parent_bone != ''):
             is_bone_attachment = True
             parent_gd_node = converters.BONE_ATTACHMENT_EXPORTER(
                 self.escn_file,
-                node,
+                obj,
                 parent_gd_node
             )
 
-        # Perform the export, note that `exported_node.paren`t not
+        # Perform the export, note that `exported_node.parent` not
         # always the same as `parent_gd_node`, as sometimes, one
         # blender node exported as two parented node
-        exported_node = exporter(self.escn_file, self.config, node,
+        exported_node = exporter(self.escn_file, self.config, obj,
                                  parent_gd_node)
 
         if is_bone_attachment:
             for child in parent_gd_node.children:
                 child['transform'] = structures.fix_bone_attachment_transform(
-                    node, child['transform']
+                    obj, child['transform']
                 )
 
         # CollisionShape node has different direction in blender
         # and godot, so it has a -90 rotation around X axis,
         # here rotate its children back
-        if exported_node.parent.get_type() == 'CollisionShape':
+        if (exported_node.parent is not None and
+                exported_node.parent.get_type() == 'CollisionShape'):
             exported_node['transform'] = (
-                mathutils.Matrix.Rotation(math.radians(90), 4, 'X') *
+                mathutils.Matrix.Rotation(math.radians(90), 4, 'X') @
                 exported_node['transform'])
 
         # if the blender node is exported and it has animation data
@@ -135,36 +138,53 @@ class GodotExporter:
                 self.escn_file,
                 self.config,
                 exported_node,
-                node,
+                obj,
                 "transform"
             )
 
-        for child in node.children:
-            self.export_node(child, exported_node)
+        for child in obj.children:
+            self.export_object(child, exported_node)
 
-        bpy.context.scene.objects.active = prev_node
+        bpy.context.view_layer.objects.active = prev_node
 
-    def should_export_node(self, node):
+    def should_export_object(self, obj):
         """Checks if a node should be exported:"""
-        if node.type not in self.config["object_types"]:
+        if obj.type not in self.config["object_types"]:
             return False
 
-        if self.config["use_active_layers"]:
-            valid = False
-            for i in range(20):
-                if node.layers[i] and self.scene.layers[i]:
-                    valid = True
-                    break
-            if not valid:
+        if self.config["use_visible_objects"]:
+            view_layer = bpy.context.view_layer
+            if obj.name not in view_layer.objects:
+                return False
+            if not obj.visible_get():
                 return False
 
-        if self.config["use_export_selected"] and not node.select:
+        if self.config["use_export_selected"] and not obj.select:
             return False
 
+        self.exporting_objects.add(obj)
         return True
 
     def export_scene(self):
         """Decide what objects to export, and export them!"""
+        logging.info("Exporting scene: %s", self.scene.name)
+
+        # Decide what objects to export
+        for obj in self.scene.objects:
+            if obj in self.valid_objects:
+                continue
+            if self.should_export_object(obj):
+                # Ensure  parents of current valid object is
+                # going to the exporting recursion
+                tmp = obj
+                while tmp is not None:
+                    if tmp not in self.valid_objects:
+                        self.valid_objects.add(tmp)
+                    else:
+                        break
+                    tmp = tmp.parent
+        logging.info("Exporting %d objects", len(self.valid_objects))
+
         # Scene root
         root_gd_node = structures.NodeTemplate(
             self.scene.name,
@@ -172,25 +192,10 @@ class GodotExporter:
             None
         )
         self.escn_file.add_node(root_gd_node)
-        logging.info("Exporting scene: %s", self.scene.name)
-
-        # Decide what objects to export
-        for obj in self.scene.objects:
-            if obj in self.valid_nodes:
-                continue
-            if self.should_export_node(obj):
-                # Ensure all parents are also going to be exported
-                node = obj
-                while node is not None:
-                    if node not in self.valid_nodes:
-                        self.valid_nodes.append(node)
-                    node = node.parent
-
-        logging.info("Exporting %d objects", len(self.valid_nodes))
-
         for obj in self.scene.objects:
-            if obj in self.valid_nodes and obj.parent is None:
-                self.export_node(obj, root_gd_node)
+            if obj in self.valid_objects and obj.parent is None:
+                # recursive exporting on root object
+                self.export_object(obj, root_gd_node)
 
     def export(self):
         """Begin the export"""
@@ -218,7 +223,10 @@ class GodotExporter:
         self.config["project_path_func"] = functools.partial(
             find_godot_project_dir, path
         )
-        self.valid_nodes = []
+        # valid object would contain object should be exported
+        # and their parents to retain the hierarchy
+        self.valid_objects = set()
+        self.exporting_objects = set()
 
         self.escn_file = None
 

+ 5 - 3
io_scene_godot/structures.py

@@ -165,7 +165,7 @@ class NodeTemplate(FileEntry):
         if parent_node is not None:
             # solve duplication
             counter = 1
-            child_name_set = set([c.get_name() for c in self.parent.children])
+            child_name_set = {c.get_name() for c in self.parent.children}
             node_name_base = node_name
             while node_name in child_name_set:
                 node_name = node_name_base + str(counter).zfill(3)
@@ -334,7 +334,7 @@ class NodePath:
 
 def fix_matrix(mtx):
     """ Shuffles a matrix to change from y-up to z-up"""
-    # Todo: can this be replaced my a matrix multiplcation?
+    # TODO: can this be replaced my a matrix multiplcation?
     trans = mathutils.Matrix(mtx)
     up_axis = 2
 
@@ -360,7 +360,7 @@ _AXIS_CORRECT = mathutils.Matrix.Rotation(math.radians(-90), 4, 'X')
 def fix_directional_transform(mtx):
     """Used to correct spotlights and cameras, which in blender are
     Z-forwards and in Godot are Y-forwards"""
-    return mtx * _AXIS_CORRECT
+    return mtx @ _AXIS_CORRECT
 
 
 def fix_bone_attachment_transform(attachment_obj, blender_transform):
@@ -389,6 +389,8 @@ def gamma_correct(color):
     # note that here use a widely mentioned sRGB approximation gamma = 2.2
     # it is good enough, the exact gamma of sRGB can be find at
     # https://en.wikipedia.org/wiki/SRGB
+    if len(color) > 3:
+        color = color[:3]
     return mathutils.Color(tuple([x ** (1 / 2.2) for x in color]))
 
 

+ 1 - 1
requirements.txt

@@ -1,3 +1,3 @@
 # Python requirements for development
-pylint==1.9.2
+pylint==2.2.0
 pycodestyle==2.4.0

+ 13 - 3
tests/install_blender.sh

@@ -2,11 +2,21 @@
 
 set -e
 
-VERSION=2.79
-NAME="blender-2.79-linux-glibc219-x86_64"
+# hack, may be removed after find a stable blender2.8 build
+BLENDER_ORG_HOMEPAGE="https://builder.blender.org"
+DOWNLOAD_PAGE_HTML="`wget -qO- ${BLENDER_ORG_HOMEPAGE}/download`"
+DAILY_BUILD_REGEX_PATTERN='href="([^"]+)" title="Download Dev Linux 64 bit blender2.8"'
+[[ ${DOWNLOAD_PAGE_HTML} =~ ${DAILY_BUILD_REGEX_PATTERN} ]]
+BLENDER_28_LINUX_64_PATH=${BASH_REMATCH[1]}
+
+BLENDER_DIRNAME_REGEX_PATTERN='/download//(.+)\.tar\.bz2$'
+[[ ${BLENDER_28_LINUX_64_PATH} =~ ${BLENDER_DIRNAME_REGEX_PATTERN} ]]
+NAME=${BASH_REMATCH[1]}
+
+VERSION=2.80
 CACHE="${HOME}/.blender-cache"
 TAR="${CACHE}/${NAME}.tar.bz2"
-URL="http://mirror.cs.umn.edu/blender.org/release/Blender2.79/blender-2.79-linux-glibc219-x86_64.tar.bz2"
+URL="${BLENDER_ORG_HOMEPAGE}/${BLENDER_28_LINUX_64_PATH}"
 
 echo "Installing Blender ${VERSION}"
 mkdir -p $CACHE

File diff suppressed because it is too large
+ 0 - 0
tests/reference_exports/action_animation/animation_bone_transform.escn


+ 1 - 1
tests/reference_exports/action_animation/physics_animation.escn

@@ -97,4 +97,4 @@ anims/Cube.003Action.001 = SubResource(4)
 
 mesh = SubResource(5)
 visible = true
-transform = Transform(1.65289, 0.0, 0.0, 0.0, 1.2479e-07, -1.65289, 0.0, 1.65289, 1.2479e-07, 0.0, 3.60002e-14, 4.76837e-07)
+transform = Transform(1.65289, 0.0, 0.0, 0.0, 1.2479e-07, -1.65289, 0.0, 1.65289, 1.2479e-07, 0.0, 0.0, 0.0)

File diff suppressed because it is too large
+ 0 - 0
tests/reference_exports/action_with_constraint/bone_attachment_ik.escn


File diff suppressed because it is too large
+ 0 - 0
tests/reference_exports/action_with_constraint/constraint_external_IK.escn


File diff suppressed because it is too large
+ 0 - 0
tests/reference_exports/action_with_constraint/constraint_internal_IK.escn


File diff suppressed because it is too large
+ 0 - 0
tests/reference_exports/action_with_constraint/stashed_constraint.escn


File diff suppressed because it is too large
+ 0 - 0
tests/reference_exports/armature/armature_bone_attachment.escn


+ 6 - 6
tests/reference_exports/armature/armature_illegal_bone_name.escn

@@ -35,15 +35,15 @@ resource_name = "Cube001"
 surfaces/0 = {
 	"primitive":4,
 	"arrays":[
-		Vector3Array(-1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0),
-		Vector3Array(-1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0),
+		Vector3Array(-0.861623, 1.00707, 0.972223, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -0.852043, 1.00625, -1.02767, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.14764, 0.992919, -1.00687, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.13742, 0.993741, 0.993087, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -0.852043, 1.00625, -1.02767, 1.13742, 0.993741, 0.993087, 1.14764, 0.992919, -1.00687, -0.861623, 1.00707, 0.972223, -0.852043, 1.00625, -1.02767, -1.0, -1.0, -1.0, -0.852043, 1.00625, -1.02767, 1.14764, 0.992919, -1.00687, 1.0, -1.0, -1.0, 1.14764, 0.992919, -1.00687, 1.13742, 0.993741, 0.993087, 1.0, -1.0, 1.0, 1.13742, 0.993741, 0.993087, -0.861623, 1.00707, 0.972223, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -0.852043, 1.00625, -1.02767, -0.861623, 1.00707, 0.972223, 1.13742, 0.993741, 0.993087),
+		Vector3Array(-0.997632, 0.0687816, 0.0, -0.997632, 0.0687816, 0.0, -0.997632, 0.0687816, 0.0, 0.0, -0.0137889, -0.999905, 0.0, -0.0137889, -0.999905, 0.0, -0.0137889, -0.999905, 0.997267, -0.0738797, 0.0, 0.997267, -0.0738797, 0.0, 0.997267, -0.0738797, 0.0, 0.0, 0.00346724, 0.999994, 0.0, 0.00346724, 0.999994, 0.0, 0.00346724, 0.999994, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.00667129, 0.999978, -0.000377016, 0.00667129, 0.999978, -0.000377016, 0.00667129, 0.999978, -0.000377016, -0.997285, 0.0734815, -0.00480727, -0.997285, 0.0734815, -0.00480727, -0.997285, 0.0734815, -0.00480727, 0.0103709, -0.00421573, -0.999937, 0.0103709, -0.00421573, -0.999937, 0.0103709, -0.00421573, -0.999937, 0.997621, -0.0687459, 0.00512423, 0.997621, -0.0687459, 0.00512423, 0.997621, -0.0687459, 0.00512423, -0.0103384, 0.0145502, 0.999841, -0.0103384, 0.0145502, 0.999841, -0.0103384, 0.0145502, 0.999841, 0.0, -1.0, 0.0, 0.00667049, 0.999978, -0.000376529, 0.00667049, 0.999978, -0.000376529, 0.00667049, 0.999978, -0.000376529),
 		null, ; No Tangents,
 		null, ; no Vertex Colors,
 		null, ; No UV1,
 		null, ; No UV2,
-		IntArray(2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0),
-		FloatArray(0.925511, 0.0744892, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.923829, 0.076171, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.926358, 0.0736422, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.923954, 0.0760457, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.923829, 0.076171, 0.0, 0.0, 0.923954, 0.0760457, 0.0, 0.0, 0.926358, 0.0736422, 0.0, 0.0, 0.923829, 0.076171, 0.0, 0.0, 0.926358, 0.0736422, 0.0, 0.0, 0.923954, 0.0760457, 0.0, 0.0, 0.925511, 0.0744892, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.925511, 0.0744892, 0.0, 0.0),
-		IntArray(0, 2, 1, 3, 5, 4, 6, 8, 7, 9, 11, 10, 12, 14, 13, 15, 17, 16, 0, 1, 18, 3, 4, 19, 6, 7, 20, 9, 10, 21, 12, 13, 22, 15, 16, 23)
+		IntArray(2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0),
+		FloatArray(0.925511, 0.0744892, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.923829, 0.076171, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.926358, 0.0736422, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.923954, 0.0760457, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.923829, 0.076171, 0.0, 0.0, 0.923954, 0.0760457, 0.0, 0.0, 0.926358, 0.0736422, 0.0, 0.0, 0.925511, 0.0744892, 0.0, 0.0, 0.923829, 0.076171, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.923829, 0.076171, 0.0, 0.0, 0.926358, 0.0736422, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.926358, 0.0736422, 0.0, 0.0, 0.923954, 0.0760457, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.923954, 0.0760457, 0.0, 0.0, 0.925511, 0.0744892, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.923829, 0.076171, 0.0, 0.0, 0.925511, 0.0744892, 0.0, 0.0, 0.923954, 0.0760457, 0.0, 0.0),
+		IntArray(0, 2, 1, 3, 5, 4, 6, 8, 7, 9, 11, 10, 12, 14, 13, 15, 17, 16, 18, 20, 19, 21, 23, 22, 24, 26, 25, 27, 29, 28, 12, 13, 30, 31, 33, 32)
 	],
 	"morph_arrays":[]
 }
@@ -85,7 +85,7 @@ bone_name = "bone001"
 
 mesh = SubResource(2)
 visible = true
-transform = Transform(0.430514, -2.49202e-10, 0.0, -1.10958e-10, 0.430514, 4.88944e-09, -9.31323e-10, -1.16415e-10, 0.430514, 4.85688, 0.689524, 0.997775)
+transform = Transform(0.430514, 2.1646e-10, 0.0, -1.27329e-11, 0.430514, 0.0, 0.0, 0.0, 0.430514, 4.85688, 0.689524, 0.997775)
 
 [node name="Cube" type="MeshInstance" parent="Armature"]
 

File diff suppressed because it is too large
+ 0 - 0
tests/reference_exports/armature/armature_with_mesh.escn


File diff suppressed because it is too large
+ 0 - 0
tests/reference_exports/armature/armature_with_non_deform_bone.escn


File diff suppressed because it is too large
+ 0 - 0
tests/reference_exports/armature/armature_with_other_vertex_groups.escn


File diff suppressed because it is too large
+ 0 - 0
tests/reference_exports/armature/armature_with_physics.escn


File diff suppressed because it is too large
+ 0 - 0
tests/reference_exports/armature/armature_with_pose.escn


+ 4 - 23
tests/reference_exports/light/animation_sun.escn

@@ -23,29 +23,11 @@ surfaces/0 = {
 
 resource_name = "SunAction001"
 step = 0.1
-length = 4.58333
+length = 1.25
 tracks/0/type = "value"
-tracks/0/path = NodePath(".:light_negative")
-tracks/0/interp = 0
+tracks/0/path = NodePath(".:light_energy")
+tracks/0/interp = 1
 tracks/0/keys = {
-	"times":PoolRealArray(3.75, 4.16667, 4.58333),
-	"transitions":PoolRealArray(1, 1, 1),
-	"update":0,
-	"values":[false, true, false]
-}
-tracks/1/type = "value"
-tracks/1/path = NodePath(".:light_specular")
-tracks/1/interp = 0
-tracks/1/keys = {
-	"times":PoolRealArray(2.08333, 2.5, 2.91667),
-	"transitions":PoolRealArray(1, 1, 1),
-	"update":0,
-	"values":[1.0, 0.0, 1.0]
-}
-tracks/2/type = "value"
-tracks/2/path = NodePath(".:light_energy")
-tracks/2/interp = 1
-tracks/2/keys = {
 	"times":PoolRealArray(0.0, 0.0416667, 0.0833333, 0.125, 0.166667, 0.208333, 0.25, 0.291667, 0.333333, 0.375, 0.416667, 0.458333, 0.5, 0.541667, 0.583333, 0.625, 0.666667, 0.708333, 0.75, 0.791667, 0.833333, 0.875, 0.916667, 0.958333, 1.0, 1.04167, 1.08333, 1.125, 1.16667, 1.20833, 1.25),
 	"transitions":PoolRealArray(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
 	"update":0,
@@ -67,8 +49,7 @@ light_energy = 1.0
 light_color = Color(1.0, 1.0, 1.0, 1.0)
 shadow_color = Color(0.0, 0.0, 0.0, 1.0)
 transform = Transform(0.883713, -0.407974, 0.229367, -0.443707, -0.574356, 0.687924, -0.148916, -0.709699, -0.688587, 0.0, 5.2651, -7.49279)
-shadow_enabled = false
-light_negative = false
+shadow_enabled = true
 
 [node name="AnimationPlayer" type="AnimationPlayer" parent="Sun"]
 

+ 0 - 5
tests/reference_exports/light/animation_various_lights.escn

@@ -149,7 +149,6 @@ spot_angle_attenuation = 1.25
 spot_range = 25.0
 transform = Transform(1.0, 0.0, 0.0, 0.0, -4.37114e-08, 1.0, 0.0, -1.0, -4.37114e-08, 0.223751, 3.0266, 1.21379)
 shadow_enabled = true
-light_negative = false
 
 [node name="AnimationPlayer" type="AnimationPlayer" parent="SpotDistanceChange"]
 
@@ -167,7 +166,6 @@ spot_angle_attenuation = 1.25
 spot_range = 25.0
 transform = Transform(0.477268, -3.84117e-08, 0.878758, -0.878758, -2.0862e-08, 0.477268, 0.0, -1.0, -4.37114e-08, -0.760565, 3.14704, 6.40839)
 shadow_enabled = true
-light_negative = false
 
 [node name="AnimationPlayer" type="AnimationPlayer" parent="SpotTransformChange"]
 
@@ -191,7 +189,6 @@ spot_angle_attenuation = 1.25
 spot_range = 25.0
 transform = Transform(0.958848, -0.28392, -2.18837e-08, 0.178546, 0.602982, 0.777518, -0.220753, -0.745521, 0.628861, -4.64127, 6.11957, 1.29809)
 shadow_enabled = true
-light_negative = false
 
 [node name="AnimationPlayer" type="AnimationPlayer" parent="ShadowColorChange"]
 
@@ -215,7 +212,6 @@ spot_angle_attenuation = 1.25
 spot_range = 25.0
 transform = Transform(1.0, 0.0, 0.0, 0.0, -4.37114e-08, 1.0, 0.0, -1.0, -4.37114e-08, 6.6415, 3.84213, -6.03583)
 shadow_enabled = true
-light_negative = false
 
 [node name="AnimationPlayer" type="AnimationPlayer" parent="SpotRangeChange"]
 
@@ -231,7 +227,6 @@ shadow_color = Color(0.0, 0.0, 0.0, 1.0)
 omni_range = 1.0
 transform = Transform(-0.290865, -0.771101, 0.566393, -0.0551891, 0.604525, 0.794672, -0.955171, 0.199883, -0.218391, 5.25185, 0.215087, 5.49347)
 shadow_enabled = true
-light_negative = false
 
 [node name="AnimationPlayer" type="AnimationPlayer" parent="LightColorChange"]
 

+ 0 - 4
tests/reference_exports/light/just_point_lights.escn

@@ -68,7 +68,6 @@ shadow_color = Color(0.0, 0.0, 0.0, 1.0)
 omni_range = 5.0
 transform = Transform(1.0, 0.0, 0.0, 0.0, -4.37114e-08, 1.0, 0.0, -1.0, -4.37114e-08, 0.0, 0.4, 1.0)
 shadow_enabled = true
-light_negative = false
 
 [node name="Cube001" type="MeshInstance" parent="."]
 
@@ -91,7 +90,6 @@ shadow_color = Color(0.0, 0.0, 0.0, 1.0)
 omni_range = 5.0
 transform = Transform(1.0, 0.0, 0.0, 0.0, -4.37114e-08, 1.0, 0.0, -1.0, -4.37114e-08, -2.0, 0.4, 1.0)
 shadow_enabled = false
-light_negative = false
 
 [node name="Lamp001" type="OmniLight" parent="."]
 
@@ -102,7 +100,6 @@ shadow_color = Color(0.0, 0.0, 0.0, 1.0)
 omni_range = 2.0
 transform = Transform(1.0, 0.0, 0.0, 0.0, -4.37114e-08, 1.0, 0.0, -1.0, -4.37114e-08, -6.0, 1.0, 3.0)
 shadow_enabled = false
-light_negative = false
 
 [node name="Plane" type="MeshInstance" parent="."]
 
@@ -119,7 +116,6 @@ shadow_color = Color(0.0, 0.0, 0.0, 1.0)
 omni_range = 2.0
 transform = Transform(1.0, 0.0, 0.0, 0.0, -4.37114e-08, 1.0, 0.0, -1.0, -4.37114e-08, -6.0, 1.0, 0.0)
 shadow_enabled = false
-light_negative = false
 
 [node name="Camera" type="Camera" parent="."]
 

+ 0 - 8
tests/reference_exports/light/just_spot_lights.escn

@@ -70,7 +70,6 @@ spot_angle_attenuation = 20.0
 spot_range = 3.0
 transform = Transform(1.0, 0.0, 0.0, 0.0, -4.37114e-08, 1.0, 0.0, -1.0, -4.37114e-08, 1.0, 2.0, -3.0)
 shadow_enabled = false
-light_negative = false
 
 [node name="Lamp006" type="SpotLight" parent="."]
 
@@ -83,7 +82,6 @@ spot_angle_attenuation = 0.19802
 spot_range = 3.0
 transform = Transform(1.0, 0.0, 0.0, 0.0, -4.37114e-08, 1.0, 0.0, -1.0, -4.37114e-08, 2.0, 2.0, -3.0)
 shadow_enabled = false
-light_negative = false
 
 [node name="Lamp005" type="SpotLight" parent="."]
 
@@ -96,7 +94,6 @@ spot_angle_attenuation = 0.19802
 spot_range = 3.0
 transform = Transform(1.0, 0.0, 0.0, 0.0, -4.37114e-08, 1.0, 0.0, -1.0, -4.37114e-08, 2.0, 2.0, -2.0)
 shadow_enabled = false
-light_negative = false
 
 [node name="Lamp002" type="SpotLight" parent="."]
 
@@ -109,7 +106,6 @@ spot_angle_attenuation = 20.0
 spot_range = 3.0
 transform = Transform(1.0, 0.0, 0.0, 0.0, -4.37114e-08, 1.0, 0.0, -1.0, -4.37114e-08, 1.0, 2.0, -2.0)
 shadow_enabled = false
-light_negative = false
 
 [node name="Lamp001" type="SpotLight" parent="."]
 
@@ -122,7 +118,6 @@ spot_angle_attenuation = 1.25
 spot_range = 3.0
 transform = Transform(1.0, 0.0, 0.0, 0.0, 0.906308, 0.422618, 0.0, -0.422618, 0.906308, 1.0, 1.0, 2.0)
 shadow_enabled = false
-light_negative = false
 
 [node name="Lamp000" type="SpotLight" parent="."]
 
@@ -135,7 +130,6 @@ spot_angle_attenuation = 1.25
 spot_range = 5.0
 transform = Transform(1.0, 0.0, 0.0, 0.0, 0.906308, 0.422618, 0.0, -0.422618, 0.906308, -1.0, 1.0, 2.0)
 shadow_enabled = false
-light_negative = false
 
 [node name="Cube001" type="MeshInstance" parent="."]
 
@@ -160,7 +154,6 @@ spot_angle_attenuation = 1.25
 spot_range = 5.0
 transform = Transform(1.0, 0.0, 0.0, 0.0, 0.906308, 0.422618, 0.0, -0.422618, 0.906308, -4.0, 1.0, 2.0)
 shadow_enabled = true
-light_negative = false
 
 [node name="Lamp003" type="SpotLight" parent="."]
 
@@ -173,7 +166,6 @@ spot_angle_attenuation = 1.25
 spot_range = 5.0
 transform = Transform(1.0, 0.0, 0.0, 0.0, 0.906308, 0.422618, 0.0, -0.422618, 0.906308, -6.0, 1.0, 2.0)
 shadow_enabled = false
-light_negative = false
 
 [node name="Plane" type="MeshInstance" parent="."]
 

+ 0 - 1
tests/reference_exports/material/material_search.escn

@@ -38,7 +38,6 @@ shadow_color = Color(0.0, 0.0, 0.0, 1.0)
 omni_range = 30.0
 transform = Transform(-0.290865, -0.771101, 0.566393, -0.0551891, 0.604525, 0.794672, -0.955171, 0.199883, -0.218391, 4.07625, 5.90386, -1.00545)
 shadow_enabled = true
-light_negative = false
 
 [node name="Camera" type="Camera" parent="."]
 

+ 0 - 20
tests/reference_exports/material/object_link_material.escn

@@ -3,22 +3,12 @@
 [sub_resource id=1 type="SpatialMaterial"]
 
 resource_name = ""
-flags_unshaded = false
-flags_vertex_lighting = false
-flags_transparent = false
-vertex_color_use_as_albedo = false
 albedo_color = Color(0.229957, 0.274814, 0.903545, 1.0)
-subsurf_scatter_enabled = false
 
 [sub_resource id=2 type="SpatialMaterial"]
 
 resource_name = ""
-flags_unshaded = false
-flags_vertex_lighting = false
-flags_transparent = false
-vertex_color_use_as_albedo = false
 albedo_color = Color(0.903545, 0.903545, 0.903545, 1.0)
-subsurf_scatter_enabled = false
 
 [sub_resource id=3 type="ArrayMesh"]
 
@@ -59,22 +49,12 @@ surfaces/1 = {
 [sub_resource id=4 type="SpatialMaterial"]
 
 resource_name = ""
-flags_unshaded = false
-flags_vertex_lighting = false
-flags_transparent = false
-vertex_color_use_as_albedo = false
 albedo_color = Color(0.903545, 0.169508, 0.242857, 1.0)
-subsurf_scatter_enabled = false
 
 [sub_resource id=5 type="SpatialMaterial"]
 
 resource_name = ""
-flags_unshaded = false
-flags_vertex_lighting = false
-flags_transparent = false
-vertex_color_use_as_albedo = false
 albedo_color = Color(0.121702, 0.903545, 0.139942, 1.0)
-subsurf_scatter_enabled = false
 [node type="Spatial" name="Scene"]
 
 

+ 0 - 11
tests/reference_exports/material/simple_materials.escn

@@ -3,22 +3,12 @@
 [sub_resource id=1 type="SpatialMaterial"]
 
 resource_name = ""
-flags_unshaded = false
-flags_vertex_lighting = false
-flags_transparent = false
-vertex_color_use_as_albedo = false
 albedo_color = Color(0.138926, 0.903545, 0.0, 1.0)
-subsurf_scatter_enabled = false
 
 [sub_resource id=2 type="SpatialMaterial"]
 
 resource_name = ""
-flags_unshaded = false
-flags_vertex_lighting = false
-flags_transparent = false
-vertex_color_use_as_albedo = false
 albedo_color = Color(0.903545, 0.903545, 0.903545, 1.0)
-subsurf_scatter_enabled = false
 
 [sub_resource id=3 type="ArrayMesh"]
 
@@ -73,7 +63,6 @@ shadow_color = Color(0.0, 0.0, 0.0, 1.0)
 omni_range = 30.0
 transform = Transform(-0.290865, -0.771101, 0.566393, -0.0551891, 0.604525, 0.794672, -0.955171, 0.199883, -0.218391, 4.07625, 5.90386, -1.00545)
 shadow_enabled = true
-light_negative = false
 
 [node name="Camera" type="Camera" parent="."]
 

File diff suppressed because it is too large
+ 0 - 0
tests/reference_exports/material_cycle/material_anistropy.escn


File diff suppressed because it is too large
+ 2 - 2
tests/reference_exports/material_cycle/material_cycle.escn


+ 23 - 106
tests/reference_exports/material_cycle/material_normal.escn

@@ -372,98 +372,16 @@ void fragment() {
 resource_name = ""
 shader = SubResource(11)
 
-[sub_resource id=13 type="Shader"]
-
-resource_name = "Shader Nodetree"
-code = "shader_type spatial;
-render_mode blend_mix,depth_draw_always,cull_back,diffuse_burley,specular_schlick_ggx;
-uniform sampler2D uni1_ImageTexturetexture_image;
-
-
-void node_bsdf_diffuse(vec4 color, float roughness, out vec3 albedo,
-        out float specular_out, out float roughness_out) {
-    albedo = color.rgb;
-    specular_out = 0.5;
-    roughness_out = 1.0;
-}
-
-
-void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha) {
-    color = texture(ima, co.xy);
-    alpha = color.a;
-}
-
-
-void node_rgb_to_bw(vec4 color, out float result){
-    result = color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722;
-}
-
-
-void node_bump(float strength, float dist, float height, vec3 normal,
-               vec3 surf_pos, float invert, out vec3 out_normal){
-    if (invert != 0.0) {
-        dist *= -1.0;
-    }
-    vec3 dPdx = dFdx(surf_pos);
-    vec3 dPdy = dFdy(surf_pos);
-
-    /* Get surface tangents from normal. */
-    vec3 Rx = cross(dPdy, normal);
-    vec3 Ry = cross(normal, dPdx);
-
-    /* Compute surface gradient and determinant. */
-    float det = dot(dPdx, Rx);
-    float absdet = abs(det);
-
-    float dHdx = dFdx(height);
-    float dHdy = dFdy(height);
-    vec3 surfgrad = dHdx * Rx + dHdy * Ry;
-
-    strength = max(strength, 0.0);
-
-    out_normal = normalize(absdet * normal - dist * sign(det) * surfgrad);
-    out_normal = normalize(strength * out_normal + (1.0 - strength) * normal);
-}
-
-
-
-void vertex() {
-	
-}
-
-
-void fragment() {
-	vec4 var1_DiffuseBSDF_Color;
-	var1_DiffuseBSDF_Color = vec4(0.800000011920929, 0.800000011920929, 0.800000011920929, 1.0);
-	float var2_DiffuseBSDF_Roughness;
-	var2_DiffuseBSDF_Roughness = 0.0;
-	vec3 var3_DiffuseBSDF_output_albedo;
-	float var4_DiffuseBSDF_output_specular;
-	float var5_DiffuseBSDF_output_roughness;
-	node_bsdf_diffuse(var1_DiffuseBSDF_Color, var2_DiffuseBSDF_Roughness, var3_DiffuseBSDF_output_albedo, var4_DiffuseBSDF_output_specular, var5_DiffuseBSDF_output_roughness);
-	ALBEDO = var3_DiffuseBSDF_output_albedo;
-	SPECULAR = var4_DiffuseBSDF_output_specular;
-	ROUGHNESS = var5_DiffuseBSDF_output_roughness;
-	vec4 var6_ImageTexture_Color;
-	float var7_ImageTexture_Alpha;
-	node_tex_image(vec3(UV, 0.0), uni1_ImageTexturetexture_image, var6_ImageTexture_Color, var7_ImageTexture_Alpha);
-	float var8_auto_insert_RGBtoBW;
-	node_rgb_to_bw(var6_ImageTexture_Color, var8_auto_insert_RGBtoBW);
-	node_bump(1.0, 0.1, var8_auto_insert_RGBtoBW, NORMAL, VERTEX, 0.0, NORMAL);
-}
-"
-
-[sub_resource id=14 type="ShaderMaterial"]
+[sub_resource id=13 type="SpatialMaterial"]
 
 resource_name = ""
-shader = SubResource(13)
-shader_param/uni1_ImageTexturetexture_image = ExtResource(2)
+albedo_color = Color(0.903545, 0.903545, 0.903545, 1.0)
 
-[sub_resource id=15 type="ArrayMesh"]
+[sub_resource id=14 type="ArrayMesh"]
 
 resource_name = "Plane001"
 surfaces/0 = {
-	"material":SubResource(14),
+	"material":SubResource(13),
 	"primitive":4,
 	"arrays":[
 		Vector3Array(1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 0.0, -1.0),
@@ -479,7 +397,7 @@ surfaces/0 = {
 	"morph_arrays":[]
 }
 
-[sub_resource id=16 type="Shader"]
+[sub_resource id=15 type="Shader"]
 
 resource_name = "Shader Nodetree"
 code = "shader_type spatial;
@@ -542,17 +460,17 @@ void fragment() {
 }
 "
 
-[sub_resource id=17 type="ShaderMaterial"]
+[sub_resource id=16 type="ShaderMaterial"]
 
 resource_name = ""
-shader = SubResource(16)
+shader = SubResource(15)
 shader_param/uni1_ImageTexturetexture_image = ExtResource(1)
 
-[sub_resource id=18 type="ArrayMesh"]
+[sub_resource id=17 type="ArrayMesh"]
 
 resource_name = "Plane002"
 surfaces/0 = {
-	"material":SubResource(17),
+	"material":SubResource(16),
 	"primitive":4,
 	"arrays":[
 		Vector3Array(1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 0.0, -1.0),
@@ -568,7 +486,7 @@ surfaces/0 = {
 	"morph_arrays":[]
 }
 
-[sub_resource id=19 type="Shader"]
+[sub_resource id=18 type="Shader"]
 
 resource_name = "Shader Nodetree"
 code = "shader_type spatial;
@@ -630,17 +548,17 @@ void fragment() {
 }
 "
 
-[sub_resource id=20 type="ShaderMaterial"]
+[sub_resource id=19 type="ShaderMaterial"]
 
 resource_name = ""
-shader = SubResource(19)
+shader = SubResource(18)
 shader_param/uni1_ImageTexturetexture_image = ExtResource(1)
 
-[sub_resource id=21 type="ArrayMesh"]
+[sub_resource id=20 type="ArrayMesh"]
 
 resource_name = "Plane003"
 surfaces/0 = {
-	"material":SubResource(20),
+	"material":SubResource(19),
 	"primitive":4,
 	"arrays":[
 		Vector3Array(1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 0.0, -1.0),
@@ -656,7 +574,7 @@ surfaces/0 = {
 	"morph_arrays":[]
 }
 
-[sub_resource id=22 type="Shader"]
+[sub_resource id=21 type="Shader"]
 
 resource_name = "Shader Nodetree"
 code = "shader_type spatial;
@@ -745,17 +663,17 @@ void fragment() {
 }
 "
 
-[sub_resource id=23 type="ShaderMaterial"]
+[sub_resource id=22 type="ShaderMaterial"]
 
 resource_name = ""
-shader = SubResource(22)
+shader = SubResource(21)
 shader_param/uni1_ImageTexture001texture_image = ExtResource(2)
 
-[sub_resource id=24 type="ArrayMesh"]
+[sub_resource id=23 type="ArrayMesh"]
 
 resource_name = "Plane004"
 surfaces/0 = {
-	"material":SubResource(23),
+	"material":SubResource(22),
 	"primitive":4,
 	"arrays":[
 		Vector3Array(1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 0.0, -1.0),
@@ -814,28 +732,27 @@ light_color = Color(1.0, 1.0, 1.0, 1.0)
 shadow_color = Color(0.0, 0.0, 0.0, 1.0)
 transform = Transform(-0.404791, -0.439839, 0.801677, 0.221124, 0.803611, 0.552553, -0.88727, 0.400938, -0.228035, 4.07625, 1.70784, -1.00545)
 shadow_enabled = true
-light_negative = false
 
 [node name="test_displacement" type="MeshInstance" parent="."]
 
-mesh = SubResource(15)
+mesh = SubResource(14)
 visible = true
 transform = Transform(2.17434, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 2.089, 5.56855, 0.111502, 4.35828)
 
 [node name="test_normal_object" type="MeshInstance" parent="."]
 
-mesh = SubResource(18)
+mesh = SubResource(17)
 visible = true
 transform = Transform(2.17434, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 2.089, -4.51125, 0.111502, -5.04673)
 
 [node name="test_normal_world" type="MeshInstance" parent="."]
 
-mesh = SubResource(21)
+mesh = SubResource(20)
 visible = true
 transform = Transform(2.17434, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 2.089, -4.6612, 0.111502, 4.30586)
 
 [node name="test_bump" type="MeshInstance" parent="."]
 
-mesh = SubResource(24)
+mesh = SubResource(23)
 visible = true
 transform = Transform(2.17434, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 2.089, 0.134761, 0.111502, -0.424369)

+ 6 - 6
tests/reference_exports/mesh/just_mesh.escn

@@ -14,7 +14,7 @@ surfaces/0 = {
 		null, ; No UV2,
 		null, ; No Bones,
 		null, ; No Weights,
-		IntArray(0, 2, 1, 3, 1, 4, 5, 4, 6, 7, 6, 8, 0, 5, 9, 9, 8, 10, 11, 10, 2, 1, 10, 8, 0, 1, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 5, 0, 3, 0, 9, 11, 9, 5, 7, 9, 10, 11, 11, 2, 0, 10, 1, 2, 1, 6, 4, 6, 1, 8)
+		IntArray(0, 2, 1, 3, 1, 4, 5, 4, 6, 7, 6, 8, 0, 5, 9, 9, 8, 10, 11, 10, 2, 1, 10, 6, 0, 1, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 5, 0, 3, 0, 9, 11, 9, 5, 7, 9, 10, 11, 11, 2, 0, 10, 1, 2, 1, 6, 4, 6, 10, 8)
 	],
 	"morph_arrays":[]
 }
@@ -25,15 +25,15 @@ resource_name = "Cylinder002"
 surfaces/0 = {
 	"primitive":4,
 	"arrays":[
-		Vector3Array(0.0, 1.0, -1.0, 0.866025, -1.0, -0.5, 0.0, -1.0, -1.0, 0.866025, 1.0, -0.5, 0.866025, -1.0, 0.5, 0.866025, 1.0, 0.5, -8.74228e-08, -1.0, 1.0, -8.74228e-08, 1.0, 1.0, -0.866025, -1.0, 0.5, 0.0, 1.0, -1.0, -0.866025, 1.0, 0.5, 0.866025, 1.0, 0.5, -0.866025, 1.0, 0.5, -0.866025, -1.0, -0.5, -0.866025, 1.0, -0.5, 0.866025, -1.0, -0.5, -0.866025, -1.0, 0.5, -0.866025, -1.0, -0.5, 0.866025, 1.0, -0.5, -0.866025, 1.0, -0.5, -8.74228e-08, 1.0, 1.0, 0.0, -1.0, -1.0, 0.866025, -1.0, 0.5, -8.74228e-08, -1.0, 1.0),
-		Vector3Array(-6.57235e-08, 0.0, -1.0, 0.866025, 0.0, -0.5, -2.19078e-08, 0.0, -1.0, 0.866025, 0.0, -0.5, 0.866025, 0.0, 0.5, 0.866025, 0.0, 0.5, -8.76314e-08, 0.0, 1.0, -8.76314e-08, 0.0, 1.0, -0.866025, 0.0, 0.5, 4.58837e-08, 1.0, 0.0, 6.30901e-08, 1.0, 0.0, 2.86773e-08, 1.0, 0.0, -0.866025, 0.0, 0.5, -0.866025, 0.0, -0.5, -0.866025, 0.0, -0.5, 6.88255e-08, -1.0, 0.0, 0.0, -1.0, 0.0, 3.44128e-08, -1.0, 0.0, 0.0, 1.0, 0.0, 1.37651e-07, 1.0, 0.0, 6.88255e-08, 1.0, 0.0, 1.37651e-07, -1.0, 0.0, 1.37651e-07, -1.0, 0.0, 3.44128e-08, -1.0, 0.0),
+		Vector3Array(0.0, 1.0, -1.0, 0.866025, -1.0, -0.5, 0.0, -1.0, -1.0, 0.866025, 1.0, -0.5, 0.866025, -1.0, 0.5, 0.866025, 1.0, 0.5, -8.74228e-08, -1.0, 1.0, -8.74228e-08, 1.0, 1.0, -0.866025, -1.0, 0.5, 0.0, 1.0, -1.0, -0.866025, 1.0, 0.5, 0.866025, 1.0, 0.5, -0.866025, 1.0, 0.5, -0.866025, -1.0, -0.5, -0.866025, 1.0, -0.5, 0.866025, -1.0, -0.5, -8.74228e-08, -1.0, 1.0, -0.866025, -1.0, -0.5, 0.866025, 1.0, -0.5, -0.866025, 1.0, -0.5, -8.74228e-08, 1.0, 1.0, 0.0, -1.0, -1.0, 0.866025, -1.0, 0.5, -0.866025, -1.0, 0.5),
+		Vector3Array(-6.57235e-08, 0.0, -1.0, 0.866025, 0.0, -0.5, -2.19078e-08, 0.0, -1.0, 0.866025, 0.0, -0.5, 0.866025, 0.0, 0.5, 0.866025, 0.0, 0.5, -8.76314e-08, 0.0, 1.0, -8.76314e-08, 0.0, 1.0, -0.866025, 0.0, 0.5, 4.58837e-08, 1.0, 0.0, 6.30901e-08, 1.0, 0.0, 2.86773e-08, 1.0, 0.0, -0.866025, 0.0, 0.5, -0.866025, 0.0, -0.5, -0.866025, 0.0, -0.5, 2.29418e-08, -1.0, 0.0, 2.29418e-08, -1.0, 0.0, 2.29419e-08, -1.0, 0.0, 0.0, 1.0, 0.0, 1.37651e-07, 1.0, 0.0, 6.88255e-08, 1.0, 0.0, 1.37651e-07, -1.0, 0.0, 1.37651e-07, -1.0, 0.0, 1.37651e-07, -1.0, 0.0),
 		null, ; No Tangents,
 		null, ; no Vertex Colors,
 		null, ; No UV1,
 		null, ; No UV2,
 		null, ; No Bones,
 		null, ; No Weights,
-		IntArray(0, 2, 1, 3, 1, 4, 5, 4, 6, 7, 6, 8, 9, 11, 10, 12, 8, 13, 14, 13, 2, 15, 17, 16, 0, 1, 3, 3, 4, 5, 5, 6, 7, 7, 8, 12, 11, 9, 18, 9, 10, 19, 10, 11, 20, 12, 13, 14, 14, 2, 0, 17, 15, 21, 15, 23, 22, 23, 15, 16)
+		IntArray(0, 2, 1, 3, 1, 4, 5, 4, 6, 7, 6, 8, 9, 11, 10, 12, 8, 13, 14, 13, 2, 15, 17, 16, 0, 1, 3, 3, 4, 5, 5, 6, 7, 7, 8, 12, 11, 9, 18, 9, 10, 19, 10, 11, 20, 12, 13, 14, 14, 2, 0, 17, 15, 21, 15, 16, 22, 16, 17, 23)
 	],
 	"morph_arrays":[]
 }
@@ -44,8 +44,8 @@ resource_name = "Cylinder001"
 surfaces/0 = {
 	"primitive":4,
 	"arrays":[
-		Vector3Array(0.0, 1.0, -1.0, 0.866025, -1.0, -0.5, 0.0, -1.0, -1.0, 0.866025, 1.0, -0.5, 0.866025, -1.0, 0.5, 0.866025, -1.0, -0.5, 0.866025, 1.0, 0.5, -8.74228e-08, -1.0, 1.0, 0.866025, -1.0, 0.5, -8.74228e-08, 1.0, 1.0, -0.866025, -1.0, 0.5, -8.74228e-08, -1.0, 1.0, 0.0, 1.0, -1.0, -0.866025, 1.0, 0.5, 0.866025, 1.0, 0.5, -0.866025, 1.0, 0.5, -0.866025, -1.0, -0.5, -0.866025, -1.0, 0.5, -0.866025, 1.0, -0.5, 0.0, -1.0, -1.0, -0.866025, -1.0, -0.5, 0.866025, -1.0, -0.5, -0.866025, -1.0, 0.5, -0.866025, -1.0, -0.5, 0.866025, 1.0, -0.5, 0.866025, 1.0, -0.5, 0.866025, 1.0, 0.5, 0.866025, -1.0, 0.5, 0.866025, 1.0, 0.5, -8.74228e-08, 1.0, 1.0, -8.74228e-08, -1.0, 1.0, -8.74228e-08, 1.0, 1.0, -0.866025, 1.0, 0.5, -0.866025, -1.0, 0.5, 0.866025, 1.0, 0.5, 0.866025, 1.0, -0.5, 0.0, 1.0, -1.0, 0.0, 1.0, -1.0, -0.866025, 1.0, -0.5, -0.866025, 1.0, 0.5, -0.866025, 1.0, 0.5, -8.74228e-08, 1.0, 1.0, 0.866025, 1.0, 0.5, -0.866025, 1.0, -0.5, 0.0, 1.0, -1.0, -0.866025, -1.0, -0.5, 0.0, -1.0, -1.0, 0.866025, -1.0, -0.5, 0.866025, -1.0, -0.5, 0.866025, -1.0, 0.5, -8.74228e-08, -1.0, 1.0, -8.74228e-08, -1.0, 1.0, -0.866025, -1.0, 0.5, 0.866025, -1.0, -0.5),
-		Vector3Array(0.5, 0.0, -0.866025, 0.5, 0.0, -0.866025, 0.5, 0.0, -0.866025, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.0, 0.866025, 0.5, 0.0, 0.866025, 0.5, 0.0, 0.866025, -0.5, 0.0, 0.866025, -0.5, 0.0, 0.866025, -0.5, 0.0, 0.866025, 2.29418e-08, 1.0, 0.0, 2.29418e-08, 1.0, 0.0, 2.29418e-08, 1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -0.5, 0.0, -0.866025, -0.5, 0.0, -0.866025, -0.5, 0.0, -0.866025, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.5, 0.0, -0.866025, 1.0, 0.0, 1.19209e-07, 1.0, 0.0, 1.19209e-07, 1.0, 0.0, 1.19209e-07, 0.5, 0.0, 0.866026, 0.5, 0.0, 0.866026, 0.5, 0.0, 0.866026, -0.5, 0.0, 0.866025, -0.5, 0.0, 0.866025, -0.5, 0.0, 0.866025, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.37651e-07, 1.0, 0.0, 1.37651e-07, 1.0, 0.0, 1.37651e-07, 1.0, 0.0, 6.88255e-08, 1.0, 0.0, 6.88255e-08, 1.0, 0.0, 6.88255e-08, 1.0, 0.0, -1.0, 0.0, 0.0, -0.5, 0.0, -0.866025, 1.37651e-07, -1.0, 0.0, 1.37651e-07, -1.0, 0.0, 1.37651e-07, -1.0, 0.0, 1.37651e-07, -1.0, 0.0, 1.37651e-07, -1.0, 0.0, 1.37651e-07, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0),
+		Vector3Array(0.0, 1.0, -1.0, 0.866025, -1.0, -0.5, 0.0, -1.0, -1.0, 0.866025, 1.0, -0.5, 0.866025, -1.0, 0.5, 0.866025, -1.0, -0.5, 0.866025, 1.0, 0.5, -8.74228e-08, -1.0, 1.0, 0.866025, -1.0, 0.5, -8.74228e-08, 1.0, 1.0, -0.866025, -1.0, 0.5, -8.74228e-08, -1.0, 1.0, 0.0, 1.0, -1.0, -0.866025, 1.0, 0.5, 0.866025, 1.0, 0.5, -0.866025, 1.0, 0.5, -0.866025, -1.0, -0.5, -0.866025, -1.0, 0.5, -0.866025, 1.0, -0.5, 0.0, -1.0, -1.0, -0.866025, -1.0, -0.5, 0.866025, -1.0, -0.5, -8.74228e-08, -1.0, 1.0, -0.866025, -1.0, -0.5, 0.866025, 1.0, -0.5, 0.866025, 1.0, -0.5, 0.866025, 1.0, 0.5, 0.866025, -1.0, 0.5, 0.866025, 1.0, 0.5, -8.74228e-08, 1.0, 1.0, -8.74228e-08, -1.0, 1.0, -8.74228e-08, 1.0, 1.0, -0.866025, 1.0, 0.5, -0.866025, -1.0, 0.5, 0.866025, 1.0, 0.5, 0.866025, 1.0, -0.5, 0.0, 1.0, -1.0, 0.0, 1.0, -1.0, -0.866025, 1.0, -0.5, -0.866025, 1.0, 0.5, -0.866025, 1.0, 0.5, -8.74228e-08, 1.0, 1.0, 0.866025, 1.0, 0.5, -0.866025, 1.0, -0.5, 0.0, 1.0, -1.0, -0.866025, -1.0, -0.5, 0.0, -1.0, -1.0, 0.866025, -1.0, -0.5, 0.866025, -1.0, -0.5, 0.866025, -1.0, 0.5, -8.74228e-08, -1.0, 1.0, -8.74228e-08, -1.0, 1.0, -0.866025, -1.0, 0.5, -0.866025, -1.0, -0.5),
+		Vector3Array(0.5, 0.0, -0.866025, 0.5, 0.0, -0.866025, 0.5, 0.0, -0.866025, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.0, 0.866025, 0.5, 0.0, 0.866025, 0.5, 0.0, 0.866025, -0.5, 0.0, 0.866025, -0.5, 0.0, 0.866025, -0.5, 0.0, 0.866025, 2.29418e-08, 1.0, 0.0, 2.29418e-08, 1.0, 0.0, 2.29418e-08, 1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -0.5, 0.0, -0.866025, -0.5, 0.0, -0.866025, -0.5, 0.0, -0.866025, -9.17674e-08, -1.0, 0.0, -9.17674e-08, -1.0, 0.0, -9.17674e-08, -1.0, 0.0, 0.5, 0.0, -0.866025, 1.0, 0.0, 1.19209e-07, 1.0, 0.0, 1.19209e-07, 1.0, 0.0, 1.19209e-07, 0.5, 0.0, 0.866026, 0.5, 0.0, 0.866026, 0.5, 0.0, 0.866026, -0.5, 0.0, 0.866025, -0.5, 0.0, 0.866025, -0.5, 0.0, 0.866025, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.37651e-07, 1.0, 0.0, 1.37651e-07, 1.0, 0.0, 1.37651e-07, 1.0, 0.0, 6.88255e-08, 1.0, 0.0, 6.88255e-08, 1.0, 0.0, 6.88255e-08, 1.0, 0.0, -1.0, 0.0, 0.0, -0.5, 0.0, -0.866025, 1.37651e-07, -1.0, 0.0, 1.37651e-07, -1.0, 0.0, 1.37651e-07, -1.0, 0.0, 1.37651e-07, -1.0, 0.0, 1.37651e-07, -1.0, 0.0, 1.37651e-07, -1.0, 0.0, 1.37651e-07, -1.0, 0.0, 1.37651e-07, -1.0, 0.0, 1.37651e-07, -1.0, 0.0),
 		null, ; No Tangents,
 		null, ; no Vertex Colors,
 		null, ; No UV1,

+ 2 - 2
tests/reference_exports/mesh/parented_meshes.escn

@@ -49,7 +49,7 @@ transform = Transform(-4.37114e-08, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, -4.37114
 
 mesh = SubResource(1)
 visible = true
-transform = Transform(1.0, 1.19209e-07, 4.37114e-08, -4.37114e-08, 1.35103e-07, 1.0, 1.19209e-07, -1.0, 7.54979e-08, 4.37114e-08, -2.0, -1.0)
+transform = Transform(1.0, 1.19209e-07, 4.37114e-08, -4.37114e-08, 1.053e-07, 1.0, 1.19209e-07, -1.0, 7.54979e-08, 4.37114e-08, -2.0, -1.0)
 
 [node name="Suzanne" type="MeshInstance" parent="."]
 
@@ -61,4 +61,4 @@ transform = Transform(1.0, 0.0, 0.0, 0.0, 0.642788, -0.766044, 0.0, 0.766044, 0.
 
 mesh = SubResource(1)
 visible = true
-transform = Transform(1.0, 0.0, 0.0, 0.0, 1.0, -2.98023e-08, 0.0, 0.0, 1.0, 0.0, 3.0, 1.19209e-07)
+transform = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 2.98023e-08, 0.0, -2.98023e-08, 1.0, 0.0, 3.0, 0.0)

+ 1 - 2
tests/reference_exports/mesh/physics.escn

@@ -280,7 +280,7 @@ transform = Transform(1.0, 0.0, 0.0, 0.0, 7.54979e-08, -1.0, 0.0, 1.0, 7.54979e-
 
 [node name="Sphere002Collision" type="CollisionShape" parent="SpherePhysics"]
 
-transform = Transform(1.0, 1.30385e-08, 2.98023e-08, 1.49012e-08, -2.97416e-08, 1.0, 2.42144e-08, -1.0, -5.1162e-08, 0.565972, 0.864336, 0.166554)
+transform = Transform(1.0, 1.30385e-08, 2.98023e-08, 1.49012e-08, -2.97416e-08, 1.0, 2.42144e-08, -1.0, -5.1162e-08, 0.565972, 0.864336, 0.166555)
 shape = SubResource(12)
 
 [node name="Sphere002" type="MeshInstance" parent="SpherePhysics/Sphere002Collision"]
@@ -321,7 +321,6 @@ shadow_color = Color(0.0, 0.0, 0.0, 1.0)
 omni_range = 30.0
 transform = Transform(-0.290865, -0.771101, 0.566393, -0.0551891, 0.604525, 0.794672, -0.955171, 0.199883, -0.218391, 4.07625, 7.32356, -1.00545)
 shadow_enabled = true
-light_negative = false
 
 [node name="Camera" type="Camera" parent="."]
 

+ 0 - 0
tests/reference_exports/duplicate_name.escn → tests/reference_exports/misc/duplicate_name.escn


File diff suppressed because it is too large
+ 8 - 0
tests/reference_exports/misc/invisible_objects.escn


+ 1 - 1
tests/reference_exports/nla_animation/animation_with_empty_strip.escn

@@ -35,7 +35,7 @@ tracks/0/keys = [0.0, 1.0, 0.0, 0.0, -3.77384, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0
 
 mesh = SubResource(1)
 visible = true
-transform = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 4.1733)
+transform = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, -3.6196)
 
 [node name="AnimationPlayer" type="AnimationPlayer" parent="Cube"]
 

File diff suppressed because it is too large
+ 0 - 0
tests/reference_exports/nla_animation/nla_with_stashed_action.escn


+ 0 - 10
tests/reference_exports/shape_key/shapekey_with_multi_surface.escn

@@ -3,22 +3,12 @@
 [sub_resource id=1 type="SpatialMaterial"]
 
 resource_name = ""
-flags_unshaded = false
-flags_vertex_lighting = false
-flags_transparent = false
-vertex_color_use_as_albedo = false
 albedo_color = Color(0.413475, 0.685345, 0.903545, 1.0)
-subsurf_scatter_enabled = false
 
 [sub_resource id=2 type="SpatialMaterial"]
 
 resource_name = ""
-flags_unshaded = false
-flags_vertex_lighting = false
-flags_transparent = false
-vertex_color_use_as_albedo = false
 albedo_color = Color(0.364638, 0.903545, 0.264181, 1.0)
-subsurf_scatter_enabled = false
 
 [sub_resource id=3 type="ArrayMesh"]
 

BIN
tests/test_scenes/action_animation/animation_bone_transform.blend


BIN
tests/test_scenes/action_animation/animation_object_transform.blend


BIN
tests/test_scenes/action_animation/animation_rotation_euler.blend


BIN
tests/test_scenes/action_animation/animation_shared_action.blend


BIN
tests/test_scenes/action_animation/physics_animation.blend


BIN
tests/test_scenes/action_with_constraint/bone_attachment_ik.blend


BIN
tests/test_scenes/action_with_constraint/constraint_external_IK.blend


BIN
tests/test_scenes/action_with_constraint/constraint_internal_IK.blend


BIN
tests/test_scenes/action_with_constraint/stashed_constraint.blend


BIN
tests/test_scenes/armature/armature_bone_attachment.blend


BIN
tests/test_scenes/armature/armature_illegal_bone_name.blend


BIN
tests/test_scenes/armature/armature_with_mesh.blend


BIN
tests/test_scenes/armature/armature_with_non_deform_bone.blend


BIN
tests/test_scenes/armature/armature_with_other_vertex_groups.blend


BIN
tests/test_scenes/armature/armature_with_physics.blend


BIN
tests/test_scenes/armature/armature_with_pose.blend


BIN
tests/test_scenes/armature/just_armature.blend


BIN
tests/test_scenes/camera/animation_camera.blend


BIN
tests/test_scenes/camera/just_cameras.blend


BIN
tests/test_scenes/light/animation_sun.blend


BIN
tests/test_scenes/light/animation_various_lights.blend


BIN
tests/test_scenes/light/just_point_lights.blend


BIN
tests/test_scenes/light/just_spot_lights.blend


BIN
tests/test_scenes/material/material_search.blend


BIN
tests/test_scenes/material/object_link_material.blend


BIN
tests/test_scenes/material/simple_materials.blend


BIN
tests/test_scenes/material_cycle/material_anistropy.blend


BIN
tests/test_scenes/material_cycle/material_cycle.blend


BIN
tests/test_scenes/material_cycle/material_normal.blend


BIN
tests/test_scenes/material_cycle/material_unpack_texture.blend


BIN
tests/test_scenes/mesh/just_mesh.blend


BIN
tests/test_scenes/mesh/parented_meshes.blend


BIN
tests/test_scenes/mesh/physics.blend


BIN
tests/test_scenes/mesh/single_edge_and_vertex.blend


BIN
tests/test_scenes/mesh/tangent_test.blend


BIN
tests/test_scenes/mesh/uv_testing.blend


BIN
tests/test_scenes/mesh/vertex_color.blend


+ 0 - 0
tests/test_scenes/duplicate_name.blend → tests/test_scenes/misc/duplicate_name.blend


BIN
tests/test_scenes/misc/invisible_objects.blend


BIN
tests/test_scenes/nla_animation/animation_multi_strip.blend


BIN
tests/test_scenes/nla_animation/animation_with_empty_strip.blend


BIN
tests/test_scenes/nla_animation/nla_with_active_action.blend


BIN
tests/test_scenes/nla_animation/nla_with_no_active_action.blend


BIN
tests/test_scenes/nla_animation/nla_with_stashed_action.blend


BIN
tests/test_scenes/scene_animation/animation_parented_objects.blend


BIN
tests/test_scenes/shape_key/animation_shapekey.blend


BIN
tests/test_scenes/shape_key/animation_shapekey_with_transform.blend


BIN
tests/test_scenes/shape_key/just_shapekey.blend


Some files were not shown because too many files changed in this diff