From 682cdc319c37322481285a0a4e1992dfd3116cd4 Mon Sep 17 00:00:00 2001 From: Horrowind Date: Mon, 11 Oct 2021 22:29:24 +0200 Subject: [PATCH] Add DrawCylinderEx and DrawCylinderWiresEx --- src/raylib.h | 2 + src/rmodels.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/src/raylib.h b/src/raylib.h index 7bcb39e37..3ef4133e8 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1384,7 +1384,9 @@ RLAPI void DrawSphere(Vector3 centerPos, float radius, Color color); RLAPI void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters RLAPI void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires RLAPI void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone +RLAPI void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder with base at startPos and top at endPos RLAPI void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires +RLAPI void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder wires with base at startPos and top at endPos RLAPI void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ RLAPI void DrawRay(Ray ray, Color color); // Draw a ray line RLAPI void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0)) diff --git a/src/rmodels.c b/src/rmodels.c index 2069aaabb..708a25cf9 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -767,6 +767,64 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h rlPopMatrix(); } +// Draw a cylinder with base at startPos and top at endPos +// NOTE: It could be also used for pyramid and cone +void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color) +{ + if (sides < 3) sides = 3; + + int numVertex = sides*6; + rlCheckRenderBatchLimit(numVertex); + if(sides < 3) sides = 3; + + Vector3 difference = Vector3Subtract(endPos, startPos); + // Construct a basis of the base and the top face: + Vector3 b1 = Vector3Normalize(Vector3Perpendicular(difference)); + Vector3 b2 = Vector3Normalize(Vector3CrossProduct(b1, difference)); + + float base_angle = (2.0 * PI) / sides; + + rlBegin(RL_TRIANGLES); + rlColor4ub(color.r, color.g, color.b, color.a); + + for (int i = 0; i < sides; i++) { + // compute the four vertices + float s1 = sinf(base_angle * (i+0)) * startRadius; + float c1 = cosf(base_angle * (i+0)) * startRadius; + Vector3 w1 = Vector3Add(startPos, Vector3Add(Vector3Scale(b1, s1), Vector3Scale(b2, c1))); + float s2 = sinf(base_angle * (i+1)) * startRadius; + float c2 = cosf(base_angle * (i+1)) * startRadius; + Vector3 w2 = Vector3Add(startPos, Vector3Add(Vector3Scale(b1, s2), Vector3Scale(b2, c2))); + float s3 = sinf(base_angle * (i+0)) * endRadius; + float c3 = cosf(base_angle * (i+0)) * endRadius; + Vector3 w3 = Vector3Add(endPos, Vector3Add(Vector3Scale(b1, s3), Vector3Scale(b2, c3))); + float s4 = sinf(base_angle * (i+1)) * endRadius; + float c4 = cosf(base_angle * (i+1)) * endRadius; + Vector3 w4 = Vector3Add(endPos, Vector3Add(Vector3Scale(b1, s4), Vector3Scale(b2, c4))); + + if (startRadius > 0) { // + rlVertex3f(startPos.x, startPos.y, startPos.z); // | + rlVertex3f(w2.x, w2.y, w2.z); // T0 + rlVertex3f(w1.x, w1.y, w1.z); // | + } // + // w2 x.-----------x startPos + rlVertex3f(w1.x, w1.y, w1.z); // | |\'. T0 / + rlVertex3f(w2.x, w2.y, w2.z); // T1 | \ '. / + rlVertex3f(w3.x, w3.y, w3.z); // | |T \ '. / + // | 2 \ T 'x w1 + rlVertex3f(w2.x, w2.y, w2.z); // | w4 x.---\-1-|---x endPos + rlVertex3f(w4.x, w4.y, w4.z); // T2 '. \ |T3/ + rlVertex3f(w3.x, w3.y, w3.z); // | '. \ | / + // '.\|/ + if (endRadius > 0) { // 'x w3 + rlVertex3f(endPos.x, endPos.y, endPos.z); // | + rlVertex3f(w3.x, w3.y, w3.z); // T3 + rlVertex3f(w4.x, w4.y, w4.z); // | + } // + } + rlEnd(); +} + // Draw a wired cylinder // NOTE: It could be also used for pyramid and cone void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int sides, Color color) @@ -800,6 +858,54 @@ void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, fl rlPopMatrix(); } + +// Draw a wired cylinder with base at startPos and top at endPos +// NOTE: It could be also used for pyramid and cone +void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color) +{ + if (sides < 3) sides = 3; + + int numVertex = sides*6; + rlCheckRenderBatchLimit(numVertex); + + Vector3 difference = Vector3Subtract(endPos, startPos); + // Construct a basis of the base and the top face: + Vector3 b1 = Vector3Normalize(Vector3Perpendicular(difference)); + Vector3 b2 = Vector3Normalize(Vector3CrossProduct(b1, difference)); + + float base_angle = (2.0 * PI) / sides; + + rlBegin(RL_LINES); + rlColor4ub(color.r, color.g, color.b, color.a); + + for (int i = 0; i < sides; i++) { + // compute the four vertices + float s1 = sinf(base_angle * (i+0)) * startRadius; + float c1 = cosf(base_angle * (i+0)) * startRadius; + Vector3 w1 = Vector3Add(startPos, Vector3Add(Vector3Scale(b1, s1), Vector3Scale(b2, c1))); + float s2 = sinf(base_angle * (i+1)) * startRadius; + float c2 = cosf(base_angle * (i+1)) * startRadius; + Vector3 w2 = Vector3Add(startPos, Vector3Add(Vector3Scale(b1, s2), Vector3Scale(b2, c2))); + float s3 = sinf(base_angle * (i+0)) * endRadius; + float c3 = cosf(base_angle * (i+0)) * endRadius; + Vector3 w3 = Vector3Add(endPos, Vector3Add(Vector3Scale(b1, s3), Vector3Scale(b2, c3))); + float s4 = sinf(base_angle * (i+1)) * endRadius; + float c4 = cosf(base_angle * (i+1)) * endRadius; + Vector3 w4 = Vector3Add(endPos, Vector3Add(Vector3Scale(b1, s4), Vector3Scale(b2, c4))); + + rlVertex3f(w1.x, w1.y, w1.z); + rlVertex3f(w2.x, w2.y, w2.z); + + rlVertex3f(w1.x, w1.y, w1.z); + rlVertex3f(w3.x, w3.y, w3.z); + + rlVertex3f(w3.x, w3.y, w3.z); + rlVertex3f(w4.x, w4.y, w4.z); + } + rlEnd(); +} + + // Draw a plane void DrawPlane(Vector3 centerPos, Vector2 size, Color color) {