Skip to content

Commit

Permalink
linear_algebra bindings improvements, don't crash when nav data not f…
Browse files Browse the repository at this point in the history
…ound (#38)

* Improve linear_algebra bindings

- better indentation
- named and default arguments in vector constructors
- implemented `__repr__` for vectors and matrices
- some binary operators for matrices
- named a few function args
- exposed `det`, `eye`, `lerp`

* Don't crash when navigation data not found

* Fix regex in stubgen
  • Loading branch information
Darxeal committed Nov 22, 2021
1 parent 546c650 commit 78b9663
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 77 deletions.
6 changes: 3 additions & 3 deletions inc/experimental/navigator.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ class Navigator {
Curve path_to(vec3, vec3, float);

static void init_statics(
std::vector< Graph::edge > nav_edges,
std::vector< vec3 > nav_nodes,
std::vector< vec3 > nav_normals);
const std::vector< Graph::edge > & nav_edges,
const std::vector< vec3 > & nav_nodes,
const std::vector< vec3 > & nav_normals);

static std::vector < vec3 > navigation_nodes;
static std::vector < vec3 > navigation_tangents;
Expand Down
2 changes: 1 addition & 1 deletion python/pybind11_stubgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def apply_classname_replacements(s): # type: (str) -> Any
def function_signatures_from_docstring(func, module_name): # type: (Any, str) -> List[FunctionSignature]
name = func.__name__
try:
signature_regex = r"(\s*(?P<overload_number>\d+).)?\s*{name}\s*\((?P<args>[^\(\)]*)\)\s*->\s*(?P<rtype>[^\(\)]+)\s*".format(
signature_regex = r".*{name}\((?P<args>.*)\) -> (?P<rtype>.*).*".format(
name=name)
doc_lines = func.__doc__
signatures = []
Expand Down
174 changes: 108 additions & 66 deletions python/src/math_pybind11.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <string>
#include <utility>
#include <sstream>

#include "linear_algebra/math.h"

Expand All @@ -9,20 +10,26 @@
#include <pybind11/operators.h>
void init_linalg(pybind11::module & m) {

using namespace pybind11::literals;

pybind11::class_<vec2>(m, "vec2")
.def(pybind11::init< float, float >())
.def(pybind11::init< float, float >(), "x"_a = 0.0f, "y"_a = 0.0f)
.def(pybind11::init< const vec2 & >())
.def(pybind11::init([](const vec3 & v) {
return vec2{ v[0], v[1] };
}))
return vec2{ v[0], v[1] };
}))
.def("__getitem__", [](const vec2 & v, size_t i) { return v[i]; })
.def("__setitem__", [](vec2 & v, size_t i, float f) { v[i] = f; })
.def_property("x", [](const vec2 & v) {return v[0];}, [](vec2 & v, float f) {v[0] = f;})
.def_property("y", [](const vec2 & v) {return v[1];}, [](vec2 & v, float f) {v[1] = f;})
.def("__str__", [](const vec2 & v) {
return std::to_string(v[0]) + std::string(" ") +
std::to_string(v[1]);
})
return std::to_string(v[0]) + " " + std::to_string(v[1]);
})
.def("__repr__", [](const vec2 & v) {
std::stringstream ss;
ss << "vec2(" << v[0] << ", " << v[1] << ")";
return ss.str();
})
.def(pybind11::self - pybind11::self)
.def(pybind11::self + pybind11::self)
.def(pybind11::self -= pybind11::self)
Expand All @@ -34,21 +41,24 @@ void init_linalg(pybind11::module & m) {
.def(pybind11::self / float());

pybind11::class_<vec3>(m, "vec3")
.def(pybind11::init< float, float, float >())
.def(pybind11::init< float, float, float >(), "x"_a = 0.0f, "y"_a = 0.0f, "z"_a = 0.0f)
.def(pybind11::init< const vec3 & >())
.def(pybind11::init([](const vec2 & v) {
return vec3{ v[0], v[1], 0.0f };
}))
return vec3{ v[0], v[1], 0.0f };
}))
.def("__getitem__", [](const vec3 & v, size_t i) { return v[i]; })
.def("__setitem__", [](vec3 & v, size_t i, float f) { v[i] = f; })
.def_property("x", [](const vec3 & v) {return v[0];}, [](vec3 & v, float f) {v[0] = f;})
.def_property("y", [](const vec3 & v) {return v[1];}, [](vec3 & v, float f) {v[1] = f;})
.def_property("z", [](const vec3 & v) {return v[2];}, [](vec3 & v, float f) {v[2] = f;})
.def("__str__", [](const vec3 & v) {
return std::to_string(v[0]) + std::string(" ") +
std::to_string(v[1]) + std::string(" ") +
std::to_string(v[2]);
})
return std::to_string(v[0]) + " " + std::to_string(v[1]) + " " + std::to_string(v[2]);
})
.def("__repr__", [](const vec3 & v) {
std::stringstream ss;
ss << "vec3(" << v[0] << ", " << v[1] << ", " << v[2] << ")";
return ss.str();
})
.def(pybind11::self - pybind11::self)
.def(pybind11::self + pybind11::self)
.def(pybind11::self -= pybind11::self)
Expand All @@ -60,41 +70,53 @@ void init_linalg(pybind11::module & m) {
.def(pybind11::self / float());

pybind11::class_<mat2>(m, "mat2")
.def(pybind11::init([](float a11, float a12,
float a21, float a22) {
return mat2{
{a11, a12},
{a21, a22}
};
}))
.def(pybind11::init([](float a11, float a12, float a21, float a22) {
return mat2{
{a11, a12},
{a21, a22}
};
}))
.def("__getitem__", [](const mat2 & A, std::pair < size_t, size_t > i) {
return A(i.first, i.second);
})
return A(i.first, i.second);
})
.def("__setitem__", [](mat2 & A, std::pair < size_t, size_t > i, float v) {
A(i.first, i.second) = v;
})
A(i.first, i.second) = v;
})
.def("__str__", [](const mat2 & A) {
std::string s;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
s += std::to_string(A(i, j));
if (j == 1) s += "\n";
else s += " ";
std::string s;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
s += std::to_string(A(i, j));
if (j == 1) s += "\n";
else s += " ";
}
}
}
return s;
});
return s;
})
.def("__repr__", [](const mat2 & A) {
std::stringstream ss;
ss << "mat2(" << A(0, 0) << ", " << A(0, 1) << ", " << A(1, 0) << ", " << A(1, 1) << ")";
return ss.str();
})
.def(pybind11::self - pybind11::self)
.def(pybind11::self + pybind11::self)
.def(float() * pybind11::self)
.def(pybind11::self * float())
.def(pybind11::self / float());

pybind11::class_<vec4>(m, "vec4")
.def(pybind11::init< float, float, float, float >())
.def("__getitem__", [](const vec4 & v, size_t i) { return v[i]; })
.def("__setitem__", [](vec4 & v, size_t i, float f) { v[i] = f; })
.def("__str__", [](const vec4 & v) {
return std::to_string(v[0]) + std::string(" ") +
std::to_string(v[1]) + std::string(" ") +
std::to_string(v[2]) + std::string(" ") +
std::to_string(v[3]);
})
return std::to_string(v[0]) + " " + std::to_string(v[1]) +
" " + std::to_string(v[2]) + " " + std::to_string(v[3]);
})
.def("__repr__", [](const vec4 & v) {
std::stringstream ss;
ss << "vec4(" << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << ")";
return ss.str();
})
.def(pybind11::self - pybind11::self)
.def(pybind11::self + pybind11::self)
.def(pybind11::self -= pybind11::self)
Expand All @@ -107,31 +129,43 @@ void init_linalg(pybind11::module & m) {

pybind11::class_<mat3>(m, "mat3")
.def(pybind11::init([](float a11, float a12, float a13,
float a21, float a22, float a23,
float a31, float a32, float a33) {
return mat3{
{a11, a12, a13},
{a21, a22, a23},
{a31, a32, a33}
};
}))
float a21, float a22, float a23,
float a31, float a32, float a33) {
return mat3{
{a11, a12, a13},
{a21, a22, a23},
{a31, a32, a33}
};
}))
.def("__getitem__", [](const mat3 & A, std::pair < size_t, size_t > i) {
return A(i.first, i.second);
})
return A(i.first, i.second);
})
.def("__setitem__", [](mat3 & A, std::pair < size_t, size_t > i, float v) {
A(i.first, i.second) = v;
})
A(i.first, i.second) = v;
})
.def("__str__", [](const mat3 & A) {
std::string s;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
s += std::to_string(A(i, j));
if (j == 2) s += "\n";
else s += " ";
std::string s;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
s += std::to_string(A(i, j));
if (j == 2) s += "\n";
else s += " ";
}
}
}
return s;
});
return s;
})
.def("__repr__", [](const mat3 & A) {
std::stringstream ss;
ss << "mat3(" << A(0, 0) << ", " << A(0, 1) << ", " << A(0, 2) << ", " <<
A(1, 0) << ", " << A(1, 1) << ", " << A(1, 2) << ", " <<
A(2, 0) << ", " << A(2, 1) << ", " << A(2, 2) << ")";
return ss.str();
})
.def(pybind11::self - pybind11::self)
.def(pybind11::self + pybind11::self)
.def(float() * pybind11::self)
.def(pybind11::self * float())
.def(pybind11::self / float());

// free functions
m.def("dot", (float(*)(const vec2 &, const vec2 &)) &dot);
Expand All @@ -150,15 +184,21 @@ void init_linalg(pybind11::module & m) {
m.def("cross", (vec3(*)(const vec3 &)) &cross);
m.def("cross", (vec2(*)(const vec2 &)) &cross);

m.def("eye2", (mat2(*)()) &eye);
m.def("eye3", (mat3(*)()) &eye);

m.def("det", (float(*)(const mat2 &)) &det);
m.def("det", (float(*)(const mat3 &)) &det);

m.def("inv", (mat2(*)(const mat2 &)) &inv);
m.def("inv", (mat3(*)(const mat3 &)) &inv);
m.def("look_at", (mat2(*)(const vec2 &)) &look_at, pybind11::arg("forward"));
m.def("look_at", (mat3(*)(const vec3 &, const vec3 &)) &look_at, pybind11::arg("forward"), pybind11::arg("up"));
m.def("rotation", &rotation);
m.def("euler_to_rotation", &euler_to_rotation);
m.def("rotation_to_euler", &rotation_to_euler);
m.def("axis_to_rotation", &axis_to_rotation);
m.def("rotation_to_axis", &rotation_to_axis);
m.def("look_at", (mat2(*)(const vec2 &)) &look_at, "forward"_a);
m.def("look_at", (mat3(*)(const vec3 &, const vec3 &)) &look_at, "forward"_a, "up"_a = vec3{0, 0, 1});
m.def("rotation", &rotation, "angle"_a);
m.def("euler_to_rotation", &euler_to_rotation, "euler_angles"_a);
m.def("rotation_to_euler", &rotation_to_euler, "rotation_matrix"_a);
m.def("axis_to_rotation", &axis_to_rotation, "axis"_a);
m.def("rotation_to_axis", &rotation_to_axis, "rotation_matrix"_a);
m.def("transpose", (mat2(*)(const mat2 &)) &transpose);
m.def("transpose", (mat3(*)(const mat3 &)) &transpose);
m.def("angle_between", (float(*)(const vec2 &, const vec2 &)) &angle_between);
Expand All @@ -175,4 +215,6 @@ void init_linalg(pybind11::module & m) {
m.def("normalize", (vec3(*)(const vec3 &)) &normalize);
m.def("normalize", (vec2(*)(const vec2 &)) &normalize);

m.def("lerp", (vec2(*)(const vec2 &, const vec2 &, const float)) &lerp);
m.def("lerp", (vec3(*)(const vec3 &, const vec3 &, const float)) &lerp);
}
6 changes: 3 additions & 3 deletions src/experimental/navigator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ std::vector < vec3 > Navigator::navigation_normals;
std::vector < vec3 > Navigator::directions;

void Navigator::init_statics(
std::vector< Graph::edge > nav_edges,
std::vector< vec3 > nav_nodes,
std::vector< vec3 > nav_normals) {
const std::vector< Graph::edge > & nav_edges,
const std::vector< vec3 > & nav_nodes,
const std::vector< vec3 > & nav_normals) {

//scale = float(parameters[0]);
//nx = parameters[1];
Expand Down
10 changes: 6 additions & 4 deletions src/rlutilities.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,12 @@ namespace rlu {
throwback_corner_wall_2 = read_mesh("throwback/throwback_corner_wall_2");

auto prefix = asset_dir + std::string("soccar/soccar_navigation_");
Navigator::init_statics(
read_binary<Graph::edge>(prefix + "graph.bin"),
read_binary<vec3>(prefix + "nodes.bin"),
read_binary<vec3>(prefix + "normals.bin"));
auto navigation_graph = read_binary<Graph::edge>(prefix + "graph.bin");
auto navigation_nodes = read_binary<vec3>(prefix + "nodes.bin");
auto navigation_normals = read_binary<vec3>(prefix + "normals.bin");
if (!navigation_graph.empty() && !navigation_nodes.empty() && !navigation_normals.empty()) {
Navigator::init_statics(navigation_graph, navigation_nodes, navigation_normals);
}

ReorientML::set_model(Model(read_binary<float>(asset_dir + "ML/reorient_ML_model.bin")));

Expand Down

0 comments on commit 78b9663

Please sign in to comment.