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 _partialSphere(cls, latsteps, longsteps): """Create a partial-sphere data-set for latsteps and longsteps returns (coordarray, indexarray) """ ystep = len(longsteps) zstep = len(latsteps) xstep = 1 coords = zeros((zstep, ystep, 8), 'f') coords[:, :, 0] = sin(longsteps) coords[:, :, 1] = cos(latsteps).reshape((-1, 1)) coords[:, :, 2] = cos(longsteps) coords[:, :, 3] = longsteps / (2 * pi) coords[:, :, 4] = latsteps.reshape((-1, 1)) / pi # now scale by sin of y's scale = sin(latsteps).reshape((-1, 1)) coords[:, :, 0] *= scale coords[:, :, 2] *= scale coords[:, :, 5:8] = coords[:, :, 0:3] # normals indices = mesh_indices(zstep, ystep) # now optimize/simplify the data-set... new_indices = [] for (i, iSet) in enumerate(indices): angle = latsteps[i] nextAngle = latsteps[i + 1] if allclose(angle % (pi * 2), 0): iSet = iSet.reshape((-1, 3))[::2] elif allclose(nextAngle % (pi), 0): iSet = iSet.reshape((-1, 3))[1::2] else: iSet = iSet.reshape((-1, 3)) new_indices.append(iSet) indices = concatenate(new_indices) return coords.reshape((-1, 8)), indices.reshape((-1, ))
def OnTimerFraction( self, event ): """Update light position/direction""" '''Every cycle we want to do a full rotation, and we want the light to be 10 units from the y axis in the x,z plane. All else is math.''' light = self.lights[0] a = event.fraction() * 2 * pi xz = array( [ sin(a),cos(a), ],'f') * 10 # radius position = light.location position[0] = xz[0] position[2] = xz[1] light.location = position '''We point the light at the origin, mostly because it's easy.''' light.direction = -position
def OnTimerFraction(self, event): """Update light position/direction""" '''Every cycle we want to do a full rotation, and we want the light to be 10 units from the y axis in the x,z plane. All else is math.''' light = self.lights[0] a = event.fraction() * 2 * pi xz = array([ sin(a), cos(a), ], 'f') * 10 # radius position = light.location position[0] = xz[0] position[2] = xz[1] light.location = position '''We point the light at the origin, mostly because it's easy.''' light.direction = -position
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, ))