from __future__ import absolute_import, division, print_function, unicode_literals
from pi3d.Buffer import Buffer
from pi3d.Shape import Shape
import logging
LOGGER = logging.getLogger(__name__)
[docs]class Extrude(Shape):
""" 3d model inherits from Shape
NB this shape has an array of three Buffers representing each end face
and the sides of the prism. Each can be textured seperately for drawing.
"""
def __init__(self, camera=None, light=None, path=None, height=1.0, name="", x=0.0, y=0.0, z=0.0,
rx=0.0, ry=0.0, rz=0.0, sx=1.0, sy=1.0, sz=1.0,
cx=0.0, cy=0.0, cz=0.0):
"""uses standard constructor for Shape extra Keyword arguments:
*path*
Coordinates defining crossection of prism [(x0,z0),(x1,z1)..]
*height*
Distance between end faces in the y direction.
"""
super(Extrude, self).__init__(camera, light, name, x, y, z, rx, ry, rz,
sx, sy, sz, cx, cy, cz)
LOGGER.debug("Creating Extrude ...")
s = len(path) if path != None else 0
ht = height * 0.5
verts = []
norms = []
botface = []
topface = []
sidefaces = []
tex_coords = []
minx = path[0][0]
maxx = path[0][0]
minz = path[0][1]
maxz = path[0][1]
#find min/max values for texture coords
for p in range(0, s):
px = path[p][0]
pz = path[p][1]
minx = min(minx, px)
minz = min(minz, pz)
maxx = max(maxx, px)
maxz = max(maxz, pz)
tx = 1.0 / (maxx - minx)
tz = 1.0 / (maxz - minz)
#vertices for sides
for p in range(s):
px = path[p][0]
pz = path[p][1]
dx = path[(p+1)%s][0] - px
dz = path[(p+1)%s][1] - pz
#TODO normalize these vector components, not needed for shadows = 0:2s
for i in (-1, 1):
verts.append((px, i*ht, pz))
norms.append((-dz, 0.0, dx))
tex_coords.append((1.0*p/s, i*0.5))
#vertices for edges of top and bottom, bottom first (n=2s to 3s-1) 2s:3s then top (3s+1 to 4s) 3s+1:4s+1
for i in (-1, 1):
for p in range(s):
px = path[p][0]
pz = path[p][1]
verts.append((px, i*ht, pz))
norms.append((0.0, i, 0.0))
tex_coords.append(((px - minx) * tx, (pz - minz) * tz))
#top and bottom face mid points verts number 3*s and 4*s+1 (bottom and top respectively)
verts.append(((minx+maxx)/2, i*ht, (minz+maxz)/2))
norms.append((0, i, 0))
tex_coords.append((0.5, 0.5))
for p in range(s): #sides - triangle strip
v0, v1, v2, v3 = 2*p, 2*p+1, (2*p+2)%(2*s), (2*p+3)%(2*s)
sidefaces.append((v0, v2, v1))
sidefaces.append((v1, v2, v3))
for p in range(s): #bottom face indices - triangle fan
botface.append((s, (p+1)%s, p))
for p in range(s): #top face indices - triangle fan
topface.append((s, p, (p+1)%s))
# sides, top, bottom
self.buf = [Buffer(self, verts[0:(2*s)], tex_coords[0:(2*s)], sidefaces, norms[0:(2*s)]),
Buffer(self, verts[(2*s):(3*s+1)], tex_coords[(2*s):(3*s+1)], botface, norms[(2*s):(3*s+1)]),
Buffer(self, verts[(3*s+1):(4*s+2)], tex_coords[(3*s+1):(4*s+2)], topface, norms[(3*s+1):(4*s+2)])]