|  |  | @ -13,7 +13,6 @@ | 
		
	
		
			
			|  |  |  | * | 
		
	
		
			
			|  |  |  | ********************************************************************************************/ | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | #include "raylib.h" | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | #include "raymath.h" | 
		
	
	
		
			
				|  |  | @ -43,12 +42,8 @@ static Vector2 *curveSelectedPoint = NULL; | 
		
	
		
			
			|  |  |  | //---------------------------------------------------------------------------------- | 
		
	
		
			
			|  |  |  | // Module Functions Declaration | 
		
	
		
			
			|  |  |  | //---------------------------------------------------------------------------------- | 
		
	
		
			
			|  |  |  | static void UpdateOptions(void); | 
		
	
		
			
			|  |  |  | static void UpdateCurve(void); | 
		
	
		
			
			|  |  |  | static void DrawCurve(void); | 
		
	
		
			
			|  |  |  | static void DrawTexturedCurve(void); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | //------------------------------------------------------------------------------------ | 
		
	
		
			
			|  |  |  | // Program main entry point | 
		
	
		
			
			|  |  |  | //------------------------------------------------------------------------------------ | 
		
	
	
		
			
				|  |  | @ -81,9 +76,31 @@ int main() | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | // Update | 
		
	
		
			
			|  |  |  | //---------------------------------------------------------------------------------- | 
		
	
		
			
			|  |  |  | UpdateCurve(); | 
		
	
		
			
			|  |  |  | UpdateOptions(); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // Curve config options | 
		
	
		
			
			|  |  |  | if (IsKeyPressed(KEY_SPACE)) showCurve = !showCurve; | 
		
	
		
			
			|  |  |  | if (IsKeyPressed(KEY_EQUAL)) curveWidth += 2; | 
		
	
		
			
			|  |  |  | if (IsKeyPressed(KEY_MINUS)) curveWidth -= 2; | 
		
	
		
			
			|  |  |  | if (curveWidth < 2) curveWidth = 2; | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // Update segments | 
		
	
		
			
			|  |  |  | if (IsKeyPressed(KEY_LEFT)) curveSegments -= 2; | 
		
	
		
			
			|  |  |  | if (IsKeyPressed(KEY_RIGHT)) curveSegments += 2; | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if (curveSegments < 2) curveSegments = 2; | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // Update curve logic | 
		
	
		
			
			|  |  |  | // If the mouse is not down, we are not editing the curve so clear the selection | 
		
	
		
			
			|  |  |  | if (!IsMouseButtonDown(MOUSE_LEFT_BUTTON))  curveSelectedPoint = NULL; | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // If a point was selected, move it | 
		
	
		
			
			|  |  |  | if (curveSelectedPoint) *curveSelectedPoint = Vector2Add(*curveSelectedPoint, GetMouseDelta()); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // The mouse is down, and nothing was selected, so see if anything was picked | 
		
	
		
			
			|  |  |  | Vector2 mouse = GetMousePosition(); | 
		
	
		
			
			|  |  |  | if (CheckCollisionPointCircle(mouse, curveStartPosition, 6)) curveSelectedPoint = &curveStartPosition; | 
		
	
		
			
			|  |  |  | else if (CheckCollisionPointCircle(mouse, curveStartPositionTangent, 6)) curveSelectedPoint = &curveStartPositionTangent; | 
		
	
		
			
			|  |  |  | else if (CheckCollisionPointCircle(mouse, curveEndPosition, 6)) curveSelectedPoint = &curveEndPosition; | 
		
	
		
			
			|  |  |  | else if (CheckCollisionPointCircle(mouse, curveEndPositionTangent, 6)) curveSelectedPoint = &curveEndPositionTangent; | 
		
	
		
			
			|  |  |  | //---------------------------------------------------------------------------------- | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // Draw | 
		
	
	
		
			
				|  |  | @ -92,9 +109,29 @@ int main() | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | ClearBackground(RAYWHITE); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | DrawTexturedCurve(); | 
		
	
		
			
			|  |  |  | DrawCurve(); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | DrawTexturedCurve();    // Draw a textured Spline Cubic Bezier | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // Draw spline for reference | 
		
	
		
			
			|  |  |  | if (showCurve) DrawSplineSegmentBezierCubic(curveStartPosition, curveEndPosition, curveStartPositionTangent, curveEndPositionTangent, 2, BLUE); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // Draw the various control points and highlight where the mouse is | 
		
	
		
			
			|  |  |  | DrawLineV(curveStartPosition, curveStartPositionTangent, SKYBLUE); | 
		
	
		
			
			|  |  |  | DrawLineV(curveStartPositionTangent, curveEndPositionTangent, Fade(LIGHTGRAY, 0.4f)); | 
		
	
		
			
			|  |  |  | DrawLineV(curveEndPosition, curveEndPositionTangent, PURPLE); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if (CheckCollisionPointCircle(mouse, curveStartPosition, 6)) DrawCircleV(curveStartPosition, 7, YELLOW); | 
		
	
		
			
			|  |  |  | DrawCircleV(curveStartPosition, 5, RED); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if (CheckCollisionPointCircle(mouse, curveStartPositionTangent, 6)) DrawCircleV(curveStartPositionTangent, 7, YELLOW); | 
		
	
		
			
			|  |  |  | DrawCircleV(curveStartPositionTangent, 5, MAROON); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if (CheckCollisionPointCircle(mouse, curveEndPosition, 6)) DrawCircleV(curveEndPosition, 7, YELLOW); | 
		
	
		
			
			|  |  |  | DrawCircleV(curveEndPosition, 5, GREEN); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if (CheckCollisionPointCircle(mouse, curveEndPositionTangent, 6)) DrawCircleV(curveEndPositionTangent, 7, YELLOW); | 
		
	
		
			
			|  |  |  | DrawCircleV(curveEndPositionTangent, 5, DARKGREEN); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // Draw usage info | 
		
	
		
			
			|  |  |  | DrawText("Drag points to move curve, press SPACE to show/hide base curve", 10, 10, 10, DARKGRAY); | 
		
	
		
			
			|  |  |  | DrawText(TextFormat("Curve width: %2.0f (Use + and - to adjust)", curveWidth), 10, 30, 10, DARKGRAY); | 
		
	
		
			
			|  |  |  | DrawText(TextFormat("Curve segments: %d (Use LEFT and RIGHT to adjust)", curveSegments), 10, 50, 10, DARKGRAY); | 
		
	
	
		
			
				|  |  | @ -116,54 +153,8 @@ int main() | 
		
	
		
			
			|  |  |  | //---------------------------------------------------------------------------------- | 
		
	
		
			
			|  |  |  | // Module Functions Definition | 
		
	
		
			
			|  |  |  | //---------------------------------------------------------------------------------- | 
		
	
		
			
			|  |  |  | static void DrawCurve(void) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | if (showCurve) DrawSplineSegmentBezierCubic(curveStartPosition, curveEndPosition, curveStartPositionTangent, curveEndPositionTangent, 2, BLUE); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // Draw the various control points and highlight where the mouse is | 
		
	
		
			
			|  |  |  | DrawLineV(curveStartPosition, curveStartPositionTangent, SKYBLUE); | 
		
	
		
			
			|  |  |  | DrawLineV(curveStartPositionTangent, curveEndPositionTangent, Fade(LIGHTGRAY, 0.4f)); | 
		
	
		
			
			|  |  |  | DrawLineV(curveEndPosition, curveEndPositionTangent, PURPLE); | 
		
	
		
			
			|  |  |  | Vector2 mouse = GetMousePosition(); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if (CheckCollisionPointCircle(mouse, curveStartPosition, 6)) DrawCircleV(curveStartPosition, 7, YELLOW); | 
		
	
		
			
			|  |  |  | DrawCircleV(curveStartPosition, 5, RED); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if (CheckCollisionPointCircle(mouse, curveStartPositionTangent, 6)) DrawCircleV(curveStartPositionTangent, 7, YELLOW); | 
		
	
		
			
			|  |  |  | DrawCircleV(curveStartPositionTangent, 5, MAROON); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if (CheckCollisionPointCircle(mouse, curveEndPosition, 6)) DrawCircleV(curveEndPosition, 7, YELLOW); | 
		
	
		
			
			|  |  |  | DrawCircleV(curveEndPosition, 5, GREEN); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if (CheckCollisionPointCircle(mouse, curveEndPositionTangent, 6)) DrawCircleV(curveEndPositionTangent, 7, YELLOW); | 
		
	
		
			
			|  |  |  | DrawCircleV(curveEndPositionTangent, 5, DARKGREEN); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | static void UpdateCurve(void) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | // If the mouse is not down, we are not editing the curve so clear the selection | 
		
	
		
			
			|  |  |  | if (!IsMouseButtonDown(MOUSE_LEFT_BUTTON)) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | curveSelectedPoint = NULL; | 
		
	
		
			
			|  |  |  | return; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // If a point was selected, move it | 
		
	
		
			
			|  |  |  | if (curveSelectedPoint) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | *curveSelectedPoint = Vector2Add(*curveSelectedPoint, GetMouseDelta()); | 
		
	
		
			
			|  |  |  | return; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // The mouse is down, and nothing was selected, so see if anything was picked | 
		
	
		
			
			|  |  |  | Vector2 mouse = GetMousePosition(); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if (CheckCollisionPointCircle(mouse, curveStartPosition, 6)) curveSelectedPoint = &curveStartPosition; | 
		
	
		
			
			|  |  |  | else if (CheckCollisionPointCircle(mouse, curveStartPositionTangent, 6)) curveSelectedPoint = &curveStartPositionTangent; | 
		
	
		
			
			|  |  |  | else if (CheckCollisionPointCircle(mouse, curveEndPosition, 6)) curveSelectedPoint = &curveEndPosition; | 
		
	
		
			
			|  |  |  | else if (CheckCollisionPointCircle(mouse, curveEndPositionTangent, 6)) curveSelectedPoint = &curveEndPositionTangent; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // Draw textured curve using Spline Cubic Bezier | 
		
	
		
			
			|  |  |  | static void DrawTexturedCurve(void) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | const float step = 1.0f/curveSegments; | 
		
	
	
		
			
				|  |  | @ -180,11 +171,11 @@ static void DrawTexturedCurve(void) | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | for (int i = 1; i <= curveSegments; i++) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | o">// Segment the curve | 
		
	
		
			
			|  |  |  | t = step*i; | 
		
	
		
			
			|  |  |  | float a = powf(i">1 - t, 3); | 
		
	
		
			
			|  |  |  | float b = i">3*powf(1 - t, 2)*t; | 
		
	
		
			
			|  |  |  | float c = i">3*(1 - t)*powf(t, 2); | 
		
	
		
			
			|  |  |  | n">t = step*(float)i; | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | float a = powf(f">1.0f - t, 3); | 
		
	
		
			
			|  |  |  | float b = f">3.0f*powf(1.0f - t, 2)*t; | 
		
	
		
			
			|  |  |  | float c = f">3.0f*(1.0f - t)*powf(t, 2); | 
		
	
		
			
			|  |  |  | float d = powf(t, 3); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // Compute the endpoint for this segment | 
		
	
	
		
			
				|  |  | @ -217,22 +208,20 @@ static void DrawTexturedCurve(void) | 
		
	
		
			
			|  |  |  | // Draw the segment as a quad | 
		
	
		
			
			|  |  |  | rlSetTexture(texRoad.id); | 
		
	
		
			
			|  |  |  | rlBegin(RL_QUADS); | 
		
	
		
			
			|  |  |  | rlColor4ub(255,255,255,255); | 
		
	
		
			
			|  |  |  | rlNormal3f(0.0f, 0.0f, 1.0f); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | rlColor4ub(255,255,255,255); | 
		
	
		
			
			|  |  |  | rlNormal3f(0.0f, 0.0f, 1.0f); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | rlTexCoord2f(0, previousV); | 
		
	
		
			
			|  |  |  | rlVertex2f(prevNegNormal.x, prevNegNormal.y); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | rlTexCoord2f(1, previousV); | 
		
	
		
			
			|  |  |  | rlVertex2f(prevPosNormal.x, prevPosNormal.y); | 
		
	
		
			
			|  |  |  | rlTexCoord2f(0, previousV); | 
		
	
		
			
			|  |  |  | rlVertex2f(prevNegNormal.x, prevNegNormal.y); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | rlTexCoord2f(1, v); | 
		
	
		
			
			|  |  |  | rlVertex2f(currentPosNormal.x, currentPosNormal.y); | 
		
	
		
			
			|  |  |  | rlTexCoord2f(1, previousV); | 
		
	
		
			
			|  |  |  | rlVertex2f(prevPosNormal.x, prevPosNormal.y); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | rlTexCoord2f(0, v); | 
		
	
		
			
			|  |  |  | rlVertex2f(currentNegNormal.x, currentNegNormal.y); | 
		
	
		
			
			|  |  |  | rlTexCoord2f(1, v); | 
		
	
		
			
			|  |  |  | rlVertex2f(currentPosNormal.x, currentPosNormal.y); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | rlTexCoord2f(0, v); | 
		
	
		
			
			|  |  |  | rlVertex2f(currentNegNormal.x, currentNegNormal.y); | 
		
	
		
			
			|  |  |  | rlEnd(); | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // The current step is the start of the next step | 
		
	
	
		
			
				|  |  | @ -242,19 +231,3 @@ static void DrawTexturedCurve(void) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | static void UpdateOptions(void) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | if (IsKeyPressed(KEY_SPACE)) showCurve = !showCurve; | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // Update with | 
		
	
		
			
			|  |  |  | if (IsKeyPressed(KEY_EQUAL)) curveWidth += 2; | 
		
	
		
			
			|  |  |  | if (IsKeyPressed(KEY_MINUS)) curveWidth -= 2; | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if (curveWidth < 2) curveWidth = 2; | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // Update segments | 
		
	
		
			
			|  |  |  | if (IsKeyPressed(KEY_LEFT)) curveSegments -= 2; | 
		
	
		
			
			|  |  |  | if (IsKeyPressed(KEY_RIGHT)) curveSegments += 2; | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if (curveSegments < 2) curveSegments = 2; | 
		
	
		
			
			|  |  |  | } |