Editor 3D view mesh stats
Similar to information window, add a small optional window to display face count and other stats.
This commit is contained in:
parent
a73715cf55
commit
bdf0f78e07
4 changed files with 186 additions and 4 deletions
|
@ -47,6 +47,7 @@
|
||||||
#include "scene/3d/collision_shape.h"
|
#include "scene/3d/collision_shape.h"
|
||||||
#include "scene/3d/lod_manager.h"
|
#include "scene/3d/lod_manager.h"
|
||||||
#include "scene/3d/mesh_instance.h"
|
#include "scene/3d/mesh_instance.h"
|
||||||
|
#include "scene/3d/multimesh_instance.h"
|
||||||
#include "scene/3d/physics_body.h"
|
#include "scene/3d/physics_body.h"
|
||||||
#include "scene/3d/room_manager.h"
|
#include "scene/3d/room_manager.h"
|
||||||
#include "scene/3d/visual_instance.h"
|
#include "scene/3d/visual_instance.h"
|
||||||
|
@ -2779,6 +2780,19 @@ void SpatialEditorViewport::_notification(int p_what) {
|
||||||
|
|
||||||
_update_camera(delta);
|
_update_camera(delta);
|
||||||
|
|
||||||
|
bool show_selected_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_SELECTED_INFO)) && (message_time <= 0);
|
||||||
|
|
||||||
|
struct SelectedInfo {
|
||||||
|
bool filled = false;
|
||||||
|
uint32_t tri_count = 0;
|
||||||
|
uint32_t vertex_count = 0;
|
||||||
|
uint32_t index_count = 0;
|
||||||
|
uint32_t mesh_count = 0;
|
||||||
|
uint32_t multimesh_count = 0;
|
||||||
|
uint32_t surface_count = 0;
|
||||||
|
uint32_t array_format = 0;
|
||||||
|
} selected_info;
|
||||||
|
|
||||||
Map<Node *, Object *> &selection = editor_selection->get_selection();
|
Map<Node *, Object *> &selection = editor_selection->get_selection();
|
||||||
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -2790,6 +2804,48 @@ void SpatialEditorViewport::_notification(int p_what) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only retrieve stats for selected items if we are currently showing the selection stats box.
|
||||||
|
if (show_selected_info) {
|
||||||
|
MeshInstance *mi = Object::cast_to<MeshInstance>(sp);
|
||||||
|
if (mi) {
|
||||||
|
const Ref<Mesh> &mesh = mi->get_mesh();
|
||||||
|
if (mesh.is_valid()) {
|
||||||
|
selected_info.filled = true;
|
||||||
|
const Mesh::CachedStats &stats = mesh->get_cached_stats();
|
||||||
|
selected_info.tri_count += stats.triangle_count;
|
||||||
|
selected_info.vertex_count += stats.vertex_count;
|
||||||
|
selected_info.index_count += stats.index_count;
|
||||||
|
selected_info.mesh_count += 1;
|
||||||
|
selected_info.surface_count += mesh->get_surface_count();
|
||||||
|
selected_info.array_format |= stats.array_format;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiMeshInstance *mmi = Object::cast_to<MultiMeshInstance>(sp);
|
||||||
|
if (mmi) {
|
||||||
|
const Ref<MultiMesh> &mm = mmi->get_multimesh();
|
||||||
|
if (mm.is_valid()) {
|
||||||
|
const Ref<Mesh> &mesh = mm->get_mesh();
|
||||||
|
int icount = mm->get_visible_instance_count();
|
||||||
|
if (icount < 0) {
|
||||||
|
icount = mm->get_instance_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mesh.is_valid() && icount) {
|
||||||
|
selected_info.filled = true;
|
||||||
|
const Mesh::CachedStats &stats = mesh->get_cached_stats();
|
||||||
|
selected_info.tri_count += stats.triangle_count * icount;
|
||||||
|
selected_info.vertex_count += stats.vertex_count * icount;
|
||||||
|
selected_info.index_count += stats.index_count * icount;
|
||||||
|
selected_info.mesh_count += icount;
|
||||||
|
selected_info.multimesh_count += 1;
|
||||||
|
selected_info.surface_count += mesh->get_surface_count() * icount;
|
||||||
|
selected_info.array_format |= stats.array_format;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SpatialEditorSelectedItem *se = editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
|
SpatialEditorSelectedItem *se = editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
|
||||||
if (!se) {
|
if (!se) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -2841,13 +2897,19 @@ void SpatialEditorViewport::_notification(int p_what) {
|
||||||
if (message != last_message) {
|
if (message != last_message) {
|
||||||
surface->update();
|
surface->update();
|
||||||
last_message = message;
|
last_message = message;
|
||||||
}
|
|
||||||
|
|
||||||
|
// If there is now no message,
|
||||||
|
// disable the timing counter.
|
||||||
|
if (message == "") {
|
||||||
|
message_time = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
message_time -= get_physics_process_delta_time();
|
message_time -= get_physics_process_delta_time();
|
||||||
if (message_time < 0) {
|
if (message_time < 0) {
|
||||||
surface->update();
|
surface->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_project_settings_change_pending) {
|
if (_project_settings_change_pending) {
|
||||||
_project_settings_changed();
|
_project_settings_changed();
|
||||||
|
@ -2893,6 +2955,29 @@ void SpatialEditorViewport::_notification(int p_what) {
|
||||||
info_label->set_text(text);
|
info_label->set_text(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selected_info_label->set_visible(show_selected_info && selected_info.filled);
|
||||||
|
if (show_selected_info) {
|
||||||
|
if (selected_info.filled) {
|
||||||
|
String text;
|
||||||
|
if (selected_info.multimesh_count > 0) {
|
||||||
|
text += TTR("MultiMeshes:") + " " + itos(selected_info.multimesh_count) + "\n";
|
||||||
|
}
|
||||||
|
if (selected_info.mesh_count > 1) {
|
||||||
|
text += TTR("Meshes:") + " " + itos(selected_info.mesh_count) + "\n";
|
||||||
|
}
|
||||||
|
if (selected_info.surface_count > 1) {
|
||||||
|
text += TTR("Surfaces:") + " " + itos(selected_info.surface_count) + "\n";
|
||||||
|
}
|
||||||
|
text += TTR("Triangles:") + " " + itos(selected_info.tri_count) + "\n";
|
||||||
|
text += TTR("Vertices:") + " " + itos(selected_info.vertex_count) + "\n";
|
||||||
|
text += TTR("Indices:") + " " + itos(selected_info.index_count);
|
||||||
|
|
||||||
|
selected_info_label->set_text(text);
|
||||||
|
} else {
|
||||||
|
selected_info_label->set_text("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FPS Counter.
|
// FPS Counter.
|
||||||
bool show_fps = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FPS));
|
bool show_fps = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FPS));
|
||||||
fps_label->set_visible(show_fps);
|
fps_label->set_visible(show_fps);
|
||||||
|
@ -2959,6 +3044,7 @@ void SpatialEditorViewport::_notification(int p_what) {
|
||||||
preview_camera->add_style_override("disabled", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
|
preview_camera->add_style_override("disabled", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
|
||||||
|
|
||||||
info_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
|
info_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
|
||||||
|
selected_info_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
|
||||||
fps_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
|
fps_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
|
||||||
cinema_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
|
cinema_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
|
||||||
locked_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
|
locked_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
|
||||||
|
@ -3374,6 +3460,12 @@ void SpatialEditorViewport::_menu_option(int p_option) {
|
||||||
bool current = view_menu->get_popup()->is_item_checked(idx);
|
bool current = view_menu->get_popup()->is_item_checked(idx);
|
||||||
view_menu->get_popup()->set_item_checked(idx, !current);
|
view_menu->get_popup()->set_item_checked(idx, !current);
|
||||||
|
|
||||||
|
} break;
|
||||||
|
case VIEW_SELECTED_INFO: {
|
||||||
|
int idx = view_menu->get_popup()->get_item_index(VIEW_SELECTED_INFO);
|
||||||
|
bool current = view_menu->get_popup()->is_item_checked(idx);
|
||||||
|
view_menu->get_popup()->set_item_checked(idx, !current);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case VIEW_FPS: {
|
case VIEW_FPS: {
|
||||||
int idx = view_menu->get_popup()->get_item_index(VIEW_FPS);
|
int idx = view_menu->get_popup()->get_item_index(VIEW_FPS);
|
||||||
|
@ -3744,6 +3836,14 @@ void SpatialEditorViewport::set_state(const Dictionary &p_state) {
|
||||||
_menu_option(VIEW_INFORMATION);
|
_menu_option(VIEW_INFORMATION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (p_state.has("selected_info")) {
|
||||||
|
bool selected_info = p_state["selected_info"];
|
||||||
|
|
||||||
|
int idx = view_menu->get_popup()->get_item_index(VIEW_SELECTED_INFO);
|
||||||
|
if (view_menu->get_popup()->is_item_checked(idx) != selected_info) {
|
||||||
|
_menu_option(VIEW_SELECTED_INFO);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (p_state.has("fps")) {
|
if (p_state.has("fps")) {
|
||||||
bool fps = p_state["fps"];
|
bool fps = p_state["fps"];
|
||||||
|
|
||||||
|
@ -3806,6 +3906,7 @@ Dictionary SpatialEditorViewport::get_state() const {
|
||||||
d["doppler"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_AUDIO_DOPPLER));
|
d["doppler"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_AUDIO_DOPPLER));
|
||||||
d["gizmos"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_GIZMOS));
|
d["gizmos"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_GIZMOS));
|
||||||
d["information"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
|
d["information"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
|
||||||
|
d["selected_info"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_SELECTED_INFO));
|
||||||
d["fps"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FPS));
|
d["fps"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FPS));
|
||||||
d["half_res"] = viewport_container->get_stretch_shrink() > 1;
|
d["half_res"] = viewport_container->get_stretch_shrink() > 1;
|
||||||
d["cinematic_preview"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW));
|
d["cinematic_preview"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW));
|
||||||
|
@ -4344,6 +4445,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
|
||||||
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_gizmos", TTR("View Gizmos")), VIEW_GIZMOS);
|
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_gizmos", TTR("View Gizmos")), VIEW_GIZMOS);
|
||||||
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_GIZMOS), true);
|
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_GIZMOS), true);
|
||||||
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_information", TTR("View Information")), VIEW_INFORMATION);
|
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_information", TTR("View Information")), VIEW_INFORMATION);
|
||||||
|
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_selected_info", TTR("View Selected Mesh Stats")), VIEW_SELECTED_INFO);
|
||||||
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_fps", TTR("View FPS")), VIEW_FPS);
|
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_fps", TTR("View FPS")), VIEW_FPS);
|
||||||
view_menu->get_popup()->add_separator();
|
view_menu->get_popup()->add_separator();
|
||||||
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_half_resolution", TTR("Half Resolution")), VIEW_HALF_RESOLUTION);
|
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_half_resolution", TTR("Half Resolution")), VIEW_HALF_RESOLUTION);
|
||||||
|
@ -4428,6 +4530,16 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
|
||||||
surface->add_child(info_label);
|
surface->add_child(info_label);
|
||||||
info_label->hide();
|
info_label->hide();
|
||||||
|
|
||||||
|
selected_info_label = memnew(Label);
|
||||||
|
selected_info_label->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_BEGIN, 10 * EDSCALE);
|
||||||
|
selected_info_label->set_anchor_and_margin(MARGIN_TOP, ANCHOR_END, -20 * EDSCALE);
|
||||||
|
selected_info_label->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_BEGIN, 90 * EDSCALE);
|
||||||
|
selected_info_label->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, -10 * EDSCALE);
|
||||||
|
selected_info_label->set_h_grow_direction(GROW_DIRECTION_END);
|
||||||
|
selected_info_label->set_v_grow_direction(GROW_DIRECTION_BEGIN);
|
||||||
|
surface->add_child(selected_info_label);
|
||||||
|
selected_info_label->hide();
|
||||||
|
|
||||||
cinema_label = memnew(Label);
|
cinema_label = memnew(Label);
|
||||||
cinema_label->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 10 * EDSCALE);
|
cinema_label->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 10 * EDSCALE);
|
||||||
cinema_label->set_h_grow_direction(GROW_DIRECTION_END);
|
cinema_label->set_h_grow_direction(GROW_DIRECTION_END);
|
||||||
|
|
|
@ -204,6 +204,7 @@ class SpatialEditorViewport : public Control {
|
||||||
VIEW_AUDIO_DOPPLER,
|
VIEW_AUDIO_DOPPLER,
|
||||||
VIEW_GIZMOS,
|
VIEW_GIZMOS,
|
||||||
VIEW_INFORMATION,
|
VIEW_INFORMATION,
|
||||||
|
VIEW_SELECTED_INFO,
|
||||||
VIEW_FPS,
|
VIEW_FPS,
|
||||||
VIEW_DISPLAY_NORMAL,
|
VIEW_DISPLAY_NORMAL,
|
||||||
VIEW_DISPLAY_WIREFRAME,
|
VIEW_DISPLAY_WIREFRAME,
|
||||||
|
@ -283,6 +284,7 @@ private:
|
||||||
Vector2 previous_mouse_position;
|
Vector2 previous_mouse_position;
|
||||||
|
|
||||||
Label *info_label;
|
Label *info_label;
|
||||||
|
Label *selected_info_label;
|
||||||
Label *cinema_label;
|
Label *cinema_label;
|
||||||
Label *locked_label;
|
Label *locked_label;
|
||||||
Label *zoom_limit_label;
|
Label *zoom_limit_label;
|
||||||
|
|
|
@ -42,6 +42,52 @@
|
||||||
|
|
||||||
Mesh::ConvexDecompositionFunc Mesh::convex_decomposition_function = nullptr;
|
Mesh::ConvexDecompositionFunc Mesh::convex_decomposition_function = nullptr;
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
const Mesh::CachedStats &Mesh::get_cached_stats() const {
|
||||||
|
if (_cached_stats.dirty) {
|
||||||
|
_cached_stats.dirty = false;
|
||||||
|
|
||||||
|
_cached_stats.triangle_count = get_triangle_count();
|
||||||
|
|
||||||
|
// Vertex count.
|
||||||
|
_cached_stats.vertex_count = 0;
|
||||||
|
for (int i = 0; i < get_surface_count(); i++) {
|
||||||
|
_cached_stats.vertex_count += surface_get_array_len(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Index count.
|
||||||
|
_cached_stats.index_count = 0;
|
||||||
|
for (int i = 0; i < get_surface_count(); i++) {
|
||||||
|
_cached_stats.index_count += surface_get_index_count(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Array format.
|
||||||
|
_cached_stats.array_format = 0;
|
||||||
|
for (int i = 0; i < get_surface_count(); i++) {
|
||||||
|
_cached_stats.array_format |= surface_get_format(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _cached_stats;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int Mesh::surface_get_index_count(int p_idx) const {
|
||||||
|
ERR_FAIL_INDEX_V(p_idx, get_surface_count(), 0);
|
||||||
|
|
||||||
|
switch (surface_get_primitive_type(p_idx)) {
|
||||||
|
case PRIMITIVE_TRIANGLES:
|
||||||
|
case PRIMITIVE_TRIANGLE_FAN:
|
||||||
|
case PRIMITIVE_TRIANGLE_STRIP: {
|
||||||
|
return (surface_get_format(p_idx) & ARRAY_FORMAT_INDEX) ? surface_get_array_index_len(p_idx) : surface_get_array_len(p_idx);
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int Mesh::surface_get_triangle_count(int p_idx) const {
|
int Mesh::surface_get_triangle_count(int p_idx) const {
|
||||||
ERR_FAIL_INDEX_V(p_idx, get_surface_count(), 0);
|
ERR_FAIL_INDEX_V(p_idx, get_surface_count(), 0);
|
||||||
|
|
||||||
|
@ -625,6 +671,9 @@ void Mesh::set_storage_mode(StorageMode p_storage_mode) {
|
||||||
void Mesh::clear_cache() const {
|
void Mesh::clear_cache() const {
|
||||||
triangle_mesh.unref();
|
triangle_mesh.unref();
|
||||||
debug_lines.clear();
|
debug_lines.clear();
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
_cached_stats.dirty = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<Ref<Shape>> Mesh::convex_decompose(int p_max_convex_hulls) const {
|
Vector<Ref<Shape>> Mesh::convex_decompose(int p_max_convex_hulls) const {
|
||||||
|
|
|
@ -126,6 +126,14 @@ public:
|
||||||
STORAGE_MODE_CPU_AND_GPU,
|
STORAGE_MODE_CPU_AND_GPU,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CachedStats {
|
||||||
|
bool dirty = true;
|
||||||
|
uint32_t triangle_count = 0;
|
||||||
|
uint32_t vertex_count = 0;
|
||||||
|
uint32_t index_count = 0;
|
||||||
|
uint32_t array_format = 0;
|
||||||
|
};
|
||||||
|
|
||||||
virtual int get_surface_count() const = 0;
|
virtual int get_surface_count() const = 0;
|
||||||
virtual int surface_get_array_len(int p_idx) const = 0;
|
virtual int surface_get_array_len(int p_idx) const = 0;
|
||||||
virtual int surface_get_array_index_len(int p_idx) const = 0;
|
virtual int surface_get_array_index_len(int p_idx) const = 0;
|
||||||
|
@ -138,11 +146,15 @@ public:
|
||||||
virtual Ref<Material> surface_get_material(int p_idx) const = 0;
|
virtual Ref<Material> surface_get_material(int p_idx) const = 0;
|
||||||
virtual int get_blend_shape_count() const = 0;
|
virtual int get_blend_shape_count() const = 0;
|
||||||
int surface_get_triangle_count(int p_idx) const;
|
int surface_get_triangle_count(int p_idx) const;
|
||||||
|
int surface_get_index_count(int p_idx) const;
|
||||||
virtual StringName get_blend_shape_name(int p_index) const = 0;
|
virtual StringName get_blend_shape_name(int p_index) const = 0;
|
||||||
virtual void set_blend_shape_name(int p_index, const StringName &p_name) = 0;
|
virtual void set_blend_shape_name(int p_index, const StringName &p_name) = 0;
|
||||||
|
|
||||||
int get_triangle_count() const;
|
int get_triangle_count() const;
|
||||||
PoolVector<Face3> get_faces() const;
|
PoolVector<Face3> get_faces() const;
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
const CachedStats &get_cached_stats() const;
|
||||||
|
#endif
|
||||||
Ref<TriangleMesh> generate_triangle_mesh() const;
|
Ref<TriangleMesh> generate_triangle_mesh() const;
|
||||||
Ref<TriangleMesh> generate_triangle_mesh_from_aabb() const;
|
Ref<TriangleMesh> generate_triangle_mesh_from_aabb() const;
|
||||||
void generate_debug_mesh_lines(Vector<Vector3> &r_lines);
|
void generate_debug_mesh_lines(Vector<Vector3> &r_lines);
|
||||||
|
@ -167,6 +179,13 @@ public:
|
||||||
Vector<Ref<Shape>> convex_decompose(int p_max_convex_hulls = -1) const;
|
Vector<Ref<Shape>> convex_decompose(int p_max_convex_hulls = -1) const;
|
||||||
|
|
||||||
Mesh();
|
Mesh();
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
// Only for use in the editor.
|
||||||
|
// No need to bloat exports.
|
||||||
|
mutable CachedStats _cached_stats;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArrayMesh : public Mesh {
|
class ArrayMesh : public Mesh {
|
||||||
|
|
Loading…
Reference in a new issue