Untitled

 avatar
unknown
plain_text
2 months ago
5.4 kB
3
Indexable
#include "raylib.h"
#include "raymath.h"
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include "glm/glm.hpp"

#define DB_PERLIN_IMPL
#include "db_perlin.hpp"

#define SCR_WIDTH	1024
#define SCR_HEIGHT	780 
#define GRIDW	2048
#define GRIDH	1560
#define CELL_SIZE	20
#define COLS		GRIDW / CELL_SIZE
#define ROWS		GRIDH / CELL_SIZE
#define MIN_HEIGHT  -10
#define MAX_HEIGHT  5
#define MOVE_SPEED  60

#define CAM_INIT_POS { 35.f,  SCR_WIDTH, 210.0f }
#define CAM_INIT_TARGET { 120.f, SCR_WIDTH, 150.f}
#define CAM_UP { 0.0,  0.0f,	 1.0f }
#define CAM_FOVY 45.0f
#define FLYING_SPEED 0.01f

float flying = 0.f;

float map(float value, float inMin, float inMax, float outMin, float outMax);

void Init(Camera3D& camera, float terrain[COLS][ROWS]);
void SetTerrain(float terrain[COLS][ROWS]);
void Update(Camera3D& camera);
void ProcessInput(Camera3D& camera);
void Draw(Camera& camera,float terrain[COLS][ROWS]);

int main(void)
{
	// Initialization
	Camera3D camera = { 0 };
	float terrain[COLS][ROWS];
	Init(camera,terrain);

	while (!WindowShouldClose())
	{
		Update(camera);
		ProcessInput(camera);
		Draw(camera,terrain);
	}

	// De-Initialization
	CloseWindow();
	return 0;
}

void Init(Camera3D& camera, float terrain[COLS][ROWS])
{
	// Initialization
	InitWindow(SCR_WIDTH, SCR_HEIGHT, "Raylib - 3D Terrain Generation");

	camera.position = CAM_INIT_POS;
	camera.target = CAM_INIT_TARGET;
	camera.up = CAM_UP;
	camera.fovy = CAM_FOVY;
	camera.projection = CAMERA_PERSPECTIVE;

	SetTargetFPS(60);
	DisableCursor();
}

void SetTerrain(float terrain[COLS][ROWS])
{
	flying += FLYING_SPEED;

	float yoff = flying;
	for (int x = 0; x < COLS; x++)
	{
		float xoff = 0.f;
		for (int y = 0; y < ROWS; y++)
		{
			// Generate noise value
			float noiseValue = db::perlin(xoff, yoff);

			// Map the noise value to the desired range
			terrain[x][y] = map(noiseValue, 0.f, 1.0f, MIN_HEIGHT, MAX_HEIGHT);

			xoff += 0.2f;
		}
		yoff += 0.2f;
	}
}


void Update(Camera3D& camera)
{
	// Update
	UpdateCamera(&camera, CAMERA_FREE);

	// Print camera settings to the console
	//printf("Camera Position: x: %.2f, y: %.2f, z: %.2f\n", camera.position.x, camera.position.y, camera.position.z);
	//printf("Camera Target:   x: %.2f, y: %.2f, z: %.2f\n", camera.target.x, camera.target.y, camera.target.z);
	//printf("Camera Up:       x: %.2f, y: %.2f, z: %.2f\n", camera.up.x, camera.up.y, camera.up.z);
	//printf("Camera FOV:      %.2f\n\n", camera.fovy);
}

void ProcessInput(Camera3D& camera)
{

	float moveAmount = MOVE_SPEED * GetFrameTime();

	// Calculate forward and right vectors
	Vector3 forward = Vector3Normalize(Vector3Subtract(camera.target, camera.position));
	Vector3 right = Vector3Normalize(Vector3CrossProduct(forward, camera.up));

	// Forward and Backward Movement
	if (IsKeyDown(KEY_W))
	{
		camera.position = Vector3Add(camera.position, Vector3Scale(forward, moveAmount));
		camera.target = Vector3Add(camera.target, Vector3Scale(forward, moveAmount));
	}
	if (IsKeyDown(KEY_S))
	{
		camera.position = Vector3Subtract(camera.position, Vector3Scale(forward, moveAmount));
		camera.target = Vector3Subtract(camera.target, Vector3Scale(forward, moveAmount));
	}

	// Left and Right Movement
	if (IsKeyDown(KEY_A))
	{
		camera.position = Vector3Subtract(camera.position, Vector3Scale(right, moveAmount));
		camera.target = Vector3Subtract(camera.target, Vector3Scale(right, moveAmount));
	}
	if (IsKeyDown(KEY_D))
	{
		camera.position = Vector3Add(camera.position, Vector3Scale(right, moveAmount));
		camera.target = Vector3Add(camera.target, Vector3Scale(right, moveAmount));
	}

	// Up and Down Movement
	if (IsKeyDown(KEY_E))
	{
		camera.position.z += moveAmount;
		camera.target.z += moveAmount;
	}
	if (IsKeyDown(KEY_Q))
	{
		camera.position.z -= moveAmount;
		camera.target.z -= moveAmount;
	}

	// Ensure camera.up remains consistent
	camera.up = CAM_UP;
}

void Draw(Camera& camera,float terrain[COLS][ROWS])
{
	SetTerrain(terrain);
	
	BeginDrawing();
	ClearBackground(BLACK);

	BeginMode3D(camera);

	// Draw the terrain grid
	for (int x = 0; x < COLS - 1; x++)
	{
		for (int y = 0; y < ROWS - 1; y++)
		{
			// Get heights from the terrain array
			float zTopLeft = terrain[x][y];
			float zTopRight = terrain[x + 1][y];
			float zBottomLeft = terrain[x][y + 1];
			float zBottomRight = terrain[x + 1][y + 1];

			// Define corners of the current cell
			Vector3 topLeft = { (float) x * CELL_SIZE, (float) y * CELL_SIZE, zTopLeft };
			Vector3 topRight = { (float) (x + 1) * CELL_SIZE, (float) y * CELL_SIZE, zTopRight };
			Vector3 bottomLeft = { (float) x * CELL_SIZE, (float) (y + 1) * CELL_SIZE, zBottomLeft };
			Vector3 bottomRight = { (float) (x + 1) * CELL_SIZE, (float) (y + 1) * CELL_SIZE, zBottomRight };

			// Draw horizontal and vertical lines
			DrawLine3D(topLeft, topRight, RAYWHITE);       // Top edge
			DrawLine3D(topLeft, bottomLeft, RAYWHITE);     // Left edge

			// Draw diagonal lines
			DrawLine3D(topRight, bottomLeft, RAYWHITE);     // Diagonal (top-right to bottom-left)
			DrawLine3D(topLeft, bottomRight, RAYWHITE);     // Diagonal (top-left to bottom-right)
		}
	}

	EndMode3D();
	DrawFPS(10, 10);
	EndDrawing();
}

float map(float value, float inMin, float inMax, float outMin, float outMax)
{
	float t = (value - inMin) / (inMax - inMin); // Normalize the input
	return glm::mix(outMin, outMax, t);         // Interpolate using glm::mix
}

Editor is loading...
Leave a Comment