Browse Source

Depth-sort decals properly, add decal offset, and fix painting cursor position

master
C. J. Howard 4 years ago
parent
commit
12020be05a
7 changed files with 63 additions and 11 deletions
  1. +1
    -0
      src/game/components/tool-component.hpp
  2. +2
    -0
      src/game/events/tool-events.cpp
  3. +3
    -0
      src/game/events/tool-events.hpp
  4. +12
    -8
      src/game/systems/painting-system.cpp
  5. +1
    -0
      src/game/systems/painting-system.hpp
  6. +5
    -0
      src/game/systems/tool-system.cpp
  7. +39
    -3
      src/renderer/passes/material-pass.cpp

+ 1
- 0
src/game/components/tool-component.hpp View File

@ -28,6 +28,7 @@ struct tool_component
float idle_distance; float idle_distance;
float active_distance; float active_distance;
bool heliotropic; bool heliotropic;
float3 cursor;
//float activation_speed; //float activation_speed;
}; };

+ 2
- 0
src/game/events/tool-events.cpp View File

@ -23,6 +23,7 @@ event_base* tool_pressed_event::clone() const
{ {
tool_pressed_event* event = new tool_pressed_event(); tool_pressed_event* event = new tool_pressed_event();
event->entity = entity; event->entity = entity;
event->position = position;
return event; return event;
} }
@ -30,5 +31,6 @@ event_base* tool_released_event::clone() const
{ {
tool_released_event* event = new tool_released_event(); tool_released_event* event = new tool_released_event();
event->entity = entity; event->entity = entity;
event->position = position;
return event; return event;
} }

+ 3
- 0
src/game/events/tool-events.hpp View File

@ -21,6 +21,7 @@
#define ANTKEEPER_TOOL_EVENTS_HPP #define ANTKEEPER_TOOL_EVENTS_HPP
#include "event/event.hpp" #include "event/event.hpp"
#include "utility/fundamental-types.hpp"
#include <entt/entt.hpp> #include <entt/entt.hpp>
class tool_pressed_event: public event<tool_pressed_event> class tool_pressed_event: public event<tool_pressed_event>
@ -28,6 +29,7 @@ class tool_pressed_event: public event
public: public:
virtual event_base* clone() const; virtual event_base* clone() const;
entt::entity entity; entt::entity entity;
float3 position;
}; };
class tool_released_event: public event<tool_released_event> class tool_released_event: public event<tool_released_event>
@ -35,6 +37,7 @@ class tool_released_event: public event
public: public:
virtual event_base* clone() const; virtual event_base* clone() const;
entt::entity entity; entt::entity entity;
float3 position;
}; };
#endif // ANTKEEPER_TOOL_EVENTS_HPP #endif // ANTKEEPER_TOOL_EVENTS_HPP

+ 12
- 8
src/game/systems/painting-system.cpp View File

@ -20,6 +20,7 @@
#include "painting-system.hpp" #include "painting-system.hpp"
#include "game/components/transform-component.hpp" #include "game/components/transform-component.hpp"
#include "game/components/brush-component.hpp" #include "game/components/brush-component.hpp"
#include "game/components/tool-component.hpp"
#include "event/event-dispatcher.hpp" #include "event/event-dispatcher.hpp"
#include "resources/resource-manager.hpp" #include "resources/resource-manager.hpp"
#include "scene/scene.hpp" #include "scene/scene.hpp"
@ -49,6 +50,7 @@ painting_system::painting_system(entt::registry& registry, ::event_dispatcher* e
event_dispatcher->subscribe<tool_released_event>(this); event_dispatcher->subscribe<tool_released_event>(this);
max_miter_angle = math::radians(135.0f); max_miter_angle = math::radians(135.0f);
decal_offset = 0.01f;
stroke_width = 1.0f; stroke_width = 1.0f;
min_stroke_length = 1.0f; min_stroke_length = 1.0f;
min_stroke_length_squared = min_stroke_length * min_stroke_length; min_stroke_length_squared = min_stroke_length * min_stroke_length;
@ -93,7 +95,9 @@ void painting_system::update(double t, double dt)
{ {
if (painting) if (painting)
{ {
auto cast_result = cast_ray(ec::get_world_transform(registry, brush_entity).translation);
const tool_component& tool = registry.get<tool_component>(brush_entity);
auto cast_result = cast_ray(tool.cursor);
if (cast_result.has_value()) if (cast_result.has_value())
{ {
float3 p2 = float3 p2 =
@ -123,10 +127,10 @@ void painting_system::update(double t, double dt)
float3 a = p0a; float3 a = p0a;
float3 b = p0b; float3 b = p0b;
float3 c = p1 - segment_right * stroke_width * 0.5f;
float3 d = p1 + segment_right * stroke_width * 0.5f;
float3 e = p2 - segment_right * stroke_width * 0.5f;
float3 f = p2 + segment_right * stroke_width * 0.5f;
float3 c = p1 - segment_right * stroke_width * 0.5f + segment_up * decal_offset;
float3 d = p1 + segment_right * stroke_width * 0.5f + segment_up * decal_offset;
float3 e = p2 - segment_right * stroke_width * 0.5f + segment_up * decal_offset;
float3 f = p2 + segment_right * stroke_width * 0.5f + segment_up * decal_offset;
// Adjust c and d // Adjust c and d
bool mitered = false; bool mitered = false;
@ -136,8 +140,8 @@ void painting_system::update(double t, double dt)
if (angle < max_miter_angle) if (angle < max_miter_angle)
{ {
mitered = true; mitered = true;
c = p1 - float3{miter.x, 0.0f, miter.y} * miter_length * 0.5f;
d = p1 + float3{miter.x, 0.0f, miter.y} * miter_length * 0.5f;
c = p1 - float3{miter.x, 0.0f, miter.y} * miter_length * 0.5f + segment_up * decal_offset;
d = p1 + float3{miter.x, 0.0f, miter.y} * miter_length * 0.5f + segment_up * decal_offset;
} }
} }
@ -201,7 +205,7 @@ void painting_system::handle_event(const tool_pressed_event& event)
{ {
if (registry.has<brush_component>(event.entity)) if (registry.has<brush_component>(event.entity))
{ {
auto cast_result = cast_ray(ec::get_world_transform(registry, event.entity).translation);
auto cast_result = cast_ray(event.position);
if (cast_result.has_value()) if (cast_result.has_value())
{ {

+ 1
- 0
src/game/systems/painting-system.hpp View File

@ -67,6 +67,7 @@ private:
int max_stroke_segments; int max_stroke_segments;
int current_stroke_segment; int current_stroke_segment;
float max_miter_angle; float max_miter_angle;
float decal_offset;
float3 stroke_bounds_min; float3 stroke_bounds_min;
float3 stroke_bounds_max; float3 stroke_bounds_max;
float3 p0; float3 p0;

+ 5
- 0
src/game/systems/tool-system.cpp View File

@ -208,6 +208,9 @@ void tool_system::update(double t, double dt)
ec::assign_render_layers(registry, active_tool, 1); ec::assign_render_layers(registry, active_tool, 1);
warp = false; warp = false;
} }
// Update tool's cursor position
tool.cursor = pick_spring.x0;
//math::quaternion<float> rotation = math::angle_axis(orbit_cam->get_azimuth() + pick_angle, float3{0, 1, 0}); //math::quaternion<float> rotation = math::angle_axis(orbit_cam->get_azimuth() + pick_angle, float3{0, 1, 0});
//transform.transform.rotation = rotation; //transform.transform.rotation = rotation;
@ -296,6 +299,7 @@ void tool_system::set_tool_active(bool active)
// Queue tool pressed event // Queue tool pressed event
tool_pressed_event event; tool_pressed_event event;
event.entity = active_tool; event.entity = active_tool;
event.position = pick_spring.x0;
event_dispatcher->queue(event); event_dispatcher->queue(event);
} }
else else
@ -306,6 +310,7 @@ void tool_system::set_tool_active(bool active)
// Queue tool pressed event // Queue tool pressed event
tool_released_event event; tool_released_event event;
event.entity = active_tool; event.entity = active_tool;
event.position = pick_spring.x0;
event_dispatcher->queue(event); event_dispatcher->queue(event);
} }
} }

+ 39
- 3
src/renderer/passes/material-pass.cpp View File

@ -347,14 +347,22 @@ void material_pass::render(render_context* context) const
{ {
if (material_flags & MATERIAL_FLAG_DECAL) if (material_flags & MATERIAL_FLAG_DECAL)
{ {
glDisable(GL_DEPTH_TEST);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_FALSE);
glEnable(GL_STENCIL_TEST); glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_EQUAL, 1, ~0); glStencilFunc(GL_EQUAL, 1, ~0);
//glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);
//glStencilMask(~0);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glStencilMask(0); glStencilMask(0);
} }
else else
{ {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
glStencilMask(0); glStencilMask(0);
} }
@ -582,8 +590,36 @@ bool operation_compare(const render_operation& a, const render_operation& b)
{ {
if (transparent_b) if (transparent_b)
{ {
// A and B are both transparent, render back to front
return (a.depth >= b.depth);
// Determine decal status
bool decal_a = a.material->get_flags() & MATERIAL_FLAG_DECAL;
bool decal_b = b.material->get_flags() & MATERIAL_FLAG_DECAL;
if (decal_a)
{
if (decal_b)
{
// A and B are both transparent decals, render back to front
return (a.depth >= b.depth);
}
else
{
// A is a transparent decal, B is transparent but not a decal, render A first
return true;
}
}
else
{
if (decal_b)
{
// A is transparent but not a decal, B is a transparent decal, render B first
return false;
}
else
{
// A and B are both transparent, but not decals, render back to front
return (a.depth >= b.depth);
}
}
} }
else else
{ {

Loading…
Cancel
Save