mirror of
https://github.com/godotengine/godot-blender-exporter.git
synced 2026-01-04 14:09:56 +03:00
Export Curve objects as Godot Path nodes. (#380)
* Export Curve objects as Godot Path nodes. Fixes #330. Relates to godotengine/godot-proposals#527. Previously, curves in blender were exported to meshes in Godot. Now, a bezier curve created in blender will be exported as a Path node with a Curve3D resource matching the blender data. The curve will have a child MeshInstance that renders the bevel. Only bezier curves are exported to Godot Path nodes. Other curves, such as Nurbs, export only as meshes as they did previously. * Export all splines but only assign the active one. * Remove curve test scenes for now. They are generated with too recent of a blender version. We'll add them again after bumping the blender CI version. * Fix pylint warnings.
This commit is contained in:
committed by
GitHub
parent
0619f241ee
commit
3e66e12d7c
@@ -30,7 +30,7 @@ BLENDER_TYPE_TO_EXPORTER = {
|
||||
"CAMERA": export_camera_node,
|
||||
"LIGHT": export_light_node,
|
||||
"EMPTY": export_empty_node,
|
||||
"CURVE": export_mesh_node,
|
||||
"CURVE": export_curve_node,
|
||||
"SURFACE": export_mesh_node,
|
||||
"META": export_mesh_node,
|
||||
"FONT": export_mesh_node
|
||||
|
||||
@@ -3,12 +3,15 @@ Any exporters that can be written in a single function can go in here.
|
||||
Anything more complex should go in it's own file
|
||||
"""
|
||||
|
||||
import math
|
||||
import logging
|
||||
import math
|
||||
import mathutils
|
||||
from ..structures import (
|
||||
NodeTemplate, fix_directional_transform, gamma_correct
|
||||
NodeTemplate, fix_directional_transform, gamma_correct, InternalResource,
|
||||
Map, Array
|
||||
)
|
||||
from .animation import export_animation_data, AttributeConvertInfo
|
||||
from .mesh import export_mesh_node
|
||||
|
||||
|
||||
def export_empty_node(escn_file, export_settings, node, parent_gd_node):
|
||||
@@ -165,3 +168,64 @@ def export_light_node(escn_file, export_settings, node, parent_gd_node):
|
||||
light_node, node.data, 'light')
|
||||
|
||||
return light_node
|
||||
|
||||
|
||||
def _export_spline(escn_file, spline, name):
|
||||
points = Array("PoolVector3Array(")
|
||||
tilts = Array("PoolRealArray(")
|
||||
axis_correct = mathutils.Matrix((
|
||||
(1, 0, 0), # X in blender is X in Godot
|
||||
(0, 0, -1), # Y in blender is -Z in Godot
|
||||
(0, 1, 0), # Z in blender is Y in Godot
|
||||
)).normalized()
|
||||
|
||||
src_points = spline.bezier_points
|
||||
if spline.use_cyclic_u:
|
||||
# Godot fakes a closed path by adding the start point at the end
|
||||
# https://github.com/godotengine/godot-proposals/issues/527
|
||||
src_points = [*src_points, src_points[0]]
|
||||
|
||||
for point in src_points:
|
||||
# blender handles are absolute
|
||||
# godot handles are relative to the control point
|
||||
points.extend((point.handle_left - point.co) @ axis_correct)
|
||||
points.extend((point.handle_right - point.co) @ axis_correct)
|
||||
points.extend(point.co @ axis_correct)
|
||||
tilts.append(point.tilt)
|
||||
|
||||
data = Map()
|
||||
data["points"] = points
|
||||
data["tilts"] = tilts
|
||||
|
||||
curve_resource = InternalResource("Curve3D", name)
|
||||
curve_resource["_data"] = data
|
||||
curve_id = escn_file.get_internal_resource(spline)
|
||||
if curve_id is None:
|
||||
return escn_file.add_internal_resource(curve_resource, spline)
|
||||
return escn_file.get_internal_resource(spline)
|
||||
|
||||
|
||||
def export_curve_node(escn_file, export_settings, node, parent_gd_node):
|
||||
"""Export a curve to a Path node, with a child mesh."""
|
||||
splines = node.data.splines
|
||||
|
||||
path_node = NodeTemplate(node.name, "Path", parent_gd_node)
|
||||
path_node["transform"] = node.matrix_local
|
||||
escn_file.add_node(path_node)
|
||||
|
||||
for spline in splines:
|
||||
# https://docs.blender.org/manual/en/latest/modeling/curves/editing/curve.html#set-spline-type
|
||||
# Godot only supports bezier, and blender cannot convert losslessly
|
||||
if spline.type == "BEZIER":
|
||||
curve_id = _export_spline(escn_file, splines[0], node.data.name)
|
||||
if spline == splines.active:
|
||||
path_node["curve"] = "SubResource({})".format(curve_id)
|
||||
|
||||
# Create child MeshInstance renders the bevel for any curve type
|
||||
mesh_node = export_mesh_node(
|
||||
escn_file, export_settings, node, path_node
|
||||
)
|
||||
# The transform is already set on the path, don't duplicate it
|
||||
mesh_node["transform"] = mathutils.Matrix.Identity(4)
|
||||
|
||||
return path_node
|
||||
|
||||
Reference in New Issue
Block a user