|
@@ -2234,24 +2234,35 @@ CSGBrush *CSGPolygon3D::_build_brush() {
|
|
|
base_xform = path->get_global_transform();
|
|
|
}
|
|
|
|
|
|
- Vector3 current_point = curve->sample_baked(0);
|
|
|
- Vector3 next_point = curve->sample_baked(extrusion_step);
|
|
|
+ Vector3 current_point;
|
|
|
Vector3 current_up = Vector3(0, 1, 0);
|
|
|
- Vector3 direction = next_point - current_point;
|
|
|
-
|
|
|
- if (path_joined) {
|
|
|
- Vector3 last_point = curve->sample_baked(curve->get_baked_length());
|
|
|
- direction = next_point - last_point;
|
|
|
- }
|
|
|
+ Vector3 direction;
|
|
|
|
|
|
switch (path_rotation) {
|
|
|
case PATH_ROTATION_POLYGON:
|
|
|
+ current_point = curve->sample_baked(0);
|
|
|
direction = Vector3(0, 0, -1);
|
|
|
break;
|
|
|
case PATH_ROTATION_PATH:
|
|
|
- break;
|
|
|
case PATH_ROTATION_PATH_FOLLOW:
|
|
|
- current_up = curve->sample_baked_up_vector(0, true);
|
|
|
+ if (!path_rotation_accurate) {
|
|
|
+ current_point = curve->sample_baked(0);
|
|
|
+ Vector3 next_point = curve->sample_baked(extrusion_step);
|
|
|
+ direction = next_point - current_point;
|
|
|
+
|
|
|
+ if (path_joined) {
|
|
|
+ Vector3 last_point = curve->sample_baked(curve->get_baked_length());
|
|
|
+ direction = next_point - last_point;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ Transform3D current_sample_xform = curve->sample_baked_with_rotation(0);
|
|
|
+ current_point = current_sample_xform.get_origin();
|
|
|
+ direction = current_sample_xform.get_basis().xform(Vector3(0, 0, -1));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (path_rotation == PATH_ROTATION_PATH_FOLLOW) {
|
|
|
+ current_up = curve->sample_baked_up_vector(0, true);
|
|
|
+ }
|
|
|
break;
|
|
|
}
|
|
|
|
|
@@ -2307,32 +2318,26 @@ CSGBrush *CSGPolygon3D::_build_brush() {
|
|
|
case MODE_PATH: {
|
|
|
double previous_offset = x0 * extrusion_step;
|
|
|
double current_offset = (x0 + 1) * extrusion_step;
|
|
|
- double next_offset = (x0 + 2) * extrusion_step;
|
|
|
- if (x0 == extrusions - 1) {
|
|
|
- if (path_joined) {
|
|
|
- current_offset = 0;
|
|
|
- next_offset = extrusion_step;
|
|
|
- } else {
|
|
|
- next_offset = current_offset;
|
|
|
- }
|
|
|
+ if (path_joined && x0 == extrusions - 1) {
|
|
|
+ current_offset = 0;
|
|
|
}
|
|
|
|
|
|
Vector3 previous_point = curve->sample_baked(previous_offset);
|
|
|
- Vector3 current_point = curve->sample_baked(current_offset);
|
|
|
- Vector3 next_point = curve->sample_baked(next_offset);
|
|
|
+ Transform3D current_sample_xform = curve->sample_baked_with_rotation(current_offset);
|
|
|
+ Vector3 current_point = current_sample_xform.get_origin();
|
|
|
Vector3 current_up = Vector3(0, 1, 0);
|
|
|
- Vector3 direction = next_point - previous_point;
|
|
|
- Vector3 current_dir = (current_point - previous_point).normalized();
|
|
|
+ Vector3 current_extrusion_dir = (current_point - previous_point).normalized();
|
|
|
+ Vector3 direction;
|
|
|
|
|
|
// If the angles are similar, remove the previous face and replace it with this one.
|
|
|
- if (path_simplify_angle > 0.0 && x0 > 0 && previous_simplify_dir.dot(current_dir) > angle_simplify_dot) {
|
|
|
+ if (path_simplify_angle > 0.0 && x0 > 0 && previous_simplify_dir.dot(current_extrusion_dir) > angle_simplify_dot) {
|
|
|
faces_combined += 1;
|
|
|
previous_xform = previous_previous_xform;
|
|
|
face -= extrusion_face_count;
|
|
|
faces_removed += extrusion_face_count;
|
|
|
} else {
|
|
|
faces_combined = 0;
|
|
|
- previous_simplify_dir = current_dir;
|
|
|
+ previous_simplify_dir = current_extrusion_dir;
|
|
|
}
|
|
|
|
|
|
switch (path_rotation) {
|
|
@@ -2340,9 +2345,21 @@ CSGBrush *CSGPolygon3D::_build_brush() {
|
|
|
direction = Vector3(0, 0, -1);
|
|
|
break;
|
|
|
case PATH_ROTATION_PATH:
|
|
|
- break;
|
|
|
case PATH_ROTATION_PATH_FOLLOW:
|
|
|
- current_up = curve->sample_baked_up_vector(current_offset, true);
|
|
|
+ if (!path_rotation_accurate) {
|
|
|
+ double next_offset = (x0 + 2) * extrusion_step;
|
|
|
+ if (x0 == extrusions - 1) {
|
|
|
+ next_offset = path_joined ? extrusion_step : current_offset;
|
|
|
+ }
|
|
|
+ Vector3 next_point = curve->sample_baked(next_offset);
|
|
|
+ direction = next_point - previous_point;
|
|
|
+ } else {
|
|
|
+ direction = current_sample_xform.get_basis().xform(Vector3(0, 0, -1));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (path_rotation == PATH_ROTATION_PATH_FOLLOW) {
|
|
|
+ current_up = curve->sample_baked_up_vector(current_offset, true);
|
|
|
+ }
|
|
|
break;
|
|
|
}
|
|
|
|
|
@@ -2512,6 +2529,9 @@ void CSGPolygon3D::_bind_methods() {
|
|
|
ClassDB::bind_method(D_METHOD("set_path_rotation", "path_rotation"), &CSGPolygon3D::set_path_rotation);
|
|
|
ClassDB::bind_method(D_METHOD("get_path_rotation"), &CSGPolygon3D::get_path_rotation);
|
|
|
|
|
|
+ ClassDB::bind_method(D_METHOD("set_path_rotation_accurate", "enable"), &CSGPolygon3D::set_path_rotation_accurate);
|
|
|
+ ClassDB::bind_method(D_METHOD("get_path_rotation_accurate"), &CSGPolygon3D::get_path_rotation_accurate);
|
|
|
+
|
|
|
ClassDB::bind_method(D_METHOD("set_path_local", "enable"), &CSGPolygon3D::set_path_local);
|
|
|
ClassDB::bind_method(D_METHOD("is_path_local"), &CSGPolygon3D::is_path_local);
|
|
|
|
|
@@ -2543,6 +2563,7 @@ void CSGPolygon3D::_bind_methods() {
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_interval", PROPERTY_HINT_RANGE, "0.01,1.0,0.01,exp,or_greater"), "set_path_interval", "get_path_interval");
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_simplify_angle", PROPERTY_HINT_RANGE, "0.0,180.0,0.1"), "set_path_simplify_angle", "get_path_simplify_angle");
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_rotation", PROPERTY_HINT_ENUM, "Polygon,Path,PathFollow"), "set_path_rotation", "get_path_rotation");
|
|
|
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "path_rotation_accurate"), "set_path_rotation_accurate", "get_path_rotation_accurate");
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "path_local"), "set_path_local", "is_path_local");
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "path_continuous_u"), "set_path_continuous_u", "is_path_continuous_u");
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_u_distance", PROPERTY_HINT_RANGE, "0.0,10.0,0.01,or_greater,suffix:m"), "set_path_u_distance", "get_path_u_distance");
|
|
@@ -2685,6 +2706,16 @@ CSGPolygon3D::PathRotation CSGPolygon3D::get_path_rotation() const {
|
|
|
return path_rotation;
|
|
|
}
|
|
|
|
|
|
+void CSGPolygon3D::set_path_rotation_accurate(bool p_enabled) {
|
|
|
+ path_rotation_accurate = p_enabled;
|
|
|
+ _make_dirty();
|
|
|
+ update_gizmos();
|
|
|
+}
|
|
|
+
|
|
|
+bool CSGPolygon3D::get_path_rotation_accurate() const {
|
|
|
+ return path_rotation_accurate;
|
|
|
+}
|
|
|
+
|
|
|
void CSGPolygon3D::set_path_local(bool p_enable) {
|
|
|
path_local = p_enable;
|
|
|
_make_dirty();
|
|
@@ -2746,6 +2777,7 @@ CSGPolygon3D::CSGPolygon3D() {
|
|
|
path_interval = 1.0;
|
|
|
path_simplify_angle = 0.0;
|
|
|
path_rotation = PATH_ROTATION_PATH_FOLLOW;
|
|
|
+ path_rotation_accurate = false;
|
|
|
path_local = false;
|
|
|
path_continuous_u = true;
|
|
|
path_u_distance = 1.0;
|