diff options
Diffstat (limited to 'modules/csg/csg_shape.cpp')
-rw-r--r-- | modules/csg/csg_shape.cpp | 295 |
1 files changed, 168 insertions, 127 deletions
diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index 39e4751be3..3932c2377f 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -53,6 +53,7 @@ void CSGShape3D::set_use_collision(bool p_enable) { PhysicsServer3D::get_singleton()->body_attach_object_instance_id(root_collision_instance, get_instance_id()); set_collision_layer(collision_layer); set_collision_mask(collision_mask); + set_collision_priority(collision_priority); _make_dirty(); //force update } else { PhysicsServer3D::get_singleton()->free(root_collision_instance); @@ -124,8 +125,19 @@ bool CSGShape3D::get_collision_mask_value(int p_layer_number) const { return get_collision_mask() & (1 << (p_layer_number - 1)); } +void CSGShape3D::set_collision_priority(real_t p_priority) { + collision_priority = p_priority; + if (root_collision_instance.is_valid()) { + PhysicsServer3D::get_singleton()->body_set_collision_priority(root_collision_instance, p_priority); + } +} + +real_t CSGShape3D::get_collision_priority() const { + return collision_priority; +} + bool CSGShape3D::is_root_shape() const { - return !parent; + return !parent_shape; } void CSGShape3D::set_snap(float p_snap) { @@ -136,13 +148,13 @@ float CSGShape3D::get_snap() const { return snap; } -void CSGShape3D::_make_dirty() { - if (!is_inside_tree()) { - return; +void CSGShape3D::_make_dirty(bool p_parent_removing) { + if ((p_parent_removing || is_root_shape()) && !dirty) { + call_deferred(SNAME("_update_shape")); // Must be deferred; otherwise, is_root_shape() will use the previous parent } - if (parent) { - parent->_make_dirty(); + if (!is_root_shape()) { + parent_shape->_make_dirty(); } else if (!dirty) { call_deferred(SNAME("_update_shape")); } @@ -164,7 +176,7 @@ CSGBrush *CSGShape3D::_get_brush() { if (!child) { continue; } - if (!child->is_visible_in_tree()) { + if (!child->is_visible()) { continue; } @@ -280,7 +292,7 @@ void CSGShape3D::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const } void CSGShape3D::_update_shape() { - if (parent || !is_inside_tree()) { + if (!is_root_shape()) { return; } @@ -303,17 +315,19 @@ void CSGShape3D::_update_shape() { ERR_CONTINUE(mat < -1 || mat >= face_count.size()); int idx = mat == -1 ? face_count.size() - 1 : mat; - Plane p(n->faces[i].vertices[0], n->faces[i].vertices[1], n->faces[i].vertices[2]); + if (n->faces[i].smooth) { + Plane p(n->faces[i].vertices[0], n->faces[i].vertices[1], n->faces[i].vertices[2]); - for (int j = 0; j < 3; j++) { - Vector3 v = n->faces[i].vertices[j]; - Vector3 add; - if (vec_map.lookup(v, add)) { - add += p.normal; - } else { - add = p.normal; + for (int j = 0; j < 3; j++) { + Vector3 v = n->faces[i].vertices[j]; + Vector3 add; + if (vec_map.lookup(v, add)) { + add += p.normal; + } else { + add = p.normal; + } + vec_map.set(v, add); } - vec_map.set(v, add); } face_count.write[idx]++; @@ -345,27 +359,6 @@ void CSGShape3D::_update_shape() { } } - // Update collision faces. - if (root_collision_shape.is_valid()) { - Vector<Vector3> physics_faces; - physics_faces.resize(n->faces.size() * 3); - Vector3 *physicsw = physics_faces.ptrw(); - - for (int i = 0; i < n->faces.size(); i++) { - int order[3] = { 0, 1, 2 }; - - if (n->faces[i].invert) { - SWAP(order[1], order[2]); - } - - physicsw[i * 3 + 0] = n->faces[i].vertices[order[0]]; - physicsw[i * 3 + 1] = n->faces[i].vertices[order[1]]; - physicsw[i * 3 + 2] = n->faces[i].vertices[order[2]]; - } - - root_collision_shape->set_faces(physics_faces); - } - //fill arrays { for (int i = 0; i < n->faces.size(); i++) { @@ -458,6 +451,32 @@ void CSGShape3D::_update_shape() { } set_base(root_mesh->get_rid()); + + _update_collision_faces(); +} + +void CSGShape3D::_update_collision_faces() { + if (use_collision && is_root_shape() && root_collision_shape.is_valid()) { + CSGBrush *n = _get_brush(); + ERR_FAIL_COND_MSG(!n, "Cannot get CSGBrush."); + Vector<Vector3> physics_faces; + physics_faces.resize(n->faces.size() * 3); + Vector3 *physicsw = physics_faces.ptrw(); + + for (int i = 0; i < n->faces.size(); i++) { + int order[3] = { 0, 1, 2 }; + + if (n->faces[i].invert) { + SWAP(order[1], order[2]); + } + + physicsw[i * 3 + 0] = n->faces[i].vertices[order[0]]; + physicsw[i * 3 + 1] = n->faces[i].vertices[order[1]]; + physicsw[i * 3 + 2] = n->faces[i].vertices[order[2]]; + } + + root_collision_shape->set_faces(physics_faces); + } } AABB CSGShape3D::get_aabb() const { @@ -486,67 +505,75 @@ Vector<Vector3> CSGShape3D::get_brush_faces() { return faces; } -Vector<Face3> CSGShape3D::get_faces(uint32_t p_usage_flags) const { - return Vector<Face3>(); -} - void CSGShape3D::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_ENTER_TREE: { + case NOTIFICATION_PARENTED: { Node *parentn = get_parent(); if (parentn) { - parent = Object::cast_to<CSGShape3D>(parentn); - if (parent) { + parent_shape = Object::cast_to<CSGShape3D>(parentn); + if (parent_shape) { set_base(RID()); root_mesh.unref(); } } - - if (use_collision && is_root_shape()) { - root_collision_shape.instantiate(); - root_collision_instance = PhysicsServer3D::get_singleton()->body_create(); - PhysicsServer3D::get_singleton()->body_set_mode(root_collision_instance, PhysicsServer3D::BODY_MODE_STATIC); - PhysicsServer3D::get_singleton()->body_set_state(root_collision_instance, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform()); - PhysicsServer3D::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid()); - PhysicsServer3D::get_singleton()->body_set_space(root_collision_instance, get_world_3d()->get_space()); - PhysicsServer3D::get_singleton()->body_attach_object_instance_id(root_collision_instance, get_instance_id()); - set_collision_layer(collision_layer); - set_collision_mask(collision_mask); + if (!brush || parent_shape) { + // Update this node if uninitialized, or both this node and its new parent if it gets added to another CSG shape + _make_dirty(); } + last_visible = is_visible(); + } break; - _make_dirty(); + case NOTIFICATION_UNPARENTED: { + if (!is_root_shape()) { + // Update this node and its previous parent only if it's currently being removed from another CSG shape + _make_dirty(true); // Must be forced since is_root_shape() uses the previous parent + } + parent_shape = nullptr; } break; - case NOTIFICATION_TRANSFORM_CHANGED: { - if (use_collision && is_root_shape() && root_collision_instance.is_valid()) { - PhysicsServer3D::get_singleton()->body_set_state(root_collision_instance, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform()); + case NOTIFICATION_VISIBILITY_CHANGED: { + if (!is_root_shape() && last_visible != is_visible()) { + // Update this node's parent only if its own visibility has changed, not the visibility of parent nodes + parent_shape->_make_dirty(); } + last_visible = is_visible(); } break; case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { - if (parent) { - parent->_make_dirty(); + if (!is_root_shape()) { + // Update this node's parent only if its own transformation has changed, not the transformation of parent nodes + parent_shape->_make_dirty(); } } break; - case NOTIFICATION_VISIBILITY_CHANGED: { - if (parent) { - parent->_make_dirty(); + case NOTIFICATION_ENTER_TREE: { + if (use_collision && is_root_shape()) { + root_collision_shape.instantiate(); + root_collision_instance = PhysicsServer3D::get_singleton()->body_create(); + PhysicsServer3D::get_singleton()->body_set_mode(root_collision_instance, PhysicsServer3D::BODY_MODE_STATIC); + PhysicsServer3D::get_singleton()->body_set_state(root_collision_instance, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform()); + PhysicsServer3D::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid()); + PhysicsServer3D::get_singleton()->body_set_space(root_collision_instance, get_world_3d()->get_space()); + PhysicsServer3D::get_singleton()->body_attach_object_instance_id(root_collision_instance, get_instance_id()); + set_collision_layer(collision_layer); + set_collision_mask(collision_mask); + set_collision_priority(collision_priority); + _update_collision_faces(); } } break; case NOTIFICATION_EXIT_TREE: { - if (parent) { - parent->_make_dirty(); - } - parent = nullptr; - if (use_collision && is_root_shape() && root_collision_instance.is_valid()) { PhysicsServer3D::get_singleton()->free(root_collision_instance); root_collision_instance = RID(); root_collision_shape.unref(); } - _make_dirty(); + } break; + + case NOTIFICATION_TRANSFORM_CHANGED: { + if (use_collision && is_root_shape() && root_collision_instance.is_valid()) { + PhysicsServer3D::get_singleton()->body_set_state(root_collision_instance, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform()); + } } break; } } @@ -570,15 +597,14 @@ bool CSGShape3D::is_calculating_tangents() const { return calculate_tangents; } -void CSGShape3D::_validate_property(PropertyInfo &property) const { - bool is_collision_prefixed = property.name.begins_with("collision_"); - if ((is_collision_prefixed || property.name.begins_with("use_collision")) && is_inside_tree() && !is_root_shape()) { +void CSGShape3D::_validate_property(PropertyInfo &p_property) const { + bool is_collision_prefixed = p_property.name.begins_with("collision_"); + if ((is_collision_prefixed || p_property.name.begins_with("use_collision")) && is_inside_tree() && !is_root_shape()) { //hide collision if not root - property.usage = PROPERTY_USAGE_NO_EDITOR; + p_property.usage = PROPERTY_USAGE_NO_EDITOR; } else if (is_collision_prefixed && !bool(get("use_collision"))) { - property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; + p_property.usage = PROPERTY_USAGE_NO_EDITOR; } - GeometryInstance3D::_validate_property(property); } Array CSGShape3D::get_meshes() const { @@ -618,19 +644,23 @@ void CSGShape3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_collision_layer_value", "layer_number", "value"), &CSGShape3D::set_collision_layer_value); ClassDB::bind_method(D_METHOD("get_collision_layer_value", "layer_number"), &CSGShape3D::get_collision_layer_value); + ClassDB::bind_method(D_METHOD("set_collision_priority", "priority"), &CSGShape3D::set_collision_priority); + ClassDB::bind_method(D_METHOD("get_collision_priority"), &CSGShape3D::get_collision_priority); + ClassDB::bind_method(D_METHOD("set_calculate_tangents", "enabled"), &CSGShape3D::set_calculate_tangents); ClassDB::bind_method(D_METHOD("is_calculating_tangents"), &CSGShape3D::is_calculating_tangents); ClassDB::bind_method(D_METHOD("get_meshes"), &CSGShape3D::get_meshes); ADD_PROPERTY(PropertyInfo(Variant::INT, "operation", PROPERTY_HINT_ENUM, "Union,Intersection,Subtraction"), "set_operation", "get_operation"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "snap", PROPERTY_HINT_RANGE, "0.0001,1,0.001"), "set_snap", "get_snap"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "snap", PROPERTY_HINT_RANGE, "0.0001,1,0.001,suffix:m"), "set_snap", "get_snap"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "calculate_tangents"), "set_calculate_tangents", "is_calculating_tangents"); ADD_GROUP("Collision", "collision_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_collision"), "set_use_collision", "is_using_collision"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_priority"), "set_collision_priority", "get_collision_priority"); BIND_ENUM_CONSTANT(OPERATION_UNION); BIND_ENUM_CONSTANT(OPERATION_INTERSECTION); @@ -668,7 +698,7 @@ CSGBrush *CSGPrimitive3D::_create_brush_from_arrays(const Vector<Vector3> &p_ver int ic = invert.size(); bool *w = invert.ptrw(); for (int i = 0; i < ic; i++) { - w[i] = invert_faces; + w[i] = flip_faces; } } brush->build_from_faces(p_vertices, p_uv, p_smooth, p_materials, invert); @@ -677,28 +707,28 @@ CSGBrush *CSGPrimitive3D::_create_brush_from_arrays(const Vector<Vector3> &p_ver } void CSGPrimitive3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_invert_faces", "invert_faces"), &CSGPrimitive3D::set_invert_faces); - ClassDB::bind_method(D_METHOD("is_inverting_faces"), &CSGPrimitive3D::is_inverting_faces); + ClassDB::bind_method(D_METHOD("set_flip_faces", "flip_faces"), &CSGPrimitive3D::set_flip_faces); + ClassDB::bind_method(D_METHOD("get_flip_faces"), &CSGPrimitive3D::get_flip_faces); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "invert_faces"), "set_invert_faces", "is_inverting_faces"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_faces"), "set_flip_faces", "get_flip_faces"); } -void CSGPrimitive3D::set_invert_faces(bool p_invert) { - if (invert_faces == p_invert) { +void CSGPrimitive3D::set_flip_faces(bool p_invert) { + if (flip_faces == p_invert) { return; } - invert_faces = p_invert; + flip_faces = p_invert; _make_dirty(); } -bool CSGPrimitive3D::is_inverting_faces() { - return invert_faces; +bool CSGPrimitive3D::get_flip_faces() { + return flip_faces; } CSGPrimitive3D::CSGPrimitive3D() { - invert_faces = false; + flip_faces = false; } ///////////////////// @@ -907,7 +937,7 @@ CSGBrush *CSGSphere3D::_build_brush() { int face_count = rings * radial_segments * 2 - radial_segments * 2; - bool invert_val = is_inverting_faces(); + bool invert_val = get_flip_faces(); Ref<Material> material = get_material(); Vector<Vector3> faces; @@ -955,6 +985,10 @@ CSGBrush *CSGSphere3D::_build_brush() { double u0 = double(j) / radial_segments; double longitude1 = longitude_step * (j + 1); + if (j == radial_segments - 1) { + longitude1 = 0; + } + double x1 = Math::sin(longitude1); double z1 = Math::cos(longitude1); double u1 = double(j + 1) / radial_segments; @@ -1034,7 +1068,7 @@ void CSGSphere3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_material", "material"), &CSGSphere3D::set_material); ClassDB::bind_method(D_METHOD("get_material"), &CSGSphere3D::get_material); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,suffix:m"), "set_radius", "get_radius"); ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1"), "set_radial_segments", "get_radial_segments"); ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1"), "set_rings", "get_rings"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces"); @@ -1092,7 +1126,7 @@ Ref<Material> CSGSphere3D::get_material() const { CSGSphere3D::CSGSphere3D() { // defaults - radius = 1.0; + radius = 0.5; radial_segments = 12; rings = 6; smooth_faces = true; @@ -1107,7 +1141,7 @@ CSGBrush *CSGBox3D::_build_brush() { int face_count = 12; //it's a cube.. - bool invert_val = is_inverting_faces(); + bool invert_val = get_flip_faces(); Ref<Material> material = get_material(); Vector<Vector3> faces; @@ -1207,7 +1241,7 @@ void CSGBox3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_material", "material"), &CSGBox3D::set_material); ClassDB::bind_method(D_METHOD("get_material"), &CSGBox3D::get_material); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size"), "set_size", "get_size"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_NONE, "suffix:m"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial"), "set_material", "get_material"); } @@ -1240,7 +1274,7 @@ CSGBrush *CSGCylinder3D::_build_brush() { int face_count = sides * (cone ? 1 : 2) + sides + (cone ? 0 : sides); - bool invert_val = is_inverting_faces(); + bool invert_val = get_flip_faces(); Ref<Material> material = get_material(); Vector<Vector3> faces; @@ -1271,6 +1305,9 @@ CSGBrush *CSGCylinder3D::_build_brush() { for (int i = 0; i < sides; i++) { float inc = float(i) / sides; float inc_n = float((i + 1)) / sides; + if (i == sides - 1) { + inc_n = 0; + } float ang = inc * Math_TAU; float ang_n = inc_n * Math_TAU; @@ -1384,8 +1421,8 @@ void CSGCylinder3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_smooth_faces", "smooth_faces"), &CSGCylinder3D::set_smooth_faces); ClassDB::bind_method(D_METHOD("get_smooth_faces"), &CSGCylinder3D::get_smooth_faces); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.001,1000.0,0.001,or_greater,exp"), "set_radius", "get_radius"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.001,1000.0,0.001,or_greater,exp"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.001,1000.0,0.001,or_greater,exp,suffix:m"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.001,1000.0,0.001,or_greater,exp,suffix:m"), "set_height", "get_height"); ADD_PROPERTY(PropertyInfo(Variant::INT, "sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_sides", "get_sides"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cone"), "set_cone", "is_cone"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces"); @@ -1482,7 +1519,7 @@ CSGBrush *CSGTorus3D::_build_brush() { int face_count = ring_sides * sides * 2; - bool invert_val = is_inverting_faces(); + bool invert_val = get_flip_faces(); Ref<Material> material = get_material(); Vector<Vector3> faces; @@ -1511,6 +1548,9 @@ CSGBrush *CSGTorus3D::_build_brush() { for (int i = 0; i < sides; i++) { float inci = float(i) / sides; float inci_n = float((i + 1)) / sides; + if (i == sides - 1) { + inci_n = 0; + } float angi = inci * Math_TAU; float angi_n = inci_n * Math_TAU; @@ -1521,6 +1561,9 @@ CSGBrush *CSGTorus3D::_build_brush() { for (int j = 0; j < ring_sides; j++) { float incj = float(j) / ring_sides; float incj_n = float((j + 1)) / ring_sides; + if (j == ring_sides - 1) { + incj_n = 0; + } float angj = incj * Math_TAU; float angj_n = incj_n * Math_TAU; @@ -1603,8 +1646,8 @@ void CSGTorus3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_smooth_faces", "smooth_faces"), &CSGTorus3D::set_smooth_faces); ClassDB::bind_method(D_METHOD("get_smooth_faces"), &CSGTorus3D::get_smooth_faces); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "inner_radius", PROPERTY_HINT_RANGE, "0.001,1000.0,0.001,or_greater,exp"), "set_inner_radius", "get_inner_radius"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "outer_radius", PROPERTY_HINT_RANGE, "0.001,1000.0,0.001,or_greater,exp"), "set_outer_radius", "get_outer_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "inner_radius", PROPERTY_HINT_RANGE, "0.001,1000.0,0.001,or_greater,exp,suffix:m"), "set_inner_radius", "get_inner_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "outer_radius", PROPERTY_HINT_RANGE, "0.001,1000.0,0.001,or_greater,exp,suffix:m"), "set_outer_radius", "get_outer_radius"); ADD_PROPERTY(PropertyInfo(Variant::INT, "sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_sides", "get_sides"); ADD_PROPERTY(PropertyInfo(Variant::INT, "ring_sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_ring_sides", "get_ring_sides"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces"); @@ -1795,7 +1838,7 @@ CSGBrush *CSGPolygon3D::_build_brush() { u_step *= curve_length / path_u_distance; } double v_step = 1.0 / shape_sides; - double spin_step = Math::deg2rad(spin_degrees / spin_sides); + double spin_step = Math::deg_to_rad(spin_degrees / spin_sides); double extrusion_step = 1.0 / extrusions; if (mode == MODE_PATH) { if (path_joined) { @@ -1809,13 +1852,13 @@ CSGBrush *CSGPolygon3D::_build_brush() { base_xform = path->get_global_transform(); } - Vector3 current_point = curve->interpolate_baked(0); - Vector3 next_point = curve->interpolate_baked(extrusion_step); + Vector3 current_point = curve->sample_baked(0); + Vector3 next_point = curve->sample_baked(extrusion_step); Vector3 current_up = Vector3(0, 1, 0); Vector3 direction = next_point - current_point; if (path_joined) { - Vector3 last_point = curve->interpolate_baked(curve->get_baked_length()); + Vector3 last_point = curve->sample_baked(curve->get_baked_length()); direction = next_point - last_point; } @@ -1826,12 +1869,12 @@ CSGBrush *CSGPolygon3D::_build_brush() { case PATH_ROTATION_PATH: break; case PATH_ROTATION_PATH_FOLLOW: - current_up = curve->interpolate_baked_up_vector(0); + current_up = curve->sample_baked_up_vector(0); break; } Transform3D facing = Transform3D().looking_at(direction, current_up); - current_xform = base_xform.translated(current_point) * facing; + current_xform = base_xform.translated_local(current_point) * facing; } // Create the mesh. @@ -1854,12 +1897,12 @@ CSGBrush *CSGPolygon3D::_build_brush() { smoothw[face] = false; materialsw[face] = material; - invertw[face] = invert_faces; + invertw[face] = flip_faces; face++; } } - real_t angle_simplify_dot = Math::cos(Math::deg2rad(path_simplify_angle)); + real_t angle_simplify_dot = Math::cos(Math::deg_to_rad(path_simplify_angle)); Vector3 previous_simplify_dir = Vector3(0, 0, 0); int faces_combined = 0; @@ -1870,7 +1913,7 @@ CSGBrush *CSGPolygon3D::_build_brush() { switch (mode) { case MODE_DEPTH: { - current_xform.translate(Vector3(0, 0, -depth)); + current_xform.translate_local(Vector3(0, 0, -depth)); } break; case MODE_SPIN: { current_xform.rotate(Vector3(0, 1, 0), spin_step); @@ -1888,9 +1931,9 @@ CSGBrush *CSGPolygon3D::_build_brush() { } } - Vector3 previous_point = curve->interpolate_baked(previous_offset); - Vector3 current_point = curve->interpolate_baked(current_offset); - Vector3 next_point = curve->interpolate_baked(next_offset); + Vector3 previous_point = curve->sample_baked(previous_offset); + Vector3 current_point = curve->sample_baked(current_offset); + Vector3 next_point = curve->sample_baked(next_offset); Vector3 current_up = Vector3(0, 1, 0); Vector3 direction = next_point - previous_point; Vector3 current_dir = (current_point - previous_point).normalized(); @@ -1913,12 +1956,12 @@ CSGBrush *CSGPolygon3D::_build_brush() { case PATH_ROTATION_PATH: break; case PATH_ROTATION_PATH_FOLLOW: - current_up = curve->interpolate_baked_up_vector(current_offset); + current_up = curve->sample_baked_up_vector(current_offset); break; } Transform3D facing = Transform3D().looking_at(direction, current_up); - current_xform = base_xform.translated(current_point) * facing; + current_xform = base_xform.translated_local(current_point) * facing; } break; } @@ -1959,7 +2002,7 @@ CSGBrush *CSGPolygon3D::_build_brush() { uvsw[face * 3 + 2] = u[2]; smoothw[face] = smooth_faces; - invertw[face] = invert_faces; + invertw[face] = flip_faces; materialsw[face] = material; face++; @@ -1974,7 +2017,7 @@ CSGBrush *CSGPolygon3D::_build_brush() { uvsw[face * 3 + 2] = u[0]; smoothw[face] = smooth_faces; - invertw[face] = invert_faces; + invertw[face] = flip_faces; materialsw[face] = material; face++; @@ -1999,7 +2042,7 @@ CSGBrush *CSGPolygon3D::_build_brush() { smoothw[face] = false; materialsw[face] = material; - invertw[face] = invert_faces; + invertw[face] = flip_faces; face++; } } @@ -2031,18 +2074,16 @@ void CSGPolygon3D::_notification(int p_what) { } } -void CSGPolygon3D::_validate_property(PropertyInfo &property) const { - if (property.name.begins_with("spin") && mode != MODE_SPIN) { - property.usage = PROPERTY_USAGE_NONE; +void CSGPolygon3D::_validate_property(PropertyInfo &p_property) const { + if (p_property.name.begins_with("spin") && mode != MODE_SPIN) { + p_property.usage = PROPERTY_USAGE_NONE; } - if (property.name.begins_with("path") && mode != MODE_PATH) { - property.usage = PROPERTY_USAGE_NONE; + if (p_property.name.begins_with("path") && mode != MODE_PATH) { + p_property.usage = PROPERTY_USAGE_NONE; } - if (property.name == "depth" && mode != MODE_DEPTH) { - property.usage = PROPERTY_USAGE_NONE; + if (p_property.name == "depth" && mode != MODE_DEPTH) { + p_property.usage = PROPERTY_USAGE_NONE; } - - CSGShape3D::_validate_property(property); } void CSGPolygon3D::_path_changed() { @@ -2108,7 +2149,7 @@ void CSGPolygon3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Depth,Spin,Path"), "set_mode", "get_mode"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth", PROPERTY_HINT_RANGE, "0.01,100.0,0.01,or_greater,exp"), "set_depth", "get_depth"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth", PROPERTY_HINT_RANGE, "0.01,100.0,0.01,or_greater,exp,suffix:m"), "set_depth", "get_depth"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "spin_degrees", PROPERTY_HINT_RANGE, "1,360,0.1"), "set_spin_degrees", "get_spin_degrees"); ADD_PROPERTY(PropertyInfo(Variant::INT, "spin_sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_spin_sides", "get_spin_sides"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "path_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Path3D"), "set_path_node", "get_path_node"); @@ -2118,7 +2159,7 @@ void CSGPolygon3D::_bind_methods() { 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_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"), "set_path_u_distance", "get_path_u_distance"); + 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"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "path_joined"), "set_path_joined", "is_path_joined"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial"), "set_material", "get_material"); |