-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Big refactor, separate the library code and the usage examples.
- Loading branch information
Showing
14 changed files
with
989 additions
and
625 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,6 @@ | ||
cmake_minimum_required(VERSION 3.16) | ||
|
||
project(metaball) | ||
project(metaballs) | ||
set(CMAKE_C_STANDARD 99) | ||
# set(CMAKE_C_STANDARD_REQUIRED TRUE) | ||
|
||
# raylib | ||
find_package(raylib QUIET) | ||
if (NOT raylib_FOUND) | ||
include(FetchContent) | ||
FetchContent_Declare( | ||
raylib | ||
GIT_REPOSITORY https://github.com/raysan5/raylib.git | ||
GIT_TAG 4.5.0 | ||
) | ||
FetchContent_MakeAvailable(raylib) | ||
endif() | ||
|
||
message(STATUS "PROJECT_NAME: ${PROJECT_NAME}") | ||
add_executable(${PROJECT_NAME} main.c metaballs.h) | ||
target_link_libraries(${PROJECT_NAME} PUBLIC raylib) | ||
|
||
add_custom_target(copy_assets | ||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/assets ${CMAKE_CURRENT_BINARY_DIR}/assets | ||
) | ||
add_dependencies(${PROJECT_NAME} copy_assets) | ||
add_subdirectory(examples) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# raylib | ||
find_package(raylib QUIET) | ||
if (NOT raylib_FOUND) | ||
include(FetchContent) | ||
FetchContent_Declare( | ||
raylib | ||
GIT_REPOSITORY https://github.com/raysan5/raylib.git | ||
GIT_TAG 4.5.0 | ||
) | ||
FetchContent_MakeAvailable(raylib) | ||
endif() | ||
|
||
add_library(metaball_dependency | ||
raylib_wrapper.h | ||
raylib_wrapper.c | ||
ball.h | ||
ball.c | ||
) | ||
target_link_libraries(metaball_dependency PUBLIC raylib) | ||
|
||
add_custom_target(copy_assets | ||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/assets ${CMAKE_CURRENT_BINARY_DIR}/assets | ||
) | ||
add_dependencies(metaball_dependency copy_assets) | ||
|
||
add_executable(example0 example0.c) | ||
target_link_libraries(example0 PUBLIC metaball_dependency) | ||
|
||
add_executable(example1 example1.c) | ||
target_link_libraries(example1 PUBLIC metaball_dependency) | ||
|
||
add_executable(example2 example2.c) | ||
target_link_libraries(example2 PUBLIC metaball_dependency) | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#include "ball.h" | ||
|
||
void ball_push(BallArray *balls, Ball ball) | ||
{ | ||
balls->items[balls->count] = ball; | ||
balls->count++; | ||
} | ||
|
||
Ball ball_create_random(Grid grid) | ||
{ | ||
float radius_x = (grid.count.x * grid.size.x) / 4; | ||
float radius_y = (grid.count.y * grid.size.y) / 4; | ||
float radius_z = (grid.count.z * grid.size.z) / 4; | ||
|
||
Vector3d speed = { | ||
.x = 0.1f + (float)rand() / ((float)RAND_MAX / 2.0f), | ||
.y = 0.1f + (float)rand() / ((float)RAND_MAX / 2.0f), | ||
.z = 0.1f + (float)rand() / ((float)RAND_MAX / 2.0f)}; | ||
|
||
Vector3d initial = { | ||
.x = 2.0f - (float)rand() / ((float)RAND_MAX / 4.0f), | ||
.y = 2.0f - (float)rand() / ((float)RAND_MAX / 4.0f), | ||
.z = 2.0f - (float)rand() / ((float)RAND_MAX / 4.0f)}; | ||
|
||
Vector3d p = (Vector3d){ | ||
.x = grid.center.x + radius_x * cos(initial.x), | ||
.y = grid.center.y + radius_y * sin(initial.y), | ||
.z = grid.center.z + radius_z * cos(initial.z)}; | ||
|
||
Color4C color = (Color4C){ | ||
.r = (unsigned char)(64 + (rand() % 192)), | ||
.g = (unsigned char)(128 + (rand() % 128)), | ||
.b = (unsigned char)(128 + (rand() % 128)), | ||
.a = (unsigned char)(255) | ||
}; | ||
|
||
float ball_mass = 50.0f + (float)(rand() % 200); | ||
|
||
return (Ball){.pos = p, .mass = ball_mass, .color = color}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#ifndef _BALL_H_ | ||
#define _BALL_H_ | ||
|
||
#include "../metaballs.h" | ||
|
||
void ball_push(BallArray *balls, Ball ball); | ||
Ball ball_create_random(Grid grid); | ||
|
||
#endif //_BALL_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
#include "ball.h" | ||
#include "raylib_wrapper.h" | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
const int screenWidth = 800; | ||
const int screenHeight = 400; | ||
InitWindow(screenWidth, screenHeight, "Metaballs"); | ||
//DisableCursor(); | ||
|
||
Index3d count = {.x = 10, .y = 10, .z = 10}; | ||
Vector3d size = {.x = 2, .y = 2, .z = 2}; | ||
Vector3d pos = {.x = 0, .y = 0, .z = 0}; | ||
Grid grid = grid_create(count, size, pos); | ||
|
||
BallArray balls = MB_CREATE_ARRAY(Ball, 3); | ||
|
||
Vector3d zero = { | ||
.x = 0.0f, | ||
.y = 0.0f, | ||
.z = 0.0f}; | ||
|
||
Vector3d center = (Vector3d){ | ||
.x = grid.center.x, | ||
.y = grid.center.y, | ||
.z = grid.center.z}; | ||
|
||
Color4C color = (Color4C){ | ||
.r = 0xff, | ||
.g = 0xff, | ||
.b = 0xff, | ||
.a = 0xff | ||
}; | ||
ball_push(&balls, (Ball){.pos = center, .mass = 15, .color = color}); | ||
|
||
// Define the camera to look into our 3d world | ||
Camera camera = {0}; | ||
camera.position = (Vector3){grid.center.x, grid.center.y, grid.center.z - grid.count.z * grid.size.z * 1.5}; // Camera position | ||
camera.target = (Vector3){grid.center.x, grid.center.y, grid.center.z}; // Camera looking at point | ||
camera.up = (Vector3){0.0f, 1.0f, 0.0f}; // Camera up vector (rotation towards target) | ||
camera.fovy = 45.0f; // Camera field-of-view Y | ||
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type | ||
|
||
|
||
Material wired = LoadMaterialDefault(); | ||
wired.maps[MATERIAL_MAP_DIFFUSE].color = GRAY; | ||
wired.maps[MATERIAL_MAP_SPECULAR].color = GRAY; | ||
|
||
Texture2D text2d = LoadTexture("assets/uv.png"); | ||
SetTextureWrap(text2d, TEXTURE_WRAP_CLAMP); | ||
Material material = LoadMaterialDefault(); | ||
material.maps[MATERIAL_MAP_DIFFUSE].texture = text2d; | ||
material.maps[MATERIAL_MAP_SPECULAR].color = GRAY; | ||
|
||
Matrix transform = (Matrix){1.0f, 0.0f, 0.0f, 0.0f, | ||
0.0f, 1.0f, 0.0f, 0.0f, | ||
0.0f, 0.0f, 1.0f, 0.0f, | ||
0.0f, 0.0f, 0.0f, 1.0f}; | ||
|
||
// RL upload mesh | ||
Mesh rayMesh = raylib_upload_mesh(grid); | ||
|
||
while (!WindowShouldClose()) // Detect window close button or ESC key | ||
{ | ||
|
||
UpdateCamera(&camera, CAMERA_THIRD_PERSON); | ||
camera.target = (Vector3){grid.center.x, grid.center.y, grid.center.z}; | ||
|
||
if(IsKeyPressed(KEY_U)) { | ||
grid.config.wired = !grid.config.wired; | ||
} | ||
if(IsKeyPressed(KEY_P)) { | ||
grid.config.mapping = MAPPING_PLANAR; | ||
} | ||
if(IsKeyPressed(KEY_L)) { | ||
grid.config.mapping = MAPPING_SPHERIC; | ||
} | ||
|
||
if(IsKeyPressed(KEY_H)) { | ||
grid.config.threshold += 0.05f; | ||
} | ||
if(IsKeyPressed(KEY_J)) { | ||
grid.config.threshold -= 0.05f; | ||
} | ||
|
||
generate_mesh(&grid, balls); | ||
|
||
BeginDrawing(); | ||
ClearBackground(RAYWHITE); | ||
BeginMode3D(camera); | ||
// RL render mesh | ||
raylib_render_mesh(grid, &rayMesh, material, wired, transform); | ||
EndMode3D(); | ||
|
||
char label_fps[256]; | ||
sprintf(label_fps, "FPS: %d", GetFPS()); | ||
DrawText(label_fps, 10, 10, 20, BLACK); | ||
|
||
// sprintf(label_fps, "CACHE HIT: %lu, MISS: %lu", cache_hit, cache_miss); | ||
// DrawText(label_fps, 10, 50, 20, BLACK); | ||
EndDrawing(); | ||
} | ||
|
||
|
||
// RL unload mesh | ||
raylib_unload_mesh(&rayMesh); | ||
MB_DESTROY_ARRAY(balls); | ||
grid_destroy(&grid); | ||
|
||
CloseWindow(); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
#include "ball.h" | ||
#include "raylib_wrapper.h" | ||
|
||
|
||
void update_balls(BallArray balls, Vector3d pos, float radius) { | ||
|
||
float t = GetTime(); | ||
|
||
Vector3d movement[] = {{.x = 1.1, .y = 1.3, .z = 1.7}, | ||
{.x = 0.7, .y = 1.9, .z = 2.3}, | ||
{.x = 0.3, .y = 2.9, .z = 1.1}, | ||
{.x = 1.3, .y = 1.7, .z = 0.7}, | ||
{.x = 2.3, .y = 1.9, .z = 2.9}}; | ||
const size_t count = sizeof(movement) / sizeof(movement[0]); | ||
|
||
|
||
float ec = radius; | ||
for (size_t i = 0; i < balls.count; i++) | ||
{ | ||
Vector3d m = movement[i % count]; | ||
balls.items[i].pos = (Vector3d){.x = pos.x - cos(t*m.x) * radius, | ||
.y = pos.y - cos(t*m.y) * radius, | ||
.z = pos.z - cos(t*m.z) * radius}; | ||
|
||
} | ||
} | ||
|
||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
const int screenWidth = 800; | ||
const int screenHeight = 400; | ||
InitWindow(screenWidth, screenHeight, "Metaballs"); | ||
DisableCursor(); | ||
|
||
Index3d count = {.x = 20 * 2, .y = 20 * 2, .z = 20 * 2}; | ||
Vector3d size = {.x = 10 / 2, .y = 10 / 2, .z = 10 / 2}; | ||
Vector3d pos = {.x = 0, .y = 0, .z = 0}; | ||
Grid grid = grid_create(count, size, pos); | ||
|
||
BallArray balls = MB_CREATE_ARRAY(Ball, 5); | ||
for (size_t i = 0; i < balls.capacity; i++) | ||
{ | ||
ball_push(&balls, ball_create_random(grid)); | ||
} | ||
|
||
// Define the camera to look into our 3d world | ||
Camera camera = {0}; | ||
camera.position = (Vector3){grid.center.x, grid.center.y, grid.center.z - grid.count.z * grid.size.z * 1.5}; // Camera position | ||
camera.target = (Vector3){grid.center.x, grid.center.y, grid.center.z}; // Camera looking at point | ||
camera.up = (Vector3){0.0f, 1.0f, 0.0f}; // Camera up vector (rotation towards target) | ||
camera.fovy = 45.0f; // Camera field-of-view Y | ||
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type | ||
|
||
|
||
Material wired = LoadMaterialDefault(); | ||
wired.maps[MATERIAL_MAP_DIFFUSE].color = GRAY; | ||
wired.maps[MATERIAL_MAP_SPECULAR].color = GRAY; | ||
|
||
Texture2D text2d = LoadTexture("assets/uv.png"); | ||
SetTextureWrap(text2d, TEXTURE_WRAP_MIRROR_REPEAT); | ||
Material material = LoadMaterialDefault(); | ||
material.maps[MATERIAL_MAP_DIFFUSE].texture = text2d; | ||
material.maps[MATERIAL_MAP_SPECULAR].color = GRAY; | ||
|
||
Matrix transform = (Matrix){1.0f, 0.0f, 0.0f, 0.0f, | ||
0.0f, 1.0f, 0.0f, 0.0f, | ||
0.0f, 0.0f, 1.0f, 0.0f, | ||
0.0f, 0.0f, 0.0f, 1.0f}; | ||
|
||
// RL upload mesh | ||
Mesh rayMesh = raylib_upload_mesh(grid); | ||
|
||
while (!WindowShouldClose()) // Detect window close button or ESC key | ||
{ | ||
|
||
UpdateCamera(&camera, CAMERA_THIRD_PERSON); | ||
camera.target = (Vector3){grid.center.x, grid.center.y, grid.center.z}; | ||
|
||
if (!IsKeyDown(KEY_SPACE)) | ||
{ | ||
update_balls(balls, grid.center, grid.size.x * 10); | ||
} | ||
if(IsKeyPressed(KEY_U)) { | ||
grid.config.wired = !grid.config.wired; | ||
} | ||
if(IsKeyPressed(KEY_P)) { | ||
grid.config.mapping = MAPPING_PLANAR; | ||
} | ||
if(IsKeyPressed(KEY_L)) { | ||
grid.config.mapping = MAPPING_SPHERIC; | ||
} | ||
|
||
if(IsKeyPressed(KEY_H)) { | ||
grid.config.threshold += 0.05f; | ||
} | ||
if(IsKeyPressed(KEY_J)) { | ||
grid.config.threshold -= 0.05f; | ||
} | ||
|
||
generate_mesh(&grid, balls); | ||
|
||
BeginDrawing(); | ||
ClearBackground(RAYWHITE); | ||
BeginMode3D(camera); | ||
// RL render mesh | ||
raylib_render_mesh(grid, &rayMesh, material, wired, transform); | ||
EndMode3D(); | ||
|
||
char label_fps[256]; | ||
sprintf(label_fps, "FPS: %d", GetFPS()); | ||
DrawText(label_fps, 10, 10, 20, BLACK); | ||
|
||
// sprintf(label_fps, "CACHE HIT: %lu, MISS: %lu", cache_hit, cache_miss); | ||
// DrawText(label_fps, 10, 50, 20, BLACK); | ||
EndDrawing(); | ||
} | ||
|
||
|
||
// RL unload mesh | ||
raylib_unload_mesh(&rayMesh); | ||
MB_DESTROY_ARRAY(balls); | ||
grid_destroy(&grid); | ||
|
||
CloseWindow(); | ||
|
||
return 0; | ||
} |
Oops, something went wrong.