技术方向可行
使用鼠标轨迹生成偏移应用到材质上实现扭曲技术可行
This commit is contained in:
		| @ -2,8 +2,7 @@ local DataTableUtils = require("Utils.DataTableUtils") | |||||||
| local ESlateVisibility = import("ESlateVisibility") | local ESlateVisibility = import("ESlateVisibility") | ||||||
| local SlateBlueprintLibrary = import("SlateBlueprintLibrary") | local SlateBlueprintLibrary = import("SlateBlueprintLibrary") | ||||||
| local WidgetLayoutLibrary = import("WidgetLayoutLibrary") | local WidgetLayoutLibrary = import("WidgetLayoutLibrary") | ||||||
|  | local BusyGamePlayLibrary = import("BusyGamePlayLibrary") | ||||||
|  |  | ||||||
|  |  | ||||||
| --- @class PreCookCenterWidget | --- @class PreCookCenterWidget | ||||||
| --- @field ImgContainer table | --- @field ImgContainer table | ||||||
| @ -33,6 +32,8 @@ function PreCookCenterWidget:OnInitialized() | |||||||
|     -- self.BtnMain.OnClicked:Add(function() |     -- self.BtnMain.OnClicked:Add(function() | ||||||
|     --     print("onclicked") |     --     print("onclicked") | ||||||
|     -- end) |     -- end) | ||||||
|  |  | ||||||
|  |     self.DataTexture = BusyGamePlayLibrary.CreateTextureBuffer(self) | ||||||
| end | end | ||||||
|  |  | ||||||
| function PreCookCenterWidget:Construct() | function PreCookCenterWidget:Construct() | ||||||
| @ -69,7 +70,6 @@ end | |||||||
|  |  | ||||||
| local function UpdateOldMouseTrack(old_mouse_tracks, delta_time) | local function UpdateOldMouseTrack(old_mouse_tracks, delta_time) | ||||||
|     local new_mouse_tracks = {} |     local new_mouse_tracks = {} | ||||||
|     -- local new_track = {x=fixed_x, y=fixed_y, remain=1.0} |  | ||||||
|     for _, track in pairs(old_mouse_tracks) do |     for _, track in pairs(old_mouse_tracks) do | ||||||
|         track.remain = track.remain - delta_time |         track.remain = track.remain - delta_time | ||||||
|         if track.remain > 0 then |         if track.remain > 0 then | ||||||
| @ -79,15 +79,6 @@ local function UpdateOldMouseTrack(old_mouse_tracks, delta_time) | |||||||
|     return new_mouse_tracks |     return new_mouse_tracks | ||||||
| end | end | ||||||
|  |  | ||||||
| --- 将鼠标的轨迹坐标规范到以起始点到终点所连直线为x轴的坐标系下 |  | ||||||
| local function NormalizeTrackParam(mouse_tracks) |  | ||||||
|  |  | ||||||
| end |  | ||||||
|  |  | ||||||
| --- 根据指定点坐标,求解三次样条参数 |  | ||||||
| local function GetSplineParams(normalize_params) |  | ||||||
|  |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local function UpdateCutMaskByTracks(widget, mouse_tracks) | local function UpdateCutMaskByTracks(widget, mouse_tracks) | ||||||
|     local FVector2D = import("Vector2D") |     local FVector2D = import("Vector2D") | ||||||
| @ -108,32 +99,59 @@ local function UpdateCutMaskByTracks(widget, mouse_tracks) | |||||||
|     render_transform.Scale = scale |     render_transform.Scale = scale | ||||||
|     render_transform.Translation = translation |     render_transform.Translation = translation | ||||||
|     render_transform.Angle = (math.atan(delta_y, delta_x) / (2 * math.pi)) * 360 |     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) |     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 | 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) | function PreCookCenterWidget:Tick(geometry, delta_time) | ||||||
|     local size = SlateBlueprintLibrary.GetLocalSize(geometry) |     local size = SlateBlueprintLibrary.GetLocalSize(geometry) | ||||||
|     local cursor_pos = WidgetLayoutLibrary.GetMousePositionOnViewport(self) |     local cursor_pos = WidgetLayoutLibrary.GetMousePositionOnViewport(self) | ||||||
| @ -148,28 +166,26 @@ function PreCookCenterWidget:Tick(geometry, delta_time) | |||||||
|     end |     end | ||||||
|  |  | ||||||
|     -- 计算样条参数 |     -- 计算样条参数 | ||||||
|     local normalize_params = NormalizeTrackParam(mouse_tracks) |     if #mouse_tracks > 2 then | ||||||
|     local A, B, C, D = GetSplineParams(normalize_params)  -- Ax^3 + Bx^2 + Cx + D |         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 | ||||||
|  |  | ||||||
|  |         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) |         UpdateCutMaskByTracks(self.ImgMask, mouse_tracks) | ||||||
|  |     end | ||||||
|  |  | ||||||
|     self.mouse_tracks = mouse_tracks |     self.mouse_tracks = mouse_tracks | ||||||
|  |  | ||||||
|  |  | ||||||
|     -- print(fixed_x, fixed_y, #self.mouse_tracks) |  | ||||||
| end | end | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| -- function PreCookCenterWidget:LuaMouseButtonDown() |  | ||||||
| --     print("on mouse button down") |  | ||||||
| -- end |  | ||||||
|  |  | ||||||
| -- function PreCookCenterWidget:LuaMouseButtonUp() |  | ||||||
| --     print("on mouse button up") |  | ||||||
| -- end |  | ||||||
|  |  | ||||||
|  |  | ||||||
| return Class(nil, nil, PreCookCenterWidget) | return Class(nil, nil, PreCookCenterWidget) | ||||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -83,9 +83,26 @@ bool UBusyGamePlayLibrary::GetCookMaterialStateConfig(const FName& RowName, FBus | |||||||
| 	return GetTableConfig<FBusyCookMaterialStateConfig>(TEXT("CookMaterialStateConfig"), RowName, RowData); | 	return GetTableConfig<FBusyCookMaterialStateConfig>(TEXT("CookMaterialStateConfig"), RowName, RowData); | ||||||
| } | } | ||||||
|  |  | ||||||
| FLuaBPVar UBusyGamePlayLibrary::TestTable(const FName& RowName){ | FLuaBPVar UBusyGamePlayLibrary::CreateTextureBuffer(UObject* WorldContextObject){ | ||||||
| 	UDataTable* Table = UBusyGamePlayLibrary::GetGameDataTable("CookMaterialStateConfig"); | 	// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||||
| 	auto Config = Table->FindRow<FTableRowBase>(RowName, "", true); | 	auto DataTexture = UTexture2D::CreateTransient(512, 1, PF_R32_FLOAT); | ||||||
|  | 	DataTexture->Filter = TF_Trilinear; | ||||||
| 	return FLuaBPVar(); | 	DataTexture->AddressX = TA_Clamp; | ||||||
|  | 	DataTexture->AddressY = TA_Clamp; | ||||||
|  | 	DataTexture->UpdateResource(); | ||||||
|  | 	return ULuaBlueprintLibrary::CreateVarFromObject(WorldContextObject, DataTexture); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void UBusyGamePlayLibrary::UpdateTextureBuffer(UTexture2D *DataTexture, TArray<float> FloatData){ | ||||||
|  | 	// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ա<EFBFBD>д<EFBFBD><D0B4> | ||||||
|  | 	DataTexture->GetPlatformData()->Mips[0]; | ||||||
|  | 	FTexture2DMipMap& Mip = DataTexture->GetPlatformData()->Mips[0]; | ||||||
|  | 	void* Data = Mip.BulkData.Lock(LOCK_READ_WRITE); | ||||||
|  |  | ||||||
|  | 	// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD><DDB8>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD> | ||||||
|  | 	FMemory::Memcpy(Data, FloatData.GetData(), FloatData.Num() * sizeof(float)); | ||||||
|  |  | ||||||
|  | 	// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||||
|  | 	Mip.BulkData.Unlock(); | ||||||
|  | 	DataTexture->UpdateResource(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -60,6 +60,10 @@ public: | |||||||
| 	static bool GetCookMaterialStateConfig(const FName& RowName, FBusyCookMaterialStateConfig& RowData); | 	static bool GetCookMaterialStateConfig(const FName& RowName, FBusyCookMaterialStateConfig& RowData); | ||||||
| 	 | 	 | ||||||
| 	UFUNCTION(BlueprintPure) | 	UFUNCTION(BlueprintPure) | ||||||
| 	static FLuaBPVar TestTable(const FName& RowName); | 	static FLuaBPVar CreateTextureBuffer(UObject* WorldContextObject); | ||||||
|  |  | ||||||
|  | 	UFUNCTION(BlueprintCallable) | ||||||
|  | 	static void UpdateTextureBuffer(UTexture2D* DataTexture, TArray<float> FloatData); | ||||||
|  |  | ||||||
|  |  | ||||||
| }; | }; | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user