技术方向可行
使用鼠标轨迹生成偏移应用到材质上实现扭曲技术可行
This commit is contained in:
		| @ -2,8 +2,7 @@ local DataTableUtils = require("Utils.DataTableUtils") | ||||
| local ESlateVisibility = import("ESlateVisibility") | ||||
| local SlateBlueprintLibrary = import("SlateBlueprintLibrary") | ||||
| local WidgetLayoutLibrary = import("WidgetLayoutLibrary") | ||||
|  | ||||
|  | ||||
| local BusyGamePlayLibrary = import("BusyGamePlayLibrary") | ||||
|  | ||||
| --- @class PreCookCenterWidget | ||||
| --- @field ImgContainer table | ||||
| @ -33,6 +32,8 @@ function PreCookCenterWidget:OnInitialized() | ||||
|     -- self.BtnMain.OnClicked:Add(function() | ||||
|     --     print("onclicked") | ||||
|     -- end) | ||||
|  | ||||
|     self.DataTexture = BusyGamePlayLibrary.CreateTextureBuffer(self) | ||||
| end | ||||
|  | ||||
| function PreCookCenterWidget:Construct() | ||||
| @ -69,7 +70,6 @@ end | ||||
|  | ||||
| local function UpdateOldMouseTrack(old_mouse_tracks, delta_time) | ||||
|     local new_mouse_tracks = {} | ||||
|     -- local new_track = {x=fixed_x, y=fixed_y, remain=1.0} | ||||
|     for _, track in pairs(old_mouse_tracks) do | ||||
|         track.remain = track.remain - delta_time | ||||
|         if track.remain > 0 then | ||||
| @ -79,15 +79,6 @@ local function UpdateOldMouseTrack(old_mouse_tracks, delta_time) | ||||
|     return new_mouse_tracks | ||||
| end | ||||
|  | ||||
| --- 将鼠标的轨迹坐标规范到以起始点到终点所连直线为x轴的坐标系下 | ||||
| local function NormalizeTrackParam(mouse_tracks) | ||||
|  | ||||
| end | ||||
|  | ||||
| --- 根据指定点坐标,求解三次样条参数 | ||||
| local function GetSplineParams(normalize_params) | ||||
|  | ||||
| end | ||||
|  | ||||
| local function UpdateCutMaskByTracks(widget, mouse_tracks) | ||||
|     local FVector2D = import("Vector2D") | ||||
| @ -108,32 +99,59 @@ local function UpdateCutMaskByTracks(widget, mouse_tracks) | ||||
|     render_transform.Scale = scale | ||||
|     render_transform.Translation = translation | ||||
|     render_transform.Angle = (math.atan(delta_y, delta_x) / (2 * math.pi)) * 360 | ||||
|     -- render_transform.Scale = FVector2D(mask_length / 512, 1) | ||||
|     print(render_transform.Angle, math.atan(delta_y, delta_x)) | ||||
|  | ||||
|     widget:SetRenderTransform(render_transform) | ||||
| --[[ | ||||
|  | ||||
| 	/** The amount to translate the widget in slate units */ | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Transform, meta=( Delta = "1" )) | ||||
| 	FVector2D Translation; | ||||
|  | ||||
| 	/** The scale to apply to the widget */ | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Transform, meta=( UIMin = "-5", UIMax = "5", Delta = "0.05" )) | ||||
| 	FVector2D Scale; | ||||
|  | ||||
| 	/** The amount to shear the widget in slate units */ | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Transform, meta=( UIMin = "-89", ClampMin = "-89", UIMax = "89", ClampMax = "89", Delta = "1" )) | ||||
| 	FVector2D Shear; | ||||
|  | ||||
| 	/** The angle in degrees to rotate */ | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Transform, meta=( UIMin = "-180", UIMax = "180", Delta = "1" )) | ||||
| 	float Angle; | ||||
|  | ||||
| ]] | ||||
|  | ||||
| end | ||||
|  | ||||
|  | ||||
| --- 从起点到终点画一条线,以这条线为新的x坐标轴,将所有的点坐标映射到新坐标系下 | ||||
| local function TransformCurveToEndpointAxes(points) | ||||
|     local A = points[1] | ||||
|     local B = points[#points] | ||||
|  | ||||
|     -- 计算向量AB | ||||
|     local dx = B.X - A.X | ||||
|     local dy = B.Y - A.Y | ||||
|     local len = math.sqrt(dx * dx + dy * dy) | ||||
|     if len == 0 then | ||||
|         return {} | ||||
|         -- error("Start and end points are the same, cannot define X-axis.") | ||||
|     end | ||||
|  | ||||
|     -- 计算X轴单位向量 | ||||
|     local ux = dx / len | ||||
|     local uy = dy / len | ||||
|  | ||||
|     -- 计算Y轴单位向量(逆时针旋转90度) | ||||
|     local vx = -uy | ||||
|     local vy = ux | ||||
|  | ||||
|     -- 映射所有点到新坐标系 | ||||
|     local new_points = {} | ||||
|     for i, point in ipairs(points) do | ||||
|         local apx = point.X - A.X | ||||
|         local apy = point.Y - A.Y | ||||
|         local new_x = apx * ux + apy * uy  -- 点积与X轴单位向量 | ||||
|         local new_y = apx * vx + apy * vy  -- 点积与Y轴单位向量 | ||||
|         new_points[i] = {X = new_x, Y = new_y} | ||||
|     end | ||||
|  | ||||
|     return new_points | ||||
| end | ||||
|  | ||||
|  | ||||
| --- 将曲线的Y坐标规范到(-0.5,0.5)的范围内,供材质使用 | ||||
| local function NormalizeCurveYToHalfRange(points) | ||||
|     if #points < 2 then return end | ||||
|     local length = points[#points].X - points[1].X | ||||
|     for _, point in pairs(points) do | ||||
|         point.Y = - point.Y / length  -- 临时加个取反 | ||||
|         point.X = point.X / length | ||||
|     end | ||||
|     return points | ||||
| end | ||||
|  | ||||
|  | ||||
| function PreCookCenterWidget:Tick(geometry, delta_time) | ||||
|     local size = SlateBlueprintLibrary.GetLocalSize(geometry) | ||||
|     local cursor_pos = WidgetLayoutLibrary.GetMousePositionOnViewport(self) | ||||
| @ -148,28 +166,26 @@ function PreCookCenterWidget:Tick(geometry, delta_time) | ||||
|     end | ||||
|  | ||||
|     -- 计算样条参数 | ||||
|     local normalize_params = NormalizeTrackParam(mouse_tracks) | ||||
|     local A, B, C, D = GetSplineParams(normalize_params)  -- Ax^3 + Bx^2 + Cx + D | ||||
|     if #mouse_tracks > 2 then | ||||
|         local transformed_tracks = TransformCurveToEndpointAxes(mouse_tracks) | ||||
|         local normalize_tracks = NormalizeCurveYToHalfRange(transformed_tracks) | ||||
|  | ||||
|     -- 计算划痕位置 | ||||
|         local offsets = {} | ||||
|         for _, track in pairs(normalize_tracks) do | ||||
|             table.insert(offsets, track.Y) | ||||
|         end | ||||
|  | ||||
|     UpdateCutMaskByTracks(self.ImgMask, mouse_tracks) | ||||
|         BusyGamePlayLibrary.UpdateTextureBuffer(self.DataTexture, offsets) | ||||
|  | ||||
|         local mi = self.ImgMask:GetDynamicMaterial() | ||||
|         mi:SetTextureParameterValue("Param", self.DataTexture) | ||||
|         mi:SetScalarParameterValue("VertexCount", #offsets) | ||||
|         mi:SetScalarParameterValue("SourceWidth", 512) | ||||
|         UpdateCutMaskByTracks(self.ImgMask, mouse_tracks) | ||||
|     end | ||||
|  | ||||
|     self.mouse_tracks = mouse_tracks | ||||
|  | ||||
|  | ||||
|     -- print(fixed_x, fixed_y, #self.mouse_tracks) | ||||
| end | ||||
|  | ||||
|  | ||||
|  | ||||
| -- function PreCookCenterWidget:LuaMouseButtonDown() | ||||
| --     print("on mouse button down") | ||||
| -- end | ||||
|  | ||||
| -- function PreCookCenterWidget:LuaMouseButtonUp() | ||||
| --     print("on mouse button up") | ||||
| -- end | ||||
|  | ||||
|  | ||||
| return Class(nil, nil, PreCookCenterWidget) | ||||
		Reference in New Issue
	
	Block a user