# Copyright (c) 2001, Stanford University # All rights reserved # # See the file LICENSE.txt for information on redistributing this software. # Demo of combining stereo with non-planar tilesort. # This example relies on true quad-buffered stereo. # Each view of the city (or whatever demo) is an active stereo rendering. import sys sys.path.append( "../server" ) from mothership import * from crmatrix import * if len(sys.argv) > 1: Demo = sys.argv[1] else: Demo = "city" WALLS = 2 WALL_WIDTH = 200 WALL_HEIGHT = 200 ForceQuadBuffering = 0 xTranslate = 0 yTranslate = 0 zTranslate = 0 # Set stereo / non-planar view params if Demo == "city": EyeSep = 0.3 Hither = 1.0 Yon = 2500.0 FocalDist = 5.0 zTranslate = 0.0 zTranslate = 50.0 yTranslate = -3.0 Demo += " -b 20" # fewer buildings ForceQuadBuffering = 1 elif Demo == "atlantis": # atlantis uses some really big numbers! # not a great demo for stereo, either. EyeSep = 0.3 Hither = 10000.0 Yon = 400000.0 FocalDist = Hither * 2.0 zTranslate = 80000.0 # put us in the middle of the fish Demo += " -s 20" # more sharks! ForceQuadBuffering = 1 elif Demo == "stereocube": # Parameters copied from sterecube.c demo # This isn't a great demo. EyeSep = 0.3 Hither = 1.0 Yon = 25.0 FocalDist = 5.0 ForceQuadBuffering = 0 Demo += " -s" # real stereo mode else: # some default values that seem to work for some Mesa demos EyeSep = 0.3 # half of interocular distance Hither = 1.0 # near clip plane distance from eye Yon = 250.0 # far clip plane distance from eye FocalDist = 4.0 # focal distance for stereo imaging yTranslate = -5.0 zTranslate = 50.0 ForceQuadBuffering = 1 Width = 2.0 * FocalDist # frustum width at FocalDist Aspect = float(WALL_WIDTH) / float(WALL_HEIGHT) cr = CR() cr.MTU( 1024*1024 ) tilesortspu = SPU( 'tilesort' ) # Do bucketing by testing bounding boxes against viewing frustums tilesortspu.Conf('bucket_mode', 'Frustum') tilesortspu.Conf('stereo_mode', 'None') # Don't do anything special tilesortspu.Conf('force_quad_buffering', ForceQuadBuffering) clientnode = CRApplicationNode( ) clientnode.StartDir( crbindir ) clientnode.SetApplication( Demo ) clientnode.AddSPU( tilesortspu ) WinTitles = [ '-Z view', '+X view', '+Z view', '-X view' ] EyeNames = [ "left", "right" ] Width = 0.5 * Width # want half width below s = Hither / FocalDist # a scaling factor between focal dist and hither plane top = s * Width bottom = -top #print "Hither=%f yon=%f FocalDist=%f" % (Hither, Yon, FocalDist) #print "zTrans=%f Width=%f s=%f top=%f" % (zTranslate, Width, s, top) # create the four walls for wall in range(WALLS): # Render SPU w/ geometry renderspu = SPU( 'render' ) x = wall * (WALL_WIDTH + 10) y = 0 w = WALL_WIDTH h = WALL_HEIGHT renderspu.Conf( 'window_geometry', [x, y, w, h] ) renderspu.Conf( 'title', WinTitles[wall] ) node = CRNetworkNode( ) node.Conf('optimize_bucket', 0) # Same tiling for all views and both eyes # Left half of tile for left view, right half for right eye (SideBySide) node.AddTile( 0, 0, WALL_WIDTH, WALL_HEIGHT ) for eye in range(2): # View Matrix v = CRMatrix() # per-eye transform if eye == 0: v.Translate(+EyeSep, 0, 0) else: v.Translate(-EyeSep, 0, 0) # per-view transform # each view is another 90 degree rotation about the Y axis v.YRotate(90 * wall) v.Translate(xTranslate, yTranslate, zTranslate) # Projection matrix p = CRMatrix() if eye == 0: left = s * ((Width * -Aspect) - EyeSep); right = s * ((Width * Aspect) - EyeSep); else: left = s * (Width * -Aspect + EyeSep); right = s * (Width * Aspect + EyeSep); p.Frustum(left, right, bottom, top, Hither, Yon) if eye == 0: node.Conf('view_matrix', v.ToList()) node.Conf('projection_matrix', p.ToList()) else: node.Conf('right_view_matrix', v.ToList()) node.Conf('right_projection_matrix', p.ToList()) node.AddSPU( renderspu ) cr.AddNode( node ) tilesortspu.AddServer( node, protocol='tcpip', port=7000 + wall * 2 + eye ) cr.AddNode( clientnode ) cr.Go()