summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorsmalltimewizard <[email protected]>2024-06-30 05:09:21 -0400
committerGitHub <[email protected]>2024-06-30 11:09:21 +0200
commit953df38ac47e7e05a8f7b5eef12990aa07522af8 (patch)
tree7ccb1fbc8b53e4b268fe762c3ffe68ffe5df1392
parentd8214c916e6b80188cb8f9b18e11f50767b165b8 (diff)
downloadraylib-953df38ac47e7e05a8f7b5eef12990aa07522af8.tar.gz
raylib-953df38ac47e7e05a8f7b5eef12990aa07522af8.zip
[rmodels] `DrawSphereEx()` optimization (#4106)
* Optimize DrawSphereEx() Precalculates sin/cos to eliminate unnecessary calls. * Formatting correction to previous commit * Bugfix to optimized DrawSphereEx() OBO error -- added 1 additional precalculated cos/sin value to each array to complete the 360-degree wraparound. Technically the value of these last elements will always be the same as the first element due to 360-degree wraparound, but this is the simplest solution. * Corrected missing free() * Formatting correction * New DrawSphereEx() algorithm
-rw-r--r--src/rmodels.c52
1 files changed, 29 insertions, 23 deletions
diff --git a/src/rmodels.c b/src/rmodels.c
index 432413cd..6de27021 100644
--- a/src/rmodels.c
+++ b/src/rmodels.c
@@ -432,30 +432,36 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
- for (int i = 0; i < (rings + 2); i++)
- {
- for (int j = 0; j < slices; j++)
- {
- rlVertex3f(cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*i))*sinf(DEG2RAD*(360.0f*j/slices)),
- sinf(DEG2RAD*(270 + (180.0f/(rings + 1))*i)),
- cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*i))*cosf(DEG2RAD*(360.0f*j/slices)));
- rlVertex3f(cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1)))*sinf(DEG2RAD*(360.0f*(j + 1)/slices)),
- sinf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1))),
- cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1)))*cosf(DEG2RAD*(360.0f*(j + 1)/slices)));
- rlVertex3f(cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1)))*sinf(DEG2RAD*(360.0f*j/slices)),
- sinf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1))),
- cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1)))*cosf(DEG2RAD*(360.0f*j/slices)));
-
- rlVertex3f(cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*i))*sinf(DEG2RAD*(360.0f*j/slices)),
- sinf(DEG2RAD*(270 + (180.0f/(rings + 1))*i)),
- cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*i))*cosf(DEG2RAD*(360.0f*j/slices)));
- rlVertex3f(cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i)))*sinf(DEG2RAD*(360.0f*(j + 1)/slices)),
- sinf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i))),
- cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i)))*cosf(DEG2RAD*(360.0f*(j + 1)/slices)));
- rlVertex3f(cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1)))*sinf(DEG2RAD*(360.0f*(j + 1)/slices)),
- sinf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1))),
- cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1)))*cosf(DEG2RAD*(360.0f*(j + 1)/slices)));
+ float ringangle = DEG2RAD*(180.0f/(rings + 1)); // Angle between latitudinal parallels
+ float sliceangle = DEG2RAD*(360.0f/slices); // Angle between longitudinal meridians
+
+ float cosring = cosf(ringangle);
+ float sinring = sinf(ringangle);
+ float cosslice = cosf(sliceangle);
+ float sinslice = sinf(sliceangle);
+
+ Vector3 vertices[4]; // Store face vertices
+ vertices[2] = (Vector3){0,1,0};
+ vertices[3] = (Vector3){sinring, cosring, 0};
+
+ for (int i = 0; i < rings + 1; i++) {
+ for (int j = 0; j < slices; j++) {
+ vertices[0] = vertices[2]; // Rotate around y axis to set up vertices for next face
+ vertices[1] = vertices[3];
+ vertices[2] = (Vector3){cosslice*vertices[2].x - sinslice*vertices[2].z, vertices[2].y, sinslice*vertices[2].x + cosslice*vertices[2].z}; // Rotation matrix around y axis
+ vertices[3] = (Vector3){cosslice*vertices[3].x - sinslice*vertices[3].z, vertices[3].y, sinslice*vertices[3].x + cosslice*vertices[3].z};
+
+ rlVertex3f(vertices[0].x, vertices[0].y, vertices[0].z);
+ rlVertex3f(vertices[3].x, vertices[3].y, vertices[3].z);
+ rlVertex3f(vertices[1].x, vertices[1].y, vertices[1].z);
+
+ rlVertex3f(vertices[0].x, vertices[0].y, vertices[0].z);
+ rlVertex3f(vertices[2].x, vertices[2].y, vertices[2].z);
+ rlVertex3f(vertices[3].x, vertices[3].y, vertices[3].z);
}
+
+ vertices[2] = vertices[3]; // Rotate around z axis to set up starting vertices for next ring
+ vertices[3] = (Vector3){cosring*vertices[3].x + sinring*vertices[3].y, -sinring*vertices[3].x + cosring*vertices[3].y, vertices[3].z}; // Rotation matrix around z axis
}
rlEnd();
rlPopMatrix();