1 | /******************************************************************************************* |
2 | * |
3 | * raylib [models] example - Plane rotations (yaw, pitch, roll) |
4 | * |
5 | * This example has been created using raylib 1.8 (www.raylib.com) |
6 | * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) |
7 | * |
8 | * Example contributed by Berni (@Berni8k) and reviewed by Ramon Santamaria (@raysan5) |
9 | * |
10 | * Copyright (c) 2017 Berni (@Berni8k) and Ramon Santamaria (@raysan5) |
11 | * |
12 | ********************************************************************************************/ |
13 | |
14 | #include "raylib.h" |
15 | #include "raymath.h" |
16 | |
17 | // Draw angle gauge controls |
18 | void DrawAngleGauge(Texture2D angleGauge, int x, int y, float angle, char title[], Color color); |
19 | |
20 | int main(void) |
21 | { |
22 | // Initialization |
23 | //-------------------------------------------------------------------------------------- |
24 | const int screenWidth = 800; |
25 | const int screenHeight = 450; |
26 | |
27 | InitWindow(screenWidth, screenHeight, "raylib [models] example - plane rotations (yaw, pitch, roll)" ); |
28 | |
29 | Texture2D texAngleGauge = LoadTexture("resources/angle_gauge.png" ); |
30 | Texture2D texBackground = LoadTexture("resources/background.png" ); |
31 | Texture2D texPitch = LoadTexture("resources/pitch.png" ); |
32 | Texture2D texPlane = LoadTexture("resources/plane.png" ); |
33 | |
34 | RenderTexture2D framebuffer = LoadRenderTexture(192, 192); |
35 | |
36 | // Model loading |
37 | Model model = LoadModel("resources/plane.obj" ); // Load OBJ model |
38 | model.materials[0].maps[MAP_DIFFUSE].texture = LoadTexture("resources/plane_diffuse.png" ); // Set map diffuse texture |
39 | |
40 | GenTextureMipmaps(&model.materials[0].maps[MAP_DIFFUSE].texture); |
41 | |
42 | Camera camera = { 0 }; |
43 | camera.position = (Vector3){ 0.0f, 60.0f, -120.0f };// Camera position perspective |
44 | camera.target = (Vector3){ 0.0f, 12.0f, 0.0f }; // Camera looking at point |
45 | camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) |
46 | camera.fovy = 30.0f; // Camera field-of-view Y |
47 | camera.type = CAMERA_PERSPECTIVE; // Camera type |
48 | |
49 | float pitch = 0.0f; |
50 | float roll = 0.0f; |
51 | float yaw = 0.0f; |
52 | |
53 | SetTargetFPS(60); // Set our game to run at 60 frames-per-second |
54 | //-------------------------------------------------------------------------------------- |
55 | |
56 | // Main game loop |
57 | while (!WindowShouldClose()) // Detect window close button or ESC key |
58 | { |
59 | // Update |
60 | //---------------------------------------------------------------------------------- |
61 | |
62 | // Plane roll (x-axis) controls |
63 | if (IsKeyDown(KEY_LEFT)) roll += 1.0f; |
64 | else if (IsKeyDown(KEY_RIGHT)) roll -= 1.0f; |
65 | else |
66 | { |
67 | if (roll > 0.0f) roll -= 0.5f; |
68 | else if (roll < 0.0f) roll += 0.5f; |
69 | } |
70 | |
71 | // Plane yaw (y-axis) controls |
72 | if (IsKeyDown(KEY_S)) yaw += 1.0f; |
73 | else if (IsKeyDown(KEY_A)) yaw -= 1.0f; |
74 | else |
75 | { |
76 | if (yaw > 0.0f) yaw -= 0.5f; |
77 | else if (yaw < 0.0f) yaw += 0.5f; |
78 | } |
79 | |
80 | // Plane pitch (z-axis) controls |
81 | if (IsKeyDown(KEY_DOWN)) pitch += 0.6f; |
82 | else if (IsKeyDown(KEY_UP)) pitch -= 0.6f; |
83 | else |
84 | { |
85 | if (pitch > 0.3f) pitch -= 0.3f; |
86 | else if (pitch < -0.3f) pitch += 0.3f; |
87 | } |
88 | |
89 | // Wraps the phase of an angle to fit between -180 and +180 degrees |
90 | int pitchOffset = pitch; |
91 | while (pitchOffset > 180) pitchOffset -= 360; |
92 | while (pitchOffset < -180) pitchOffset += 360; |
93 | pitchOffset *= 10; |
94 | |
95 | /* matrix transform done with multiplication to combine rotations |
96 | Matrix transform = MatrixIdentity(); |
97 | |
98 | transform = MatrixMultiply(transform, MatrixRotateZ(DEG2RAD*roll)); |
99 | transform = MatrixMultiply(transform, MatrixRotateX(DEG2RAD*pitch)); |
100 | transform = MatrixMultiply(transform, MatrixRotateY(DEG2RAD*yaw)); |
101 | |
102 | model.transform = transform; |
103 | */ |
104 | // matrix created from multiple axes at once |
105 | model.transform = MatrixRotateXYZ((Vector3){DEG2RAD*pitch,DEG2RAD*yaw,DEG2RAD*roll}); |
106 | |
107 | //---------------------------------------------------------------------------------- |
108 | // Draw |
109 | //---------------------------------------------------------------------------------- |
110 | BeginDrawing(); |
111 | |
112 | ClearBackground(RAYWHITE); |
113 | |
114 | // Draw framebuffer texture (Ahrs Display) |
115 | int centerX = framebuffer.texture.width/2; |
116 | int centerY = framebuffer.texture.height/2; |
117 | float scaleFactor = 0.5f; |
118 | |
119 | BeginTextureMode(framebuffer); |
120 | |
121 | BeginBlendMode(BLEND_ALPHA); |
122 | |
123 | DrawTexturePro(texBackground, (Rectangle){ 0, 0, texBackground.width, texBackground.height }, |
124 | (Rectangle){ centerX, centerY, texBackground.width*scaleFactor, texBackground.height*scaleFactor}, |
125 | (Vector2){ texBackground.width/2*scaleFactor, texBackground.height/2*scaleFactor + pitchOffset*scaleFactor }, roll, WHITE); |
126 | |
127 | DrawTexturePro(texPitch, (Rectangle){ 0, 0, texPitch.width, texPitch.height }, |
128 | (Rectangle){ centerX, centerY, texPitch.width*scaleFactor, texPitch.height*scaleFactor }, |
129 | (Vector2){ texPitch.width/2*scaleFactor, texPitch.height/2*scaleFactor + pitchOffset*scaleFactor }, roll, WHITE); |
130 | |
131 | DrawTexturePro(texPlane, (Rectangle){ 0, 0, texPlane.width, texPlane.height }, |
132 | (Rectangle){ centerX, centerY, texPlane.width*scaleFactor, texPlane.height*scaleFactor }, |
133 | (Vector2){ texPlane.width/2*scaleFactor, texPlane.height/2*scaleFactor }, 0, WHITE); |
134 | |
135 | EndBlendMode(); |
136 | |
137 | EndTextureMode(); |
138 | |
139 | // Draw 3D model (recomended to draw 3D always before 2D) |
140 | BeginMode3D(camera); |
141 | |
142 | DrawModel(model, (Vector3){ 0, 6.0f, 0 }, 1.0f, WHITE); // Draw 3d model with texture |
143 | DrawGrid(10, 10.0f); |
144 | |
145 | EndMode3D(); |
146 | |
147 | // Draw 2D GUI stuff |
148 | DrawAngleGauge(texAngleGauge, 80, 70, roll, "roll" , RED); |
149 | DrawAngleGauge(texAngleGauge, 190, 70, pitch, "pitch" , GREEN); |
150 | DrawAngleGauge(texAngleGauge, 300, 70, yaw, "yaw" , SKYBLUE); |
151 | |
152 | DrawRectangle(30, 360, 260, 70, Fade(SKYBLUE, 0.5f)); |
153 | DrawRectangleLines(30, 360, 260, 70, Fade(DARKBLUE, 0.5f)); |
154 | DrawText("Pitch controlled with: KEY_UP / KEY_DOWN" , 40, 370, 10, DARKGRAY); |
155 | DrawText("Roll controlled with: KEY_LEFT / KEY_RIGHT" , 40, 390, 10, DARKGRAY); |
156 | DrawText("Yaw controlled with: KEY_A / KEY_S" , 40, 410, 10, DARKGRAY); |
157 | |
158 | // Draw framebuffer texture |
159 | DrawTextureRec(framebuffer.texture, (Rectangle){ 0, 0, framebuffer.texture.width, -framebuffer.texture.height }, |
160 | (Vector2){ screenWidth - framebuffer.texture.width - 20, 20 }, Fade(WHITE, 0.8f)); |
161 | |
162 | DrawRectangleLines(screenWidth - framebuffer.texture.width - 20, 20, framebuffer.texture.width, framebuffer.texture.height, DARKGRAY); |
163 | |
164 | EndDrawing(); |
165 | //---------------------------------------------------------------------------------- |
166 | } |
167 | |
168 | // De-Initialization |
169 | //-------------------------------------------------------------------------------------- |
170 | |
171 | // Unload all loaded data |
172 | UnloadTexture(model.materials[0].maps[MAP_DIFFUSE].texture); |
173 | UnloadModel(model); |
174 | |
175 | UnloadRenderTexture(framebuffer); |
176 | |
177 | UnloadTexture(texAngleGauge); |
178 | UnloadTexture(texBackground); |
179 | UnloadTexture(texPitch); |
180 | UnloadTexture(texPlane); |
181 | |
182 | CloseWindow(); // Close window and OpenGL context |
183 | //-------------------------------------------------------------------------------------- |
184 | |
185 | return 0; |
186 | } |
187 | |
188 | // Draw angle gauge controls |
189 | void DrawAngleGauge(Texture2D angleGauge, int x, int y, float angle, char title[], Color color) |
190 | { |
191 | Rectangle srcRec = { 0, 0, angleGauge.width, angleGauge.height }; |
192 | Rectangle dstRec = { x, y, angleGauge.width, angleGauge.height }; |
193 | Vector2 origin = { angleGauge.width/2, angleGauge.height/2}; |
194 | int textSize = 20; |
195 | |
196 | DrawTexturePro(angleGauge, srcRec, dstRec, origin, angle, color); |
197 | |
198 | DrawText(FormatText("%5.1f" , angle), x - MeasureText(FormatText("%5.1f" , angle), textSize) / 2, y + 10, textSize, DARKGRAY); |
199 | DrawText(title, x - MeasureText(title, textSize) / 2, y + 60, textSize, DARKGRAY); |
200 | } |
201 | |