GPv3: Add DrawingTransforms
This makes sure that when the object is transformed, the painting code will take that transformation into account. Resolves #113424. Pull Request: https://projects.blender.org/blender/blender/pulls/113442
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include "BLI_color.hh"
|
||||
#include "BLI_function_ref.hh"
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_math_matrix_types.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_shared_cache.hh"
|
||||
#include "BLI_utility_mixins.hh"
|
||||
@@ -34,6 +35,14 @@ namespace blender::bke {
|
||||
|
||||
namespace greasepencil {
|
||||
|
||||
struct DrawingTransforms {
|
||||
float4x4 world_space_to_layer_space;
|
||||
float4x4 layer_space_to_world_space;
|
||||
|
||||
DrawingTransforms() = default;
|
||||
DrawingTransforms(const Object &grease_pencil_ob);
|
||||
};
|
||||
|
||||
class DrawingRuntime {
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "DNA_grease_pencil_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "DEG_depsgraph.hh"
|
||||
#include "DEG_depsgraph_query.hh"
|
||||
@@ -224,6 +225,12 @@ IDTypeInfo IDType_ID_GP = {
|
||||
|
||||
namespace blender::bke::greasepencil {
|
||||
|
||||
DrawingTransforms::DrawingTransforms(const Object &grease_pencil_ob)
|
||||
{
|
||||
this->layer_space_to_world_space = float4x4_view(grease_pencil_ob.object_to_world);
|
||||
this->world_space_to_layer_space = math::invert(this->layer_space_to_world_space);
|
||||
}
|
||||
|
||||
static const std::string ATTR_RADIUS = "radius";
|
||||
static const std::string ATTR_OPACITY = "opacity";
|
||||
static const std::string ATTR_VERTEX_COLOR = "vertex_color";
|
||||
|
||||
@@ -119,6 +119,8 @@ struct PaintOperationExecutor {
|
||||
|
||||
bke::greasepencil::Drawing *drawing_;
|
||||
|
||||
bke::greasepencil::DrawingTransforms transforms_;
|
||||
|
||||
PaintOperationExecutor(const bContext &C)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(&C);
|
||||
@@ -155,16 +157,18 @@ struct PaintOperationExecutor {
|
||||
BLI_assert(drawing_index >= 0);
|
||||
drawing_ =
|
||||
&reinterpret_cast<GreasePencilDrawing *>(grease_pencil_->drawing(drawing_index))->wrap();
|
||||
|
||||
transforms_ = bke::greasepencil::DrawingTransforms(*object);
|
||||
}
|
||||
|
||||
float3 screen_space_to_object_space(const float2 co)
|
||||
float3 screen_space_to_drawing_plane(const float2 co)
|
||||
{
|
||||
/* TODO: Use correct plane/projection. */
|
||||
const float4 plane{0.0f, -1.0f, 0.0f, 0.0f};
|
||||
/* TODO: Use object transform. */
|
||||
float3 proj_point;
|
||||
ED_view3d_win_to_3d_on_plane(region_, plane, co, false, proj_point);
|
||||
return proj_point;
|
||||
ED_view3d_win_to_3d_on_plane(
|
||||
region_, transforms_.layer_space_to_world_space * plane, co, false, proj_point);
|
||||
return math::transform_point(transforms_.world_space_to_layer_space, proj_point);
|
||||
}
|
||||
|
||||
float radius_from_input_sample(const InputSample &sample)
|
||||
@@ -204,7 +208,7 @@ struct PaintOperationExecutor {
|
||||
curves.resize(curves.points_num() + 1, curves.curves_num() + 1);
|
||||
curves.offsets_for_write().last(1) = num_old_points;
|
||||
|
||||
curves.positions_for_write().last() = screen_space_to_object_space(start_coords);
|
||||
curves.positions_for_write().last() = screen_space_to_drawing_plane(start_coords);
|
||||
drawing_->radii_for_write().last() = start_radius;
|
||||
drawing_->opacities_for_write().last() = start_opacity;
|
||||
drawing_->vertex_colors_for_write().last() = start_vertex_color;
|
||||
@@ -298,7 +302,7 @@ struct PaintOperationExecutor {
|
||||
|
||||
/* Update the positions in the current cache. */
|
||||
smoothed_coords_slice[i] = new_pos;
|
||||
positions_slice[i] = screen_space_to_object_space(new_pos);
|
||||
positions_slice[i] = screen_space_to_drawing_plane(new_pos);
|
||||
}
|
||||
|
||||
/* Remove all the converged points from the active window and shrink the window accordingly. */
|
||||
@@ -332,7 +336,7 @@ struct PaintOperationExecutor {
|
||||
|
||||
/* Overwrite last point if it's very close. */
|
||||
if (math::distance(coords, prev_coords) < POINT_OVERRIDE_THRESHOLD_PX) {
|
||||
curves.positions_for_write().last() = screen_space_to_object_space(coords);
|
||||
curves.positions_for_write().last() = screen_space_to_drawing_plane(coords);
|
||||
drawing_->radii_for_write().last() = math::max(radius, prev_radius);
|
||||
drawing_->opacities_for_write().last() = math::max(opacity, prev_opacity);
|
||||
return;
|
||||
@@ -376,7 +380,7 @@ struct PaintOperationExecutor {
|
||||
if (points.size() < min_active_smoothing_points_num) {
|
||||
MutableSpan<float3> positions_slice = curves.positions_for_write().slice(new_range);
|
||||
for (const int64_t i : new_screen_space_coords.index_range()) {
|
||||
positions_slice[i] = screen_space_to_object_space(new_screen_space_coords[i]);
|
||||
positions_slice[i] = screen_space_to_drawing_plane(new_screen_space_coords[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user