Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show visual-oriented 3D node gizmos only when selected #75303

Merged
merged 1 commit into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
229 changes: 115 additions & 114 deletions editor/plugins/gizmos/audio_stream_player_3d_gizmo_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,136 +121,137 @@ void AudioStreamPlayer3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gi
}

void AudioStreamPlayer3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
const AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_node_3d());

p_gizmo->clear();

const Ref<Material> icon = get_material("stream_player_3d_icon", p_gizmo);

if (player->get_attenuation_model() != AudioStreamPlayer3D::ATTENUATION_DISABLED || player->get_max_distance() > CMP_EPSILON) {
// Draw a circle to represent sound volume attenuation.
// Use only a billboard circle to represent radius.
// This helps distinguish AudioStreamPlayer3D gizmos from OmniLight3D gizmos.
const Ref<Material> lines_billboard_material = get_material("stream_player_3d_material_billboard", p_gizmo);

// Soft distance cap varies depending on attenuation model, as some will fade out more aggressively than others.
// Multipliers were empirically determined through testing.
float soft_multiplier;
switch (player->get_attenuation_model()) {
case AudioStreamPlayer3D::ATTENUATION_INVERSE_DISTANCE:
soft_multiplier = 12.0;
break;
case AudioStreamPlayer3D::ATTENUATION_INVERSE_SQUARE_DISTANCE:
soft_multiplier = 4.0;
break;
case AudioStreamPlayer3D::ATTENUATION_LOGARITHMIC:
soft_multiplier = 3.25;
break;
default:
// Ensures Max Distance's radius visualization is not capped by Unit Size
// (when the attenuation mode is Disabled).
soft_multiplier = 10000.0;
break;
}

// Draw the distance at which the sound can be reasonably heard.
// This can be either a hard distance cap with the Max Distance property (if set above 0.0),
// or a soft distance cap with the Unit Size property (sound never reaches true zero).
// When Max Distance is 0.0, `r` represents the distance above which the
// sound can't be heard in *most* (but not all) scenarios.
float r;
if (player->get_max_distance() > CMP_EPSILON) {
r = MIN(player->get_unit_size() * soft_multiplier, player->get_max_distance());
} else {
r = player->get_unit_size() * soft_multiplier;
}
Vector<Vector3> points_billboard;

for (int i = 0; i < 120; i++) {
// Create a circle.
const float ra = Math::deg_to_rad((float)(i * 3));
const float rb = Math::deg_to_rad((float)((i + 1) * 3));
const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r;

// Draw a billboarded circle.
points_billboard.push_back(Vector3(a.x, a.y, 0));
points_billboard.push_back(Vector3(b.x, b.y, 0));
}

Color color;
switch (player->get_attenuation_model()) {
// Pick cold colors for all attenuation models (except Disabled),
// so that soft caps can be easily distinguished from hard caps
// (which use warm colors).
case AudioStreamPlayer3D::ATTENUATION_INVERSE_DISTANCE:
color = Color(0.4, 0.8, 1);
break;
case AudioStreamPlayer3D::ATTENUATION_INVERSE_SQUARE_DISTANCE:
color = Color(0.4, 0.5, 1);
break;
case AudioStreamPlayer3D::ATTENUATION_LOGARITHMIC:
color = Color(0.4, 0.2, 1);
break;
default:
// Disabled attenuation mode.
// This is never reached when Max Distance is 0, but the
// hue-inverted form of this color will be used if Max Distance is greater than 0.
color = Color(1, 1, 1);
break;
if (p_gizmo->is_selected()) {
const AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_node_3d());

if (player->get_attenuation_model() != AudioStreamPlayer3D::ATTENUATION_DISABLED || player->get_max_distance() > CMP_EPSILON) {
// Draw a circle to represent sound volume attenuation.
// Use only a billboard circle to represent radius.
// This helps distinguish AudioStreamPlayer3D gizmos from OmniLight3D gizmos.
const Ref<Material> lines_billboard_material = get_material("stream_player_3d_material_billboard", p_gizmo);

// Soft distance cap varies depending on attenuation model, as some will fade out more aggressively than others.
// Multipliers were empirically determined through testing.
float soft_multiplier;
switch (player->get_attenuation_model()) {
case AudioStreamPlayer3D::ATTENUATION_INVERSE_DISTANCE:
soft_multiplier = 12.0;
break;
case AudioStreamPlayer3D::ATTENUATION_INVERSE_SQUARE_DISTANCE:
soft_multiplier = 4.0;
break;
case AudioStreamPlayer3D::ATTENUATION_LOGARITHMIC:
soft_multiplier = 3.25;
break;
default:
// Ensures Max Distance's radius visualization is not capped by Unit Size
// (when the attenuation mode is Disabled).
soft_multiplier = 10000.0;
break;
}

// Draw the distance at which the sound can be reasonably heard.
// This can be either a hard distance cap with the Max Distance property (if set above 0.0),
// or a soft distance cap with the Unit Size property (sound never reaches true zero).
// When Max Distance is 0.0, `r` represents the distance above which the
// sound can't be heard in *most* (but not all) scenarios.
float r;
if (player->get_max_distance() > CMP_EPSILON) {
r = MIN(player->get_unit_size() * soft_multiplier, player->get_max_distance());
} else {
r = player->get_unit_size() * soft_multiplier;
}
Vector<Vector3> points_billboard;

for (int i = 0; i < 120; i++) {
// Create a circle.
const float ra = Math::deg_to_rad((float)(i * 3));
const float rb = Math::deg_to_rad((float)((i + 1) * 3));
const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r;

// Draw a billboarded circle.
points_billboard.push_back(Vector3(a.x, a.y, 0));
points_billboard.push_back(Vector3(b.x, b.y, 0));
}

Color color;
switch (player->get_attenuation_model()) {
// Pick cold colors for all attenuation models (except Disabled),
// so that soft caps can be easily distinguished from hard caps
// (which use warm colors).
case AudioStreamPlayer3D::ATTENUATION_INVERSE_DISTANCE:
color = Color(0.4, 0.8, 1);
break;
case AudioStreamPlayer3D::ATTENUATION_INVERSE_SQUARE_DISTANCE:
color = Color(0.4, 0.5, 1);
break;
case AudioStreamPlayer3D::ATTENUATION_LOGARITHMIC:
color = Color(0.4, 0.2, 1);
break;
default:
// Disabled attenuation mode.
// This is never reached when Max Distance is 0, but the
// hue-inverted form of this color will be used if Max Distance is greater than 0.
color = Color(1, 1, 1);
break;
}

if (player->get_max_distance() > CMP_EPSILON) {
// Sound is hard-capped by max distance. The attenuation model still matters,
// so invert the hue of the color that was chosen above.
color.set_h(color.get_h() + 0.5);
}

p_gizmo->add_lines(points_billboard, lines_billboard_material, true, color);
}

if (player->get_max_distance() > CMP_EPSILON) {
// Sound is hard-capped by max distance. The attenuation model still matters,
// so invert the hue of the color that was chosen above.
color.set_h(color.get_h() + 0.5);
}
if (player->is_emission_angle_enabled()) {
const float pc = player->get_emission_angle();
const float ofs = -Math::cos(Math::deg_to_rad(pc));
const float radius = Math::sin(Math::deg_to_rad(pc));

p_gizmo->add_lines(points_billboard, lines_billboard_material, true, color);
}
Vector<Vector3> points_primary;
points_primary.resize(200);

if (player->is_emission_angle_enabled()) {
const float pc = player->get_emission_angle();
const float ofs = -Math::cos(Math::deg_to_rad(pc));
const float radius = Math::sin(Math::deg_to_rad(pc));
real_t step = Math_TAU / 100.0;
for (int i = 0; i < 100; i++) {
const float a = i * step;
const float an = (i + 1) * step;

Vector<Vector3> points_primary;
points_primary.resize(200);
const Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
const Vector3 to(Math::sin(an) * radius, Math::cos(an) * radius, ofs);

real_t step = Math_TAU / 100.0;
for (int i = 0; i < 100; i++) {
const float a = i * step;
const float an = (i + 1) * step;
points_primary.write[i * 2 + 0] = from;
points_primary.write[i * 2 + 1] = to;
}

const Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
const Vector3 to(Math::sin(an) * radius, Math::cos(an) * radius, ofs);
const Ref<Material> material_primary = get_material("stream_player_3d_material_primary", p_gizmo);
p_gizmo->add_lines(points_primary, material_primary);

points_primary.write[i * 2 + 0] = from;
points_primary.write[i * 2 + 1] = to;
}
Vector<Vector3> points_secondary;
points_secondary.resize(16);

const Ref<Material> material_primary = get_material("stream_player_3d_material_primary", p_gizmo);
p_gizmo->add_lines(points_primary, material_primary);
for (int i = 0; i < 8; i++) {
const float a = i * (Math_TAU / 8.0);
const Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);

Vector<Vector3> points_secondary;
points_secondary.resize(16);
points_secondary.write[i * 2 + 0] = from;
points_secondary.write[i * 2 + 1] = Vector3();
}

for (int i = 0; i < 8; i++) {
const float a = i * (Math_TAU / 8.0);
const Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
const Ref<Material> material_secondary = get_material("stream_player_3d_material_secondary", p_gizmo);
p_gizmo->add_lines(points_secondary, material_secondary);

points_secondary.write[i * 2 + 0] = from;
points_secondary.write[i * 2 + 1] = Vector3();
Vector<Vector3> handles;
const float ha = Math::deg_to_rad(player->get_emission_angle());
handles.push_back(Vector3(Math::sin(ha), 0, -Math::cos(ha)));
p_gizmo->add_handles(handles, get_material("handles"));
}

const Ref<Material> material_secondary = get_material("stream_player_3d_material_secondary", p_gizmo);
p_gizmo->add_lines(points_secondary, material_secondary);

Vector<Vector3> handles;
const float ha = Math::deg_to_rad(player->get_emission_angle());
handles.push_back(Vector3(Math::sin(ha), 0, -Math::cos(ha)));
p_gizmo->add_handles(handles, get_material("handles"));
}

const Ref<Material> icon = get_material("stream_player_3d_icon", p_gizmo);
p_gizmo->add_unscaled_billboard(icon, 0.05);
}
63 changes: 32 additions & 31 deletions editor/plugins/gizmos/gpu_particles_3d_gizmo_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,49 +151,50 @@ void GPUParticles3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo,
}

void GPUParticles3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_node_3d());

p_gizmo->clear();

Vector<Vector3> lines;
AABB aabb = particles->get_visibility_aabb();
if (p_gizmo->is_selected()) {
GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_node_3d());

for (int i = 0; i < 12; i++) {
Vector3 a, b;
aabb.get_edge(i, a, b);
lines.push_back(a);
lines.push_back(b);
}
Vector<Vector3> lines;
AABB aabb = particles->get_visibility_aabb();

Vector<Vector3> handles;
for (int i = 0; i < 12; i++) {
Vector3 a, b;
aabb.get_edge(i, a, b);
lines.push_back(a);
lines.push_back(b);
}

for (int i = 0; i < 3; i++) {
Vector3 ax;
ax[i] = aabb.position[i] + aabb.size[i];
ax[(i + 1) % 3] = aabb.position[(i + 1) % 3] + aabb.size[(i + 1) % 3] * 0.5;
ax[(i + 2) % 3] = aabb.position[(i + 2) % 3] + aabb.size[(i + 2) % 3] * 0.5;
handles.push_back(ax);
}
Vector<Vector3> handles;

Vector3 center = aabb.get_center();
for (int i = 0; i < 3; i++) {
Vector3 ax;
ax[i] = 1.0;
handles.push_back(center + ax);
lines.push_back(center);
lines.push_back(center + ax);
}
for (int i = 0; i < 3; i++) {
Vector3 ax;
ax[i] = aabb.position[i] + aabb.size[i];
ax[(i + 1) % 3] = aabb.position[(i + 1) % 3] + aabb.size[(i + 1) % 3] * 0.5;
ax[(i + 2) % 3] = aabb.position[(i + 2) % 3] + aabb.size[(i + 2) % 3] * 0.5;
handles.push_back(ax);
}

Ref<Material> material = get_material("particles_material", p_gizmo);
Ref<Material> icon = get_material("particles_icon", p_gizmo);
Vector3 center = aabb.get_center();
for (int i = 0; i < 3; i++) {
Vector3 ax;
ax[i] = 1.0;
handles.push_back(center + ax);
lines.push_back(center);
lines.push_back(center + ax);
}

p_gizmo->add_lines(lines, material);
Ref<Material> material = get_material("particles_material", p_gizmo);

p_gizmo->add_lines(lines, material);

if (p_gizmo->is_selected()) {
Ref<Material> solid_material = get_material("particles_solid_material", p_gizmo);
p_gizmo->add_solid_box(solid_material, aabb.get_size(), aabb.get_center());

p_gizmo->add_handles(handles, get_material("handles"));
}

p_gizmo->add_handles(handles, get_material("handles"));
Ref<Material> icon = get_material("particles_icon", p_gizmo);
p_gizmo->add_unscaled_billboard(icon, 0.05);
}
Loading
Loading