@@ -2234,24 +2234,35 @@ CSGBrush *CSGPolygon3D::_build_brush() {
22342234 base_xform = path->get_global_transform ();
22352235 }
22362236
2237- Vector3 current_point = curve->sample_baked (0 );
2238- Vector3 next_point = curve->sample_baked (extrusion_step);
2237+ Vector3 current_point;
22392238 Vector3 current_up = Vector3 (0 , 1 , 0 );
2240- Vector3 direction = next_point - current_point;
2241-
2242- if (path_joined) {
2243- Vector3 last_point = curve->sample_baked (curve->get_baked_length ());
2244- direction = next_point - last_point;
2245- }
2239+ Vector3 direction;
22462240
22472241 switch (path_rotation) {
22482242 case PATH_ROTATION_POLYGON:
2243+ current_point = curve->sample_baked (0 );
22492244 direction = Vector3 (0 , 0 , -1 );
22502245 break ;
22512246 case PATH_ROTATION_PATH:
2252- break ;
22532247 case PATH_ROTATION_PATH_FOLLOW:
2254- current_up = curve->sample_baked_up_vector (0 , true );
2248+ if (!path_rotation_accurate) {
2249+ current_point = curve->sample_baked (0 );
2250+ Vector3 next_point = curve->sample_baked (extrusion_step);
2251+ direction = next_point - current_point;
2252+
2253+ if (path_joined) {
2254+ Vector3 last_point = curve->sample_baked (curve->get_baked_length ());
2255+ direction = next_point - last_point;
2256+ }
2257+ } else {
2258+ Transform3D current_sample_xform = curve->sample_baked_with_rotation (0 );
2259+ current_point = current_sample_xform.get_origin ();
2260+ direction = current_sample_xform.get_basis ().xform (Vector3 (0 , 0 , -1 ));
2261+ }
2262+
2263+ if (path_rotation == PATH_ROTATION_PATH_FOLLOW) {
2264+ current_up = curve->sample_baked_up_vector (0 , true );
2265+ }
22552266 break ;
22562267 }
22572268
@@ -2307,42 +2318,48 @@ CSGBrush *CSGPolygon3D::_build_brush() {
23072318 case MODE_PATH: {
23082319 double previous_offset = x0 * extrusion_step;
23092320 double current_offset = (x0 + 1 ) * extrusion_step;
2310- double next_offset = (x0 + 2 ) * extrusion_step;
2311- if (x0 == extrusions - 1 ) {
2312- if (path_joined) {
2313- current_offset = 0 ;
2314- next_offset = extrusion_step;
2315- } else {
2316- next_offset = current_offset;
2317- }
2321+ if (path_joined && x0 == extrusions - 1 ) {
2322+ current_offset = 0 ;
23182323 }
23192324
23202325 Vector3 previous_point = curve->sample_baked (previous_offset);
2321- Vector3 current_point = curve->sample_baked (current_offset);
2322- Vector3 next_point = curve-> sample_baked (next_offset );
2326+ Transform3D current_sample_xform = curve->sample_baked_with_rotation (current_offset);
2327+ Vector3 current_point = current_sample_xform. get_origin ( );
23232328 Vector3 current_up = Vector3 (0 , 1 , 0 );
2324- Vector3 direction = next_point - previous_point;
2325- Vector3 current_dir = (current_point - previous_point). normalized () ;
2329+ Vector3 current_extrusion_dir = (current_point - previous_point). normalized () ;
2330+ Vector3 direction ;
23262331
23272332 // If the angles are similar, remove the previous face and replace it with this one.
2328- if (path_simplify_angle > 0.0 && x0 > 0 && previous_simplify_dir.dot (current_dir ) > angle_simplify_dot) {
2333+ if (path_simplify_angle > 0.0 && x0 > 0 && previous_simplify_dir.dot (current_extrusion_dir ) > angle_simplify_dot) {
23292334 faces_combined += 1 ;
23302335 previous_xform = previous_previous_xform;
23312336 face -= extrusion_face_count;
23322337 faces_removed += extrusion_face_count;
23332338 } else {
23342339 faces_combined = 0 ;
2335- previous_simplify_dir = current_dir ;
2340+ previous_simplify_dir = current_extrusion_dir ;
23362341 }
23372342
23382343 switch (path_rotation) {
23392344 case PATH_ROTATION_POLYGON:
23402345 direction = Vector3 (0 , 0 , -1 );
23412346 break ;
23422347 case PATH_ROTATION_PATH:
2343- break ;
23442348 case PATH_ROTATION_PATH_FOLLOW:
2345- current_up = curve->sample_baked_up_vector (current_offset, true );
2349+ if (!path_rotation_accurate) {
2350+ double next_offset = (x0 + 2 ) * extrusion_step;
2351+ if (x0 == extrusions - 1 ) {
2352+ next_offset = path_joined ? extrusion_step : current_offset;
2353+ }
2354+ Vector3 next_point = curve->sample_baked (next_offset);
2355+ direction = next_point - previous_point;
2356+ } else {
2357+ direction = current_sample_xform.get_basis ().xform (Vector3 (0 , 0 , -1 ));
2358+ }
2359+
2360+ if (path_rotation == PATH_ROTATION_PATH_FOLLOW) {
2361+ current_up = curve->sample_baked_up_vector (current_offset, true );
2362+ }
23462363 break ;
23472364 }
23482365
@@ -2512,6 +2529,9 @@ void CSGPolygon3D::_bind_methods() {
25122529 ClassDB::bind_method (D_METHOD (" set_path_rotation" , " path_rotation" ), &CSGPolygon3D::set_path_rotation);
25132530 ClassDB::bind_method (D_METHOD (" get_path_rotation" ), &CSGPolygon3D::get_path_rotation);
25142531
2532+ ClassDB::bind_method (D_METHOD (" set_path_rotation_accurate" , " enable" ), &CSGPolygon3D::set_path_rotation_accurate);
2533+ ClassDB::bind_method (D_METHOD (" get_path_rotation_accurate" ), &CSGPolygon3D::get_path_rotation_accurate);
2534+
25152535 ClassDB::bind_method (D_METHOD (" set_path_local" , " enable" ), &CSGPolygon3D::set_path_local);
25162536 ClassDB::bind_method (D_METHOD (" is_path_local" ), &CSGPolygon3D::is_path_local);
25172537
@@ -2543,6 +2563,7 @@ void CSGPolygon3D::_bind_methods() {
25432563 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" );
25442564 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" );
25452565 ADD_PROPERTY (PropertyInfo (Variant::INT, " path_rotation" , PROPERTY_HINT_ENUM, " Polygon,Path,PathFollow" ), " set_path_rotation" , " get_path_rotation" );
2566+ ADD_PROPERTY (PropertyInfo (Variant::BOOL, " path_rotation_accurate" ), " set_path_rotation_accurate" , " get_path_rotation_accurate" );
25462567 ADD_PROPERTY (PropertyInfo (Variant::BOOL, " path_local" ), " set_path_local" , " is_path_local" );
25472568 ADD_PROPERTY (PropertyInfo (Variant::BOOL, " path_continuous_u" ), " set_path_continuous_u" , " is_path_continuous_u" );
25482569 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 {
26852706 return path_rotation;
26862707}
26872708
2709+ void CSGPolygon3D::set_path_rotation_accurate (bool p_enabled) {
2710+ path_rotation_accurate = p_enabled;
2711+ _make_dirty ();
2712+ update_gizmos ();
2713+ }
2714+
2715+ bool CSGPolygon3D::get_path_rotation_accurate () const {
2716+ return path_rotation_accurate;
2717+ }
2718+
26882719void CSGPolygon3D::set_path_local (bool p_enable) {
26892720 path_local = p_enable;
26902721 _make_dirty ();
@@ -2746,6 +2777,7 @@ CSGPolygon3D::CSGPolygon3D() {
27462777 path_interval = 1.0 ;
27472778 path_simplify_angle = 0.0 ;
27482779 path_rotation = PATH_ROTATION_PATH_FOLLOW;
2780+ path_rotation_accurate = false ;
27492781 path_local = false ;
27502782 path_continuous_u = true ;
27512783 path_u_distance = 1.0 ;
0 commit comments