Games101学习 - 变换

在UE中灵活使用矩阵修改变换信息并不方便,不过UE有ProceduralMeshComponent可以动态创建Mesh,可以通过这个组件应用矩阵进行变换测试。

1.平移矩阵

在这里插入图片描述
注意平移矩阵101里叫做Shear而不是Skew
转换到3D空间需要注意a的位置放在哪里。

测试用.h文件:

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "ProceduralMeshComponent.h"
#include "MyActor.generated.h"

UCLASS()
class MYPROJECT6_API AMyActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AMyActor();

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	UProceduralMeshComponent* MeshComponent;

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;
};

测试用.cpp文件:

#include "MyActor.h"

AMyActor::AMyActor()
{
	PrimaryActorTick.bCanEverTick = true;

	MeshComponent = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("ProceduralMesh"));
	RootComponent = MeshComponent;
}

void AMyActor::BeginPlay()
{
	Super::BeginPlay();

    TArray<FVector> Vertices;
    Vertices.Add(FVector(0.0f, 0.0f, 0.0f));
    Vertices.Add(FVector(0.0f, 100.0f, 0.0f));
    Vertices.Add(FVector(100.0f, 100.0f, 0.0f));
    Vertices.Add(FVector(100.0f, 0.0f, 0.0f));

    TArray<int32> Triangles;
    Triangles.Add(0);
    Triangles.Add(1);
    Triangles.Add(2);

    Triangles.Add(0);
    Triangles.Add(2);
    Triangles.Add(3);

    // 定义 UV 坐标
    TArray<FVector2D> UV0;
    UV0.Add(FVector2D(0.0f, 0.0f));
    UV0.Add(FVector2D(0.0f, 1.0f));
    UV0.Add(FVector2D(1.0f, 1.0f));
    UV0.Add(FVector2D(1.0f, 0.0f));

    // 法线
    TArray<FVector> Normals;
    Normals.Add(FVector(0.0f, 0.0f, 1.0f));
    Normals.Add(FVector(0.0f, 0.0f, 1.0f));
    Normals.Add(FVector(0.0f, 0.0f, 1.0f));
    Normals.Add(FVector(0.0f, 0.0f, 1.0f));

    // 切线
    TArray<FProcMeshTangent> Tangents;
    Tangents.Add(FProcMeshTangent(1.0f, 0.0f, 0.0f));
    Tangents.Add(FProcMeshTangent(1.0f, 0.0f, 0.0f));
    Tangents.Add(FProcMeshTangent(1.0f, 0.0f, 0.0f));
    Tangents.Add(FProcMeshTangent(1.0f, 0.0f, 0.0f));

    TArray<FColor> VertexColors;
    VertexColors.Add(FLinearColor::White.ToFColor(true));
    VertexColors.Add(FLinearColor::White.ToFColor(true));
    VertexColors.Add(FLinearColor::White.ToFColor(true));
    VertexColors.Add(FLinearColor::White.ToFColor(true));

    // 平移矩阵
    float a = 1.1f;
    FMatrix SkewMatrix = FMatrix(
        FPlane(1.0f, a, 0.0f, 0.0f),
        FPlane(0.0f, 1.0f, 0.0f, 0.0f),
        FPlane(0.0f, 0.0f, 1.0f, 0.0f),
        FPlane(0.0f, 0.0f, 0.0f, 1.0f)
    );

    for (FVector& Vertex : Vertices)
    {
        FVector TransformedVertex = SkewMatrix.TransformPosition(Vertex);
        Vertex = TransformedVertex;
    }

    MeshComponent->CreateMeshSection(0, Vertices, Triangles, Normals, UV0, VertexColors, Tangents, true);
}

效果:
在这里插入图片描述

2.旋转矩阵

为了更好的检验应用旋转矩阵后的效果,可以将创建Mesh的过程封装一下,先看下最终效果:
在这里插入图片描述

首先将创建Mesh的过程封装为一个函数:

void AMyActor::CreateQuadMesh(float zOffset, FMatrix TransformMatrix, int32 MeshSectionIndex)
{
    // 顶点位置定义
    TArray<FVector> Vertices;
    Vertices.Add(FVector(0.0f, 0.0f, 0.0f + zOffset));
    Vertices.Add(FVector(0.0f, 100.0f, 0.0f + zOffset));
    Vertices.Add(FVector(100.0f, 100.0f, 0.0f + zOffset));
    Vertices.Add(FVector(100.0f, 0.0f, 0.0f + zOffset));

    // 使用传入的矩阵进行顶点变换
    for (FVector& Vertex : Vertices)
    {
        Vertex = TransformMatrix.TransformPosition(Vertex);
    }

    // 三角形索引
    TArray<int32> Triangles;
    Triangles.Add(0);
    Triangles.Add(1);
    Triangles.Add(2);
    Triangles.Add(0);
    Triangles.Add(2);
    Triangles.Add(3);

    // UV 坐标
    TArray<FVector2D> UV0;
    UV0.Add(FVector2D(0.0f, 0.0f));
    UV0.Add(FVector2D(0.0f, 1.0f));
    UV0.Add(FVector2D(1.0f, 1.0f));
    UV0.Add(FVector2D(1.0f, 0.0f));

    // 法线
    TArray<FVector> Normals;
    Normals.Add(FVector(0.0f, 0.0f, 1.0f));
    Normals.Add(FVector(0.0f, 0.0f, 1.0f));
    Normals.Add(FVector(0.0f, 0.0f, 1.0f));
    Normals.Add(FVector(0.0f, 0.0f, 1.0f));

    // 切线
    TArray<FProcMeshTangent> Tangents;
    Tangents.Add(FProcMeshTangent(1.0f, 0.0f, 0.0f));
    Tangents.Add(FProcMeshTangent(1.0f, 0.0f, 0.0f));
    Tangents.Add(FProcMeshTangent(1.0f, 0.0f, 0.0f));
    Tangents.Add(FProcMeshTangent(1.0f, 0.0f, 0.0f));

    // 顶点颜色
    TArray<FColor> VertexColors;
    VertexColors.Add(FLinearColor::White.ToFColor(true));
    VertexColors.Add(FLinearColor::White.ToFColor(true));
    VertexColors.Add(FLinearColor::White.ToFColor(true));
    VertexColors.Add(FLinearColor::White.ToFColor(true));

    // 创建网格
    MeshComponent->CreateMeshSection(MeshSectionIndex, Vertices, Triangles, Normals, UV0, VertexColors, Tangents, true);
}

然后在外部创建旋转矩阵即可:

void AMyActor::BeginPlay()
{
	Super::BeginPlay();
	
    for (int32 i = 0; i < 10; ++i)
    {
        float RotationAngle = i * 36.0f; // 每次旋转36度
        FMatrix RotationMatrix = FRotationMatrix(FRotator(0.0f, RotationAngle, 0.0f));
        CreateQuadMesh(i*100.0f, RotationMatrix, i);
    }
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值