bridge: add weight

This commit is contained in:
Zack Buhman 2025-07-20 00:21:52 -05:00
parent 843afed274
commit 22a144bcd4
4 changed files with 90 additions and 5 deletions

View File

@ -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++) {

View File

@ -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];

View File

@ -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() {}

View File

@ -168,7 +168,7 @@ namespace graphics {
auto& data = data_fields.data;
//float dx = static_cast<float>(data.analog_coordinate_axis[2] - 0x80) * 0.001;
float dx = static_cast<float>(data.analog_coordinate_axis[2] - 0x80) * 0.001;
float dy = static_cast<float>(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);
}
}