def mesh_indices(zstep, ystep, xstep=1): # now the indices, same as all quadratics indices = zeros((zstep - 1, ystep - 1, 6), dtype='H') # all indices now render the first rectangle... indices[:] = (0, 0 + ystep, 0 + ystep + xstep, 0, 0 + ystep + xstep, 0 + xstep) xoffsets = arange(0, ystep - 1, 1, dtype='H').reshape((-1, 1)) indices += xoffsets yoffsets = arange(0, zstep - 1, 1, dtype='H').reshape((-1, 1, 1)) indices += (yoffsets * ystep) return indices
def sphere(cls, phi=pi / 8.0, latAngle=pi, longAngle=(pi * 2)): """Create arrays for rendering a unit-sphere phi -- angle between points on the sphere (stacks/slices) Note: creates 'H' type indices... returns coordarray, indexarray """ latsteps = arange(0, latAngle + 0.000003, phi) longsteps = arange(0, longAngle + 0.000003, phi) return cls._partialSphere(latsteps, longsteps)
def OnTime(self, event): count = int(event.fraction() * 100000) points = lorentz(count) count = len(points) line = arange(0.0, 1.0, 1.0 / float(count + 1))[:count] line2 = line[::-1] self.ps.coord.point = points self.ps.color.color = zip(line, line2, [0] * len(line)) self.ils.coordIndex = range(len(points))
def OnInit( self ): """Generate scenegraph and lorentz equation on load""" count = 10000 points = lorentz( count ) line = arange(0.0,1.0,1.0/float(count)) line2 = line[::-1] coord = Coordinate( point = points, ) color = Color( color = map( None, line, line2, [0]*len(line) ), ) self.ps = PointSet( coord = coord, color = color, ) self.ils = IndexedLineSet( coordIndex=range(len(points)), coord=coord, color=color ) self.switch = Switch( whichChoice = 1, choice = [ Shape( geometry = self.ps ), Shape( geometry = self.ils, ), ], ) ts = TimeSensor( cycleInterval=300, loop=True ) self.sg = sceneGraph( children = [ Transform( #scale = (.1,.1,.1), # it's pretty big without this, but makes it easier to walk around in children = [ self.switch, ], ), ts, ], ) # register key 's' to switch rendering types... self.addEventHandler( "keypress", name="s", function = self.OnSwitch) print 'Should display a Lorentz Attractor' print ' s -- switch between IndexedLineset and Pointset presentation' timer = ts.getTimer( self ) timer.addEventHandler( "fraction", function = self.OnTime )
def OnTime( self, event ): count = int(event.fraction() * 100000) points = lorentz( count ) count = len(points) line = arange(0.0,1.0,1.0/float(count+1))[:count] line2 = line[::-1] self.ps.coord.point = points self.ps.color.color = map( None, line, line2, [0]*len(line) ) self.ils.coordIndex = range(len(points))
def cone(cls, height=2.0, radius=1.0, bottom=True, side=True, phi=pi / 16, longAngle=(pi * 2), top=False, cylinder=False): """Generate a VBO data-set to render a cone""" tip = (0, height / 2.0, 0) longsteps = arange(0, longAngle + 0.000003, phi) ystep = len(longsteps) zstep = 0 if top and cylinder: zstep += 2 if side: zstep += 2 if bottom: zstep += 2 # need top-ring coords and 2 sets for coords = zeros((zstep, ystep, 8), 'f') coords[:, :, 0] = sin(longsteps) * radius coords[:, :, 2] = cos(longsteps) * radius coords[:, :, 3] = longsteps / (2 * pi) def fill_disk(area, ycoord, normal=(0, -1, 0), degenerate=1): """fill in disk elements for given area""" other = not degenerate # disk texture coordinates area[:, :, 1] = ycoord # x and z are 0 at center area[degenerate, :, 0] = 0.0 area[degenerate, :, 2] = 0.0 area[other, :, 3] = (sin(longsteps) / 2.0 + .5)[:area.shape[2]] area[other, :, 4] = (cos(longsteps) / 2.0 + .5)[:area.shape[2]] area[degenerate, :, 3:5] = .5 # normal for the disk is all the same... area[:, :, 5:8] = normal def fill_sides(area): """Fill in side-of-cylinder/cone components""" if not cylinder: area[0, :, 0:3] = (0, height / 2.0, 0) else: area[0, :, 1] = height / 2.0 area[1, :, 1] = -height / 2.0 area[0, :, 4] = 0 area[1, :, 4] = 1.0 # normals for the sides... area[0:2, :-1, 5:8] = vectorutilities.normalise( vectorutilities.crossProduct( area[0, :-1, 0:3] - area[1, :-1, 0:3], area[1, :-1, 0:3] - area[1, 1:, 0:3])) area[0:2, -1, 5:8] = area[0:2, 0, 5:8] offset = 0 tocompress = {} if top and cylinder: fill_disk(coords[offset:offset + 2], height / 2.0, (0, 1, 0), degenerate=0) tocompress[offset] = 0 offset += 2 if side: fill_sides(coords[offset:offset + 2]) offset += 2 if bottom: # disk texture coordinates fill_disk(coords[offset:offset + 2], -height / 2.0, (0, -1, 0), degenerate=1) tocompress[offset] = 1 offset += 2 # now the indices, same as all quadratics indices = mesh_indices(zstep, ystep) new_indices = [] for (i, iSet) in enumerate(indices): iSet = iSet.reshape((-1, 3)) if i in tocompress: if not tocompress[i]: iSet = iSet[::2] else: iSet = iSet[1::2] new_indices.append(iSet) # compress out degenerate indices if present... indices = concatenate(new_indices) return coords.reshape((-1, 8)), indices.reshape((-1, ))
from OpenGLContext.browser.visual import * import time from OpenGLContext.arrays import arange scene.visible = 1 sphere() ##scene._context.loadUrl( "z:\\wrls\\figure.wrl" ) for x in arange(0.01, 3.14159, 0.01): scene.fov = x time.sleep(.001) scene.visible = 0 print('exit')
"""Test range and scale""" from OpenGLContext.browser.visual import * import time from OpenGLContext.arrays import arange scene.visible = 1 sphere() ##scene._context.loadUrl( "z:\\wrls\\figure.wrl" ) print('playing with range') for x in range(-20, 20): scene.range = x time.sleep(.001) print('playing with scale') for x in arange(2.0, -2.0, -.01): scene.scale = x time.sleep(.001) scene.visible = 0 print('exit')