Merge branch 'master' into master

This commit is contained in:
Jon Daniel 2025-08-08 02:24:57 +02:00 • committed by GitHub
commit 0842aabe5c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 2557 additions and 769 deletions

View file

@ -25,6 +25,9 @@
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 450
Vector2 screenSize = { SCREEN_WIDTH, SCREEN_HEIGHT };
Vector2 screenCenter = CalculateCenter(screenSize);
// Constant for Simulation
#define SIMULATION_STEPS 30
#define G 9.81
@ -42,19 +45,19 @@ int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
SetConfigFlags(FLAG_WINDOW_HIGHDPI);
InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "raylib [shapes] example - Double Pendulum");
Vector2 screenSize = { GetScreenWidth(), GetScreenHeight() };
Vector2 screenCenter = CalculateCenter(screenSize);
SetConfigFlags(FLAG_WINDOW_HIGHDPI);
InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "raylib [shapes] example - Double Pendulum");
// Simulation Paramters
//--------------------------------------------------------------------------------------
float l1 = 15, m1 = 0.2, theta1 = DEG2RAD * 170, w1 = 0;
float l2 = 15, m2 = 0.1, theta2 = DEG2RAD * 0, w2 = 0;
float lengthScaler = 0.1;
float totalM = m1 + m2;
Vector2 previousPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2);
previousPosition.x += screenCenter.x;
previousPosition.y += screenCenter.y;
@ -62,11 +65,10 @@ int main(void)
float L1 = l1 * lengthScaler;
float L2 = l2 * lengthScaler;
// Draw Parameters
//--------------------------------------------------------------------------------------
// Draw parameters
int lineThick = 20, trailThick = 2;
float fateAlpha = 0.01;
// Create Framebuffer
//--------------------------------------------------------------------------------------
RenderTexture2D target = LoadRenderTexture(screenSize.x, screenSize.y);
@ -79,6 +81,7 @@ int main(void)
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
float dt = GetFrameTime();
float step = dt / SIMULATION_STEPS, step2 = step * step;
if(IsWindowResized())
@ -93,56 +96,51 @@ int main(void)
}
// Update Physics - larger steps = better approximation
//----------------------------------------------------------------------------------
for (int i = 0; i < SIMULATION_STEPS; ++i)
{
float delta = theta1 - theta2;
float sinD = sin(delta), cosD = cos(delta), cos2D = cos(2 * delta);
float sinD = sinf(delta), cosD = cosf(delta), cos2D = cosf(2*delta);
float ww1 = w1 * w1, ww2 = w2 * w2;
// Calculate a1
float a1 = (-G * (2 * m1 + m2) * sin(theta1)
- m2 * G * sin(theta1 - 2 * theta2)
- 2 * sinD * m2 * (ww2 * L2 + ww1 * L1 * cosD))
/ (L1 * (2 * m1 + m2 - m2 * cos2D));
float a1 = (-G*(2*m1 + m2)*sinf(theta1)
- m2*G*sinf(theta1 - 2*theta2)
- 2*sinD*m2*(ww2*L2 + ww1*L1*cosD))
/ (L1*(2*m1 + m2 - m2*cos2D));
// Calculate a2
float a2 = (2 * sinD * (ww1 * L1 * totalM
+ G * totalM * cos(theta1)
+ ww2 * L2 * m2 * cosD))
/ (L2 * (2 * m1 + m2 - m2 * cos2D));
float a2 = (2*sinD*(ww1*L1*totalM
+ G*totalM*cosf(theta1)
+ ww2*L2*m2*cosD))
/ (L2*(2*m1 + m2 - m2*cos2D));
// Update thetas
theta1 += w1 * step + 0.5 * a1 * step2;
theta2 += w2 * step + 0.5 * a2 * step2;
theta1 += w1*step + 0.5f*a1*step2;
theta2 += w2*step + 0.5f*a2*step2;
// Update omegas
w1 += a1 * step;
w2 += a2 * step;
w1 += a1*step;
w2 += a2*step;
}
//----------------------------------------------------------------------------------
// Calculate position
Vector2 currentPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2);
currentPosition.x += screenCenter.x;
currentPosition.y += screenCenter.y;
// Draw to framebuffer
//----------------------------------------------------------------------------------
// Draw to render texture
BeginTextureMode(target);
// Draw a transparent rectangle - smaller alpha = longer trails
DrawRectangle(0, 0, screenSize.x, screenSize.y, Fade(BLACK, fateAlpha));
DrawRectangle(0, 0, screenSize.x, screenSize.y, Fade(BLACK, fateAlpha));
// Draw trail
DrawCircleV(previousPosition, trailThick, RED);
DrawLineEx(previousPosition, currentPosition, trailThick * 2, RED);
EndTextureMode();
//----------------------------------------------------------------------------------
// Update previous position
previousPosition = currentPosition;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
@ -150,9 +148,8 @@ int main(void)
ClearBackground(BLACK);
// Draw Trails Texture
DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height },
(Vector2){ 0, 0 }, WHITE);
// Draw trails texture
DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE);
// Draw Double Pendulum
DrawRectanglePro((Rectangle){ screenCenter.x, screenCenter.y, 10 * l1, lineThick },
@ -162,6 +159,14 @@ int main(void)
DrawRectanglePro((Rectangle){ screenCenter.x + endpoint1.x, screenCenter.y + endpoint1.y, 10 * l2, lineThick },
(Vector2){0, lineThick * 0.5}, 90 - RAD2DEG * theta2, RAYWHITE);
// Draw double pendulum
DrawRectanglePro((Rectangle){ screenWidth/2, screenHeight/2 - 100, 10 * l1, lineThick },
(Vector2){0, lineThick * 0.5}, 90 - RAD2DEG * theta1, RAYWHITE);
Vector2 endpoint1 = CalculatePendulumEndPoint(l1, theta1);
DrawRectanglePro((Rectangle){ screenWidth/2 + endpoint1.x, screenHeight/2 - 100 + endpoint1.y, 10 * l2, lineThick },
(Vector2){0, lineThick * 0.5}, 90 - RAD2DEG * theta2, RAYWHITE);
EndDrawing();
//----------------------------------------------------------------------------------
}

View file

@ -5,7 +5,7 @@
* Example complexity rating: [★★★☆] 3/4
*
* NOTE: This example requires 'easings.h' library, provided on raylib/src. Just copy
* the library to same directory as example or make sure it's available on include path.
* the library to same directory as example or make sure it's available on include path
*
* Example originally created with raylib 2.0, last time updated with raylib 2.5
*

View file

@ -69,7 +69,7 @@ int main(void)
// Draw line Cubic Bezier, in-out interpolation (easing), no control points
DrawLineBezier(startPoint, endPoint, 4.0f, BLUE);
// Draw start-end spline circles with some details
DrawCircleV(startPoint, CheckCollisionPointCircle(mouse, startPoint, 10.0f)? 14.0f : 8.0f, moveStartPoint? RED : BLUE);
DrawCircleV(endPoint, CheckCollisionPointCircle(mouse, endPoint, 10.0f)? 14.0f : 8.0f, moveEndPoint? RED : BLUE);

View file

@ -1,6 +1,6 @@
/*******************************************************************************************
*
* raylib [shapes] example - Draw raylib logo using basic shapes
* raylib [shapes] example - draw raylib logo using basic shapes
*
* Example complexity rating: [★☆☆☆] 1/4
*

View file

@ -1,6 +1,6 @@
/*******************************************************************************************
*
* raylib [shapes] example - Rectangle advanced
* raylib [shapes] example - advanced rectangle drawing
*
* Example complexity rating: [★★★★] 4/4
*
@ -33,9 +33,9 @@ int main(void)
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - rectangle avanced");
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@ -195,7 +195,7 @@ static void DrawRectangleRoundedGradientH(Rectangle rec, float roundnessLeft, fl
}
// Here we use the 'Diagram' to guide ourselves to which point receives what color
// By choosing the color correctly associated with a pointe the gradient effect
// By choosing the color correctly associated with a pointe the gradient effect
// will naturally come from OpenGL interpolation
// [2] Upper Rectangle
@ -265,10 +265,10 @@ static void DrawRectangleRoundedGradientH(Rectangle rec, float roundnessLeft, fl
rlSetTexture(0);
#else
// Here we use the 'Diagram' to guide ourselves to which point receives what color.
// By choosing the color correctly associated with a pointe the gradient effect
// will naturally come from OpenGL interpolation.
// But this time instead of Quad, we think in triangles.
// Here we use the 'Diagram' to guide ourselves to which point receives what color
// By choosing the color correctly associated with a pointe the gradient effect
// will naturally come from OpenGL interpolation
// But this time instead of Quad, we think in triangles
rlBegin(RL_TRIANGLES);
// Draw all of the 4 corners: [1] Upper Left Corner, [3] Upper Right Corner, [5] Lower Right Corner, [7] Lower Left Corner
@ -280,10 +280,10 @@ static void DrawRectangleRoundedGradientH(Rectangle rec, float roundnessLeft, fl
if (k == 1) color = right, radius = radiusRight; // [3] Upper Right Corner
if (k == 2) color = right, radius = radiusRight; // [5] Lower Right Corner
if (k == 3) color = left, radius = radiusLeft; // [7] Lower Left Corner
float angle = angles[k];
const Vector2 center = centers[k];
for (int i = 0; i < segments; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);

View file

@ -65,7 +65,7 @@ int main(void)
// Check minimum rec size
if (rec.width < MOUSE_SCALE_MARK_SIZE) rec.width = MOUSE_SCALE_MARK_SIZE;
if (rec.height < MOUSE_SCALE_MARK_SIZE) rec.height = MOUSE_SCALE_MARK_SIZE;
// Check maximum rec size
if (rec.width > (GetScreenWidth() - rec.x)) rec.width = GetScreenWidth() - rec.x;
if (rec.height > (GetScreenHeight() - rec.y)) rec.height = GetScreenHeight() - rec.y;

View file

@ -23,7 +23,7 @@
#define MAX_SPLINE_POINTS 32
// Cubic Bezier spline control points
// NOTE: Every segment has two control points
// NOTE: Every segment has two control points
typedef struct {
Vector2 start;
Vector2 end;
@ -57,17 +57,17 @@ int main(void)
{ 520.0f, 60.0f },
{ 710.0f, 260.0f },
};
// Array required for spline bezier-cubic,
// Array required for spline bezier-cubic,
// including control points interleaved with start-end segment points
Vector2 pointsInterleaved[3*(MAX_SPLINE_POINTS - 1) + 1] = { 0 };
int pointCount = 5;
int selectedPoint = -1;
int focusedPoint = -1;
Vector2 *selectedControlPoint = NULL;
Vector2 *focusedControlPoint = NULL;
// Cubic Bezier control points initialization
ControlPoint control[MAX_SPLINE_POINTS-1] = { 0 };
for (int i = 0; i < pointCount - 1; i++)
@ -79,9 +79,9 @@ int main(void)
// Spline config variables
float splineThickness = 8.0f;
int splineTypeActive = SPLINE_LINEAR; // 0-Linear, 1-BSpline, 2-CatmullRom, 3-Bezier
bool splineTypeEditMode = false;
bool splineTypeEditMode = false;
bool splineHelpersActive = true;
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@ -114,14 +114,14 @@ int main(void)
}
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) selectedPoint = focusedPoint;
}
// Spline point movement logic
if (selectedPoint >= 0)
{
points[selectedPoint] = GetMousePosition();
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) selectedPoint = -1;
}
// Cubic Bezier spline control points logic
if ((splineTypeActive == SPLINE_BEZIER) && (focusedPoint == -1))
{
@ -144,7 +144,7 @@ int main(void)
}
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) selectedControlPoint = focusedControlPoint;
}
// Spline control point movement logic
if (selectedControlPoint != NULL)
{
@ -152,7 +152,7 @@ int main(void)
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) selectedControlPoint = NULL;
}
}
// Spline selection logic
if (IsKeyPressed(KEY_ONE)) splineTypeActive = 0;
else if (IsKeyPressed(KEY_TWO)) splineTypeActive = 1;
@ -168,7 +168,7 @@ int main(void)
BeginDrawing();
ClearBackground(RAYWHITE);
if (splineTypeActive == SPLINE_LINEAR)
{
// Draw spline: linear
@ -191,7 +191,7 @@ int main(void)
{
// Draw spline: catmull-rom
DrawSplineCatmullRom(points, pointCount, splineThickness, RED); // Provide connected points array
/*
for (int i = 0; i < (pointCount - 3); i++)
{
@ -202,20 +202,20 @@ int main(void)
}
else if (splineTypeActive == SPLINE_BEZIER)
{
// NOTE: Cubic-bezier spline requires the 2 control points of each segnment to be
// NOTE: Cubic-bezier spline requires the 2 control points of each segnment to be
// provided interleaved with the start and end point of every segment
for (int i = 0; i < (pointCount - 1); i++)
for (int i = 0; i < (pointCount - 1); i++)
{
pointsInterleaved[3*i] = points[i];
pointsInterleaved[3*i + 1] = control[i].start;
pointsInterleaved[3*i + 2] = control[i].end;
}
pointsInterleaved[3*(pointCount - 1)] = points[pointCount - 1];
// Draw spline: cubic-bezier (with control points)
DrawSplineBezierCubic(pointsInterleaved, 3*(pointCount - 1) + 1, splineThickness, RED);
/*
for (int i = 0; i < 3*(pointCount - 1); i += 3)
{
@ -234,7 +234,7 @@ int main(void)
else if (focusedControlPoint == &control[i].end) DrawCircleV(control[i].end, 8, GREEN);
DrawLineEx(points[i], control[i].start, 1.0f, LIGHTGRAY);
DrawLineEx(points[i + 1], control[i].end, 1.0f, LIGHTGRAY);
// Draw spline control lines
DrawLineV(points[i], control[i].start, GRAY);
//DrawLineV(control[i].start, control[i].end, LIGHTGRAY);
@ -258,7 +258,7 @@ int main(void)
// Check all possible UI states that require controls lock
if (splineTypeEditMode || (selectedPoint != -1) || (selectedControlPoint != NULL)) GuiLock();
// Draw spline config
GuiLabel((Rectangle){ 12, 62, 140, 24 }, TextFormat("Spline thickness: %i", (int)splineThickness));
GuiSliderBar((Rectangle){ 12, 60 + 24, 140, 16 }, NULL, NULL, &splineThickness, 1.0f, 40.0f);
@ -269,7 +269,7 @@ int main(void)
GuiLabel((Rectangle){ 12, 10, 140, 24 }, "Spline type:");
if (GuiDropdownBox((Rectangle){ 12, 8 + 24, 140, 28 }, "LINEAR;BSPLINE;CATMULLROM;BEZIER", &splineTypeActive, splineTypeEditMode)) splineTypeEditMode = !splineTypeEditMode;
GuiUnlock();
EndDrawing();

View file

@ -55,7 +55,7 @@ LightInfo lights[MAX_LIGHTS] = { 0 };
void MoveLight(int slot, float x, float y)
{
lights[slot].dirty = true;
lights[slot].position.x = x;
lights[slot].position.x = x;
lights[slot].position.y = y;
// update the cached bounds
@ -99,7 +99,7 @@ void DrawLightMask(int slot)
// If we are valid, then draw the light radius to the alpha mask
if (lights[slot].valid) DrawCircleGradient((int)lights[slot].position.x, (int)lights[slot].position.y, lights[slot].outerRadius, ColorAlpha(WHITE, 0), WHITE);
rlDrawRenderBatchActive();
// Cut out the shadows from the light radius by forcing the alpha to maximum
@ -114,7 +114,7 @@ void DrawLightMask(int slot)
}
rlDrawRenderBatchActive();
// Go back to normal blend mode
rlSetBlendMode(BLEND_ALPHA);
@ -156,7 +156,7 @@ bool UpdateLight(int slot, Rectangle* boxes, int count)
if (!CheckCollisionRecs(lights[slot].bounds, boxes[i])) continue;
// Check the edges that are on the same side we are, and cast shadow volumes out from them
// Top
Vector2 sp = (Vector2){ boxes[i].x, boxes[i].y };
Vector2 ep = (Vector2){ boxes[i].x + boxes[i].width, boxes[i].y };
@ -219,7 +219,7 @@ int main(void)
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - top down lights");
// Initialize our 'world' of boxes
@ -274,7 +274,7 @@ int main(void)
{
// Build up the light mask
BeginTextureMode(lightMask);
ClearBackground(BLACK);
// Force the blend mode to only set the alpha of the destination
@ -300,10 +300,10 @@ int main(void)
BeginDrawing();
ClearBackground(BLACK);
// Draw the tile background
DrawTextureRec(backgroundTexture, (Rectangle){ 0, 0, (float)GetScreenWidth(), (float)GetScreenHeight() }, Vector2Zero(), WHITE);
// Overlay the shadows from all the lights
DrawTextureRec(lightMask.texture, (Rectangle){ 0, 0, (float)GetScreenWidth(), -(float)GetScreenHeight() }, Vector2Zero(), ColorAlpha(WHITE, showLines? 0.75f : 1.0f));