Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /////////////////////////////////////////// Header
- #pragma once
- #include "BlockStructure.h"
- #include "GameFramework/Actor.h"
- #include "ProceduralMeshComponent.h"
- #include "KismetProceduralMeshLibrary.h"
- #include "EditableWood.generated.h"
- UCLASS()
- class CARILLON_API AEditableWood : public AActor
- {
- GENERATED_BODY()
- public:
- // Sets default values for this actor's properties
- AEditableWood();
- // Called when the game starts or when spawned
- virtual void BeginPlay() override;
- // Called every frame
- virtual void Tick( float DeltaSeconds ) override;
- void init(UBlockStructure* blocks, float uvSize);
- void Cut(int32 splitLocation);
- UPROPERTY(VisibleAnywhere, Category = Materials)
- UProceduralMeshComponent* mesh;
- UKismetProceduralMeshLibrary* lib;
- UPROPERTY(EditAnywhere)
- float cubeSize = 50;
- UPROPERTY(EditAnywhere)
- int xSize = 3;
- UPROPERTY(EditAnywhere)
- int ySize = 3;
- UPROPERTY(EditAnywhere)
- int zSize = 3;
- UPROPERTY(EditAnywhere)
- float uvSize = 0.001;
- #if WITH_EDITOR
- virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
- #endif
- private:
- UBlockStructure* blockStructure;
- TArray<FVector> vertices;
- TArray<int32> triangles;
- TArray<FVector2D> UV0;
- TArray<FVector> normals;
- TArray<FProcMeshTangent> tangents;
- TArray<FColor> vertexColors;
- void GenerateMesh();
- void AddCube(int32 x, int32 y, int32 z, float size);
- };
- /////////////////////////////////////////// Definitions
- #include "Carillon.h"
- #include "EditableWood.h"
- // Sets default values
- AEditableWood::AEditableWood()
- {
- // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
- PrimaryActorTick.bCanEverTick = true;
- //Initialization
- blockStructure = NewObject<UBlockStructure>();
- mesh = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("GeneratedMesh"));
- RootComponent = mesh;
- GenerateMesh();
- //Setting various editor properties (physics and collisions)
- mesh->SetSimulatePhysics(true);
- this->SetActorEnableCollision(true);
- mesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
- mesh->SetCollisionProfileName("PhysicsActor");
- mesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
- //GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::FromInt(blockStructure->ySiz) + " A " + FString::FromInt(blockStructure->zSiz));
- }
- void AEditableWood::AddCube(int32 x, int32 y, int32 z, float size) {
- //Calculates cube position
- FVector position = FVector(x,y,z) * size;
- //Gets the number of vertices already in the array
- int32 lastVertex = vertices.Num();
- //Front
- if (!blockStructure->getBlockSafe(x - 1, y, z).solid) {
- vertices.Add(FVector(0, 0, 0) + position);
- vertices.Add(FVector(0, size, 0) + position);
- vertices.Add(FVector(0, size, size) + position);
- vertices.Add(FVector(0, 0, size) + position);
- triangles.Add(0 + lastVertex);
- triangles.Add(1 + lastVertex);
- triangles.Add(2 + lastVertex);//
- triangles.Add(2 + lastVertex);
- triangles.Add(3 + lastVertex);
- triangles.Add(0 + lastVertex);//
- UV0.Add(FVector2D(position.Y * uvSize, position.Z * uvSize));
- UV0.Add(FVector2D(position.Y * uvSize + size * uvSize, position.Z * uvSize));
- UV0.Add(FVector2D(position.Y * uvSize + size * uvSize, position.Z * uvSize + size * uvSize));
- UV0.Add(FVector2D(position.Y * uvSize, position.Z * uvSize + size * uvSize));
- lastVertex += 4;
- }
- //Back
- if (!blockStructure->getBlockSafe(x + 1, y, z).solid) {
- vertices.Add(FVector(size, 0, 0) + position);
- vertices.Add(FVector(size, size, 0) + position);
- vertices.Add(FVector(size, size, size) + position);
- vertices.Add(FVector(size, 0, size) + position);
- triangles.Add(2 + lastVertex);
- triangles.Add(1 + lastVertex);
- triangles.Add(0 + lastVertex);//
- triangles.Add(0 + lastVertex);
- triangles.Add(3 + lastVertex);
- triangles.Add(2 + lastVertex);//
- UV0.Add(FVector2D(position.Y * uvSize, position.Z * uvSize));
- UV0.Add(FVector2D(position.Y * uvSize + size * uvSize, position.Z * uvSize));
- UV0.Add(FVector2D(position.Y * uvSize + size * uvSize, position.Z * uvSize + size * uvSize));
- UV0.Add(FVector2D(position.Y * uvSize, position.Z * uvSize + size * uvSize));
- lastVertex += 4;
- }
- //Top
- if (!blockStructure->getBlockSafe(x, y, z + 1).solid) {
- vertices.Add(FVector(0, 0, size) + position);
- vertices.Add(FVector(0, size, size) + position);
- vertices.Add(FVector(size, size, size) + position);
- vertices.Add(FVector(size, 0, size) + position);
- triangles.Add(0 + lastVertex);
- triangles.Add(1 + lastVertex);
- triangles.Add(2 + lastVertex);//
- triangles.Add(2 + lastVertex);
- triangles.Add(3 + lastVertex);
- triangles.Add(0 + lastVertex);//
- UV0.Add(FVector2D(position.Y * uvSize, position.X * uvSize));
- UV0.Add(FVector2D(position.Y * uvSize + size * uvSize, position.X * uvSize));
- UV0.Add(FVector2D(position.Y * uvSize + size * uvSize, position.X * uvSize + size * uvSize));
- UV0.Add(FVector2D(position.Y * uvSize, position.X * uvSize + size * uvSize));
- lastVertex += 4;
- }
- //Bottom
- if (!blockStructure->getBlockSafe(x, y, z - 1).solid) {
- vertices.Add(FVector(0, 0, 0) + position);
- vertices.Add(FVector(0, size, 0) + position);
- vertices.Add(FVector(size, size, 0) + position);
- vertices.Add(FVector(size, 0, 0) + position);
- triangles.Add(0 + lastVertex);
- triangles.Add(3 + lastVertex);
- triangles.Add(2 + lastVertex);//
- triangles.Add(2 + lastVertex);
- triangles.Add(1 + lastVertex);
- triangles.Add(0 + lastVertex);//
- UV0.Add(FVector2D(position.Y * uvSize, position.X * uvSize));
- UV0.Add(FVector2D(position.Y * uvSize + size * uvSize, position.X * uvSize));
- UV0.Add(FVector2D(position.Y * uvSize + size * uvSize, position.X * uvSize + size * uvSize));
- UV0.Add(FVector2D(position.Y * uvSize, position.X * uvSize + size * uvSize));
- lastVertex += 4;
- }
- //Right
- if (!blockStructure->getBlockSafe(x, y + 1, z).solid) {
- vertices.Add(FVector(0, size, 0) + position);
- vertices.Add(FVector(size, size, 0) + position);
- vertices.Add(FVector(size, size, size) + position);
- vertices.Add(FVector(0, size, size) + position);
- triangles.Add(0 + lastVertex);
- triangles.Add(1 + lastVertex);
- triangles.Add(2 + lastVertex);//
- triangles.Add(2 + lastVertex);
- triangles.Add(3 + lastVertex);
- triangles.Add(0 + lastVertex);//
- UV0.Add(FVector2D(position.X * uvSize, position.Z * uvSize));
- UV0.Add(FVector2D(position.X * uvSize + size * uvSize, position.Z * uvSize));
- UV0.Add(FVector2D(position.X * uvSize + size * uvSize, position.Z * uvSize + size * uvSize));
- UV0.Add(FVector2D(position.X * uvSize, position.Z * uvSize + size * uvSize));
- lastVertex += 4;
- }
- //Left
- if (!blockStructure->getBlockSafe(x, y - 1, z).solid) {
- vertices.Add(FVector(0, 0, 0) + position);
- vertices.Add(FVector(size, 0, 0) + position);
- vertices.Add(FVector(size, 0, size) + position);
- vertices.Add(FVector(0, 0, size) + position);
- triangles.Add(2 + lastVertex);
- triangles.Add(1 + lastVertex);
- triangles.Add(0 + lastVertex);//
- triangles.Add(0 + lastVertex);
- triangles.Add(3 + lastVertex);
- triangles.Add(2 + lastVertex);//
- UV0.Add(FVector2D(position.X * uvSize, position.Z * uvSize));
- UV0.Add(FVector2D(position.X * uvSize + size * uvSize, position.Z * uvSize));
- UV0.Add(FVector2D(position.X * uvSize + size * uvSize, position.Z * uvSize + size * uvSize));
- UV0.Add(FVector2D(position.X * uvSize, position.Z * uvSize + size * uvSize));
- lastVertex += 4;
- }
- }
- void AEditableWood::GenerateMesh() {
- blockStructure->init(xSize, ySize, zSize);
- //Clears the arrays
- vertices.Empty();
- triangles.Empty();
- UV0.Empty();
- normals.Empty();
- tangents.Empty();
- mesh->ClearCollisionConvexMeshes();
- //Mesh generation
- blockStructure->fillRandom();
- for (int i = 0; i < blockStructure->xSiz; i++) {
- for (int k = 0; k < blockStructure->ySiz; k++) {
- for (int w = 0; w < blockStructure->zSiz; w++) {
- if (blockStructure->getBlock(i, k, w).solid)
- AddCube(i, k, w, cubeSize);
- }
- }
- }
- //Calculate normals
- normals.AddZeroed(vertices.Num());
- for (int j = 0; j < triangles.Num() / 3; j++) {
- //Gets the vertex index of 3 vertices that make the first triangle
- int v1, v2, v3;
- v1 = triangles[3 * j];
- v2 = triangles[3 * j + 1];
- v3 = triangles[3 * j + 2];
- //Calculates two of the triangle edges
- FVector A = vertices[v2] - vertices[v1];
- FVector B = vertices[v3] - vertices[v1];
- //Calculates the normal with the cross product and adds it to the normals array at the correct index position
- normals[v1] = FVector(B^A).GetSafeNormal();
- normals[v2] = FVector(B^A).GetSafeNormal();
- normals[v3] = FVector(B^A).GetSafeNormal();
- }
- //Creates the mesh
- mesh->CreateMeshSection(0, vertices, triangles, normals, UV0, vertexColors, tangents, true);
- mesh->bUseComplexAsSimpleCollision = false;
- mesh->AddCollisionConvexMesh(vertices);
- //Sets Correct Material
- static ConstructorHelpers::FObjectFinder<UMaterial> MatObj(TEXT("Material'/Game/_Materials/Wood.Wood'"));
- mesh->SetMaterial(0, MatObj.Object);
- //GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::FromInt(blockStructure->ySiz) + " G " + FString::FromInt(blockStructure->zSiz));
- }
- void AEditableWood::init(UBlockStructure* blocks, float uvSize_)
- {
- blockStructure = blocks;
- xSize = blocks->xSiz;
- ySize = blocks->ySiz;
- zSize = blocks->zSiz;
- uvSize = uvSize_;
- }
- void AEditableWood::Cut(int32 splitLocation) {
- PairUBlockStructure pair = blockStructure->SplitBlocks(splitLocation, cutAlong::X_AXIS);
- AEditableWood* left = GetWorld()->SpawnActor<AEditableWood>(AEditableWood::StaticClass());
- AEditableWood* right = GetWorld()->SpawnActor<AEditableWood>(AEditableWood::StaticClass());
- left->init(pair.A, uvSize);
- right->init(pair.B, uvSize);
- }
- // Called when the game starts or when spawned
- void AEditableWood::BeginPlay()
- {
- GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::FromInt(blockStructure->ySiz) + " B1 " + FString::FromInt(blockStructure->zSiz));
- Super::BeginPlay();
- //GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::FromInt(blockStructure->ySiz) + " B2 " + FString::FromInt(blockStructure->zSiz));
- PairUBlockStructure pair = blockStructure->SplitBlocks(2, cutAlong::X_AXIS);
- }
- // Called every frame
- void AEditableWood::Tick( float DeltaTime )
- {
- Super::Tick( DeltaTime );
- }
- #if WITH_EDITOR
- void AEditableWood::PostEditChangeProperty(FPropertyChangedEvent& e)
- {
- Super::PostEditChangeProperty(e);
- FName PropertyName = (e.Property != NULL) ? e.Property->GetFName() : NAME_None;
- if (PropertyName == GET_MEMBER_NAME_CHECKED(AEditableWood, cubeSize)||
- PropertyName == GET_MEMBER_NAME_CHECKED(AEditableWood, xSize) ||
- PropertyName == GET_MEMBER_NAME_CHECKED(AEditableWood, ySize) ||
- PropertyName == GET_MEMBER_NAME_CHECKED(AEditableWood, zSize) ||
- PropertyName == GET_MEMBER_NAME_CHECKED(AEditableWood, uvSize)) {
- GenerateMesh();
- }
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment