Show visual-oriented 3D node gizmos only when selected
Affected nodes: - DirectionalLight3D, OmniLight3D, SpotLight3D - ReflectionProbe - LightmapGI - VoxelGI - GPUParticles3D (but not collision/attractor nodes) - AudioStreamPlayer3D This reduces visual clutter in the editor with 3D scenes.
This commit is contained in:
parent
b467afe65d
commit
1024ba0c0d
|
@ -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();
|
||||
|
||||
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->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));
|
||||
|
||||
Vector<Vector3> points_primary;
|
||||
points_primary.resize(200);
|
||||
|
||||
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;
|
||||
|
||||
const Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
|
||||
const Vector3 to(Math::sin(an) * radius, Math::cos(an) * radius, ofs);
|
||||
|
||||
points_primary.write[i * 2 + 0] = from;
|
||||
points_primary.write[i * 2 + 1] = to;
|
||||
}
|
||||
|
||||
const Ref<Material> material_primary = get_material("stream_player_3d_material_primary", p_gizmo);
|
||||
p_gizmo->add_lines(points_primary, material_primary);
|
||||
|
||||
Vector<Vector3> points_secondary;
|
||||
points_secondary.resize(16);
|
||||
|
||||
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);
|
||||
|
||||
points_secondary.write[i * 2 + 0] = from;
|
||||
points_secondary.write[i * 2 + 1] = Vector3();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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->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));
|
||||
|
||||
Vector<Vector3> points_primary;
|
||||
points_primary.resize(200);
|
||||
|
||||
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;
|
||||
|
||||
const Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
|
||||
const Vector3 to(Math::sin(an) * radius, Math::cos(an) * radius, ofs);
|
||||
|
||||
points_primary.write[i * 2 + 0] = from;
|
||||
points_primary.write[i * 2 + 1] = to;
|
||||
}
|
||||
|
||||
const Ref<Material> material_primary = get_material("stream_player_3d_material_primary", p_gizmo);
|
||||
p_gizmo->add_lines(points_primary, material_primary);
|
||||
|
||||
Vector<Vector3> points_secondary;
|
||||
points_secondary.resize(16);
|
||||
|
||||
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);
|
||||
|
||||
points_secondary.write[i * 2 + 0] = from;
|
||||
points_secondary.write[i * 2 + 1] = Vector3();
|
||||
}
|
||||
|
||||
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"));
|
||||
}
|
||||
|
||||
p_gizmo->add_unscaled_billboard(icon, 0.05);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
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> handles;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Ref<Material> material = get_material("particles_material", p_gizmo);
|
||||
Ref<Material> icon = get_material("particles_icon", p_gizmo);
|
||||
|
||||
p_gizmo->add_lines(lines, material);
|
||||
|
||||
if (p_gizmo->is_selected()) {
|
||||
GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_node_3d());
|
||||
|
||||
Vector<Vector3> lines;
|
||||
AABB aabb = particles->get_visibility_aabb();
|
||||
|
||||
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> handles;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Ref<Material> material = get_material("particles_material", p_gizmo);
|
||||
|
||||
p_gizmo->add_lines(lines, material);
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -158,124 +158,133 @@ void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
|
|||
p_gizmo->clear();
|
||||
|
||||
if (Object::cast_to<DirectionalLight3D>(light)) {
|
||||
Ref<Material> material = get_material("lines_primary", p_gizmo);
|
||||
Ref<Material> icon = get_material("light_directional_icon", p_gizmo);
|
||||
if (p_gizmo->is_selected()) {
|
||||
Ref<Material> material = get_material("lines_primary", p_gizmo);
|
||||
|
||||
const int arrow_points = 7;
|
||||
const float arrow_length = 1.5;
|
||||
const int arrow_points = 7;
|
||||
const float arrow_length = 1.5;
|
||||
|
||||
Vector3 arrow[arrow_points] = {
|
||||
Vector3(0, 0, -1),
|
||||
Vector3(0, 0.8, 0),
|
||||
Vector3(0, 0.3, 0),
|
||||
Vector3(0, 0.3, arrow_length),
|
||||
Vector3(0, -0.3, arrow_length),
|
||||
Vector3(0, -0.3, 0),
|
||||
Vector3(0, -0.8, 0)
|
||||
};
|
||||
Vector3 arrow[arrow_points] = {
|
||||
Vector3(0, 0, -1),
|
||||
Vector3(0, 0.8, 0),
|
||||
Vector3(0, 0.3, 0),
|
||||
Vector3(0, 0.3, arrow_length),
|
||||
Vector3(0, -0.3, arrow_length),
|
||||
Vector3(0, -0.3, 0),
|
||||
Vector3(0, -0.8, 0)
|
||||
};
|
||||
|
||||
int arrow_sides = 2;
|
||||
int arrow_sides = 2;
|
||||
|
||||
Vector<Vector3> lines;
|
||||
Vector<Vector3> lines;
|
||||
|
||||
for (int i = 0; i < arrow_sides; i++) {
|
||||
for (int j = 0; j < arrow_points; j++) {
|
||||
Basis ma(Vector3(0, 0, 1), Math_PI * i / arrow_sides);
|
||||
for (int i = 0; i < arrow_sides; i++) {
|
||||
for (int j = 0; j < arrow_points; j++) {
|
||||
Basis ma(Vector3(0, 0, 1), Math_PI * i / arrow_sides);
|
||||
|
||||
Vector3 v1 = arrow[j] - Vector3(0, 0, arrow_length);
|
||||
Vector3 v2 = arrow[(j + 1) % arrow_points] - Vector3(0, 0, arrow_length);
|
||||
Vector3 v1 = arrow[j] - Vector3(0, 0, arrow_length);
|
||||
Vector3 v2 = arrow[(j + 1) % arrow_points] - Vector3(0, 0, arrow_length);
|
||||
|
||||
lines.push_back(ma.xform(v1));
|
||||
lines.push_back(ma.xform(v2));
|
||||
lines.push_back(ma.xform(v1));
|
||||
lines.push_back(ma.xform(v2));
|
||||
}
|
||||
}
|
||||
|
||||
p_gizmo->add_lines(lines, material, false, color);
|
||||
}
|
||||
|
||||
p_gizmo->add_lines(lines, material, false, color);
|
||||
Ref<Material> icon = get_material("light_directional_icon", p_gizmo);
|
||||
p_gizmo->add_unscaled_billboard(icon, 0.05, color);
|
||||
}
|
||||
|
||||
if (Object::cast_to<OmniLight3D>(light)) {
|
||||
// Use both a billboard circle and 3 non-billboard circles for a better sphere-like representation
|
||||
const Ref<Material> lines_material = get_material("lines_secondary", p_gizmo);
|
||||
const Ref<Material> lines_billboard_material = get_material("lines_billboard", p_gizmo);
|
||||
const Ref<Material> icon = get_material("light_omni_icon", p_gizmo);
|
||||
if (p_gizmo->is_selected()) {
|
||||
// Use both a billboard circle and 3 non-billboard circles for a better sphere-like representation
|
||||
const Ref<Material> lines_material = get_material("lines_secondary", p_gizmo);
|
||||
const Ref<Material> lines_billboard_material = get_material("lines_billboard", p_gizmo);
|
||||
|
||||
OmniLight3D *on = Object::cast_to<OmniLight3D>(light);
|
||||
const float r = on->get_param(Light3D::PARAM_RANGE);
|
||||
Vector<Vector3> points;
|
||||
Vector<Vector3> points_billboard;
|
||||
OmniLight3D *on = Object::cast_to<OmniLight3D>(light);
|
||||
const float r = on->get_param(Light3D::PARAM_RANGE);
|
||||
Vector<Vector3> points;
|
||||
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;
|
||||
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 axis-aligned circles
|
||||
points.push_back(Vector3(a.x, 0, a.y));
|
||||
points.push_back(Vector3(b.x, 0, b.y));
|
||||
points.push_back(Vector3(0, a.x, a.y));
|
||||
points.push_back(Vector3(0, b.x, b.y));
|
||||
points.push_back(Vector3(a.x, a.y, 0));
|
||||
points.push_back(Vector3(b.x, b.y, 0));
|
||||
// Draw axis-aligned circles
|
||||
points.push_back(Vector3(a.x, 0, a.y));
|
||||
points.push_back(Vector3(b.x, 0, b.y));
|
||||
points.push_back(Vector3(0, a.x, a.y));
|
||||
points.push_back(Vector3(0, b.x, b.y));
|
||||
points.push_back(Vector3(a.x, a.y, 0));
|
||||
points.push_back(Vector3(b.x, b.y, 0));
|
||||
|
||||
// Draw a billboarded circle
|
||||
points_billboard.push_back(Vector3(a.x, a.y, 0));
|
||||
points_billboard.push_back(Vector3(b.x, b.y, 0));
|
||||
// Draw a billboarded circle
|
||||
points_billboard.push_back(Vector3(a.x, a.y, 0));
|
||||
points_billboard.push_back(Vector3(b.x, b.y, 0));
|
||||
}
|
||||
|
||||
p_gizmo->add_lines(points, lines_material, true, color);
|
||||
p_gizmo->add_lines(points_billboard, lines_billboard_material, true, color);
|
||||
|
||||
Vector<Vector3> handles;
|
||||
handles.push_back(Vector3(r, 0, 0));
|
||||
p_gizmo->add_handles(handles, get_material("handles_billboard"), Vector<int>(), true);
|
||||
}
|
||||
|
||||
p_gizmo->add_lines(points, lines_material, true, color);
|
||||
p_gizmo->add_lines(points_billboard, lines_billboard_material, true, color);
|
||||
const Ref<Material> icon = get_material("light_omni_icon", p_gizmo);
|
||||
p_gizmo->add_unscaled_billboard(icon, 0.05, color);
|
||||
|
||||
Vector<Vector3> handles;
|
||||
handles.push_back(Vector3(r, 0, 0));
|
||||
p_gizmo->add_handles(handles, get_material("handles_billboard"), Vector<int>(), true);
|
||||
}
|
||||
|
||||
if (Object::cast_to<SpotLight3D>(light)) {
|
||||
const Ref<Material> material_primary = get_material("lines_primary", p_gizmo);
|
||||
const Ref<Material> material_secondary = get_material("lines_secondary", p_gizmo);
|
||||
const Ref<Material> icon = get_material("light_spot_icon", p_gizmo);
|
||||
if (p_gizmo->is_selected()) {
|
||||
const Ref<Material> material_primary = get_material("lines_primary", p_gizmo);
|
||||
const Ref<Material> material_secondary = get_material("lines_secondary", p_gizmo);
|
||||
|
||||
Vector<Vector3> points_primary;
|
||||
Vector<Vector3> points_secondary;
|
||||
SpotLight3D *sl = Object::cast_to<SpotLight3D>(light);
|
||||
Vector<Vector3> points_primary;
|
||||
Vector<Vector3> points_secondary;
|
||||
SpotLight3D *sl = Object::cast_to<SpotLight3D>(light);
|
||||
|
||||
float r = sl->get_param(Light3D::PARAM_RANGE);
|
||||
float w = r * Math::sin(Math::deg_to_rad(sl->get_param(Light3D::PARAM_SPOT_ANGLE)));
|
||||
float d = r * Math::cos(Math::deg_to_rad(sl->get_param(Light3D::PARAM_SPOT_ANGLE)));
|
||||
float r = sl->get_param(Light3D::PARAM_RANGE);
|
||||
float w = r * Math::sin(Math::deg_to_rad(sl->get_param(Light3D::PARAM_SPOT_ANGLE)));
|
||||
float d = r * Math::cos(Math::deg_to_rad(sl->get_param(Light3D::PARAM_SPOT_ANGLE)));
|
||||
|
||||
for (int i = 0; i < 120; i++) {
|
||||
// Draw 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)) * w;
|
||||
const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w;
|
||||
for (int i = 0; i < 120; i++) {
|
||||
// Draw 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)) * w;
|
||||
const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w;
|
||||
|
||||
points_primary.push_back(Vector3(a.x, a.y, -d));
|
||||
points_primary.push_back(Vector3(b.x, b.y, -d));
|
||||
points_primary.push_back(Vector3(a.x, a.y, -d));
|
||||
points_primary.push_back(Vector3(b.x, b.y, -d));
|
||||
|
||||
if (i % 15 == 0) {
|
||||
// Draw 8 lines from the cone origin to the sides of the circle
|
||||
points_secondary.push_back(Vector3(a.x, a.y, -d));
|
||||
points_secondary.push_back(Vector3());
|
||||
if (i % 15 == 0) {
|
||||
// Draw 8 lines from the cone origin to the sides of the circle
|
||||
points_secondary.push_back(Vector3(a.x, a.y, -d));
|
||||
points_secondary.push_back(Vector3());
|
||||
}
|
||||
}
|
||||
|
||||
points_primary.push_back(Vector3(0, 0, -r));
|
||||
points_primary.push_back(Vector3());
|
||||
|
||||
p_gizmo->add_lines(points_primary, material_primary, false, color);
|
||||
p_gizmo->add_lines(points_secondary, material_secondary, false, color);
|
||||
|
||||
Vector<Vector3> handles = {
|
||||
Vector3(0, 0, -r),
|
||||
Vector3(w, 0, -d)
|
||||
};
|
||||
|
||||
p_gizmo->add_handles(handles, get_material("handles"));
|
||||
}
|
||||
|
||||
points_primary.push_back(Vector3(0, 0, -r));
|
||||
points_primary.push_back(Vector3());
|
||||
|
||||
p_gizmo->add_lines(points_primary, material_primary, false, color);
|
||||
p_gizmo->add_lines(points_secondary, material_secondary, false, color);
|
||||
|
||||
Vector<Vector3> handles = {
|
||||
Vector3(0, 0, -r),
|
||||
Vector3(w, 0, -d)
|
||||
};
|
||||
|
||||
p_gizmo->add_handles(handles, get_material("handles"));
|
||||
const Ref<Material> icon = get_material("light_spot_icon", p_gizmo);
|
||||
p_gizmo->add_unscaled_billboard(icon, 0.05, color);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,17 +68,17 @@ void LightmapGIGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
|
|||
LightmapGI *baker = Object::cast_to<LightmapGI>(p_gizmo->get_node_3d());
|
||||
Ref<LightmapGIData> data = baker->get_light_data();
|
||||
|
||||
p_gizmo->clear();
|
||||
|
||||
p_gizmo->add_unscaled_billboard(icon, 0.05);
|
||||
|
||||
if (data.is_null()) {
|
||||
if (data.is_null() || !p_gizmo->is_selected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<Material> material_lines = get_material("lightmap_lines", p_gizmo);
|
||||
Ref<Material> material_probes = get_material("lightmap_probe_material", p_gizmo);
|
||||
|
||||
p_gizmo->clear();
|
||||
|
||||
Vector<Vector3> lines;
|
||||
HashSet<Vector2i> lines_found;
|
||||
|
||||
|
|
|
@ -151,55 +151,57 @@ void ReflectionProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo,
|
|||
}
|
||||
|
||||
void ReflectionProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
|
||||
ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_node_3d());
|
||||
|
||||
p_gizmo->clear();
|
||||
|
||||
Vector<Vector3> lines;
|
||||
Vector<Vector3> internal_lines;
|
||||
Vector3 size = probe->get_size();
|
||||
|
||||
AABB aabb;
|
||||
aabb.position = -size / 2;
|
||||
aabb.size = size;
|
||||
|
||||
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 < 8; i++) {
|
||||
Vector3 ep = aabb.get_endpoint(i);
|
||||
internal_lines.push_back(probe->get_origin_offset());
|
||||
internal_lines.push_back(ep);
|
||||
}
|
||||
|
||||
Vector<Vector3> handles = helper->box_get_handles(probe->get_size());
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Vector3 orig_handle = probe->get_origin_offset();
|
||||
orig_handle[i] -= 0.25;
|
||||
lines.push_back(orig_handle);
|
||||
handles.push_back(orig_handle);
|
||||
|
||||
orig_handle[i] += 0.5;
|
||||
lines.push_back(orig_handle);
|
||||
}
|
||||
|
||||
Ref<Material> material = get_material("reflection_probe_material", p_gizmo);
|
||||
Ref<Material> material_internal = get_material("reflection_internal_material", p_gizmo);
|
||||
Ref<Material> icon = get_material("reflection_probe_icon", p_gizmo);
|
||||
|
||||
p_gizmo->add_lines(lines, material);
|
||||
p_gizmo->add_lines(internal_lines, material_internal);
|
||||
|
||||
if (p_gizmo->is_selected()) {
|
||||
Ref<Material> solid_material = get_material("reflection_probe_solid_material", p_gizmo);
|
||||
p_gizmo->add_solid_box(solid_material, probe->get_size());
|
||||
ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_node_3d());
|
||||
Vector<Vector3> lines;
|
||||
Vector<Vector3> internal_lines;
|
||||
Vector3 size = probe->get_size();
|
||||
|
||||
AABB aabb;
|
||||
aabb.position = -size / 2;
|
||||
aabb.size = size;
|
||||
|
||||
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 < 8; i++) {
|
||||
Vector3 ep = aabb.get_endpoint(i);
|
||||
internal_lines.push_back(probe->get_origin_offset());
|
||||
internal_lines.push_back(ep);
|
||||
}
|
||||
|
||||
Vector<Vector3> handles = helper->box_get_handles(probe->get_size());
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Vector3 orig_handle = probe->get_origin_offset();
|
||||
orig_handle[i] -= 0.25;
|
||||
lines.push_back(orig_handle);
|
||||
handles.push_back(orig_handle);
|
||||
|
||||
orig_handle[i] += 0.5;
|
||||
lines.push_back(orig_handle);
|
||||
}
|
||||
|
||||
Ref<Material> material = get_material("reflection_probe_material", p_gizmo);
|
||||
Ref<Material> material_internal = get_material("reflection_internal_material", p_gizmo);
|
||||
|
||||
p_gizmo->add_lines(lines, material);
|
||||
p_gizmo->add_lines(internal_lines, material_internal);
|
||||
|
||||
if (p_gizmo->is_selected()) {
|
||||
Ref<Material> solid_material = get_material("reflection_probe_solid_material", p_gizmo);
|
||||
p_gizmo->add_solid_box(solid_material, probe->get_size());
|
||||
}
|
||||
|
||||
p_gizmo->add_handles(handles, get_material("handles"));
|
||||
}
|
||||
|
||||
Ref<Material> icon = get_material("reflection_probe_icon", p_gizmo);
|
||||
p_gizmo->add_unscaled_billboard(icon, 0.05);
|
||||
p_gizmo->add_handles(handles, get_material("handles"));
|
||||
}
|
||||
|
|
|
@ -100,74 +100,76 @@ void VoxelGIGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_i
|
|||
}
|
||||
|
||||
void VoxelGIGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
|
||||
VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_node_3d());
|
||||
|
||||
Ref<Material> material = get_material("voxel_gi_material", p_gizmo);
|
||||
Ref<Material> icon = get_material("voxel_gi_icon", p_gizmo);
|
||||
Ref<Material> material_internal = get_material("voxel_gi_internal_material", p_gizmo);
|
||||
|
||||
p_gizmo->clear();
|
||||
|
||||
Vector<Vector3> lines;
|
||||
Vector3 size = probe->get_size();
|
||||
if (p_gizmo->is_selected()) {
|
||||
VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_node_3d());
|
||||
Ref<Material> material = get_material("voxel_gi_material", p_gizmo);
|
||||
Ref<Material> material_internal = get_material("voxel_gi_internal_material", p_gizmo);
|
||||
|
||||
static const int subdivs[VoxelGI::SUBDIV_MAX] = { 64, 128, 256, 512 };
|
||||
Vector<Vector3> lines;
|
||||
Vector3 size = probe->get_size();
|
||||
|
||||
AABB aabb = AABB(-size / 2, size);
|
||||
int subdiv = subdivs[probe->get_subdiv()];
|
||||
float cell_size = aabb.get_longest_axis_size() / subdiv;
|
||||
static const int subdivs[VoxelGI::SUBDIV_MAX] = { 64, 128, 256, 512 };
|
||||
|
||||
for (int i = 0; i < 12; i++) {
|
||||
Vector3 a, b;
|
||||
aabb.get_edge(i, a, b);
|
||||
lines.push_back(a);
|
||||
lines.push_back(b);
|
||||
}
|
||||
AABB aabb = AABB(-size / 2, size);
|
||||
int subdiv = subdivs[probe->get_subdiv()];
|
||||
float cell_size = aabb.get_longest_axis_size() / subdiv;
|
||||
|
||||
p_gizmo->add_lines(lines, material);
|
||||
for (int i = 0; i < 12; i++) {
|
||||
Vector3 a, b;
|
||||
aabb.get_edge(i, a, b);
|
||||
lines.push_back(a);
|
||||
lines.push_back(b);
|
||||
}
|
||||
|
||||
lines.clear();
|
||||
p_gizmo->add_lines(lines, material);
|
||||
|
||||
for (int i = 1; i < subdiv; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if (cell_size * i > aabb.size[j]) {
|
||||
continue;
|
||||
}
|
||||
lines.clear();
|
||||
|
||||
int j_n1 = (j + 1) % 3;
|
||||
int j_n2 = (j + 2) % 3;
|
||||
|
||||
for (int k = 0; k < 4; k++) {
|
||||
Vector3 from = aabb.position, to = aabb.position;
|
||||
from[j] += cell_size * i;
|
||||
to[j] += cell_size * i;
|
||||
|
||||
if (k & 1) {
|
||||
to[j_n1] += aabb.size[j_n1];
|
||||
} else {
|
||||
to[j_n2] += aabb.size[j_n2];
|
||||
for (int i = 1; i < subdiv; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if (cell_size * i > aabb.size[j]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (k & 2) {
|
||||
from[j_n1] += aabb.size[j_n1];
|
||||
from[j_n2] += aabb.size[j_n2];
|
||||
}
|
||||
int j_n1 = (j + 1) % 3;
|
||||
int j_n2 = (j + 2) % 3;
|
||||
|
||||
lines.push_back(from);
|
||||
lines.push_back(to);
|
||||
for (int k = 0; k < 4; k++) {
|
||||
Vector3 from = aabb.position, to = aabb.position;
|
||||
from[j] += cell_size * i;
|
||||
to[j] += cell_size * i;
|
||||
|
||||
if (k & 1) {
|
||||
to[j_n1] += aabb.size[j_n1];
|
||||
} else {
|
||||
to[j_n2] += aabb.size[j_n2];
|
||||
}
|
||||
|
||||
if (k & 2) {
|
||||
from[j_n1] += aabb.size[j_n1];
|
||||
from[j_n2] += aabb.size[j_n2];
|
||||
}
|
||||
|
||||
lines.push_back(from);
|
||||
lines.push_back(to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p_gizmo->add_lines(lines, material_internal);
|
||||
|
||||
Vector<Vector3> handles = helper->box_get_handles(probe->get_size());
|
||||
|
||||
if (p_gizmo->is_selected()) {
|
||||
Ref<Material> solid_material = get_material("voxel_gi_solid_material", p_gizmo);
|
||||
p_gizmo->add_solid_box(solid_material, aabb.get_size());
|
||||
}
|
||||
|
||||
p_gizmo->add_handles(handles, get_material("handles"));
|
||||
}
|
||||
|
||||
p_gizmo->add_lines(lines, material_internal);
|
||||
|
||||
Vector<Vector3> handles = helper->box_get_handles(probe->get_size());
|
||||
|
||||
if (p_gizmo->is_selected()) {
|
||||
Ref<Material> solid_material = get_material("voxel_gi_solid_material", p_gizmo);
|
||||
p_gizmo->add_solid_box(solid_material, aabb.get_size());
|
||||
}
|
||||
|
||||
Ref<Material> icon = get_material("voxel_gi_icon", p_gizmo);
|
||||
p_gizmo->add_unscaled_billboard(icon, 0.05);
|
||||
p_gizmo->add_handles(handles, get_material("handles"));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue