Skip to content
This repository has been archived by the owner on Sep 25, 2022. It is now read-only.

Commit

Permalink
Merge 56c15b8 into de2c2ed
Browse files Browse the repository at this point in the history
  • Loading branch information
mohammadbashiri committed Jun 9, 2018
2 parents de2c2ed + 56c15b8 commit 87720aa
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 3 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ dist/*
ratcave.egg-info/*
.idea
.cache
*.egg-info
*.egg-info
.pytest_cache/
.eggs/
1 change: 1 addition & 0 deletions .pytest_cache/v/cache/lastfailed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
14 changes: 14 additions & 0 deletions .pytest_cache/v/cache/nodeids
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
"tests/test_camera.py::test_camera_physical_attributes",
"tests/test_camera.py::test_perspective_projection_updates",
"tests/test_camera.py::test_default_projection_is_perspective",
"tests/test_camera.py::test_camera_has_all_uniforms",
"tests/test_camera.py::test_projection_attributes_change_cameras_projection_matrix_uniform",
"tests/test_camera.py::test_projection_matrix_updates_when_assigning_new_projection",
"tests/test_camera.py::test_cameragroup_contains_two_cameras",
"tests/test_camera.py::test_cameras_are_cameragroup_childrens",
"tests/test_camera.py::test_cameras_have_correct_distance",
"tests/test_camera.py::test_projection_instance_is_shared_between_cameragroup_and_its_children",
"tests/test_camera.py::test_look_at_updates_for_children",
"tests/test_camera.py::test_viewport"
]
2 changes: 1 addition & 1 deletion ratcave/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
except ImportError:
pass
from . import utils
from .camera import Camera, PerspectiveProjection, OrthoProjection
from .camera import Camera, PerspectiveProjection, OrthoProjection, CameraGroup
from .collision import CylinderCollisionChecker, SphereCollisionChecker
from .fbo import FBO
from .gl_states import GLStateManager, default_states
Expand Down
39 changes: 39 additions & 0 deletions ratcave/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,42 @@ def reset_uniforms(self):
@property
def projection_matrix(self):
return self.projection.projection_matrix.view()


class CameraGroup(PhysicalGraph):

def __init__(self, position=(0, 0, 0), rotation=(0, 0, 0), distance=.1, look_at=(0, 0, 0), projection=None, *args, **kwargs):
""" Creates a group of cameras that behave dependently"""

super(CameraGroup, self).__init__(position=position, rotation=rotation, *args, **kwargs)
self.cam_left = Camera(position=(-distance / 2, 0., 0.))
self.cam_right = Camera(position=(distance / 2, 0., 0.))
self.projection = PerspectiveProjection() if not projection else projection

self.distance = distance
self.look_at(*look_at)
self.add_children(self.cam_left, self.cam_right)

@property
def projection(self):
return self._projection

@projection.setter
def projection(self, value):
self._projection = value
self.cam_left.projection = self._projection
self.cam_right.projection = self._projection

@property
def distance(self):
return self.cam_right.position.x - self.cam_left.position.x

@distance.setter
def distance(self, value):
self.cam_left.position.x = -value / 2
self.cam_right.position.x = value / 2

def look_at(self, x, y, z):
"""Converges the two cameras to look at the specific point"""
self.cam_left.look_at(x, y, z)
self.cam_right.look_at(x, y, z)
51 changes: 50 additions & 1 deletion tests/test_camera.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from ratcave import Camera, PerspectiveProjection, OrthoProjection
from ratcave import Camera, CameraGroup, PerspectiveProjection, OrthoProjection
import pytest
import numpy as np
import pyglet
Expand Down Expand Up @@ -96,6 +96,55 @@ def test_projection_matrix_updates_when_assigning_new_projection():
assert (cam.projection_matrix == old_projmat).all()


def test_cameragroup_contains_two_cameras():
cam = CameraGroup()
assert hasattr(cam, "cam_right") and hasattr(cam, "cam_left")


def test_cameras_are_cameragroup_childrens():
cam = CameraGroup()
assert cam.cam_right in cam.children
assert cam.cam_left in cam.children


def test_cameras_have_correct_distance():
dist = 10
cam = CameraGroup(distance=dist)
assert cam.distance == dist
assert (cam.cam_right.position.x - cam.cam_left.position.x) == cam.distance

cam.distance = 20
assert (cam.cam_right.position.x - cam.cam_left.position.x) == cam.distance


def test_projection_instance_is_shared_between_cameragroup_and_its_children():
cam = CameraGroup()
assert (cam.projection == cam.cam_right.projection) and (cam.projection == cam.cam_left.projection)

cam.projection = OrthoProjection()
assert isinstance(cam.projection, OrthoProjection)
assert (cam.projection == cam.cam_right.projection) and (cam.projection == cam.cam_left.projection)


def test_look_at_updates_for_children():
dist = 2.
cam = CameraGroup(distance=dist)
point = np.array([0, 0, 0, 1]).reshape(-1, 1)
point[2] = -1 #np.random.randint(1, 6)

angle = np.arctan(point[2]/(cam.distance/2))[0]
cam.cam_right.rotation.y = -np.rad2deg(angle)
cam.cam_left.rotation.y = np.rad2deg(angle)
point_view_mat_left = np.dot(cam.cam_left.view_matrix, point)
point_view_mat_right = np.dot(cam.cam_right.view_matrix, point)
assert (point_view_mat_left == point_view_mat_right).all()

cam2 = CameraGroup(distance=dist, look_at=point[:3])
point_view_mat_left2 = np.dot(cam2.cam_left.view_matrix, point)
point_view_mat_right2 = np.dot(cam2.cam_right.view_matrix, point)
assert (point_view_mat_left == point_view_mat_left2).all() and (point_view_mat_right == point_view_mat_right2).all()


def test_viewport():
win = pyglet.window.Window(width=500, height=550)
assert win.width == 500
Expand Down

0 comments on commit 87720aa

Please sign in to comment.