summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStan Seibert <stan@mtrr.org>2011-08-05 18:36:05 -0400
committerStan Seibert <stan@mtrr.org>2011-08-05 18:36:05 -0400
commit1711f85bed5ad279d6b66d0373926da55e07c0ca (patch)
treef9182e3f8db1dae890f16e790a840a259efd833f
parentd7f835b3325611ad25209c9a25256b46d4944827 (diff)
downloadchroma-1711f85bed5ad279d6b66d0373926da55e07c0ca.tar.gz
chroma-1711f85bed5ad279d6b66d0373926da55e07c0ca.tar.bz2
chroma-1711f85bed5ad279d6b66d0373926da55e07c0ca.zip
--spnav option to camera.py enables camera control with a
locally-attached Space Navigator 3D mouse. Assumes you have the open source spacenavd and libspnav installed. (Both included in Ubuntu now.)
-rwxr-xr-xcamera.py94
1 files changed, 82 insertions, 12 deletions
diff --git a/camera.py b/camera.py
index 59c47eb..005e2cd 100755
--- a/camera.py
+++ b/camera.py
@@ -72,11 +72,17 @@ def get_rays(position, size = (800, 600), film_size = (0.035, 0.024), focal_leng
return grid, focal_point-grid
class Camera(Thread):
- def __init__(self, geometry, module, context, lock=None, size=(800,600)):
+ def __init__(self, geometry, module, context, lock=None, size=(800,600),
+ spnav=False):
Thread.__init__(self)
self.geometry = geometry
self.module = module
self.context = context
+ self.spnav = spnav
+
+ if spnav:
+ import spnav as spnav_module
+ self.spnav_module = spnav_module
if lock is None:
self.lock = Lock()
@@ -130,6 +136,7 @@ class Camera(Thread):
def initialize_render(self):
with self.lock:
self.context.push()
+ print 'beginning initialize_render()'
self.rng_states_gpu = cuda.mem_alloc(self.width*self.height*sizeof('curandStateXORWOW', '#include <curand_kernel.h>'))
self.init_rng_kernel(np.int32(self.width*self.height), self.rng_states_gpu, np.int32(0), np.int32(0), block=(self.nblocks,1,1), grid=(self.width*self.height//self.nblocks+1,1))
self.xyz_lookup1_gpu = gpuarray.zeros(len(self.geometry.mesh.triangles), dtype=gpuarray.vec.float3)
@@ -222,7 +229,7 @@ class Camera(Thread):
self.update()
- def rotate_around_point(self, phi, n, point):
+ def rotate_around_point(self, phi, n, point, redraw=True):
with self.lock:
self.context.push()
self.rotate_around_point_kernel(np.int32(self.origins_gpu.size), self.origins_gpu, np.float32(phi), gpuarray.vec.make_float3(*n), gpuarray.vec.make_float3(*point), block=(self.nblocks,1,1), grid=(self.origins_gpu.size//self.nblocks+1,1))
@@ -232,12 +239,13 @@ class Camera(Thread):
self.axis1 = rotate(self.axis1, phi, n)
self.axis2 = rotate(self.axis2, phi, n)
- if self.render:
- self.clear_image()
+ if redraw:
+ if self.render:
+ self.clear_image()
- self.update()
+ self.update()
- def translate(self, v):
+ def translate(self, v, redraw=True):
with self.lock:
self.context.push()
self.translate_kernel(np.int32(self.pixels_gpu.size), self.origins_gpu, gpuarray.vec.make_float3(*v), block=(self.nblocks,1,1), grid=(self.pixels_gpu.size//self.nblocks,1))
@@ -245,14 +253,15 @@ class Camera(Thread):
self.point += v
self.context.pop()
- if self.render:
- self.clear_image()
+ if redraw:
+ if self.render:
+ self.clear_image()
- self.update()
+ self.update()
def update(self):
if self.render:
- while self.nlookup_calls < 100:
+ while self.nlookup_calls < 10:
self.update_xyz_lookup(self.source_position)
self.update_image()
self.process_image()
@@ -273,6 +282,9 @@ class Camera(Thread):
self.movie_index += 1
def run(self):
+ if self.spnav:
+ self.spnav_module.spnav_open()
+
self.update()
done = False
@@ -287,6 +299,58 @@ class Camera(Thread):
if self.render and not clicked and not pygame.event.peek(KEYDOWN):
self.update()
+
+ # Space Navigator controls
+ if self.spnav:
+ spnav_event = self.spnav_module.spnav_poll_event()
+ if spnav_event:
+ if spnav_event.type == self.spnav_module.SPNAV_EVENT_MOTION:
+ if shift:
+ accelerate_factor = 2.0
+ else:
+ accelerate_factor = 1.0
+ #print 'raw:', spnav_event
+ v1 = self.axis1
+ v2 = self.axis2
+ v3 = np.cross(self.axis1,self.axis2)
+
+ v = -v1*spnav_event.motion.x + v2*spnav_event.motion.y \
+ + v3*spnav_event.motion.z
+ v *= self.scale / 10000.0 * accelerate_factor
+
+ #print 'translate:', v
+ self.translate(v, redraw=False)
+
+ axis = v1*spnav_event.motion.rx + -v2*spnav_event.motion.ry \
+ + -v3*spnav_event.motion.rz
+
+ # Zero all but non-max values
+ #axis[~(np.abs(axis) == np.abs(axis).max())] = 0
+ #axis[np.abs(axis) < 15] = 0
+ if (axis != 0).any():
+ axis = axis.astype(float)
+ length = np.linalg.norm(axis)
+ angle = length * 0.0001 * accelerate_factor
+ axis /= length
+ #print 'rotate:', angle, axis
+ self.rotate_around_point(angle, axis, self.point, redraw=False)
+
+ if self.render:
+ self.clear_image()
+
+ self.update()
+ self.spnav_module.spnav_remove_events(self.spnav_module.SPNAV_EVENT_MOTION)
+
+ elif spnav_event.type == self.spnav_module.SPNAV_EVENT_BUTTON:
+ if spnav_event.button.bnum == 0 and spnav_event.button.press:
+ if not hasattr(self, 'rng_states_gpu'):
+ self.initialize_render()
+
+ self.render = not self.render
+ self.clear_image()
+ self.update()
+ self.spnav_module.spnav_remove_events(self.spnav_module.SPNAV_EVENT_ANY)
+
for event in pygame.event.get():
if event.type == MOUSEBUTTONDOWN:
@@ -436,6 +500,9 @@ class Camera(Thread):
encode_movie(self.movie_dir)
pygame.display.quit()
+ if self.spnav:
+ self.spnav_module.spnav_close()
+
if __name__ == '__main__':
import optparse
@@ -452,11 +519,13 @@ if __name__ == '__main__':
parser = optparse.OptionParser('%prog filename.stl')
parser.add_option('-b', '--bits', type='int', dest='bits',
- help='bits for z-ordering space axes', default=8)
+ help='bits for z-ordering space axes', default=10)
#parser.add_option('-l', action='store_true', dest='load_bvh',
# help='load bounding volumes', default=False)
parser.add_option('-r', '--resolution', dest='resolution',
help='specify resolution', default='800,600')
+ parser.add_option('--spnav', action='store_true', dest='spnav',
+ help='activate Space Navigator support', default=False)
options, args = parser.parse_args()
if len(args) < 1:
@@ -493,5 +562,6 @@ if __name__ == '__main__':
gpu = GPU()
gpu.load_geometry(geometry)
gpu.context.pop()
- camera = Camera(geometry, gpu.module, gpu.context, lock, size=size)
+ camera = Camera(geometry, gpu.module, gpu.context, lock, size=size,
+ spnav=options.spnav)
camera.start()