diff options
| author | Ray <[email protected]> | 2023-11-07 19:25:49 +0100 |
|---|---|---|
| committer | Ray <[email protected]> | 2023-11-07 19:25:49 +0100 |
| commit | f01d3db7398037ce4a60da4d4ea9582b07834f96 (patch) | |
| tree | dfca5ae5fdae061f7551aaff5daa3cd5d9992943 /examples | |
| parent | c69e1c379b09f02902b7b4a2ee8e5a0683670345 (diff) | |
| download | raylib-f01d3db7398037ce4a60da4d4ea9582b07834f96.tar.gz raylib-f01d3db7398037ce4a60da4d4ea9582b07834f96.zip | |
ADDED: `GetSplinePoint*()` functions for spline evaluation
RENAMED: `DrawLine<spline_type>()` to `DrawSpline<spline_type>()` for more consistent and clear naming
REVIEWED: Bezier drawing parameters order, more consistent
REVIEWED: Spline-based examples -WIP-
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/shapes/shapes_lines_bezier.c | 8 | ||||
| -rw-r--r-- | examples/shapes/shapes_splines_drawing.c (renamed from examples/shapes/shapes_lines_splines.c) | 114 |
2 files changed, 85 insertions, 37 deletions
diff --git a/examples/shapes/shapes_lines_bezier.c b/examples/shapes/shapes_lines_bezier.c index 7d7bdb0c..5bd916ee 100644 --- a/examples/shapes/shapes_lines_bezier.c +++ b/examples/shapes/shapes_lines_bezier.c @@ -30,7 +30,7 @@ int main(void) Vector2 end = { (float)screenWidth, (float)screenHeight }; Vector2 startControl = { 100, 0 }; - Vector2 endControl = { (float)GetScreenWidth() - 100, (float)GetScreenHeight() }; + Vector2 endControl = { GetScreenWidth() - 100, GetScreenHeight() }; SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -60,9 +60,11 @@ int main(void) DrawText("USE MOUSE LEFT-RIGHT CLICK to DEFINE LINE START and END POINTS", 15, 20, 20, GRAY); - //DrawLineBezier(start, end, 2.0f, RED); + // Draw line cubic-bezier, in-out interpolation (easing), no control points + DrawLineBezier(start, end, 3.0f, BLUE); - DrawLineBezierCubic(start, end, startControl, endControl, 2.0f, RED); + // Draw spline cubic-bezier with control points + DrawSplineBezierCubic(start, startControl, endControl, end, 2.0f, RED); DrawLineEx(start, startControl, 1.0, LIGHTGRAY); DrawLineEx(end, endControl, 1.0, LIGHTGRAY); diff --git a/examples/shapes/shapes_lines_splines.c b/examples/shapes/shapes_splines_drawing.c index c020c60b..711aad21 100644 --- a/examples/shapes/shapes_lines_splines.c +++ b/examples/shapes/shapes_splines_drawing.c @@ -13,13 +13,25 @@ #include "raylib.h" -#define MAX_CONTROL_POINTS 32 +#include <stdlib.h> // Required for: NULL +#define MAX_SPLINE_POINTS 32 + +// Bezier spline control points +// NOTE: Every segment has two control points typedef struct { Vector2 start; Vector2 end; } ControlPoint; +// Spline types +typedef enum { + SPLINE_LINEAR = 0, + SPLINE_BASIS, // B-Spline + SPLINE_CATMULLROM, + SPLINE_BEZIER +} SplineType; + //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ @@ -33,7 +45,7 @@ int main(void) SetConfigFlags(FLAG_MSAA_4X_HINT); InitWindow(screenWidth, screenHeight, "raylib [shapes] example - splines drawing"); - Vector2 points[MAX_CONTROL_POINTS] = { + Vector2 points[MAX_SPLINE_POINTS] = { { 100.0f, 200.0f }, { 300.0f, 400.0f }, { 500.0f, 300.0f }, @@ -43,15 +55,18 @@ int main(void) int pointCount = 5; int selectedPoint = -1; + int focusedPoint = -1; + Vector2 *selectedControlPoint = NULL; + Vector2 *focusedControlPoint = NULL; - int splineType = 0; // 0-Linear, 1-BSpline, 2-CatmullRom, 3-Bezier + int splineType = SPLINE_LINEAR; // 0-Linear, 1-BSpline, 2-CatmullRom, 3-Bezier - // Cubic Bezier control points - ControlPoint control[MAX_CONTROL_POINTS] = { 0 }; + // Cubic Bezier control points initialization + ControlPoint control[MAX_SPLINE_POINTS] = { 0 }; for (int i = 0; i < pointCount - 1; i++) { - control[i].start = points[i]; - control[i].end = points[i + 1]; + control[i].start = (Vector2){ points[i].x - 20, points[i].y - 20 }; + control[i].end = (Vector2){ points[i + 1].x + 20, points[i + 1].y + 20 }; } SetTargetFPS(60); // Set our game to run at 60 frames-per-second @@ -62,30 +77,60 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - // Points movement logic - if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON) && (pointCount < MAX_CONTROL_POINTS)) + // Spline points creation logic (at the end of spline) + if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON) && (pointCount < MAX_SPLINE_POINTS)) { points[pointCount] = GetMousePosition(); pointCount++; } + // Spline point focus and selection logic for (int i = 0; i < pointCount; i++) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) && CheckCollisionPointCircle(GetMousePosition(), points[i], 6.0f)) + if (CheckCollisionPointCircle(GetMousePosition(), points[i], 8.0f)) { - selectedPoint = i; + focusedPoint = i; + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) selectedPoint = i; break; } + else focusedPoint = -1; } - + + // Spline point movement logic if (selectedPoint >= 0) { points[selectedPoint] = GetMousePosition(); if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) selectedPoint = -1; } - // TODO: Cubic Bezier spline control points logic - + // Cubic Bezier spline control points logic + if ((splineType == SPLINE_BEZIER) && (focusedPoint == -1)) + { + // Spline control point focus and selection logic + for (int i = 0; i < pointCount; i++) + { + if (CheckCollisionPointCircle(GetMousePosition(), control[i].start, 6.0f)) + { + focusedControlPoint = &control[i].start; + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) selectedControlPoint = &control[i].start; + break; + } + else if (CheckCollisionPointCircle(GetMousePosition(), control[i].end, 6.0f)) + { + focusedControlPoint = &control[i].end; + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) selectedControlPoint = &control[i].end; + break; + } + else focusedControlPoint = NULL; + } + + // Spline control point movement logic + if (selectedControlPoint != NULL) + { + *selectedControlPoint = GetMousePosition(); + if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) selectedControlPoint = NULL; + } + } // Spline selection logic if (IsKeyPressed(KEY_ONE)) splineType = 0; @@ -100,47 +145,48 @@ int main(void) ClearBackground(RAYWHITE); - if (splineType == 0) // Linear + if (splineType == SPLINE_LINEAR) { - // Draw linear spline - for (int i = 0; i < pointCount - 1; i++) - { - DrawLineEx(points[i], points[i + 1], 2.0f, RED); - } + // Draw spline: linear + DrawSplineLinear(points, pointCount, 2.0f, RED); } - else if (splineType == 1) // B-Spline + else if (splineType == SPLINE_BASIS) { - // Draw b-spline - DrawLineBSpline(points, pointCount, 2.0f, RED); - //for (int i = 0; i < (pointCount - 3); i++) DrawLineBSplineSegment(points[i], points[i + 1], points[i + 2], points[i + 3], 24.0f, BLUE); + // Draw spline: basis + DrawSplineBasis(points, pointCount, 2.0f, RED); + //for (int i = 0; i < (pointCount - 3); i++) DrawSplineBasisSegment(points[i], points[i + 1], points[i + 2], points[i + 3], 24.0f, BLUE); } - else if (splineType == 2) // CatmullRom Spline + else if (splineType == SPLINE_CATMULLROM) { // Draw spline: catmull-rom - DrawLineCatmullRom(points, pointCount, 2.0f, RED); - //for (int i = 0; i < (pointCount - 3); i++) DrawLineCatmullRomSegment(points[i], points[i + 1], points[i + 2], points[i + 3], 24.0f, Fade(BLUE, 0.4f)); + DrawSplineCatmullRom(points, pointCount, 2.0f, RED); + //for (int i = 0; i < (pointCount - 3); i++) DrawSplineCatmullRomSegment(points[i], points[i + 1], points[i + 2], points[i + 3], 24.0f, Fade(BLUE, 0.4f)); } - else if (splineType == 3) // Cubic Bezier + else if (splineType == SPLINE_BEZIER) { - // Draw line bezier cubic (with control points) + // Draw spline: cubic-bezier (with control points) for (int i = 0; i < pointCount - 1; i++) { - DrawLineBezierCubic(points[i], points[i + 1], control[i].start, control[i + 1].end, 2.0f, RED); + DrawSplineBezierCubic(points[i], control[i].start, control[i].end, points[i + 1], 2.0f, RED); - // TODO: Every cubic bezier point should have two control points + // Every cubic bezier point should have two control points DrawCircleV(control[i].start, 4, GOLD); DrawCircleV(control[i].end, 4, GOLD); + if (focusedControlPoint == &control[i].start) DrawCircleV(control[i].start, 6, GREEN); + else if (focusedControlPoint == &control[i].end) DrawCircleV(control[i].end, 6, GREEN); DrawLineEx(points[i], control[i].start, 1.0, LIGHTGRAY); DrawLineEx(points[i + 1], control[i].end, 1.0, LIGHTGRAY); } } - // Draw control points + // Draw spline key-points for (int i = 0; i < pointCount; i++) { - DrawCircleV(points[i], 6.0f, RED); - if ((splineType != 0) && (i < pointCount - 1)) DrawLineV(points[i], points[i + 1], GRAY); + DrawCircleV(points[i], (focusedPoint == i)? 8.0f : 5.0f, (focusedPoint == i)? BLUE: RED); + if ((splineType != 0) && (i < pointCount - 1)) DrawLineV(points[i], points[i + 1], LIGHTGRAY); } + + // TODO: Draw help EndDrawing(); //---------------------------------------------------------------------------------- |
