feat: modules moved and engine moved to submodule
|
|
@ -31,7 +31,7 @@ thirdparty_sources = [
|
|||
]
|
||||
|
||||
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
|
||||
env_csg.Prepend(CPPPATH=[thirdparty_dir + "include"])
|
||||
env_csg.Prepend(CPPEXTPATH=[thirdparty_dir + "include"])
|
||||
env_thirdparty = env_csg.Clone()
|
||||
env_thirdparty.disable_warnings()
|
||||
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef CSG_H
|
||||
#define CSG_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/aabb.h"
|
||||
#include "core/math/transform_3d.h"
|
||||
|
|
@ -65,5 +64,3 @@ struct CSGBrush {
|
|||
void build_from_faces(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs, const Vector<bool> &p_smooth, const Vector<Ref<Material>> &p_materials, const Vector<bool> &p_invert_faces);
|
||||
void copy_from(const CSGBrush &p_brush, const Transform3D &p_xform);
|
||||
};
|
||||
|
||||
#endif // CSG_H
|
||||
|
|
|
|||
|
|
@ -36,10 +36,13 @@
|
|||
#include "core/math/geometry_2d.h"
|
||||
#include "scene/resources/3d/navigation_mesh_source_geometry_data_3d.h"
|
||||
#include "scene/resources/navigation_mesh.h"
|
||||
#ifndef NAVIGATION_3D_DISABLED
|
||||
#include "servers/navigation_server_3d.h"
|
||||
#endif // NAVIGATION_3D_DISABLED
|
||||
|
||||
#include <manifold/manifold.h>
|
||||
|
||||
#ifndef NAVIGATION_3D_DISABLED
|
||||
Callable CSGShape3D::_navmesh_source_geometry_parsing_callback;
|
||||
RID CSGShape3D::_navmesh_source_geometry_parser;
|
||||
|
||||
|
|
@ -60,9 +63,13 @@ void CSGShape3D::navmesh_parse_source_geometry(const Ref<NavigationMesh> &p_navi
|
|||
}
|
||||
|
||||
NavigationMesh::ParsedGeometryType parsed_geometry_type = p_navigation_mesh->get_parsed_geometry_type();
|
||||
uint32_t parsed_collision_mask = p_navigation_mesh->get_collision_mask();
|
||||
|
||||
if (parsed_geometry_type == NavigationMesh::PARSED_GEOMETRY_MESH_INSTANCES || (parsed_geometry_type == NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS && csgshape3d->is_using_collision() && (csgshape3d->get_collision_layer() & parsed_collision_mask)) || parsed_geometry_type == NavigationMesh::PARSED_GEOMETRY_BOTH) {
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
bool nav_collision = (parsed_geometry_type == NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS && csgshape3d->is_using_collision() && (csgshape3d->get_collision_layer() & p_navigation_mesh->get_collision_mask()));
|
||||
#else
|
||||
bool nav_collision = false;
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
if (parsed_geometry_type == NavigationMesh::PARSED_GEOMETRY_MESH_INSTANCES || nav_collision || parsed_geometry_type == NavigationMesh::PARSED_GEOMETRY_BOTH) {
|
||||
Array meshes = csgshape3d->get_meshes();
|
||||
if (!meshes.is_empty()) {
|
||||
Ref<Mesh> mesh = meshes[1];
|
||||
|
|
@ -72,7 +79,9 @@ void CSGShape3D::navmesh_parse_source_geometry(const Ref<NavigationMesh> &p_navi
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif // NAVIGATION_3D_DISABLED
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
void CSGShape3D::set_use_collision(bool p_enable) {
|
||||
if (use_collision == p_enable) {
|
||||
return;
|
||||
|
|
@ -186,6 +195,7 @@ void CSGShape3D::set_collision_priority(real_t p_priority) {
|
|||
real_t CSGShape3D::get_collision_priority() const {
|
||||
return collision_priority;
|
||||
}
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
bool CSGShape3D::is_root_shape() const {
|
||||
return !parent_shape;
|
||||
|
|
@ -207,15 +217,20 @@ float CSGShape3D::get_snap() const {
|
|||
#endif // DISABLE_DEPRECATED
|
||||
|
||||
void CSGShape3D::_make_dirty(bool p_parent_removing) {
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
if ((p_parent_removing || is_root_shape()) && !dirty) {
|
||||
callable_mp(this, &CSGShape3D::_update_shape).call_deferred(); // Must be deferred; otherwise, is_root_shape() will use the previous parent.
|
||||
callable_mp(this, &CSGShape3D::update_shape).call_deferred(); // Must be deferred; otherwise, is_root_shape() will use the previous parent.
|
||||
}
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
if (!is_root_shape()) {
|
||||
parent_shape->_make_dirty();
|
||||
} else if (!dirty) {
|
||||
callable_mp(this, &CSGShape3D::_update_shape).call_deferred();
|
||||
}
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
else if (!dirty) {
|
||||
callable_mp(this, &CSGShape3D::update_shape).call_deferred();
|
||||
}
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
|
@ -550,7 +565,7 @@ void CSGShape3D::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const
|
|||
surface.tansw[i++] = d < 0 ? -1 : 1;
|
||||
}
|
||||
|
||||
void CSGShape3D::_update_shape() {
|
||||
void CSGShape3D::update_shape() {
|
||||
if (!is_root_shape()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -711,9 +726,20 @@ void CSGShape3D::_update_shape() {
|
|||
|
||||
set_base(root_mesh->get_rid());
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
_update_collision_faces();
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
}
|
||||
|
||||
Ref<ArrayMesh> CSGShape3D::bake_static_mesh() {
|
||||
Ref<ArrayMesh> baked_mesh;
|
||||
if (is_root_shape() && root_mesh.is_valid()) {
|
||||
baked_mesh = root_mesh;
|
||||
}
|
||||
return baked_mesh;
|
||||
}
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
Vector<Vector3> CSGShape3D::_get_brush_collision_faces() {
|
||||
Vector<Vector3> collision_faces;
|
||||
CSGBrush *n = _get_brush();
|
||||
|
|
@ -746,14 +772,6 @@ void CSGShape3D::_update_collision_faces() {
|
|||
}
|
||||
}
|
||||
|
||||
Ref<ArrayMesh> CSGShape3D::bake_static_mesh() {
|
||||
Ref<ArrayMesh> baked_mesh;
|
||||
if (is_root_shape() && root_mesh.is_valid()) {
|
||||
baked_mesh = root_mesh;
|
||||
}
|
||||
return baked_mesh;
|
||||
}
|
||||
|
||||
Ref<ConcavePolygonShape3D> CSGShape3D::bake_collision_shape() {
|
||||
Ref<ConcavePolygonShape3D> baked_collision_shape;
|
||||
if (is_root_shape() && root_collision_shape.is_valid()) {
|
||||
|
|
@ -800,6 +818,7 @@ void CSGShape3D::_on_transform_changed() {
|
|||
RS::get_singleton()->instance_set_transform(root_collision_debug_instance, debug_shape_old_transform);
|
||||
}
|
||||
}
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
AABB CSGShape3D::get_aabb() const {
|
||||
return node_aabb;
|
||||
|
|
@ -872,6 +891,7 @@ void CSGShape3D::_notification(int p_what) {
|
|||
}
|
||||
} break;
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
if (use_collision && is_root_shape()) {
|
||||
root_collision_shape.instantiate();
|
||||
|
|
@ -904,6 +924,7 @@ void CSGShape3D::_notification(int p_what) {
|
|||
}
|
||||
_on_transform_changed();
|
||||
} break;
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -969,17 +990,18 @@ Ref<TriangleMesh> CSGShape3D::generate_triangle_mesh() const {
|
|||
}
|
||||
|
||||
void CSGShape3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_update_shape"), &CSGShape3D::_update_shape);
|
||||
ClassDB::bind_method(D_METHOD("is_root_shape"), &CSGShape3D::is_root_shape);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_operation", "operation"), &CSGShape3D::set_operation);
|
||||
ClassDB::bind_method(D_METHOD("get_operation"), &CSGShape3D::get_operation);
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
ClassDB::bind_method(D_METHOD("_update_shape"), &CSGShape3D::update_shape);
|
||||
ClassDB::bind_method(D_METHOD("set_snap", "snap"), &CSGShape3D::set_snap);
|
||||
ClassDB::bind_method(D_METHOD("get_snap"), &CSGShape3D::get_snap);
|
||||
#endif // DISABLE_DEPRECATED
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
ClassDB::bind_method(D_METHOD("set_use_collision", "operation"), &CSGShape3D::set_use_collision);
|
||||
ClassDB::bind_method(D_METHOD("is_using_collision"), &CSGShape3D::is_using_collision);
|
||||
|
||||
|
|
@ -1000,13 +1022,15 @@ void CSGShape3D::_bind_methods() {
|
|||
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("bake_collision_shape"), &CSGShape3D::bake_collision_shape);
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
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);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("bake_static_mesh"), &CSGShape3D::bake_static_mesh);
|
||||
ClassDB::bind_method(D_METHOD("bake_collision_shape"), &CSGShape3D::bake_collision_shape);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "operation", PROPERTY_HINT_ENUM, "Union,Intersection,Subtraction"), "set_operation", "get_operation");
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
|
|
@ -1014,11 +1038,13 @@ void CSGShape3D::_bind_methods() {
|
|||
#endif // DISABLE_DEPRECATED
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "calculate_tangents"), "set_calculate_tangents", "is_calculating_tangents");
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
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");
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
BIND_ENUM_CONSTANT(OPERATION_UNION);
|
||||
BIND_ENUM_CONSTANT(OPERATION_INTERSECTION);
|
||||
|
|
@ -1109,13 +1135,13 @@ CSGBrush *CSGMesh3D::_build_brush() {
|
|||
|
||||
Array arrays = mesh->surface_get_arrays(i);
|
||||
|
||||
if (arrays.size() == 0) {
|
||||
if (arrays.is_empty()) {
|
||||
_make_dirty();
|
||||
ERR_FAIL_COND_V(arrays.is_empty(), memnew(CSGBrush));
|
||||
}
|
||||
|
||||
Vector<Vector3> avertices = arrays[Mesh::ARRAY_VERTEX];
|
||||
if (avertices.size() == 0) {
|
||||
if (avertices.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1231,7 +1257,7 @@ CSGBrush *CSGMesh3D::_build_brush() {
|
|||
}
|
||||
}
|
||||
|
||||
if (vertices.size() == 0) {
|
||||
if (vertices.is_empty()) {
|
||||
return memnew(CSGBrush);
|
||||
}
|
||||
|
||||
|
|
@ -1322,14 +1348,14 @@ CSGBrush *CSGSphere3D::_build_brush() {
|
|||
|
||||
// We want to follow an order that's convenient for UVs.
|
||||
// For latitude step we start at the top and move down like in an image.
|
||||
const double latitude_step = -Math_PI / rings;
|
||||
const double longitude_step = Math_TAU / radial_segments;
|
||||
const double latitude_step = -Math::PI / rings;
|
||||
const double longitude_step = Math::TAU / radial_segments;
|
||||
int face = 0;
|
||||
for (int i = 0; i < rings; i++) {
|
||||
double cos0 = 0;
|
||||
double sin0 = 1;
|
||||
if (i > 0) {
|
||||
double latitude0 = latitude_step * i + Math_TAU / 4;
|
||||
double latitude0 = latitude_step * i + Math::TAU / 4;
|
||||
cos0 = Math::cos(latitude0);
|
||||
sin0 = Math::sin(latitude0);
|
||||
}
|
||||
|
|
@ -1338,7 +1364,7 @@ CSGBrush *CSGSphere3D::_build_brush() {
|
|||
double cos1 = 0;
|
||||
double sin1 = -1;
|
||||
if (i < rings - 1) {
|
||||
double latitude1 = latitude_step * (i + 1) + Math_TAU / 4;
|
||||
double latitude1 = latitude_step * (i + 1) + Math::TAU / 4;
|
||||
cos1 = Math::cos(latitude1);
|
||||
sin1 = Math::sin(latitude1);
|
||||
}
|
||||
|
|
@ -1701,8 +1727,8 @@ CSGBrush *CSGCylinder3D::_build_brush() {
|
|||
inc_n = 0;
|
||||
}
|
||||
|
||||
float ang = inc * Math_TAU;
|
||||
float ang_n = inc_n * Math_TAU;
|
||||
float ang = inc * Math::TAU;
|
||||
float ang_n = inc_n * Math::TAU;
|
||||
|
||||
Vector3 face_base(Math::cos(ang), 0, Math::sin(ang));
|
||||
Vector3 face_base_n(Math::cos(ang_n), 0, Math::sin(ang_n));
|
||||
|
|
@ -1944,8 +1970,8 @@ CSGBrush *CSGTorus3D::_build_brush() {
|
|||
inci_n = 0;
|
||||
}
|
||||
|
||||
float angi = inci * Math_TAU;
|
||||
float angi_n = inci_n * Math_TAU;
|
||||
float angi = inci * Math::TAU;
|
||||
float angi_n = inci_n * Math::TAU;
|
||||
|
||||
Vector3 normali = Vector3(Math::cos(angi), 0, Math::sin(angi));
|
||||
Vector3 normali_n = Vector3(Math::cos(angi_n), 0, Math::sin(angi_n));
|
||||
|
|
@ -1957,8 +1983,8 @@ CSGBrush *CSGTorus3D::_build_brush() {
|
|||
incj_n = 0;
|
||||
}
|
||||
|
||||
float angj = incj * Math_TAU;
|
||||
float angj_n = incj_n * Math_TAU;
|
||||
float angj = incj * Math::TAU;
|
||||
float angj_n = incj_n * Math::TAU;
|
||||
|
||||
Vector2 normalj = Vector2(Math::cos(angj), Math::sin(angj)) * radius + Vector2(min_radius + radius, 0);
|
||||
Vector2 normalj_n = Vector2(Math::cos(angj_n), Math::sin(angj_n)) * radius + Vector2(min_radius + radius, 0);
|
||||
|
|
|
|||
|
|
@ -28,14 +28,16 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef CSG_SHAPE_H
|
||||
#define CSG_SHAPE_H
|
||||
#pragma once
|
||||
|
||||
#include "csg.h"
|
||||
|
||||
#include "scene/3d/path_3d.h"
|
||||
#include "scene/3d/visual_instance_3d.h"
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
#include "scene/resources/3d/concave_polygon_shape_3d.h"
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
#include "thirdparty/misc/mikktspace.h"
|
||||
|
||||
|
|
@ -65,6 +67,7 @@ private:
|
|||
bool last_visible = false;
|
||||
float snap = 0.001;
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
bool use_collision = false;
|
||||
uint32_t collision_layer = 1;
|
||||
uint32_t collision_mask = 1;
|
||||
|
|
@ -73,6 +76,7 @@ private:
|
|||
RID root_collision_instance;
|
||||
RID root_collision_debug_instance;
|
||||
Transform3D debug_shape_old_transform;
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
bool calculate_tangents = true;
|
||||
|
||||
|
|
@ -110,13 +114,14 @@ private:
|
|||
static void mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
|
||||
const tbool bIsOrientationPreserving, const int iFace, const int iVert);
|
||||
|
||||
void _update_shape();
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
void _update_collision_faces();
|
||||
bool _is_debug_collision_shape_visible();
|
||||
void _update_debug_collision_shape();
|
||||
void _clear_debug_collision_shape();
|
||||
void _on_transform_changed();
|
||||
Vector<Vector3> _get_brush_collision_faces();
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
|
|
@ -133,6 +138,7 @@ protected:
|
|||
|
||||
public:
|
||||
Array get_meshes() const;
|
||||
void update_shape();
|
||||
|
||||
void set_operation(Operation p_operation);
|
||||
Operation get_operation() const;
|
||||
|
|
@ -172,10 +178,13 @@ public:
|
|||
bool is_root_shape() const;
|
||||
|
||||
Ref<ArrayMesh> bake_static_mesh();
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
Ref<ConcavePolygonShape3D> bake_collision_shape();
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
virtual Ref<TriangleMesh> generate_triangle_mesh() const override;
|
||||
|
||||
#ifndef NAVIGATION_3D_DISABLED
|
||||
private:
|
||||
static Callable _navmesh_source_geometry_parsing_callback;
|
||||
static RID _navmesh_source_geometry_parser;
|
||||
|
|
@ -183,6 +192,7 @@ private:
|
|||
public:
|
||||
static void navmesh_parse_init();
|
||||
static void navmesh_parse_source_geometry(const Ref<NavigationMesh> &p_navigation_mesh, Ref<NavigationMeshSourceGeometryData3D> p_source_geometry_data, Node *p_node);
|
||||
#endif // NAVIGATION_3D_DISABLED
|
||||
|
||||
CSGShape3D();
|
||||
~CSGShape3D();
|
||||
|
|
@ -482,5 +492,3 @@ public:
|
|||
VARIANT_ENUM_CAST(CSGPolygon3D::Mode)
|
||||
VARIANT_ENUM_CAST(CSGPolygon3D::PathRotation)
|
||||
VARIANT_ENUM_CAST(CSGPolygon3D::PathIntervalType)
|
||||
|
||||
#endif // CSG_SHAPE_H
|
||||
|
|
|
|||
|
|
@ -5,11 +5,10 @@
|
|||
</brief_description>
|
||||
<description>
|
||||
This is the CSG base class that provides CSG operation support to the various CSG nodes in Godot.
|
||||
[b]Performance:[/b] CSG nodes are only intended for prototyping as they have a significant CPU performance cost.
|
||||
Consider baking final CSG operation results into static geometry that replaces the CSG nodes.
|
||||
[b]Performance:[/b] CSG nodes are only intended for prototyping as they have a significant CPU performance cost. Consider baking final CSG operation results into static geometry that replaces the CSG nodes.
|
||||
Individual CSG root node results can be baked to nodes with static resources with the editor menu that appears when a CSG root node is selected.
|
||||
Individual CSG root nodes can also be baked to static resources with scripts by calling [method bake_static_mesh] for the visual mesh or [method bake_collision_shape] for the physics collision.
|
||||
Entire scenes of CSG nodes can be baked to static geometry and exported with the editor gltf scene exporter.
|
||||
Entire scenes of CSG nodes can be baked to static geometry and exported with the editor glTF scene exporter: [b]Scene > Export As... > glTF 2.0 Scene...[/b]
|
||||
</description>
|
||||
<tutorials>
|
||||
<link title="Prototyping levels with CSG">$DOCS_URL/tutorials/3d/csg_tools.html</link>
|
||||
|
|
@ -20,12 +19,14 @@
|
|||
<description>
|
||||
Returns a baked physics [ConcavePolygonShape3D] of this node's CSG operation result. Returns an empty shape if the node is not a CSG root node or has no valid geometry.
|
||||
[b]Performance:[/b] If the CSG operation results in a very detailed geometry with many faces physics performance will be very slow. Concave shapes should in general only be used for static level geometry and not with dynamic objects that are moving.
|
||||
[b]Note:[/b] CSG mesh data updates are deferred, which means they are updated with a delay of one rendered frame. To avoid getting an empty shape or outdated mesh data, make sure to call [code]await get_tree().process_frame[/code] before using [method bake_collision_shape] in [method Node._ready] or after changing properties on the [CSGShape3D].
|
||||
</description>
|
||||
</method>
|
||||
<method name="bake_static_mesh">
|
||||
<return type="ArrayMesh" />
|
||||
<description>
|
||||
Returns a baked static [ArrayMesh] of this node's CSG operation result. Materials from involved CSG nodes are added as extra mesh surfaces. Returns an empty mesh if the node is not a CSG root node or has no valid geometry.
|
||||
[b]Note:[/b] CSG mesh data updates are deferred, which means they are updated with a delay of one rendered frame. To avoid getting an empty mesh or outdated mesh data, make sure to call [code]await get_tree().process_frame[/code] before using [method bake_static_mesh] in [method Node._ready] or after changing properties on the [CSGShape3D].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collision_layer_value" qualifiers="const">
|
||||
|
|
@ -46,6 +47,7 @@
|
|||
<return type="Array" />
|
||||
<description>
|
||||
Returns an [Array] with two elements, the first is the [Transform3D] of this node and the second is the root [Mesh] of this node. Only works when this node is the root shape.
|
||||
[b]Note:[/b] CSG mesh data updates are deferred, which means they are updated with a delay of one rendered frame. To avoid getting an empty shape or outdated mesh data, make sure to call [code]await get_tree().process_frame[/code] before using [method get_meshes] in [method Node._ready] or after changing properties on the [CSGShape3D].
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_root_shape" qualifiers="const">
|
||||
|
|
@ -73,7 +75,7 @@
|
|||
</methods>
|
||||
<members>
|
||||
<member name="calculate_tangents" type="bool" setter="set_calculate_tangents" getter="is_calculating_tangents" default="true">
|
||||
Calculate tangents for the CSG shape which allows the use of normal maps. This is only applied on the root shape, this setting is ignored on any child.
|
||||
Calculate tangents for the CSG shape which allows the use of normal and height maps. This is only applied on the root shape, this setting is ignored on any child. Setting this to [code]false[/code] can speed up shape generation slightly.
|
||||
</member>
|
||||
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" default="1">
|
||||
The physics layers this area is in.
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@
|
|||
|
||||
#include "csg_gizmos.h"
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_settings.h"
|
||||
#include "editor/editor_undo_redo_manager.h"
|
||||
|
|
@ -156,6 +154,8 @@ CSGShapeEditor::CSGShapeEditor() {
|
|||
options->hide();
|
||||
options->set_text(TTR("CSG"));
|
||||
options->set_switch_on_hover(true);
|
||||
options->set_flat(false);
|
||||
options->set_theme_type_variation("FlatMenuButton");
|
||||
Node3DEditor::get_singleton()->add_control_to_menu_panel(options);
|
||||
|
||||
options->get_popup()->add_item(TTR("Bake Mesh Instance"), MENU_OPTION_BAKE_MESH_INSTANCE);
|
||||
|
|
@ -187,9 +187,6 @@ CSGShape3DGizmoPlugin::CSGShape3DGizmoPlugin() {
|
|||
create_handle_material("handles");
|
||||
}
|
||||
|
||||
CSGShape3DGizmoPlugin::~CSGShape3DGizmoPlugin() {
|
||||
}
|
||||
|
||||
String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
|
||||
CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_node_3d());
|
||||
|
||||
|
|
@ -227,7 +224,7 @@ Variant CSGShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo
|
|||
|
||||
if (Object::cast_to<CSGCylinder3D>(cs)) {
|
||||
CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs);
|
||||
return p_id == 0 ? s->get_radius() : s->get_height();
|
||||
return Vector2(s->get_radius(), s->get_height());
|
||||
}
|
||||
|
||||
if (Object::cast_to<CSGTorus3D>(cs)) {
|
||||
|
|
@ -384,7 +381,7 @@ void CSGShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
|
|||
|
||||
Vector<Vector3> faces = cs->get_brush_faces();
|
||||
|
||||
if (faces.size() == 0) {
|
||||
if (faces.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -508,5 +505,3 @@ EditorPluginCSG::EditorPluginCSG() {
|
|||
csg_shape_editor = memnew(CSGShapeEditor);
|
||||
EditorNode::get_singleton()->get_gui_base()->add_child(csg_shape_editor);
|
||||
}
|
||||
|
||||
#endif // TOOLS_ENABLED
|
||||
|
|
|
|||
|
|
@ -28,10 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef CSG_GIZMOS_H
|
||||
#define CSG_GIZMOS_H
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
#pragma once
|
||||
|
||||
#include "../csg_shape.h"
|
||||
|
||||
|
|
@ -62,7 +59,6 @@ public:
|
|||
virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) override;
|
||||
|
||||
CSGShape3DGizmoPlugin();
|
||||
~CSGShape3DGizmoPlugin();
|
||||
};
|
||||
|
||||
class CSGShapeEditor : public Control {
|
||||
|
|
@ -104,7 +100,3 @@ public:
|
|||
|
||||
EditorPluginCSG();
|
||||
};
|
||||
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
#endif // CSG_GIZMOS_H
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><mask id="a"><path fill="#fefefe" d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z"/></mask><path fill="#5fb2ff" d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z"/><path fill="none" stroke="#fc7f7f" stroke-width="2" d="m8 2 6 3v6l-6 3-6-3V5zm0 12V8l6-3M8 8 2 5" mask="url(#a)"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><mask id="a"><path fill="#fefefe" d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z"/></mask><path fill="#5fb2ff" d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z"/><path fill="none" stroke="#fc7f7f" stroke-width="2" d="m8 2 6 3v6l-6 3-6-3V5zm0 12V8l6-3M8 8 2 5" mask="url(#a)"/></svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 450 B After Width: | Height: | Size: 451 B |
|
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><mask id="a"><path fill="#fefefe" d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z"/></mask><path fill="#5fb2ff" d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z"/><path fill="none" stroke="#fc7f7f" stroke-width="2" d="M4 6a4 4 0 0 1 8 0v4a4 4 0 0 1-8 0zm0 1.25a2.5 1 0 0 0 8 0m-4-5v12" mask="url(#a)"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><mask id="a"><path fill="#fefefe" d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z"/></mask><path fill="#5fb2ff" d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z"/><path fill="none" stroke="#fc7f7f" stroke-width="2" d="M4 6a4 4 0 0 1 8 0v4a4 4 0 0 1-8 0zm0 1.25a2.5 1 0 0 0 8 0m-4-5v12" mask="url(#a)"/></svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 475 B After Width: | Height: | Size: 476 B |
|
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#5fb2ff" d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z"/><path fill="#fc7f7f" d="M3 1a2 2 0 0 0-2 2h2zm2 0v2h2V1zm4 0v2h2V1zm4 0v2h2a2 2 0 0 0-2-2zM1 5v2h2V5zm12 0v2h2V5zM1 9v2h2V9zm0 4a2 2 0 0 0 2 2v-2zm4 0v2h2v-2z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#5fb2ff" d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z"/><path fill="#fc7f7f" d="M3 1a2 2 0 0 0-2 2h2zm2 0v2h2V1zm4 0v2h2V1zm4 0v2h2a2 2 0 0 0-2-2zM1 5v2h2V5zm12 0v2h2V5zM1 9v2h2V9zm0 4a2 2 0 0 0 2 2v-2zm4 0v2h2v-2z"/></svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 376 B After Width: | Height: | Size: 377 B |
|
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><mask id="a"><path fill="#fefefe" d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z"/></mask><path fill="#5fb2ff" d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z"/><path fill="none" stroke="#fc7f7f" stroke-width="2" d="M2 4v8a6 2 0 0 0 12 0V4A6 2 0 0 0 2 4a6 2 0 0 0 12 0" mask="url(#a)"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><mask id="a"><path fill="#fefefe" d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z"/></mask><path fill="#5fb2ff" d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z"/><path fill="none" stroke="#fc7f7f" stroke-width="2" d="M2 4v8a6 2 0 0 0 12 0V4A6 2 0 0 0 2 4a6 2 0 0 0 12 0" mask="url(#a)"/></svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 461 B After Width: | Height: | Size: 462 B |
|
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#fc7f7f" d="M4.73 2A2 2 0 1 0 2 4.73v6.541A2 2 0 1 0 4.729 14H8v-2H4.729A2 2 0 0 0 4 11.271V5.415l4.914 4.916A2 2 0 0 1 9.998 10a2 2 0 0 1 .33-1.084L5.414 4h5.856a2 2 0 0 0 .73.729V8h2V4.729A2 2 0 1 0 11.27 2z"/><path fill="#5fb2ff" d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#fc7f7f" d="M4.73 2A2 2 0 1 0 2 4.73v6.541A2 2 0 1 0 4.729 14H8v-2H4.729A2 2 0 0 0 4 11.271V5.415l4.914 4.916A2 2 0 0 1 9.998 10a2 2 0 0 1 .33-1.084L5.414 4h5.856a2 2 0 0 0 .73.729V8h2V4.729A2 2 0 1 0 11.27 2z"/><path fill="#5fb2ff" d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z"/></svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 439 B After Width: | Height: | Size: 440 B |
|
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><mask id="a"><path fill="#fefefe" d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z"/></mask><path fill="#5fb2ff" d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z"/><path fill="none" stroke="#fc7f7f" stroke-linejoin="round" stroke-width="2" d="m8 2 6 3.5v5L8 14l-6-3.5v-5h6zm6 3.5L8 9 2 5.5M8 9v5" mask="url(#a)"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><mask id="a"><path fill="#fefefe" d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z"/></mask><path fill="#5fb2ff" d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z"/><path fill="none" stroke="#fc7f7f" stroke-linejoin="round" stroke-width="2" d="m8 2 6 3.5v5L8 14l-6-3.5v-5h6zm6 3.5L8 9 2 5.5M8 9v5" mask="url(#a)"/></svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 485 B After Width: | Height: | Size: 486 B |
|
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><mask id="a"><path fill="#fefefe" d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z"/></mask><path fill="#5fb2ff" d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z"/><path fill="none" stroke="#fc7f7f" stroke-width="2" d="M8 2a6 6 0 0 0 0 12A6 6 0 0 0 8 2v12M2.05 7.4a6 2 0 0 0 11.9 0" mask="url(#a)"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><mask id="a"><path fill="#fefefe" d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z"/></mask><path fill="#5fb2ff" d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z"/><path fill="none" stroke="#fc7f7f" stroke-width="2" d="M8 2a6 6 0 0 0 0 12A6 6 0 0 0 8 2v12M2.05 7.4a6 2 0 0 0 11.9 0" mask="url(#a)"/></svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 471 B After Width: | Height: | Size: 472 B |
|
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><mask id="a"><path fill="#fefefe" d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z"/></mask><path fill="#5fb2ff" d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z"/><g fill="none" stroke="#fc7f7f" mask="url(#a)"><path stroke-width="2" d="M2.5 10a6 4 0 0 0 11 0 4 4 0 0 0 0-4 6 4 0 0 0-11 0 4 4 0 0 0 0 4z"/><path stroke-linecap="round" stroke-width="1.75" d="M6.2 7.2a2 1 0 1 0 3.6 0"/></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><mask id="a"><path fill="#fefefe" d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z"/></mask><path fill="#5fb2ff" d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z"/><g fill="none" stroke="#fc7f7f" mask="url(#a)"><path stroke-width="2" d="M2.5 10a6 4 0 0 0 11 0 4 4 0 0 0 0-4 6 4 0 0 0-11 0 4 4 0 0 0 0 4z"/><path stroke-linecap="round" stroke-width="1.75" d="M6.2 7.2a2 1 0 1 0 3.6 0"/></g></svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 561 B After Width: | Height: | Size: 562 B |
|
|
@ -47,7 +47,9 @@ void initialize_csg_module(ModuleInitializationLevel p_level) {
|
|||
GDREGISTER_CLASS(CSGTorus3D);
|
||||
GDREGISTER_CLASS(CSGPolygon3D);
|
||||
GDREGISTER_CLASS(CSGCombiner3D);
|
||||
#ifndef NAVIGATION_3D_DISABLED
|
||||
CSGShape3D::navmesh_parse_init();
|
||||
#endif // NAVIGATION_3D_DISABLED
|
||||
}
|
||||
#ifdef TOOLS_ENABLED
|
||||
if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) {
|
||||
|
|
|
|||
|
|
@ -28,12 +28,9 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef CSG_REGISTER_TYPES_H
|
||||
#define CSG_REGISTER_TYPES_H
|
||||
#pragma once
|
||||
|
||||
#include "modules/register_module_types.h"
|
||||
|
||||
void initialize_csg_module(ModuleInitializationLevel p_level);
|
||||
void uninitialize_csg_module(ModuleInitializationLevel p_level);
|
||||
|
||||
#endif // CSG_REGISTER_TYPES_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_CSG_H
|
||||
#define TEST_CSG_H
|
||||
#pragma once
|
||||
|
||||
#include "../csg.h"
|
||||
#include "../csg_shape.h"
|
||||
|
|
@ -110,5 +109,3 @@ TEST_CASE("[SceneTree][CSG] CSGPolygon3D") {
|
|||
}
|
||||
|
||||
} // namespace TestCSG
|
||||
|
||||
#endif // TEST_CSG_H
|
||||
|
|
|
|||