Guest User

Untitled

a guest
Sep 27th, 2016
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.94 KB | None | 0 0
  1. /////////////////////////////////////////// Header
  2. #pragma once
  3. #include "BlockStructure.h"
  4. #include "GameFramework/Actor.h"
  5. #include "ProceduralMeshComponent.h"
  6. #include "KismetProceduralMeshLibrary.h"
  7. #include "EditableWood.generated.h"
  8.  
  9. UCLASS()
  10. class CARILLON_API AEditableWood : public AActor
  11. {
  12.     GENERATED_BODY()
  13.    
  14. public:
  15.     // Sets default values for this actor's properties
  16.     AEditableWood();
  17.  
  18.     // Called when the game starts or when spawned
  19.     virtual void BeginPlay() override;
  20.    
  21.     // Called every frame
  22.     virtual void Tick( float DeltaSeconds ) override;
  23.    
  24.     void init(UBlockStructure* blocks, float uvSize);
  25.     void Cut(int32 splitLocation);
  26.  
  27.     UPROPERTY(VisibleAnywhere, Category = Materials)
  28.     UProceduralMeshComponent* mesh;
  29.     UKismetProceduralMeshLibrary* lib;
  30.     UPROPERTY(EditAnywhere)
  31.     float cubeSize = 50;
  32.     UPROPERTY(EditAnywhere)
  33.     int xSize = 3;
  34.     UPROPERTY(EditAnywhere)
  35.     int ySize = 3;
  36.     UPROPERTY(EditAnywhere)
  37.     int zSize = 3;
  38.     UPROPERTY(EditAnywhere)
  39.     float uvSize = 0.001;
  40.  
  41. #if WITH_EDITOR
  42.     virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
  43. #endif
  44.  
  45. private:
  46.     UBlockStructure* blockStructure;
  47.     TArray<FVector> vertices;
  48.     TArray<int32> triangles;
  49.     TArray<FVector2D> UV0;
  50.     TArray<FVector> normals;
  51.     TArray<FProcMeshTangent> tangents;
  52.     TArray<FColor> vertexColors;
  53.     void GenerateMesh();
  54.     void AddCube(int32 x, int32 y, int32 z, float size);
  55. };
  56.  
  57. /////////////////////////////////////////// Definitions
  58.  
  59. #include "Carillon.h"
  60. #include "EditableWood.h"
  61.  
  62.  
  63. // Sets default values
  64. AEditableWood::AEditableWood()
  65. {
  66.     // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
  67.     PrimaryActorTick.bCanEverTick = true;
  68.  
  69.     //Initialization
  70.     blockStructure = NewObject<UBlockStructure>();
  71.  
  72.     mesh = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("GeneratedMesh"));
  73.     RootComponent = mesh;
  74.  
  75.     GenerateMesh();
  76.  
  77.     //Setting various editor properties (physics and collisions)
  78.     mesh->SetSimulatePhysics(true);
  79.     this->SetActorEnableCollision(true);
  80.     mesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
  81.     mesh->SetCollisionProfileName("PhysicsActor");
  82.     mesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
  83.     //GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::FromInt(blockStructure->ySiz) + " A  " + FString::FromInt(blockStructure->zSiz));
  84. }
  85.  
  86. void AEditableWood::AddCube(int32 x, int32 y, int32 z, float size) {
  87.     //Calculates cube position
  88.     FVector position = FVector(x,y,z) * size;
  89.     //Gets the number of vertices already in the array
  90.     int32 lastVertex = vertices.Num();
  91.  
  92.     //Front
  93.     if (!blockStructure->getBlockSafe(x - 1, y, z).solid) {
  94.         vertices.Add(FVector(0, 0, 0) + position);
  95.         vertices.Add(FVector(0, size, 0) + position);
  96.         vertices.Add(FVector(0, size, size) + position);
  97.         vertices.Add(FVector(0, 0, size) + position);
  98.         triangles.Add(0 + lastVertex);
  99.         triangles.Add(1 + lastVertex);
  100.         triangles.Add(2 + lastVertex);//
  101.         triangles.Add(2 + lastVertex);
  102.         triangles.Add(3 + lastVertex);
  103.         triangles.Add(0 + lastVertex);//
  104.         UV0.Add(FVector2D(position.Y * uvSize, position.Z * uvSize));
  105.         UV0.Add(FVector2D(position.Y * uvSize + size * uvSize, position.Z * uvSize));
  106.         UV0.Add(FVector2D(position.Y * uvSize + size * uvSize, position.Z * uvSize + size * uvSize));
  107.         UV0.Add(FVector2D(position.Y * uvSize, position.Z * uvSize + size * uvSize));
  108.         lastVertex += 4;
  109.     }
  110.     //Back
  111.     if (!blockStructure->getBlockSafe(x + 1, y, z).solid) {
  112.         vertices.Add(FVector(size, 0, 0) + position);
  113.         vertices.Add(FVector(size, size, 0) + position);
  114.         vertices.Add(FVector(size, size, size) + position);
  115.         vertices.Add(FVector(size, 0, size) + position);
  116.         triangles.Add(2 + lastVertex);
  117.         triangles.Add(1 + lastVertex);
  118.         triangles.Add(0 + lastVertex);//
  119.         triangles.Add(0 + lastVertex);
  120.         triangles.Add(3 + lastVertex);
  121.         triangles.Add(2 + lastVertex);//
  122.         UV0.Add(FVector2D(position.Y * uvSize, position.Z * uvSize));
  123.         UV0.Add(FVector2D(position.Y * uvSize + size * uvSize, position.Z * uvSize));
  124.         UV0.Add(FVector2D(position.Y * uvSize + size * uvSize, position.Z * uvSize + size * uvSize));
  125.         UV0.Add(FVector2D(position.Y * uvSize, position.Z * uvSize + size * uvSize));
  126.         lastVertex += 4;
  127.     }
  128.     //Top
  129.     if (!blockStructure->getBlockSafe(x, y, z + 1).solid) {
  130.         vertices.Add(FVector(0, 0, size) + position);
  131.         vertices.Add(FVector(0, size, size) + position);
  132.         vertices.Add(FVector(size, size, size) + position);
  133.         vertices.Add(FVector(size, 0, size) + position);
  134.         triangles.Add(0 + lastVertex);
  135.         triangles.Add(1 + lastVertex);
  136.         triangles.Add(2 + lastVertex);//
  137.         triangles.Add(2 + lastVertex);
  138.         triangles.Add(3 + lastVertex);
  139.         triangles.Add(0 + lastVertex);//
  140.         UV0.Add(FVector2D(position.Y * uvSize, position.X * uvSize));
  141.         UV0.Add(FVector2D(position.Y * uvSize + size * uvSize, position.X * uvSize));
  142.         UV0.Add(FVector2D(position.Y * uvSize + size * uvSize, position.X * uvSize + size * uvSize));
  143.         UV0.Add(FVector2D(position.Y * uvSize, position.X * uvSize + size * uvSize));
  144.         lastVertex += 4;
  145.     }
  146.     //Bottom
  147.     if (!blockStructure->getBlockSafe(x, y, z - 1).solid) {
  148.         vertices.Add(FVector(0, 0, 0) + position);
  149.         vertices.Add(FVector(0, size, 0) + position);
  150.         vertices.Add(FVector(size, size, 0) + position);
  151.         vertices.Add(FVector(size, 0, 0) + position);
  152.         triangles.Add(0 + lastVertex);
  153.         triangles.Add(3 + lastVertex);
  154.         triangles.Add(2 + lastVertex);//
  155.         triangles.Add(2 + lastVertex);
  156.         triangles.Add(1 + lastVertex);
  157.         triangles.Add(0 + lastVertex);//
  158.         UV0.Add(FVector2D(position.Y * uvSize, position.X * uvSize));
  159.         UV0.Add(FVector2D(position.Y * uvSize + size * uvSize, position.X * uvSize));
  160.         UV0.Add(FVector2D(position.Y * uvSize + size * uvSize, position.X * uvSize + size * uvSize));
  161.         UV0.Add(FVector2D(position.Y * uvSize, position.X * uvSize + size * uvSize));
  162.         lastVertex += 4;
  163.     }
  164.     //Right
  165.     if (!blockStructure->getBlockSafe(x, y + 1, z).solid) {
  166.         vertices.Add(FVector(0, size, 0) + position);
  167.         vertices.Add(FVector(size, size, 0) + position);
  168.         vertices.Add(FVector(size, size, size) + position);
  169.         vertices.Add(FVector(0, size, size) + position);
  170.         triangles.Add(0 + lastVertex);
  171.         triangles.Add(1 + lastVertex);
  172.         triangles.Add(2 + lastVertex);//
  173.         triangles.Add(2 + lastVertex);
  174.         triangles.Add(3 + lastVertex);
  175.         triangles.Add(0 + lastVertex);//
  176.         UV0.Add(FVector2D(position.X * uvSize, position.Z * uvSize));
  177.         UV0.Add(FVector2D(position.X * uvSize + size * uvSize, position.Z * uvSize));
  178.         UV0.Add(FVector2D(position.X * uvSize + size * uvSize, position.Z * uvSize + size * uvSize));
  179.         UV0.Add(FVector2D(position.X * uvSize, position.Z * uvSize + size * uvSize));
  180.         lastVertex += 4;
  181.     }
  182.     //Left
  183.     if (!blockStructure->getBlockSafe(x, y - 1, z).solid) {
  184.         vertices.Add(FVector(0, 0, 0) + position);
  185.         vertices.Add(FVector(size, 0, 0) + position);
  186.         vertices.Add(FVector(size, 0, size) + position);
  187.         vertices.Add(FVector(0, 0, size) + position);
  188.         triangles.Add(2 + lastVertex);
  189.         triangles.Add(1 + lastVertex);
  190.         triangles.Add(0 + lastVertex);//
  191.         triangles.Add(0 + lastVertex);
  192.         triangles.Add(3 + lastVertex);
  193.         triangles.Add(2 + lastVertex);//
  194.         UV0.Add(FVector2D(position.X * uvSize, position.Z * uvSize));
  195.         UV0.Add(FVector2D(position.X * uvSize + size * uvSize, position.Z * uvSize));
  196.         UV0.Add(FVector2D(position.X * uvSize + size * uvSize, position.Z * uvSize + size * uvSize));
  197.         UV0.Add(FVector2D(position.X * uvSize, position.Z * uvSize + size * uvSize));
  198.         lastVertex += 4;
  199.     }
  200. }
  201.  
  202. void AEditableWood::GenerateMesh() {
  203.  
  204.     blockStructure->init(xSize, ySize, zSize);
  205.  
  206.     //Clears the arrays
  207.     vertices.Empty();
  208.     triangles.Empty();
  209.     UV0.Empty();
  210.     normals.Empty();
  211.     tangents.Empty();
  212.     mesh->ClearCollisionConvexMeshes();
  213.  
  214.     //Mesh generation  
  215.     blockStructure->fillRandom();
  216.  
  217.     for (int i = 0; i < blockStructure->xSiz; i++) {
  218.         for (int k = 0; k < blockStructure->ySiz; k++) {
  219.             for (int w = 0; w < blockStructure->zSiz; w++) {
  220.                 if (blockStructure->getBlock(i, k, w).solid)
  221.                     AddCube(i, k, w, cubeSize);
  222.             }
  223.         }
  224.     }
  225.  
  226.     //Calculate normals
  227.     normals.AddZeroed(vertices.Num());
  228.     for (int j = 0; j < triangles.Num() / 3; j++) {
  229.         //Gets the vertex index of 3 vertices that make the first triangle
  230.         int v1, v2, v3;
  231.         v1 = triangles[3 * j];
  232.         v2 = triangles[3 * j + 1];
  233.         v3 = triangles[3 * j + 2];
  234.         //Calculates two of the triangle edges
  235.         FVector A = vertices[v2] - vertices[v1];
  236.         FVector B = vertices[v3] - vertices[v1];
  237.         //Calculates the normal with the cross product and adds it to the normals array at the correct index position
  238.         normals[v1] = FVector(B^A).GetSafeNormal();
  239.         normals[v2] = FVector(B^A).GetSafeNormal();
  240.         normals[v3] = FVector(B^A).GetSafeNormal();
  241.     }
  242.  
  243.     //Creates the mesh
  244.     mesh->CreateMeshSection(0, vertices, triangles, normals, UV0, vertexColors, tangents, true);
  245.     mesh->bUseComplexAsSimpleCollision = false;
  246.     mesh->AddCollisionConvexMesh(vertices);
  247.  
  248.     //Sets Correct Material
  249.     static ConstructorHelpers::FObjectFinder<UMaterial> MatObj(TEXT("Material'/Game/_Materials/Wood.Wood'"));
  250.     mesh->SetMaterial(0, MatObj.Object);
  251.     //GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::FromInt(blockStructure->ySiz) + " G  " + FString::FromInt(blockStructure->zSiz));
  252.  
  253. }
  254.  
  255. void AEditableWood::init(UBlockStructure* blocks, float uvSize_)
  256. {
  257.     blockStructure = blocks;
  258.     xSize = blocks->xSiz;
  259.     ySize = blocks->ySiz;
  260.     zSize = blocks->zSiz;
  261.     uvSize = uvSize_;
  262. }
  263.  
  264. void AEditableWood::Cut(int32 splitLocation) {
  265.     PairUBlockStructure pair = blockStructure->SplitBlocks(splitLocation, cutAlong::X_AXIS);
  266.     AEditableWood* left = GetWorld()->SpawnActor<AEditableWood>(AEditableWood::StaticClass());
  267.     AEditableWood* right = GetWorld()->SpawnActor<AEditableWood>(AEditableWood::StaticClass());
  268.     left->init(pair.A, uvSize);
  269.     right->init(pair.B, uvSize);
  270. }
  271. // Called when the game starts or when spawned
  272. void AEditableWood::BeginPlay()
  273. {
  274.     GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::FromInt(blockStructure->ySiz) + " B1  " + FString::FromInt(blockStructure->zSiz));
  275.     Super::BeginPlay();
  276.  
  277.     //GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::FromInt(blockStructure->ySiz) + " B2  " + FString::FromInt(blockStructure->zSiz));
  278.  
  279.     PairUBlockStructure pair = blockStructure->SplitBlocks(2, cutAlong::X_AXIS);
  280. }
  281.  
  282. // Called every frame
  283. void AEditableWood::Tick( float DeltaTime )
  284. {
  285.     Super::Tick( DeltaTime );
  286.  
  287. }
  288.  
  289. #if WITH_EDITOR
  290. void AEditableWood::PostEditChangeProperty(FPropertyChangedEvent& e)
  291. {
  292.     Super::PostEditChangeProperty(e);
  293.  
  294.     FName PropertyName = (e.Property != NULL) ? e.Property->GetFName() : NAME_None;
  295.     if (PropertyName == GET_MEMBER_NAME_CHECKED(AEditableWood, cubeSize)||
  296.         PropertyName == GET_MEMBER_NAME_CHECKED(AEditableWood, xSize)   ||
  297.         PropertyName == GET_MEMBER_NAME_CHECKED(AEditableWood, ySize)   ||
  298.         PropertyName == GET_MEMBER_NAME_CHECKED(AEditableWood, zSize)   ||
  299.         PropertyName == GET_MEMBER_NAME_CHECKED(AEditableWood, uvSize)) {
  300.         GenerateMesh();
  301.     }
  302. }
  303. #endif
Advertisement
Add Comment
Please, Sign In to add comment