summaryrefslogtreecommitdiffhomepage
path: root/examples
diff options
context:
space:
mode:
authorRay <[email protected]>2023-11-07 19:25:49 +0100
committerRay <[email protected]>2023-11-07 19:25:49 +0100
commitf01d3db7398037ce4a60da4d4ea9582b07834f96 (patch)
treedfca5ae5fdae061f7551aaff5daa3cd5d9992943 /examples
parentc69e1c379b09f02902b7b4a2ee8e5a0683670345 (diff)
downloadraylib-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.c8
-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();
//----------------------------------------------------------------------------------