diff options
author | Stan Seibert <stan@mtrr.org> | 2011-08-05 18:36:05 -0400 |
---|---|---|
committer | Stan Seibert <stan@mtrr.org> | 2011-08-05 18:36:05 -0400 |
commit | 1711f85bed5ad279d6b66d0373926da55e07c0ca (patch) | |
tree | f9182e3f8db1dae890f16e790a840a259efd833f | |
parent | d7f835b3325611ad25209c9a25256b46d4944827 (diff) | |
download | chroma-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-x | camera.py | 94 |
1 files changed, 82 insertions, 12 deletions
@@ -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() |