Source code for wasabisg.sphere

import math
from .model import Mesh, Material
from OpenGL.GL import GL_TRIANGLES


[docs]class Sphere(Mesh): """Construct a Mesh that is a 3D UV sphere. If `inside` is given then the normals and vertex winding will be reversed such that the camera will render the inside of the sphere rather than the outside. This is useful for skydomes etc. """ def __init__( self, radius=1, inside=False, latitude_divisions=20, longitude_divisions=40, material=None): material = material or Material(name='sphere_material') self.radius = radius self.latitude_divisions = latitude_divisions self.longitude_divisions = longitude_divisions vs = [] ns = [] uvs = [] tangents = [] for lat in xrange(latitude_divisions + 1): # angle of latitude, where 0 is the north pole and pi is south theta = lat * math.pi / latitude_divisions sintheta = math.sin(theta) costheta = math.cos(theta) for lng in xrange(longitude_divisions + 1): phi = lng * 2 * math.pi / longitude_divisions sinphi = math.sin(phi) cosphi = math.cos(phi) x = cosphi * sintheta y = costheta z = sinphi * sintheta u = 1 - (float(lng) / longitude_divisions) v = 1 - (float(lat) / latitude_divisions) ns.extend([x, y, z]) uvs.extend([u, v]) vs.extend([x * radius, y * radius, z * radius]) tangents.extend([-sinphi, 0, cosphi]) indexes = [] for lat in xrange(latitude_divisions): for lng in xrange(longitude_divisions): i = lat * (longitude_divisions + 1) + lng j = i + longitude_divisions + 1 indexes.extend([ i + 1, j, i, i + 1, j + 1, j, ]) super(Sphere, self).__init__( GL_TRIANGLES, vertices=vs, normals=ns, texcoords=uvs, indices=indexes, material=material, name=repr(self) ) if inside: flipped = self.inside_out() self.normals = flipped.normals self.indices = flipped.indices def __repr__(self): return ( 'Sphere(' '%(radius)r, ' '%(latitude_divisions)r, ' '%(longitude_divisions)r)' % self.__dict__ ) # Create an alias in case users want to differentiate from other ways of # tesselating a sphere
UVSphere = Sphere