Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[gui] Add get_view_matrix() and get_projection_matrix() APIs for camera #5345

Merged
merged 18 commits into from
Jul 7, 2022
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
287656a
Add 2 new functions(get camera view/proj matrix) to Camera Class
Morcki Jul 6, 2022
3beaa94
expose 2 new functions(get camera view/proj matrix) to PyCamera
Morcki Jul 6, 2022
f930551
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 6, 2022
06bbc8b
[gui] Add 2 new functions(get camera view/projection matrix) to Camer…
Morcki Jul 6, 2022
7515d70
[gui] expose 2 new functions(get camera view/projection matrix) of Py…
Morcki Jul 6, 2022
0fef90f
add a test for getting the view/projection matrix of camera
Morcki Jul 6, 2022
18d6268
add 2 new functions to get view/projection matrix of camera
Morcki Jul 6, 2022
ea9a45b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 6, 2022
d1d866a
expose 2 new functions(get camera view/proj matrix) to PyCamera
Morcki Jul 6, 2022
7cd32d7
expose 2 new functions(get camera view/proj matrix) to PyCamera
Morcki Jul 6, 2022
b28bb81
Update taichi/python/export_ggui.cpp
Morcki Jul 6, 2022
c2eee88
Update taichi/python/export_ggui.cpp
Morcki Jul 6, 2022
74230fb
Update taichi/python/export_ggui.cpp
Morcki Jul 6, 2022
a2965ec
Update taichi/python/export_ggui.cpp
Morcki Jul 6, 2022
eea04db
Update taichi/python/export_ggui.cpp
Morcki Jul 6, 2022
702eddb
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 6, 2022
ad3dc6f
add test for get the view/projection matrix of camera
Morcki Jul 6, 2022
b22640b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 6, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions python/taichi/ui/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,28 @@ def z_far(self, z_far):
"""
self.ptr.z_far(z_far)

def get_view_matrix(self):
"""Get the view matrix(in row major) of the camera.

Example::

>>> camera.get_view_matrix()
"""
return self.ptr.get_view_matrix()

def get_projection_matrix(self, aspect):
"""Get the projection matrix(in row major) of the camera.

Args:
aspect (:mod:`taichi.types.primitive_types`): \
aspect ratio of the camera

Example::

>>> camera.get_projection_matrix(1080/720)
"""
return self.ptr.get_projection_matrix(aspect)

def track_user_inputs(self,
window,
movement_speed=1.0,
Expand Down
31 changes: 30 additions & 1 deletion taichi/python/export_ggui.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

#include <vector>
#include "pybind11/pybind11.h"
#include <pybind11/numpy.h>
#include "pybind11/stl.h"

#include "taichi/common/interface.h"
Expand Down Expand Up @@ -34,6 +35,26 @@ pybind11::tuple vec3_to_tuple(glm::vec3 v) {
return pybind11::make_tuple(v.x, v.y, v.z);
}

struct custom_deleter {
glm::mat4 operator()(glm::mat4 *m) {
return *m;
}
};

// convert 2d-array to numpy array using pybind
Morcki marked this conversation as resolved.
Show resolved Hide resolved
// ref:https://pybind11.readthedocs.io/en/stable/advanced/pycpp/numpy.html?highlight=array_t#vectorizing-functions
Morcki marked this conversation as resolved.
Show resolved Hide resolved
// ref:https://stackoverflow.com/questions/44659924/returning-numpy-arrays-via-pybind11
Morcki marked this conversation as resolved.
Show resolved Hide resolved
py::array_t<float> mat4_to_nparray(glm::mat4 mat) {
// must explicitly pass args using py::detail::any_container<ssize_t>
Morcki marked this conversation as resolved.
Show resolved Hide resolved
// ref:https://stackoverflow.com/questions/54055530/error-no-matching-function-for-call-to-pybind11buffer-infobuffer-info
Morcki marked this conversation as resolved.
Show resolved Hide resolved
return py::array_t<float>(
py::detail::any_container<ssize_t>({4, 4}), // shape (rows, cols)
py::detail::any_container<ssize_t>(
{sizeof(float) * 4, sizeof(float)}), // strides in bytes
glm::value_ptr(mat), // buffer pointer
nullptr);
}

struct PyGui {
GuiBase *gui; // not owned
void begin(std::string name, float x, float y, float width, float height) {
Expand Down Expand Up @@ -99,6 +120,12 @@ struct PyCamera {
void z_far(float z_far_) {
camera.z_far = z_far_;
}
py::array_t<float> get_view_matrix() {
return mat4_to_nparray(camera.get_view_matrix());
}
py::array_t<float> get_projection_matrix(float aspect_ratio) {
return mat4_to_nparray(camera.get_projection_matrix(aspect_ratio));
}
};

struct PyScene {
Expand Down Expand Up @@ -368,7 +395,9 @@ void export_ggui(py::module &m) {
.def("top", &PyCamera::top)
.def("bottom", &PyCamera::bottom)
.def("z_near", &PyCamera::z_near)
.def("z_far", &PyCamera::z_far);
.def("z_far", &PyCamera::z_far)
.def("get_view_matrix", &PyCamera::get_view_matrix)
.def("get_projection_matrix", &PyCamera::get_projection_matrix);

py::class_<Event>(m, "Event")
.def_property("key", &Event::get_key, &Event::set_key);
Expand Down
17 changes: 17 additions & 0 deletions tests/python/test_ggui.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,3 +296,20 @@ def render():
@test_utils.test(arch=supported_archs)
def test_exit_without_showing():
window = ti.ui.Window("Taichi", (256, 256), show_window=False)


@test_utils.test(arch=supported_archs)
def test_get_camera_view_and_projection_matrix():
scene = ti.ui.Scene()
camera = ti.ui.make_camera()
camera.position(0, 0, 3)
camera.lookat(0, 0, 0)

scene.set_camera(camera)

view_matrix = camera.get_view_matrix()
projection_matrix = camera.get_projection_matrix(1080 / 720)

for i in range(4):
assert (abs(view_matrix[i, j] - 1) <= 1e-5)
assert (abs(view_matrix[3, 2] + 3) <= 1e-5)