summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony LaTorre <tlatorre9@gmail.com>2011-07-30 21:03:45 -0400
committerAnthony LaTorre <tlatorre9@gmail.com>2011-07-30 21:03:45 -0400
commit2b1a23e20c08423dd6f0d290ec87bef2f836fbe1 (patch)
tree5746b37bdb1152d37b8943193242ab4c4ef0010b
parent1a6dc30108d3e78f72f773ec025fc98e246f68f5 (diff)
downloadchroma-2b1a23e20c08423dd6f0d290ec87bef2f836fbe1.tar.gz
chroma-2b1a23e20c08423dd6f0d290ec87bef2f836fbe1.tar.bz2
chroma-2b1a23e20c08423dd6f0d290ec87bef2f836fbe1.zip
you can rotate just the camera by holding the control key and take movies by pressing the m key.
-rw-r--r--camera.py94
-rw-r--r--solids/__init__.py4
-rw-r--r--src/kernel.cu24
3 files changed, 102 insertions, 20 deletions
diff --git a/camera.py b/camera.py
index 148ddf9..a39060d 100644
--- a/camera.py
+++ b/camera.py
@@ -16,6 +16,10 @@ from pycuda import gpuarray
from pycuda.characterize import sizeof
import pycuda.driver as cuda
+from subprocess import call
+import shutil
+import tempfile
+
def timeit(func):
def f(*args, **kwargs):
t0 = time.time()
@@ -24,6 +28,20 @@ def timeit(func):
print '%s elapsed in %s().' % (datetime.timedelta(seconds=elapsed), func.__name__)
return f
+def encode_movie(dir):
+ root, ext = 'movie', 'avi'
+ for i in count():
+ filename = '.'.join([root + str(i).zfill(5), ext])
+
+ if not os.path.exists(filename):
+ break
+
+ call(['mencoder', 'mf://' + dir + '/*.png', '-mf', 'fps=10', '-o', filename, '-ovc', 'xvid', '-xvidencopts', 'bitrate=3000'])
+
+ shutil.rmtree(dir)
+
+ print 'movie saved to %s.' % filename
+
def get_rays(position, size = (800, 600), film_size = (0.035, 0.024), focal_length=0.05):
"""
Generate ray positions and directions from a pinhole camera facing the negative y direction.
@@ -72,6 +90,7 @@ class Camera(Thread):
self.context.push()
self.ray_trace_kernel = self.module.get_function('ray_trace')
self.rotate_kernel = self.module.get_function('rotate')
+ self.rotate_around_point_kernel = self.module.get_function('rotate_around_point')
self.translate_kernel = self.module.get_function('translate')
self.update_xyz_lookup_kernel = self.module.get_function('update_xyz_lookup')
self.update_xyz_image_kernel = self.module.get_function('update_xyz_image')
@@ -97,6 +116,9 @@ class Camera(Thread):
self.pixels_gpu = gpuarray.zeros(self.width*self.height, dtype=np.int32)
self.context.pop()
+ self.movie = False
+ self.movie_index = 0
+ self.movie_dir = None
self.render = False
@timeit
@@ -167,11 +189,11 @@ class Camera(Thread):
self.process_image_kernel(np.int32(self.width*self.height), self.image_gpu, self.pixels_gpu, np.int32(self.nimages), block=(self.nblocks,1,1), grid=((self.width*self.height)//self.nblocks+1,1))
self.context.pop()
- def screenshot(self, dir=''):
+ def screenshot(self, dir='', start=0):
root, ext = 'screenshot', 'png'
- for i in count():
- filename = os.path.join(dir, '.'.join([root + str(i).zfill(4), ext]))
+ for i in count(start):
+ filename = os.path.join(dir, '.'.join([root + str(i).zfill(5), ext]))
if not os.path.exists(filename):
break
@@ -182,8 +204,8 @@ class Camera(Thread):
def rotate(self, phi, n):
with self.lock:
self.context.push()
- self.rotate_kernel(np.int32(self.pixels_gpu.size), self.origins_gpu, phi, gpuarray.vec.make_float3(*n), block=(self.nblocks,1,1), grid=(self.pixels_gpu.size//self.nblocks+1,1))
- self.rotate_kernel(np.int32(self.pixels_gpu.size), self.directions_gpu, phi, gpuarray.vec.make_float3(*n), block=(self.nblocks,1,1), grid=(self.pixels_gpu.size//self.nblocks+1,1))
+ self.rotate_kernel(np.int32(self.pixels_gpu.size), self.origins_gpu, np.float32(phi), gpuarray.vec.make_float3(*n), block=(self.nblocks,1,1), grid=(self.pixels_gpu.size//self.nblocks+1,1))
+ self.rotate_kernel(np.int32(self.pixels_gpu.size), self.directions_gpu, np.float32(phi), gpuarray.vec.make_float3(*n), block=(self.nblocks,1,1), grid=(self.pixels_gpu.size//self.nblocks+1,1))
self.point = rotate(self.point, phi, n)
self.axis1 = rotate(self.axis1, phi, n)
@@ -195,6 +217,21 @@ class Camera(Thread):
self.update()
+ def rotate_around_point(self, phi, n, point):
+ 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))
+ self.rotate_kernel(np.int32(self.directions_gpu.size), self.directions_gpu, np.float32(phi), gpuarray.vec.make_float3(*n), block=(self.nblocks,1,1), grid=(self.directions_gpu.size//self.nblocks+1,1))
+ self.context.pop()
+
+ self.axis1 = rotate(self.axis1, phi, n)
+ self.axis2 = rotate(self.axis2, phi, n)
+
+ if self.render:
+ self.clear_image()
+
+ self.update()
+
def translate(self, v):
with self.lock:
self.context.push()
@@ -210,7 +247,7 @@ class Camera(Thread):
def update(self):
if self.render:
- while self.nlookup_calls < 10:
+ while self.nlookup_calls < 100:
self.update_xyz_lookup(self.source_position)
self.update_image()
self.process_image()
@@ -226,12 +263,17 @@ class Camera(Thread):
pygame.display.flip()
self.context.pop()
+ if self.movie:
+ self.screenshot(self.movie_dir, self.movie_index)
+ self.movie_index += 1
+
def run(self):
self.update()
done = False
clicked = False
shift = False
+ ctrl = False
#current_layer = 0
@@ -277,7 +319,10 @@ class Camera(Thread):
phi = np.float32(2*np.pi*length/float(self.width))
n = rotate(mouse_direction, np.pi/2, -np.cross(self.axis1,self.axis2))
- self.rotate(phi, n)
+ if ctrl:
+ self.rotate_around_point(phi, n, self.point)
+ else:
+ self.rotate(phi, n)
if event.type == KEYDOWN:
if event.key == K_a:
@@ -300,18 +345,26 @@ class Camera(Thread):
v = self.scale*self.axis2/10.0
self.translate(v)
- if event.key == K_LCTRL:
- v = -self.scale*self.axis2/10.0
- self.translate(v)
+ # if event.key == K_LCTRL:
+ # v = -self.scale*self.axis2/10.0
+ # self.translate(v)
- if event.key == K_p:
+ if event.key == K_F6:
self.clear_xyz_lookup()
- self.update_xyz_lookup(self.point)
+ self.clear_image()
+ self.source_position = self.point
+
+ if event.key == K_p:
+ for i in range(100):
+ self.update_xyz_lookup(self.point)
self.source_position = self.point
if event.key == K_LSHIFT or event.key == K_RSHIFT:
shift = True
+ if event.key == K_LCTRL or event.key == K_RCTRL:
+ ctrl = True
+
if event.key == K_ESCAPE:
done = True
break
@@ -350,16 +403,33 @@ class Camera(Thread):
self.initialize_render()
self.render = not self.render
+ self.clear_image()
self.update()
+ if event.key == K_m:
+ if self.movie:
+ encode_movie(self.movie_dir)
+ self.movie_dir = None
+ self.movie = False
+ else:
+ self.movie_index = 0
+ self.movie_dir = tempfile.mkdtemp()
+ self.movie = True
+
if event.type == KEYUP:
if event.key == K_LSHIFT or event.key == K_RSHIFT:
shift = False
+ if event.key == K_LCTRL or event.key == K_RCTRL:
+ ctrl = False
+
if event.type == pygame.QUIT:
done = True
break
+ if self.movie:
+ encode_movie(self.movie_dir)
+
pygame.display.quit()
if __name__ == '__main__':
diff --git a/solids/__init__.py b/solids/__init__.py
index 072c220..d37af7e 100644
--- a/solids/__init__.py
+++ b/solids/__init__.py
@@ -28,9 +28,9 @@ def build_12inch_pmt_with_lc(outer_material=water, theta=np.pi/8):
return pmt + build_light_collector(pmt, a=lc_12inch_a, b=lc_12inch_b, d=lc_12inch_d, rmin=lc_12inch_rmin, rmax=lc_12inch_rmax)
@buildable('12inch_pmt_with_lc_hd')
-def build_12inch_pmt_with_lc_hd(outer_material=water, theta=np.pi/32):
+def build_12inch_pmt_with_lc_hd(outer_material=water, theta=np.pi/64):
pmt = build_12inch_pmt(outer_material, theta)
- return pmt + build_light_collector(pmt, a=lc_12inch_a, b=lc_12inch_b, d=lc_12inch_d, rmin=lc_12inch_rmin, rmax=lc_12inch_rmax, npoints=25)
+ return pmt + build_light_collector(pmt, a=lc_12inch_a, b=lc_12inch_b, d=lc_12inch_d, rmin=lc_12inch_rmin, rmax=lc_12inch_rmax, npoints=100)
@buildable('8inch_pmt')
diff --git a/src/kernel.cu b/src/kernel.cu
index be0087d..82efe88 100644
--- a/src/kernel.cu
+++ b/src/kernel.cu
@@ -62,27 +62,39 @@ __device__ __noinline__ void to_diffuse(Photon &p, State &s, curandState &rng, c
extern "C"
{
-/* Translate `points` by the vector `v` */
-__global__ void translate(int nthreads, float3 *points, float3 v)
+/* Translate the points `a` by the vector `v` */
+__global__ void translate(int nthreads, float3 *a, float3 v)
{
int id = blockIdx.x*blockDim.x + threadIdx.x;
if (id >= nthreads)
return;
- points[id] += v;
+ a[id] += v;
}
-/* Rotate `points` through an angle `phi` counter-clockwise about the
+/* Rotate the points `a` through an angle `phi` counter-clockwise about the
axis `axis` (when looking towards +infinity). */
-__global__ void rotate(int nthreads, float3 *points, float phi, float3 axis)
+__global__ void rotate(int nthreads, float3 *a, float phi, float3 axis)
{
int id = blockIdx.x*blockDim.x + threadIdx.x;
if (id >= nthreads)
return;
- points[id] = rotate(points[id], phi, axis);
+ a[id] = rotate(a[id], phi, axis);
+}
+
+__global__ void rotate_around_point(int nthreads, float3 *a, float phi, float3 axis, float3 point)
+{
+ int id = blockIdx.x*blockDim.x + threadIdx.x;
+
+ if (id >= nthreads)
+ return;
+
+ a[id] -= point;
+ a[id] = rotate(a[id], phi, axis);
+ a[id] += point;
}
__global__ void update_xyz_lookup(int nthreads, int total_threads, int offset, float3 position, curandState *rng_states, float wavelength, float3 xyz, float3 *xyz_lookup1, float3 *xyz_lookup2, int max_steps)