summaryrefslogtreecommitdiffhomepage
path: root/examples/models/models_solar_system.c
diff options
context:
space:
mode:
authorAldrin Martoq <[email protected]>2019-07-15 12:26:47 -0400
committerRay <[email protected]>2019-07-15 18:26:47 +0200
commite19616592d86791949e5386191c9ab70944ac52d (patch)
treebede1aa4febc7202b92afa04c9392f156bd77fad /examples/models/models_solar_system.c
parent24566c0cf3356fcd1af87e7e1a1fb2abbe73fcc4 (diff)
downloadraylib-e19616592d86791949e5386191c9ab70944ac52d.tar.gz
raylib-e19616592d86791949e5386191c9ab70944ac52d.zip
Adding solar system examples. (#900)
Diffstat (limited to 'examples/models/models_solar_system.c')
-rw-r--r--examples/models/models_solar_system.c244
1 files changed, 244 insertions, 0 deletions
diff --git a/examples/models/models_solar_system.c b/examples/models/models_solar_system.c
new file mode 100644
index 00000000..5e2ba72a
--- /dev/null
+++ b/examples/models/models_solar_system.c
@@ -0,0 +1,244 @@
+/*******************************************************************************************
+*
+* raylib [models] example - full solar system
+*
+* This example has been created using raylib 2.5 (www.raylib.com)
+* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+* Copyright (c) 2019 Aldrin Martoq (@aldrinmartoq)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+#include "rlgl.h"
+
+#define MAX_BODY_CHILDREN 10
+float rotationSpeed = 0.2;
+
+// A celestial body that has children bodies orbiting around
+typedef struct Body {
+ const char *label; // label of the body, for ex: moon
+ float radius; // object radius
+ float orbitRadius; // orbit average radius
+ float orbitPeriod; // time the body takes to do a full orbit loop
+ float rotationPeriod; // time the body takes to do a full rotation on itself
+ Texture2D texture; // texture of the body
+ Model model; // model of the body
+ float orbitPosition; // current orbit position
+ float rotationPosition; // current rotation position
+ Vector2 labelPosition; // label position in screen
+ struct Body *children[MAX_BODY_CHILDREN]; // children array
+ int childrenCount; // children count
+} Body;
+
+//------------------------------------------------------------------------------------
+// Module Functions Declaration
+//------------------------------------------------------------------------------------
+Body CreateBody(float radius, float orbitRadius, float orbitPeriod, const char *label, const char *texture); // Initializes a new Body with the given parameters
+void AddBodyChildren(Body *parent, Body *children); // Add a children body to the parent body
+void DrawBody(Body *body, Camera *camera); // Draw body and its children, updating labelPosition
+void DrawLabels(Body *body); // Draw body label and its children labels
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 1024;
+ const int screenHeight = 768;
+ const char *text;
+ bool gridEnabled = true;
+ bool helpEnabled = false;
+ bool labelEnabled = true;
+ bool cameraParametersEnabled = true;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - solar system");
+
+ // Define the camera to look into our 3d world
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 16.0f, 16.0f, 16.0f };
+ camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
+ camera.fovy = 45.0f;
+ camera.type = CAMERA_PERSPECTIVE;
+
+ SetCameraMode(camera, CAMERA_FREE);
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Create Bodies
+ Body sun = CreateBody(0.2, 0.0, 0, "sun", "2k_sun");
+ Body moon = CreateBody(0.05, 0.200, 24, "moon", "2k_moon");
+ Body mercury = CreateBody(0.05, 0.396, 90, "mercury", "2k_mercury");
+ Body venus = CreateBody(0.05, 0.723, 210, "venus", "2k_venus_atmosphere");
+ Body earth = CreateBody(0.05, 1.000, 365, "earth", "2k_earth_daymap");
+ Body mars = CreateBody(0.05, 1.523, 690, "mars", "2k_mars");
+ Body jupiter = CreateBody(0.05, 5.200, 4260, "jupiter", "2k_jupiter");
+ Body saturn = CreateBody(0.05, 9.532, 10620, "saturn", "2k_saturn");
+ Body uranus = CreateBody(0.05, 19.180, 30270, "uranus", "2k_uranus");
+ Body neptune = CreateBody(0.05, 30.056, 59370, "neptune", "2k_neptune");
+ Body pluto = CreateBody(0.05, 39.463, 89310, "pluto", "2k_eris_fictional");
+
+ AddBodyChildren(&sun, &mercury);
+ // AddBodyChildren(&sun, &venus);
+ AddBodyChildren(&sun, &earth);
+ // AddBodyChildren(&sun, &mars);
+ // AddBodyChildren(&sun, &jupiter);
+ // AddBodyChildren(&sun, &saturn);
+ // AddBodyChildren(&sun, &uranus);
+ // AddBodyChildren(&sun, &neptune);
+ // AddBodyChildren(&sun, &pluto);
+
+ AddBodyChildren(&earth, &moon);
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ UpdateCamera(&camera);
+
+ if (IsKeyPressed(KEY_G)) {
+ gridEnabled = !gridEnabled;
+ }
+
+ if (IsKeyPressed(KEY_H)) {
+ helpEnabled = !helpEnabled;
+ }
+
+ if (IsKeyPressed(KEY_L)) {
+ labelEnabled = !labelEnabled;
+ }
+
+ if (IsKeyPressed(KEY_P)) {
+ cameraParametersEnabled = !cameraParametersEnabled;
+ }
+
+ if (IsKeyPressed(KEY_LEFT)) {
+ rotationSpeed -= 0.1;
+ }
+
+ if (IsKeyPressed(KEY_RIGHT)) {
+ rotationSpeed += 0.1;
+ }
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(BLACK);
+
+ BeginMode3D(camera);
+
+ DrawBody(&sun, &camera);
+
+ // Some reference elements (not affected by previous matrix transformations)
+ if (gridEnabled) {
+ DrawGrid(80, 1.0f);
+ }
+
+ EndMode3D();
+
+ if (labelEnabled) {
+ DrawLabels(&sun);
+ }
+
+ DrawText("FULL SOLAR SYSTEM", 400, 10, 20, YELLOW);
+ text = FormatText("SPEED: %2.2f", rotationSpeed);
+ DrawText(text, 1024 / 2 - MeasureText(text, 20) / 2, 30, 20, YELLOW);
+
+ if (cameraParametersEnabled) {
+ text = FormatText("Camera\nposition: [%3.3f, %3.3f, %3.3f]\ntarget: [%3.3f, %3.3f, %3.3f]\nup: [%3.3f, %3.3f, %3.3f]",
+ camera.position.x, camera.position.y, camera.position.z,
+ camera.target.x, camera.target.y, camera.target.z,
+ camera.up.x, camera.up.y, camera.up.z);
+ DrawText(text, 10, 50, 20, YELLOW);
+ }
+
+ if (helpEnabled) {
+ DrawText("Keys:\n- [g] toggle grid\n- [h] toggle help\n- [l] toggle labels\n- [p] toggle camera parameters\n- [left/right arrows] increase/decrease speed by 0.1", 200, 200, 20, YELLOW);
+ } else {
+ DrawText("press [h] for help", 1016 - MeasureText("press [h] for help", 20), 740, 20, YELLOW);
+ }
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
+
+//--------------------------------------------------------------------------------------------
+// Module Functions Definitions (local)
+//--------------------------------------------------------------------------------------------
+
+// Creates a new body
+Body CreateBody(float radius, float orbitRadius, float orbitPeriod, const char *label, const char *texture_name)
+{
+ Body body;
+ Texture2D texture = LoadTexture(FormatText("resources/solar_system/%s.png", texture_name));
+
+ GenTextureMipmaps(&texture);
+
+ body.label = label;
+ body.radius = radius * 10;
+ body.orbitRadius = orbitRadius * 10;
+ body.orbitPeriod = orbitPeriod;
+ body.model = LoadModel("resources/solar_system/sphere.obj");
+ body.model.materials[0].maps[MAP_DIFFUSE].texture = texture;
+ body.childrenCount = 0;
+ body.orbitPosition = 0.0;
+ return body;
+}
+
+void AddBodyChildren(Body *parent, Body *children) {
+ if (parent->childrenCount >= MAX_BODY_CHILDREN) {
+ TraceLog(LOG_ERROR, "BODY HAS TOO MANY CHILDREN");
+ } else {
+ parent->children[parent->childrenCount] = children;
+ parent->childrenCount++;
+ }
+}
+
+// Draw body and its children
+void DrawBody(Body *body, Camera *camera)
+{
+ DrawModel(body->model, (Vector3) { 0.0f, 0.0f, 0.0f}, body->radius, WHITE);
+
+ body->labelPosition = GetWorldToScreen((Vector3) { body->orbitRadius, body->radius, 0.0 }, *camera);
+
+ for (int i = 0; i < body->childrenCount; i++) {
+ Body *child = body->children[i];
+ child->orbitPosition += rotationSpeed * 360 / child->orbitPeriod;
+ rlPushMatrix();
+ rlRotatef(child->orbitPosition, 0.0, 1.0, 0.0);
+ rlTranslatef(child->orbitRadius, 0.0, 0.0);
+ rlRotatef(-child->orbitPosition, 0.0, 1.0, 0.0);
+
+ DrawBody(child, camera);
+ rlPopMatrix();
+
+ DrawCircle3D((Vector3){ 0.0f, 0.0f, 0.0f }, child->orbitRadius, (Vector3){ 1.0f, 0.0f, 0.0f }, 90.0f, GRAY);
+ }
+}
+
+// Draw body label and its children labels
+void DrawLabels(Body *body)
+{
+ DrawText(body->label, body->labelPosition.x - MeasureText(body->label, 20) / 2, body->labelPosition.y, 20, WHITE);
+
+ for (int i = 0; i < body->childrenCount; i++) {
+ Body *child = body->children[i];
+
+ DrawLabels(child);
+ }
+}