Skip to content

Commit

Permalink
Use paired parameters like resolution, fxfy, fovxy
Browse files Browse the repository at this point in the history
  • Loading branch information
wkentaro committed Nov 21, 2018
1 parent ae1a6c3 commit 7870153
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 57 deletions.
113 changes: 61 additions & 52 deletions trimesh/scene/camera.py
@@ -1,78 +1,87 @@
import collections
import numbers

import numpy as np


class Camera(object):

def __init__(
self,
width=None,
height=None,
fx=None,
fy=None,
fovx=None,
fovy=None,
resolution=None,
fxfy=None,
fovxy=None,
transform=None,
):
# TODO(unknown): skew is not supported
# TODO(unknown): cx and cy that are not half of width and height
self.width = width
self.height = height
self._fx = fx
self._fy = fy
self._fovx = fovx
self._fovy = fovy

if resolution:
if (not isinstance(resolution, collections.Sequence) or
len(resolution) != 2 or
not all(isinstance(x, int) for x in resolution)):
raise ValueError(
'resolution must be sequence of integer as (height, width)'
)
self.resolution = resolution

if fxfy:
if (not isinstance(fxfy, collections.Sequence) or
len(fxfy) != 2 or
not all(isinstance(x, numbers.Real) for x in fxfy)):
raise ValueError(
'fxfy must be sequence of real as (fx, fy)'
)
self._fxfy = fxfy

if fovxy:
if (not isinstance(fovxy, collections.Sequence) or
len(fovxy) != 2 or
not all(isinstance(x, numbers.Real) for x in fovxy)):
raise ValueError(
'fovxy must be sequence of real as (fovx, fovy)'
)
self._fovxy = fovxy

if transform is None:
transform = np.eye(4)
self.transform = transform

@property
def fx(self):
if self._fx is None:
assert self.width is not None
assert self._fovx is not None
self._fx = (
(self.width / 2.) /
np.tan(np.deg2rad(self._fovx / 2.))
)
return self._fx
@staticmethod
def _get_f(pixel_size, fov):
assert pixel_size is not None
assert fov is not None
f = ((pixel_size / 2.) / np.tan(np.deg2rad(fov / 2.)))
return f

@property
def fy(self):
if self._fy is None:
assert self.height is not None
assert self._fovy is not None
self._fy = (
(self.height / 2.) /
np.tan(np.deg2rad(self._fovy / 2.))
)
return self._fy
def fxfy(self):
if self._fxfy is None:
fx = self._get_f(self.resolution[0], self.fovxy[0])
fy = self._get_f(self.resolution[1], self.fovxy[1])
self._fxfy = (fx, fy)
return self._fxfy

@property
def K(self):
K = np.eye(3, dtype=np.float64)
K[0, 0] = self.fx
K[1, 1] = self.fy
K[0, 2] = self.width / 2.
K[1, 2] = self.height / 2.
K[0, 0] = self.fxfy[0]
K[1, 1] = self.fxfy[1]
K[0, 2] = self.resolution[0] / 2.
K[1, 2] = self.resolution[1] / 2.
return K

@property
def fovx(self):
if self._fovx is None:
assert self.width is not None
assert self._fx is not None
self._fovx = 2 * np.rad2deg(
np.arctan(self.width / 2. / self._fx)
)
return self._fovx
@staticmethod
def _get_fov(pixel_size, f):
assert pixel_size is not None
assert f is not None
fov = 2 * np.rad2deg(np.arctan(pixel_size / 2. / f))
return fov

@property
def fovy(self):
if self._fovy is None:
assert self.height is not None
assert self._fy is not None
self._fovy = 2 * np.rad2deg(
np.arctan(self.height / 2. / self._fy)
)
return self._fovy
def fovxy(self):
if self._fovxy is None:
fovx = self._get_fov(self.resolution[0], self.fxfy[0])
fovy = self._get_fov(self.resolution[1], self.fxfy[1])
self._fovxy = (fovx, fovy)
return self._fovxy
9 changes: 4 additions & 5 deletions trimesh/scene/viewer.py
Expand Up @@ -41,13 +41,12 @@ def __init__(self,

if scene.camera is not None:
if resolution is not None:
resolution_from_cam = (scene.camera.width, scene.camera.height)
if resolution != resolution_from_cam:
if resolution != scene.camera.resolution:
log.warning(
'resolution is overwritten by Camera: '
'{} -> {}'.format(resolution, resolution_from_cam)
'{} -> {}'.format(resolution, scene.camera.resolution)
)
resolution = resolution_from_cam
resolution = scene.camera.resolution
else:
if 'camera' not in scene.graph:
# if the camera hasn't been set, set it now
Expand Down Expand Up @@ -223,7 +222,7 @@ def on_resize(self, width, height):
gl.glViewport(0, 0, width, height)
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glLoadIdentity()
fovy = self.scene.camera.fovy if self.scene.camera else 60
fovy = self.scene.camera.fovxy[1] if self.scene.camera else 60
gl.gluPerspective(fovy,
width / float(height),
.01,
Expand Down

0 comments on commit 7870153

Please sign in to comment.