diff options
author | bonmas14 <bonmas14@gmail.com> | 2025-09-20 22:28:15 +0300 |
---|---|---|
committer | bonmas14 <bonmas14@gmail.com> | 2025-09-20 22:28:15 +0300 |
commit | cdda4c4182c9ee068567529715e4a5c68a8efb58 (patch) | |
tree | 38a63f62a64018a2d35fc33354f8589fd33b7514 /deps/raylib/examples/models/models_mesh_picking.c | |
download | c_wizard-cdda4c4182c9ee068567529715e4a5c68a8efb58.tar.gz c_wizard-cdda4c4182c9ee068567529715e4a5c68a8efb58.zip |
Init commit v1.0
Diffstat (limited to 'deps/raylib/examples/models/models_mesh_picking.c')
-rw-r--r-- | deps/raylib/examples/models/models_mesh_picking.c | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/deps/raylib/examples/models/models_mesh_picking.c b/deps/raylib/examples/models/models_mesh_picking.c new file mode 100644 index 0000000..15723e3 --- /dev/null +++ b/deps/raylib/examples/models/models_mesh_picking.c @@ -0,0 +1,246 @@ +/******************************************************************************************* +* +* raylib [models] example - Mesh picking in 3d mode, ground plane, triangle, mesh +* +* Example originally created with raylib 1.7, last time updated with raylib 4.0 +* +* Example contributed by Joel Davis (@joeld42) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2017-2024 Joel Davis (@joeld42) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" +#include "raymath.h" + +#define FLT_MAX 340282346638528859811704183484516925440.0f // Maximum value of a float, from bit pattern 01111111011111111111111111111111 + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [models] example - mesh picking"); + + // Define the camera to look into our 3d world + Camera camera = { 0 }; + camera.position = (Vector3){ 20.0f, 20.0f, 20.0f }; // Camera position + camera.target = (Vector3){ 0.0f, 8.0f, 0.0f }; // Camera looking at point + camera.up = (Vector3){ 0.0f, 1.6f, 0.0f }; // Camera up vector (rotation towards target) + camera.fovy = 45.0f; // Camera field-of-view Y + camera.projection = CAMERA_PERSPECTIVE; // Camera projection type + + Ray ray = { 0 }; // Picking ray + + Model tower = LoadModel("resources/models/obj/turret.obj"); // Load OBJ model + Texture2D texture = LoadTexture("resources/models/obj/turret_diffuse.png"); // Load model texture + tower.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set model diffuse texture + + Vector3 towerPos = { 0.0f, 0.0f, 0.0f }; // Set model position + BoundingBox towerBBox = GetMeshBoundingBox(tower.meshes[0]); // Get mesh bounding box + + // Ground quad + Vector3 g0 = (Vector3){ -50.0f, 0.0f, -50.0f }; + Vector3 g1 = (Vector3){ -50.0f, 0.0f, 50.0f }; + Vector3 g2 = (Vector3){ 50.0f, 0.0f, 50.0f }; + Vector3 g3 = (Vector3){ 50.0f, 0.0f, -50.0f }; + + // Test triangle + Vector3 ta = (Vector3){ -25.0f, 0.5f, 0.0f }; + Vector3 tb = (Vector3){ -4.0f, 2.5f, 1.0f }; + Vector3 tc = (Vector3){ -8.0f, 6.5f, 0.0f }; + + Vector3 bary = { 0.0f, 0.0f, 0.0f }; + + // Test sphere + Vector3 sp = (Vector3){ -30.0f, 5.0f, 5.0f }; + float sr = 4.0f; + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + if (IsCursorHidden()) UpdateCamera(&camera, CAMERA_FIRST_PERSON); // Update camera + + // Toggle camera controls + if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) + { + if (IsCursorHidden()) EnableCursor(); + else DisableCursor(); + } + + // Display information about closest hit + RayCollision collision = { 0 }; + char *hitObjectName = "None"; + collision.distance = FLT_MAX; + collision.hit = false; + Color cursorColor = WHITE; + + // Get ray and test against objects + ray = GetScreenToWorldRay(GetMousePosition(), camera); + + // Check ray collision against ground quad + RayCollision groundHitInfo = GetRayCollisionQuad(ray, g0, g1, g2, g3); + + if ((groundHitInfo.hit) && (groundHitInfo.distance < collision.distance)) + { + collision = groundHitInfo; + cursorColor = GREEN; + hitObjectName = "Ground"; + } + + // Check ray collision against test triangle + RayCollision triHitInfo = GetRayCollisionTriangle(ray, ta, tb, tc); + + if ((triHitInfo.hit) && (triHitInfo.distance < collision.distance)) + { + collision = triHitInfo; + cursorColor = PURPLE; + hitObjectName = "Triangle"; + + bary = Vector3Barycenter(collision.point, ta, tb, tc); + } + + // Check ray collision against test sphere + RayCollision sphereHitInfo = GetRayCollisionSphere(ray, sp, sr); + + if ((sphereHitInfo.hit) && (sphereHitInfo.distance < collision.distance)) + { + collision = sphereHitInfo; + cursorColor = ORANGE; + hitObjectName = "Sphere"; + } + + // Check ray collision against bounding box first, before trying the full ray-mesh test + RayCollision boxHitInfo = GetRayCollisionBox(ray, towerBBox); + + if ((boxHitInfo.hit) && (boxHitInfo.distance < collision.distance)) + { + collision = boxHitInfo; + cursorColor = ORANGE; + hitObjectName = "Box"; + + // Check ray collision against model meshes + RayCollision meshHitInfo = { 0 }; + for (int m = 0; m < tower.meshCount; m++) + { + // NOTE: We consider the model.transform for the collision check but + // it can be checked against any transform Matrix, used when checking against same + // model drawn multiple times with multiple transforms + meshHitInfo = GetRayCollisionMesh(ray, tower.meshes[m], tower.transform); + if (meshHitInfo.hit) + { + // Save the closest hit mesh + if ((!collision.hit) || (collision.distance > meshHitInfo.distance)) collision = meshHitInfo; + + break; // Stop once one mesh collision is detected, the colliding mesh is m + } + } + + if (meshHitInfo.hit) + { + collision = meshHitInfo; + cursorColor = ORANGE; + hitObjectName = "Mesh"; + } + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginMode3D(camera); + + // Draw the tower + // WARNING: If scale is different than 1.0f, + // not considered by GetRayCollisionModel() + DrawModel(tower, towerPos, 1.0f, WHITE); + + // Draw the test triangle + DrawLine3D(ta, tb, PURPLE); + DrawLine3D(tb, tc, PURPLE); + DrawLine3D(tc, ta, PURPLE); + + // Draw the test sphere + DrawSphereWires(sp, sr, 8, 8, PURPLE); + + // Draw the mesh bbox if we hit it + if (boxHitInfo.hit) DrawBoundingBox(towerBBox, LIME); + + // If we hit something, draw the cursor at the hit point + if (collision.hit) + { + DrawCube(collision.point, 0.3f, 0.3f, 0.3f, cursorColor); + DrawCubeWires(collision.point, 0.3f, 0.3f, 0.3f, RED); + + Vector3 normalEnd; + normalEnd.x = collision.point.x + collision.normal.x; + normalEnd.y = collision.point.y + collision.normal.y; + normalEnd.z = collision.point.z + collision.normal.z; + + DrawLine3D(collision.point, normalEnd, RED); + } + + DrawRay(ray, MAROON); + + DrawGrid(10, 10.0f); + + EndMode3D(); + + // Draw some debug GUI text + DrawText(TextFormat("Hit Object: %s", hitObjectName), 10, 50, 10, BLACK); + + if (collision.hit) + { + int ypos = 70; + + DrawText(TextFormat("Distance: %3.2f", collision.distance), 10, ypos, 10, BLACK); + + DrawText(TextFormat("Hit Pos: %3.2f %3.2f %3.2f", + collision.point.x, + collision.point.y, + collision.point.z), 10, ypos + 15, 10, BLACK); + + DrawText(TextFormat("Hit Norm: %3.2f %3.2f %3.2f", + collision.normal.x, + collision.normal.y, + collision.normal.z), 10, ypos + 30, 10, BLACK); + + if (triHitInfo.hit && TextIsEqual(hitObjectName, "Triangle")) + DrawText(TextFormat("Barycenter: %3.2f %3.2f %3.2f", bary.x, bary.y, bary.z), 10, ypos + 45, 10, BLACK); + } + + DrawText("Right click mouse to toggle camera controls", 10, 430, 10, GRAY); + + DrawText("(c) Turret 3D model by Alberto Cano", screenWidth - 200, screenHeight - 20, 10, GRAY); + + DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadModel(tower); // Unload model + UnloadTexture(texture); // Unload texture + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file |