diff --git a/src/demo/bridge.cpp b/src/demo/bridge.cpp index d6fde89..9c96986 100644 --- a/src/demo/bridge.cpp +++ b/src/demo/bridge.cpp @@ -11,9 +11,38 @@ #include "assert.h" namespace demo { + void bridge::cable_interpolator::interp_add(float n) + { + const int points = particles_length / 2; + + interp += n; + if (interp < 0) { + cable_ix -= 1; + assert(n < 0 && n >= -1); + interp = 1.0 + n; + } + if (interp > 1) { + cable_ix += 1; + assert(n > 0 && n <= 1); + interp = n; + } + + if (cable_ix >= (points - 1)) { + interp = 1.0; + cable_ix = points - 2; + } + + if (cable_ix < 0) { + interp = 0; + cable_ix = 0; + } + } mat4x4 bridge::init() { + interpolator.interp = 0.0; + interpolator.cable_ix = 0; + // particles for (int i = 0; i < particles_length; i++) { float x = float(i / 2) * 2.0f - 5.0f; @@ -52,11 +81,11 @@ namespace demo { for (int i = 0; i < rods_length; i++) { rods[i].particle[0] = &particles[i * 2]; rods[i].particle[1] = &particles[i * 2 + 1]; - rods[i].length = 3; + rods[i].length = 2; } mat4x4 view_trans - = translate(vec3(0.0, 0.0, 0.5)) + = translate(vec3(0.0, 0.1, 0.5)) * rotate_x(pi / 4) * rotate_y(pi / 12) * scale(vec3(-1, -1, 1)); @@ -73,11 +102,26 @@ namespace demo { printf("en cables %d\n", en_cables); } + void bridge::analog(float dx) { + interpolator.interp_add(dx * 0.5f); + } + void bridge::_update() { for (int i = 0; i < particles_length; i++) { particles[i].force_accum = vec3(0, 0, 0); - particles[i].inverse_mass = 1.0f / 1.0f; + + if ((i / 2) == interpolator.cable_ix) { + float mul = 1.0 - interpolator.interp; + assert(mul >= 0.0 && mul <= 1.0); + particles[i].inverse_mass = 1.0f / (1.0 + 10.0 * mul); + } else if ((i / 2) == (interpolator.cable_ix + 1)) { + float mul = interpolator.interp; + assert(mul >= 0.0 && mul <= 1.0); + particles[i].inverse_mass = 1.0f / (1.0 + 10.0 * mul); + } else { + particles[i].inverse_mass = 1.0f / 1.0f; + } } float duration = 1.f / 120.0f; @@ -135,6 +179,31 @@ namespace demo { font::ter_u12n.draw_string(writer, center_p, "demo: bridge", 0xffffffff); } + static inline vec3 lerp(const vec3& a, const vec3& b, float f) + { + float dx = b.x - a.x; + float dy = b.y - a.y; + float dz = b.z - a.z; + + return { + a.x + dx * f, + a.y + dy * f, + a.z + dz * f, + }; + } + + void bridge::draw_weight(ta_parameter_writer& writer, const mat4x4& trans) + { + vec3 p1 = particles[(interpolator.cable_ix * 2)].position; + vec3 p2 = particles[((interpolator.cable_ix + 1) * 2)].position; + + vec3 p = lerp(p1, p2, interpolator.interp); + p.z = 0.0; + + const vec3 color(1.0, 0.5, 0.0); + draw_cube(writer, trans * translate(p) * scale(0.3f), color); + } + void bridge::draw(ta_parameter_writer& writer, const mat4x4& trans) { // punch through @@ -144,7 +213,9 @@ namespace demo { ta_global_parameter::end_of_list(para_control::para_type::end_of_list); // opaque - draw_axis(writer, trans * scale(5.f)); + draw_axis(writer, trans * scale(2.f)); + + draw_weight(writer, trans); // draw particles for (int i = 0; i < particles_length; i++) { diff --git a/src/demo/bridge.hpp b/src/demo/bridge.hpp index b13b764..ecd03a5 100644 --- a/src/demo/bridge.hpp +++ b/src/demo/bridge.hpp @@ -7,14 +7,25 @@ namespace demo { struct bridge : scene { + struct cable_interpolator { + float interp; + int cable_ix; + + void interp_add(float n); + }; + + cable_interpolator interpolator; + mat4x4 init() override; void _update(); void update() override; void draw_hud(ta_parameter_writer& writer); + void draw_weight(ta_parameter_writer& writer, const mat4x4& trans); void draw(ta_parameter_writer& writer, const mat4x4& trans) override; void a() override; + void analog(float dx) override; static const inline int particles_length = 12; physics::particle particles[particles_length]; diff --git a/src/demo/scene.hpp b/src/demo/scene.hpp index 7df02b5..968745a 100644 --- a/src/demo/scene.hpp +++ b/src/demo/scene.hpp @@ -7,6 +7,7 @@ namespace demo { struct scene { virtual mat4x4 init() = 0; + virtual void analog(float dx) {} virtual void a() {} virtual void b() {} virtual void x() {} diff --git a/src/platform/graphics.cpp b/src/platform/graphics.cpp index e3406b6..f64737f 100644 --- a/src/platform/graphics.cpp +++ b/src/platform/graphics.cpp @@ -168,7 +168,7 @@ namespace graphics { auto& data = data_fields.data; - //float dx = static_cast(data.analog_coordinate_axis[2] - 0x80) * 0.001; + float dx = static_cast(data.analog_coordinate_axis[2] - 0x80) * 0.001; float dy = static_cast(data.analog_coordinate_axis[3] - 0x80) * 0.001; bool a = ft0::data_transfer::digital_button::a(data.digital_button) == 0; @@ -184,6 +184,8 @@ namespace graphics { last[port_ix].x = x; last[port_ix].y = y; + current_scene->analog(dx); + view_trans = view_trans * rotate_y(dy); } }