#include "3d_renderer.h"
// standard library includes
+#include <raylib.h>
+
#include <cmath>
#include <cstring>
#include <iostream>
// local includes
#include "constants.h"
+#include "ems.h"
#include "helpers.h"
Renderer3D::Renderer3D()
- : overview_start{OVERVIEW_LEFT_X, OVERVIEW_LEFT_Y, OVERVIEW_LEFT_Z},
- overview_end{OVERVIEW_RIGHT_X, OVERVIEW_RIGHT_Y, OVERVIEW_RIGHT_Z},
- p1_pos{-1.0F, 0.0F, 0.0F},
+ : p1_pos{-1.0F, 0.0F, 0.0F},
p2_pos{1.0F, 0.0F, 0.0F},
overview_timer(OVERVIEW_TIMER_MAX) {
camera.position.x = 0.0F;
scissors_texture;
flags.set(1);
+ flags.set(4);
+ flags.set(5);
}
Renderer3D::~Renderer3D() {
overview_timer -= dt;
if (overview_timer <= 0.0F) {
overview_timer += OVERVIEW_TIMER_MAX;
- flags.flip(1);
+ const std::bitset<64> prevFlags = flags;
+ const auto is_same = [](const std::bitset<64> &l,
+ const std::bitset<64> &r) {
+ return l.test(1) == r.test(1) && l.test(4) == r.test(4) &&
+ l.test(5) == r.test(5);
+ };
+ while (is_same(prevFlags, flags)) {
+#ifdef __EMSCRIPTEN__
+ flags.set(1, call_js_get_random() > 0.5F);
+ flags.set(4, call_js_get_random() > 0.5F);
+ flags.set(5, call_js_get_random() > 0.5F);
+#else
+ flags.set(1, GetRandomValue(0, 1) == 0);
+ flags.set(4, GetRandomValue(0, 1) == 0);
+ flags.set(5, GetRandomValue(0, 1) == 0);
+#endif
+ }
}
- float value = flags.test(1) ? (1.0F - overview_timer / OVERVIEW_TIMER_MAX)
- : (overview_timer / OVERVIEW_TIMER_MAX);
- value = (std::cos(PI_F * value) + 1.0F) / 2.0F;
- Helpers::lerp_v3(&overview_start, &overview_end, &camera.position, value);
+ float value =
+ (std::cos(PI_F * (1.0F - overview_timer / OVERVIEW_TIMER_MAX)) + 1.0F) /
+ 2.0F;
+ if (!flags.test(4) && !flags.test(5) && !flags.test(6)) {
+ Helpers::overview_pan_lr(&camera.position, value, flags.test(1),
+ camera.target.x);
+ } else if (flags.test(4) && !flags.test(5) && !flags.test(6)) {
+ Helpers::overview_zoom_out_l(&camera.position, value, flags.test(1),
+ camera.target.x);
+ } else if (!flags.test(4) && flags.test(5) && !flags.test(6)) {
+ Helpers::overview_zoom_out_r(&camera.position, value, flags.test(1),
+ camera.target.x);
+ } else if (flags.test(4) && flags.test(5) && !flags.test(6)) {
+ Helpers::overview_zoom_out_c(&camera.position, value, flags.test(1),
+ camera.target.x);
+ }
}
UpdateCamera(&camera);
BeginMode3D(camera);
DrawModel(skybox_model, root_pos, 1.0F, WHITE);
DrawModel(platform_model, root_pos, 1.0F, WHITE);
+ DrawModel(qm_model, {-5.0F, 0.0F, 0.0F}, 1.0F, RED);
+ DrawModel(qm_model, {5.0F, 0.0F, 0.0F}, 1.0F, BLUE);
DrawModel(rock_model, p1_pos, 1.0F, WHITE);
DrawModel(paper_model, p2_pos, 1.0F, WHITE);
DrawModel(scissors_model, {-3.0F, 0.0F, 0.0F}, 1.0F, WHITE);
Model paper_model;
Model scissors_model;
- const Vector3 overview_start;
- const Vector3 overview_end;
Vector3 root_pos;
Vector3 p1_pos;
Vector3 p2_pos;
/*
* 0 - focus view if true, overview view if false
- * 1 - overview view movement direction (right if true)
+ * 1 - overview view direction (opposite is true)
* 2 - is player one
* 3 - is spectator
+ * 4
+ * 5
+ * 6 - overview type "654"
+ * 000 - pan left to right (opposite is right to left)
+ * 001 - from up left zoom out from target (opposite is zoom in)
+ * 010 - from up right zoom out from target (opposite is zoom out)
+ * 011 - from center zoom out (opposite is zoom in)
+ * 100 - UNUSED
+ * 101 - UNUSED
+ * 110 - UNUSED
+ * 111 - UNUSED
*/
std::bitset<64> flags;
constexpr float OVERVIEW_RIGHT_Y = 5.0F;
constexpr float OVERVIEW_RIGHT_Z = 20.0F;
+constexpr float OVERVIEW_UP_L_B_X = -4.0F;
+constexpr float OVERVIEW_UP_L_B_Y = 10.0F;
+constexpr float OVERVIEW_UP_L_B_Z = 10.0F;
+constexpr float OVERVIEW_UP_L_E_X = -20.0F;
+constexpr float OVERVIEW_UP_L_E_Y = 20.0F;
+constexpr float OVERVIEW_UP_L_E_Z = 5.0F;
+
+constexpr float OVERVIEW_UP_R_B_X = -OVERVIEW_UP_L_B_X;
+constexpr float OVERVIEW_UP_R_B_Y = OVERVIEW_UP_L_B_Y;
+constexpr float OVERVIEW_UP_R_B_Z = OVERVIEW_UP_L_B_Z;
+constexpr float OVERVIEW_UP_R_E_X = -OVERVIEW_UP_L_E_X;
+constexpr float OVERVIEW_UP_R_E_Y = OVERVIEW_UP_L_E_Y;
+constexpr float OVERVIEW_UP_R_E_Z = OVERVIEW_UP_L_E_Z;
+
+constexpr float OVERVIEW_C_B_X = 0.0F;
+constexpr float OVERVIEW_C_B_Y = 5.0F;
+constexpr float OVERVIEW_C_B_Z = 9.0F;
+constexpr float OVERVIEW_C_E_X = 0.0F;
+constexpr float OVERVIEW_C_E_Y = 7.0F;
+constexpr float OVERVIEW_C_E_Z = 22.0F;
+
#endif
EM_JS(int, canvas_get_height, (),
{ return document.getElementById("canvas").clientHeight; });
+
+EM_JS(float, get_random, (), { return Math.random(); });
#endif
#include <iostream>
return 500;
#endif
}
+
+float call_js_get_random() {
+#ifdef __EMSCRIPTEN__
+ return get_random();
+#else
+ return -1.0F;
+#endif
+}
extern void call_js_request_update();
extern int call_js_get_canvas_width();
extern int call_js_get_canvas_height();
+extern float call_js_get_random();
#endif
// third party includes
#include <raylib.h>
+// local includes
+#include "constants.h"
+
bool Helpers::isValidChoice(char choice) {
return choice == 'r' || choice == 'p' || choice == 's';
}
return size;
}
+float Helpers::lerp(const float start, const float end, const float value) {
+ return start * (1.0F - value) + end * value;
+}
+
void Helpers::lerp_v3(const Vector3 *start, const Vector3 *end, Vector3 *out,
float value) {
- out->x = start->x * (1.0F - value) + end->x * value;
- out->y = start->y * (1.0F - value) + end->y * value;
- out->z = start->z * (1.0F - value) + end->z * value;
+ out->x = lerp(start->x, end->x, value);
+ out->y = lerp(start->y, end->y, value);
+ out->z = lerp(start->z, end->z, value);
+}
+
+void Helpers::overview_pan_lr(Vector3 *out, float value, bool is_opposite,
+ float offset_x) {
+ if (is_opposite) {
+ out->x = lerp(OVERVIEW_RIGHT_X, OVERVIEW_LEFT_X, value) + offset_x;
+ out->y = lerp(OVERVIEW_RIGHT_Y, OVERVIEW_LEFT_Y, value);
+ out->z = lerp(OVERVIEW_RIGHT_Z, OVERVIEW_LEFT_Z, value);
+ } else {
+ out->x = lerp(OVERVIEW_LEFT_X, OVERVIEW_RIGHT_X, value) + offset_x;
+ out->y = lerp(OVERVIEW_LEFT_Y, OVERVIEW_RIGHT_Y, value);
+ out->z = lerp(OVERVIEW_LEFT_Z, OVERVIEW_RIGHT_Z, value);
+ }
+}
+
+void Helpers::overview_zoom_out_l(Vector3 *out, float value, bool is_opposite,
+ float offset_x) {
+ if (is_opposite) {
+ out->x = lerp(OVERVIEW_UP_L_E_X, OVERVIEW_UP_L_B_X, value) + offset_x;
+ out->y = lerp(OVERVIEW_UP_L_E_Y, OVERVIEW_UP_L_B_Y, value);
+ out->z = lerp(OVERVIEW_UP_L_E_Z, OVERVIEW_UP_L_B_Z, value);
+ } else {
+ out->x = lerp(OVERVIEW_UP_L_B_X, OVERVIEW_UP_L_E_X, value) + offset_x;
+ out->y = lerp(OVERVIEW_UP_L_B_Y, OVERVIEW_UP_L_E_Y, value);
+ out->z = lerp(OVERVIEW_UP_L_B_Z, OVERVIEW_UP_L_E_Z, value);
+ }
+}
+
+void Helpers::overview_zoom_out_r(Vector3 *out, float value, bool is_opposite,
+ float offset_x) {
+ if (is_opposite) {
+ out->x = lerp(OVERVIEW_UP_R_E_X, OVERVIEW_UP_R_B_X, value) + offset_x;
+ out->y = lerp(OVERVIEW_UP_R_E_Y, OVERVIEW_UP_R_B_Y, value);
+ out->z = lerp(OVERVIEW_UP_R_E_Z, OVERVIEW_UP_R_B_Z, value);
+ } else {
+ out->x = lerp(OVERVIEW_UP_R_B_X, OVERVIEW_UP_R_E_X, value) + offset_x;
+ out->y = lerp(OVERVIEW_UP_R_B_Y, OVERVIEW_UP_R_E_Y, value);
+ out->z = lerp(OVERVIEW_UP_R_B_Z, OVERVIEW_UP_R_E_Z, value);
+ }
+}
+
+void Helpers::overview_zoom_out_c(Vector3 *out, float value, bool is_opposite,
+ float offset_x) {
+ if (is_opposite) {
+ out->x = lerp(OVERVIEW_C_E_X, OVERVIEW_C_B_X, value) + offset_x;
+ out->y = lerp(OVERVIEW_C_E_Y, OVERVIEW_C_B_Y, value);
+ out->z = lerp(OVERVIEW_C_E_Z, OVERVIEW_C_B_Z, value);
+ } else {
+ out->x = lerp(OVERVIEW_C_B_X, OVERVIEW_C_E_X, value) + offset_x;
+ out->y = lerp(OVERVIEW_C_B_Y, OVERVIEW_C_E_Y, value);
+ out->z = lerp(OVERVIEW_C_B_Z, OVERVIEW_C_E_Z, value);
+ }
}
extern int getFitableSize(const char *text, const int default_size,
const int width);
+extern float lerp(const float start, const float end, const float value);
+
extern void lerp_v3(const Vector3 *start, const Vector3 *end, Vector3 *out,
float value);
+extern void overview_pan_lr(Vector3 *out, float value, bool is_opposite,
+ float offset_x);
+extern void overview_zoom_out_l(Vector3 *out, float value, bool is_opposite,
+ float offset_x);
+extern void overview_zoom_out_r(Vector3 *out, float value, bool is_opposite,
+ float offset_x);
+extern void overview_zoom_out_c(Vector3 *out, float value, bool is_opposite,
+ float offset_x);
+
} // namespace Helpers
#endif