From: John Tsiombikas Date: Tue, 11 Oct 2016 12:00:32 +0000 (+0300) Subject: added func_coaxial X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=antikythera;a=commitdiff_plain;h=7dded440a73971334f4536eef41d5acbae743dff added func_coaxial --- diff --git a/src/mparser.cc b/src/mparser.cc index 10ea6ba..91b1b80 100644 --- a/src/mparser.cc +++ b/src/mparser.cc @@ -81,6 +81,7 @@ static bool set_motor_var(ParserState *ps, Motor *motor, const char *name, const // built-in functions static bool func_adjacent(ParserState *ps); +static bool func_coaxial(ParserState *ps); bool parse_machine(Machine *mcn, const char *fname) @@ -100,6 +101,7 @@ bool parse_machine(Machine *mcn, const char *fname) // init built-in function table set_func(&pstate, "adjacent", func_adjacent, 2); + set_func(&pstate, "coaxial", func_coaxial, 2); nextchar(&pstate); bool res = machine(&pstate); @@ -602,6 +604,10 @@ static bool end_gear(ParserState *ps) printf("DBG: adding gear: %s\n", gear->name.c_str()); ps->gears[gear->name] = gear; ps->mcn->add_gear(gear); + + if(!ps->cur_gear.empty()) { + ps->cur_gear.top()->attach(gear); + } return true; } @@ -717,15 +723,15 @@ static bool set_motor_var(ParserState *ps, Motor *motor, const char *name, const // built-in functions static bool func_adjacent(ParserState *ps) { - Value val_dir = ps->val.top(); ps->val.pop(); + Value val_angle = ps->val.top(); ps->val.pop(); Value val_gear_name = ps->val.top(); ps->val.pop(); if(val_gear_name.type != VAL_STR) { expected(ps, "gear name (string) as 1st arg to adjacent"); return false; } - if(val_dir.type != VAL_VEC) { - expected(ps, "direction vector as 2nd arg to adjacent"); + if(val_angle.type != VAL_NUM) { + expected(ps, "angle as 2nd arg to adjacent"); return false; } @@ -741,11 +747,50 @@ static bool func_adjacent(ParserState *ps) return false; } - Vec3 dir = Vec3(val_dir.v[0], val_dir.v[1], val_dir.v[2]); + Mat4 xform; + xform.rotation(deg_to_rad(val_angle.v[0]), gother->axis); + Vec3 dir = xform * Vec3(0, 1, 0); float sum_radii = gthis->radius + gother->radius; float avg_teeth_len = (gthis->teeth_length + gother->teeth_length) * 0.5; - Vec3 pos = gother->pos + normalize(dir) * (sum_radii - avg_teeth_len * 0.75); + Vec3 pos = gother->pos + dir * (sum_radii - avg_teeth_len * 0.75); + + Value res; + res.type = VAL_VEC; + res.v[0] = pos.x; + res.v[1] = pos.y; + res.v[2] = pos.z; + ps->val.push(res); + return true; +} + +static bool func_coaxial(ParserState *ps) +{ + Value val_dist = ps->val.top(); ps->val.pop(); + Value val_gear_name = ps->val.top(); ps->val.pop(); + + if(val_gear_name.type != VAL_STR) { + expected(ps, "gear name (string) as 1st arg to func_coaxial"); + return false; + } + if(val_dist.type != VAL_NUM) { + expected(ps, "stacking distance as 2nd arg to func_coaxial"); + return false; + } + + Gear *gthis = this_gear(ps); + if(!gthis) { + errmsg(ps, "coaxial: called outside of a gear block"); + return false; + } + + Gear *gother = ps->gears[val_gear_name.s]; + if(!gother) { + errmsg(ps, "coaxial: gear \"%s\" not found", val_gear_name.s.c_str()); + return false; + } + + Vec3 pos = gother->pos + gother->axis * val_dist.v[0]; Value res; res.type = VAL_VEC;