std::map<std::string, FuncDesc> func;
std::map<std::string, Gear*> gears;
- std::stack<Gear*> cur_gear;
+ std::vector<Gear*> cur_gear;
Motor *cur_motor;
};
static Gear *begin_gear(ParserState *ps);
static bool end_gear(ParserState *ps);
static Gear *this_gear(ParserState *ps);
+static Gear *find_gear(ParserState *ps, const char *name);
static void update_gear_vars(ParserState *ps, Gear *gear);
static bool set_gear_var(Gear *gear, const char *name, const Value &val);
// built-in functions
static bool func_adjacent(ParserState *ps);
+static bool func_coaxial(ParserState *ps);
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);
static bool expression(ParserState *ps)
{
- return term(ps);
+ return term(ps); // TODO expand
}
static bool term(ParserState *ps)
expected(ps, "numbers as vector elements");
return false;
}
- vec.v[i] = tmp.v[0];
+ vec.v[nelem - i - 1] = tmp.v[0];
ps->val.pop();
}
static Gear *begin_gear(ParserState *ps)
{
Gear *res = new Gear;
- ps->cur_gear.push(res);
+ ps->cur_gear.push_back(res);
return res;
}
errmsg(ps, "parser error: unbalanced end_gear");
return false;
}
- Gear *gear = ps->cur_gear.top();
- ps->cur_gear.pop();
+ Gear *gear = ps->cur_gear.back();
+ ps->cur_gear.pop_back();
printf("DBG: end_gear: %s\n", gear->name.c_str());
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.back()->attach(gear);
+ }
return true;
}
static Gear *this_gear(ParserState *ps)
{
- return ps->cur_gear.empty() ? 0 : ps->cur_gear.top();
+ return ps->cur_gear.empty() ? 0 : ps->cur_gear.back();
+}
+
+static Gear *find_gear(ParserState *ps, const char *name)
+{
+ // search progressively wider lexical scopes
+ std::vector<Gear*>::const_reverse_iterator it = ps->cur_gear.rbegin();
+ while(it != ps->cur_gear.rend()) {
+ Gear *g = *it++;
+ if(g->name == std::string(name)) {
+ return g;
+ }
+ }
+
+ return ps->gears[name];
}
static void update_gear_vars(ParserState *ps, Gear *gear)
ASSERT_TYPE(val, VAL_VEC);
gear->axis = VVEC3(val);
gear->pdist = val.v[3];
+ printf("setting plane eqn: %f %f %f %f\n", val.v[0], val.v[1], val.v[2], val.v[3]);
} else if(strcmp(name, "thickness") == 0) {
ASSERT_TYPE(val, VAL_NUM);
// 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;
}
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 = find_gear(ps, val_gear_name.s.c_str());
+ if(!gother) {
+ errmsg(ps, "coaxial: gear \"%s\" not found", val_gear_name.s.c_str());
+ return false;
+ }
+
+ float avg_thickness = (gthis->thickness + gother->thickness) * 0.5;
+ Vec3 pos = gother->pos + gother->axis * val_dist.v[0] * avg_thickness;
Value res;
res.type = VAL_VEC;