"""The convict's body, part by part, for the four augmentation stages. Lore (GameLore.txt): both arms and both legs are machine limbs, the rest stays human, a feeding port in his side, he breathes from a tank in the water. So the torso and head are a man in an insulated suit and helmet, the limbs are hardware, and each stage refits the hardware. One reference picture per stage, in the order the user gave them: Stage 1 Issue slim gloss-black limbs as fitted before transport, plain robot hands, smooth visor helmet Stage 2 Refit heavier matte-black shells, domed shoulders, hinge discs, neck cables, a pale face plate Stage 3 Deepframe layered red plates over a grey frame, finned helmet Stage 4 Abyssal oversized gauntlets and greaves, shoulder housings, gorget, power pack All four stages share one skeleton, so joint positions never change; later stages add bulk around the same joints. Limb frames: local X = lateral (hinge axis), Y = front, Z = toward the hand/foot. Left side is built, right is mirrored. """ from math import sin, cos, radians, pi from mathutils import Vector, Matrix from lib_geo import V, K, P, T, RX, RY, RZ, Prof, frame, shell DARK, STEEL, RED, SUIT, RUB, VIS, GLOW, CER, GREY, MATTE = 'Dark', 'Steel', 'Red', 'Suit', 'Rubber', 'Visor', 'Glow', 'Ceramic', 'Grey', 'Matte' MATS = [SUIT, DARK, STEEL, RED, RUB, VIS, GLOW, CER, GREY, MATTE] SK = {1: dict(body=DARK, plate=DARK), 2: dict(body=MATTE, plate=MATTE), 3: dict(body=GREY, plate=RED), 4: dict(body=DARK, plate=GREY)} STAGE_NAMES = {1: 'Issue', 2: 'Refit', 3: 'Deepframe', 4: 'Abyssal'} I4 = Matrix.Identity(4) # ball = joint ball radius, ru/rf = upper/forearm radius (near end, far end), n = squareness, cx = shell pushed outward, # disc/bw/dt = hinge disc radius, barrel half width, disc thickness, cap = how far the shoulder dome stands off (0 = none) ARM = {1: dict(ball=.040, ru=(.043, .038), rf=(.040, .031), n=2.3, cx=.002, disc=.027, bw=.024, dt=.009, cap=.018), 2: dict(ball=.048, ru=(.056, .049), rf=(.052, .040), n=2.6, cx=.006, disc=.036, bw=.032, dt=.012, cap=.030), 3: dict(ball=.052, ru=(.060, .052), rf=(.057, .043), n=2.9, cx=.009, disc=.040, bw=.036, dt=.013, cap=.032), 4: dict(ball=.058, ru=(.074, .066), rf=(.084, .068), n=3.3, cx=.026, disc=.054, bw=.048, dt=.016, cap=.034)} HAND = {1: dict(fw=.0130, ft=.0115, pt=.021, pw=.076), 2: dict(fw=.0158, ft=.0145, pt=.028, pw=.084), 3: dict(fw=.0166, ft=.0155, pt=.030, pw=.086), 4: dict(fw=.0190, ft=.0185, pt=.037, pw=.094)} LEG = {1: dict(ball=.046, t0=(.068, .076), t1=(.048, .052), c0=(.048, .055), c1=(.034, .037), n=2.3, cx=.002, disc=.032, bw=.030, dt=.010, fw=.043, fh=.92), 2: dict(ball=.052, t0=(.084, .092), t1=(.058, .062), c0=(.060, .068), c1=(.042, .046), n=2.6, cx=.008, disc=.042, bw=.040, dt=.013, fw=.050, fh=1.05), 3: dict(ball=.056, t0=(.090, .098), t1=(.062, .066), c0=(.064, .072), c1=(.045, .049), n=2.9, cx=.012, disc=.046, bw=.044, dt=.014, fw=.054, fh=1.12), 4: dict(ball=.062, t0=(.108, .116), t1=(.080, .084), c0=(.090, .098), c1=(.068, .072), n=3.3, cx=.026, disc=.060, bw=.056, dt=.017, fw=.072, fh=1.35)} # ----------------------------------------------------------------------------------------------- skeleton def make_joints(): A = radians(38); J = {} SH = V((.19, 0, 1.415)); du = V((sin(A), 0, -cos(A))); h = V((cos(A), 0, sin(A))); fr = V((0, -1, 0)) LU, LF = .295, .265 EL = SH + LU * du; b = radians(10); df = (cos(b) * du + sin(b) * fr).normalized(); WR = EL + LF * df J.update(SH=SH, EL=EL, WR=WR, LU=LU, LF=LF, DF=df, HX=h, FU=frame(SH, du, h), FF=frame(EL, df, h), FH=frame(WR, df, h)) fing = dict(index=(.0285, .094, 5, (.042, .026, .022)), middle=(.0085, .099, 0, (.046, .029, .023)), ring=(-.0115, .095, -5, (.042, .027, .022)), pinky=(-.0305, .086, -11, (.033, .021, .019))) curl = (8, 14, 10); F = {} for nme, (y, z, sp, lens) in fing.items(): M = J['FH'] @ T(0, y, z) @ RX(-sp) @ RY(-curl[0]); frs = [M] for k in (1, 2): M = M @ T(0, 0, lens[k - 1]) @ RY(-curl[k]); frs.append(M) F[nme] = (frs, lens) Mt = J['FH'] @ T(-.006, .034, .030) @ frame((0, 0, 0), (-.30, .62, .72), (.5, .6, -.3)); tl = (.040, .032, .027); frs = [Mt] for k in (1, 2): Mt = Mt @ T(0, 0, tl[k - 1]) @ RY(-10); frs.append(Mt) F['thumb'] = (frs, tl); J['F'] = F HIP = V((.095, 0, .925)); KNEE = V((.10, -.012, .50)); ANK = V((.10, .02, .085)) FFT = Matrix(((1, 0, 0, ANK.x), (0, 0, -1, ANK.y), (0, 1, 0, 0), (0, 0, 0, 1))) # X lateral, Y up, Z toe-ward J.update(HIP=HIP, KNEE=KNEE, ANK=ANK, LT=(KNEE - HIP).length, LC=(ANK - KNEE).length, FT=frame(HIP, KNEE - HIP, (1, 0, 0)), FC=frame(KNEE, ANK - KNEE, (1, 0, 0)), FFT=FFT, BALL=FFT @ V((0, .02, .145)), TOE=FFT @ V((0, .02, .228))) return J def bone_table(J): """(name, parent, head, tail), UE mannequin names. Left side listed, right mirrored.""" c = [('root', None, (0, 0, 0), (0, .12, 0)), ('pelvis', 'root', (0, 0, .965), (0, 0, 1.05)), ('spine_01', 'pelvis', (0, 0, 1.05), (0, 0, 1.155)), ('spine_02', 'spine_01', (0, 0, 1.155), (0, 0, 1.28)), ('spine_03', 'spine_02', (0, 0, 1.28), (0, 0, 1.48)), ('neck_01', 'spine_03', (0, 0, 1.48), (0, 0, 1.555)), ('head', 'neck_01', (0, 0, 1.555), (0, 0, 1.78))] s = [('clavicle', 'spine_03', V((.02, -.01, 1.44)), J['SH']), ('upperarm', 'clavicle', J['SH'], J['EL']), ('lowerarm', 'upperarm', J['EL'], J['WR']), ('hand', 'lowerarm', J['WR'], J['WR'] + .09 * J['DF'])] for nme, (frs, lens) in J['F'].items(): for k in range(3): tail = frs[k + 1].translation if k < 2 else frs[2] @ V((0, 0, lens[2])) s.append((f'{nme}_0{k + 1}', 'hand' if k == 0 else f'{nme}_0{k}', frs[k].translation, tail)) s += [('thigh', 'pelvis', J['HIP'], J['KNEE']), ('calf', 'thigh', J['KNEE'], J['ANK']), ('foot', 'calf', J['ANK'], J['BALL']), ('ball', 'foot', J['BALL'], J['TOE'])] side_names = {b[0] for b in s}; out = [(n, p, tuple(h), tuple(t)) for n, p, h, t in c] for sfx, m in (('_l', 1), ('_r', -1)): for n, p, h, t in s: out.append((n + sfx, p + sfx if p in side_names else p, (m * h[0], h[1], h[2]), (m * t[0], t[1], t[2]))) return out _BLEND = [('pelvis', 'spine_01', .99, 1.06), ('spine_01', 'spine_02', 1.09, 1.17), ('spine_02', 'spine_03', 1.20, 1.29), ('spine_03', 'neck_01', 1.465, 1.50), ('neck_01', 'head', 1.53, 1.56)] def spine_w(co): z = co.z; last = 'pelvis' for a, b, z0, z1 in _BLEND: if z < z0: return (a, a, 0.0) if z <= z1: t = (z - z0) / (z1 - z0); return (a, b, t * t * (3 - 2 * t)) last = b return (last, last, 0.0) def joint_disc(B, p, axis, r, t, seg=20, name='joint_disc'): """Hinge cap: a stepped disc with a recessed hub, growing from p along axis by t.""" ax = Vector(axis); xh = Vector((0, 1, 0)) if abs(ax.normalized().y) < .9 else Vector((1, 0, 0)) with B.at(frame(p, ax, xh)): B.lathe([(0, 0), (0, r * .97), (t * .55, r), (t * .72, r * .93), (t * .72, r * .74), (t, r * .70), (t, r * .34), (t * .78, r * .30), (t * .78, 0)], seg, name) def bolts(B, prof, pts, off=0.0, r=.005, h=.003): for phi, z in pts: B.bolt(prof.pt(phi, z, off), prof.nrm(phi, z), r, h) def slots(a0, a1, z0, n, pitch=.02, w=.006, h=-.003, mat=DARK): return [P(a0, a1, z0 + i * pitch, z0 + i * pitch + w, h, mat) for i in range(n)] # ----------------------------------------------------------------------------------------------- arm def arm(B, st, J): s = B.sfx; ua, la, cl = 'upperarm' + s, 'lowerarm' + s, 'clavicle' + s LU, LF = J['LU'], J['LF']; c = SK[st]; SH = J['SH'] a = ARM[st]; n = a['n']; cx = a['cx']; r0, r1 = a['ru']; bw, dt, rd, rb = a['bw'], a['dt'], a['disc'], a['ball'] B.L = I4; B.bone = cl; B.mat = STEEL B.cyl((SH.x - .042, 0, SH.z), (SH.x - .018, 0, SH.z), rb + .006, seg=20, ch=.003, name='shoulder_socket') B.L = J['FU']; B.bone = ua B.ball((0, 0, 0), rb, name='shoulder_ball') pu = Prof([K(.050, r0 * .76, r0 * .80, n, cx), K(.090, r0, r0 * 1.04, n, cx), K(.20, r1 * 1.02, r1 * 1.06, n, cx), K(LU - rd - .022, r1 * .93, r1 * .97, n, cx * .5), K(LU - rd - .008, r1 * .78, r1 * .82, n, cx * .5)]) gz = LU - rd - .036; groove = P(-180, 180, gz, gz + .006, -.0025, RUB) if st == 1: pn = [P(35, 145, .125, gz - .012, .003), groove] elif st == 2: pn = [P(30, 150, .128, gz - .012, .005), P(-150, -35, .09, gz - .025, .003), groove] elif st == 3: pn = [P(-15, 155, .165, gz - .008, .006, RED), P(-150, -40, .09, gz - .02, .004), groove] else: pn = [P(-35, 170, .128, gz + .004, .008, GREY), P(15, 145, .14, gz - .012, .006, GREY), P(-160, -50, .08, gz - .02, .005, GREY)] pn += slots(55, 125, .15, 2, .024, .010, -.006, RUB) B.mat = c['body']; shell(B, pu, pn, seg=24, dz=.022, name='upperarm_shell') if st == 4: B.mat = STEEL; bolts(B, pu, [(-20, .14), (158, .14), (-20, gz - .01), (158, gz - .01)], .008, .006, .004) if a['cap']: # shoulder dome, carried by the upper arm; it covers the outer half only, so it clears the torso when the arm hangs R = r0 + cx + a['cap']; q = {1: 2.0, 2: 2.0, 3: 2.4, 4: 3.0}[st]; tk = .012 if st == 4 else .007 pc = Prof([K(-.044, R * .62, R * .64, q), K(-.022, R * .93, R * .96, q), K(.02, R, R * 1.03, q), K(.07, R * .95, R * .98, q), K(.105, R * .9, R * .93, q)]) pp = [P(.1, .9, -.03, .09, .003, RED if st == 3 else None)] if st == 2: pp.append(P(0, 1, .048, .062, 0, CER)) if st == 4: pp = [P(.08, .92, -.03, .088, .004, GREY), P(.22, .78, -.005, .07, .004, GREY), P(.3, .7, .093, .098, 0, GLOW)] B.mat = c['plate']; shell(B, pc, pp, seg=14, dz=.018, span=(90, 196, 90, 132), thick=tk, rim=.003, name='pauldron') if st in (2, 4): B.mat = STEEL; bolts(B, pc, [(20, .0), (160, .0), (90, -.03)], .004 if st == 4 else 0, .007 if st == 4 else .006, .004) if st == 3: R2 = r0 + cx + .011 B.mat = RED shell(B, Prof([K(.085, R2), K(.158, R2 * .97)], lin=True), [P(.12, .88, .095, .148, .0025, RED)], seg=10, dz=.03, span=(90, 170, 90, 120), thick=.007, rim=.003, name='pauldron_tier') with B.at(T(0, 0, LU)): for sg in (1, -1): B.mat = c['body']; B.rbox((sg * (bw + .001 + dt * .4), 0, -rd * .78), (dt * .8, rd * 1.5, rd * 1.6), name='elbow_lug') B.mat = STEEL; joint_disc(B, (sg * (bw + .001), 0, 0), (sg, 0, 0), rd, dt, name='elbow_disc') B.L = J['FF']; B.bone = la B.mat = STEEL; B.cyl((-bw, 0, 0), (bw, 0, 0), rd * .76, seg=18, ch=.003, name='elbow_barrel') f0, f1 = a['rf']; zs = rd + .004 B.mat = c['body']; B.tube(rd * .3, zs + .012, min(bw - .004, f0 * .6), seg=16, name='forearm_neck') pf = Prof([K(zs, f0 * .72, f0 * .76, n), K(zs + .042, f0, f0 * 1.05, n, cx * .5), K(.15, f0 * .96, f0, n, cx * .5), K(LF - .046, f1, f1 * 1.04, n), K(LF - .03, f1 * .9, f1 * .94, n)]) groove = P(-180, 180, .214, .22, -.0025, RUB) if st == 1: pn = [P(35, 145, zs + .03, .205, .003), groove] elif st == 2: pn = [P(30, 150, zs + .03, .208, .005), P(-150, -30, zs + .03, .19, .003), P(60, 120, .186, .197, 0, CER), groove] elif st == 3: pn = [P(-150, -30, zs + .03, .2, .004), groove] else: pn = [P(15, 165, zs + .02, .222, .009, GREY), P(45, 135, zs + .04, .2, .006, GREY), P(-165, -15, zs + .025, .21, .007, GREY)] pn += slots(70, 110, zs + .055, 4, .022, .010, -.007, RUB) shell(B, pf, pn, seg=24, dz=.022, name='forearm_shell') if st == 3: pv = Prof([K(zs + .012, f0 + .006, f0 + .008, n), K(zs + .05, f0 + .017, f0 * 1.05 + .017, n, cx * .5), K(.16, f0 * .96 + .016, f0 + .016, n, cx * .5), K(.236, f1 + .016, f1 * 1.04 + .016, n)]) B.mat = RED shell(B, pv, [P(.12, .88, zs + .035, .21, .003, RED)] + slots(.32, .68, zs + .07, 3, .02, .005), seg=16, dz=.02, span=(90, 215, 90, 150), thick=.008, rim=.003, zwarp=lambda phi, t, u: .02 * t * (1 - abs(2 * u - 1)), name='vambrace') B.mat = GREY if st == 4 else STEEL B.tube(LF - .036, LF - .012, f1 * 1.12, seg=20, ch=.003, name='wrist_cuff') if st == 4: B.mat = STEEL for sg in (1, -1): B.cyl((0, sg * f0, zs + .03), (0, sg * f1, .2), .013, seg=10, ch=.002, name='gauntlet_piston') bolts(B, pf, [(20, zs + .035), (160, zs + .035), (20, .21), (160, .21)], .009, .006, .004) if st >= 2: B.L = I4; FU, FF = J['FU'], J['FF']; B.mat = RUB B.hose([FU @ V((0, -(r1 * 1.06 + .004), .19)), FU @ V((0, -(r1 + .032), LU - .04)), FF @ V((0, -(f0 + .03), .03)), FF @ V((0, -(f0 * 1.05 + .004), zs + .06))], .010 if st == 4 else .007, seg=8, bones=[ua, ua, la, la], rib=.12, name='elbow_hose') hand(B, st, J) def hand(B, st, J): s = B.sfx; hd = 'hand' + s; h = HAND[st]; c = SK[st]; fw, ft, pt, pw = h['fw'], h['ft'], h['pt'], h['pw'] B.L = J['FH']; B.bone = hd B.mat = STEEL; B.ball((0, 0, 0), pt * .62, seg=12, rings=6, name='wrist_ball') # the thumb side of the palm stops at y = .028 near the wrist, so wider palms never run into the thumb (its joint is the same in every stage) hw = (.029 + pw * .5) / 2; cyy = (.027 - pw * .5) / 2 pp = Prof([K(.010, pt * .42, hw * .72, 3.4, 0, cyy), K(.036, pt * .5, hw, 3.4, 0, cyy), K(.072, pt * .5, pw * .5, 3.4, 0, -.001), K(.088, pt * .44, pw * .5, 3.4, 0, -.001)]) pn = [P(-140, -40, .03, .08, .0015, RUB)] if st >= 2: pn.append(P(40, 140, .024, .082, .0035, c['plate'] if st >= 3 else None)) if st == 4: pn.append(P(62, 118, .034, .074, .003, GREY)) if st == 2: pn.append(P(60, 120, .058, .068, 0, CER)) B.mat = c['body']; shell(B, pp, pn, seg=20, dz=.014, eps=.0018, name='palm') if st == 1: B.mat = STEEL for nme in ('index', 'middle', 'ring', 'pinky'): kp = J['FH'].inverted() @ J['F'][nme][0][0].translation B.cyl((pt * .5 + .0015, kp.y * .45, .016), (pt * .5 + .0015, kp.y, kp.z - .012), .0022, seg=6, name='tendon') if st >= 3: B.mat = c['plate']; B.rbox((pt * .5 + .003, -.001, .089), (.008, pw * .92, .02), n=4, ch=.002, name='knuckle_guard') for nme, (frs, lens) in J['F'].items(): thumb = nme == 'thumb' for k in range(3): B.L = frs[k]; B.bone = f'{nme}_0{k + 1}{s}' ln = lens[k]; w = fw * (1.12 if thumb else 1.0) * (1 - .06 * k); t = ft * (1.08 if thumb else 1.0) * (1 - .07 * k) B.mat = STEEL; B.cyl((0, -w * .53, 0), (0, w * .53, 0), t * .56, seg=10, ch=.001, name='knuckle') g = min(t * .64, ln * .3); z0 = g; z1 = ln - g if k < 2 else ln; e = min(.004, (z1 - z0) * .3) if k < 2: ks = [K(z0, t * .42, w * .44, 3.2), K(z0 + e, t * .5, w * .5, 3.2), K(z1 - e, t * .48, w * .48, 3.2), K(z1, t * .40, w * .42, 3.2)] else: ks = [K(z0, t * .42, w * .44, 3.2), K(z0 + e, t * .5, w * .5, 3.2), K(ln - .008, t * .46, w * .46, 3.0), K(ln - .002, t * .34, w * .36, 2.6), K(ln + .0015, t * .16, w * .2, 2.2)] pn = [] if st >= 2 and k == 0: pn.append(P(38, 142, z0 + .005, z1 - .005, .002, RED if st == 3 else (GREY if st == 4 else None))) if k == 2: pn.append(P(-140, -40, ln * .3, ln * .86, .0012, RUB)) B.mat = c['body']; shell(B, Prof(ks), pn, seg=12, dz=.012, eps=.0012, name='phalanx') # ----------------------------------------------------------------------------------------------- leg def leg(B, st, J): s = B.sfx; th, cf, ft = 'thigh' + s, 'calf' + s, 'foot' + s LT, LC = J['LT'], J['LC']; c = SK[st] g = LEG[st]; n = g['n']; cx = g['cx']; bw, dt, rd = g['bw'], g['dt'], g['disc'] (ax, ay), (bx, by) = g['t0'], g['t1']; ze = LT - rd - .016 B.L = J['FT']; B.bone = th B.mat = STEEL; B.ball((0, 0, 0), g['ball'], name='hip_ball') ptg = Prof([K(.056, ax * .74, ay * .74, n, cx), K(.105, ax, ay, n, cx), K(.24, (ax + bx) / 2, (ay + by) / 2 * 1.02, n, cx * .8), K(ze - .018, bx, by, n, cx * .4), K(ze, bx * .84, by * .84, n, cx * .4)]) groove = P(-180, 180, ze - .014, ze - .008, -.003, RUB) if st == 1: pn = [P(-50, 70, .1, .31, .004), groove] elif st == 2: pn = [P(-40, 115, .1, .33, .006), P(125, 235, .12, .3, .004), P(-40, 115, .29, .306, 0, CER), groove] elif st == 3: pn = [P(120, 240, .1, .31, .005, RED), groove] else: pn = [P(-55, 130, .09, .33, .009, GREY), P(-25, 100, .115, .3, .006, GREY), P(140, 235, .1, .32, .007, GREY)] pn += slots(20, 70, .15, 4, .026, .012, -.007, RUB) B.mat = c['body']; shell(B, ptg, pn, seg=28, dz=.026, name='thigh_shell') if st in (2, 4): B.mat = STEEL; bolts(B, ptg, [(-30, .115), (105, .115), (-30, .27), (105, .27)], .006 if st == 2 else .009, .006, .004) if st == 3: po = Prof([K(.07, ax * .8 + .012, ay * .8 + .012, n, cx), K(.11, ax + .017, ay + .017, n, cx), K(.24, (ax + bx) / 2 + .016, (ay + by) / 2 * 1.02 + .016, n, cx * .8), K(.345, bx + .017, by + .017, n, cx * .4)]) B.mat = RED shell(B, po, [P(.1, .9, .095, .32, .004, RED)] + slots(.3, .7, .15, 4, .024, .006, -.0035), seg=18, dz=.024, span=(38, 180, 38, 130), thick=.009, rim=.003, zwarp=lambda phi, t, u: .02 * t * (1 - abs(2 * u - 1)), name='thigh_plate') with B.at(T(0, 0, LT)): for sg in (1, -1): B.mat = c['body']; B.rbox((sg * (bw + .001 + dt * .4), 0, -rd * .78), (dt * .8, rd * 1.5, rd * 1.6), name='knee_lug') B.mat = STEEL; joint_disc(B, (sg * (bw + .001), 0, 0), (sg, 0, 0), rd, dt, name='knee_disc') B.L = J['FC']; B.bone = cf B.mat = STEEL; B.cyl((-bw, 0, 0), (bw, 0, 0), rd * .76, seg=18, ch=.003, name='knee_barrel') (ax2, ay2), (bx2, by2) = g['c0'], g['c1']; zs = rd + .004 B.mat = c['body']; B.tube(rd * .3, zs + .012, min(bw - .004, ax2 * .62), seg=16, name='shin_neck') pcf = Prof([K(zs, ax2 * .72, ay2 * .7, n, 0, -.003), K(zs + .055, ax2, ay2, n, cx * .3, -.01), K(.25, (ax2 + bx2) / 2, (ay2 + by2) / 2, n, cx * .2, -.006), K(LC - .078, bx2, by2, n), K(LC - .058, bx2 * .86, by2 * .86, n)]) groove = P(-180, 180, LC - .072, LC - .066, -.003, RUB) if st == 1: pn = [P(-50, 50, zs + .03, .32, .004), groove] elif st == 2: pn = [P(-55, 55, zs + .03, .33, .006), P(120, 240, zs + .03, .27, .005), groove] elif st == 3: pn = [P(125, 235, zs + .03, .27, .005, RED), groove] else: pn = [P(-70, 70, zs + .02, .34, .009, GREY), P(-35, 35, zs + .05, .3, .006, GREY), P(110, 250, zs + .03, .3, .008, GREY)] pn += slots(-20, 20, zs + .08, 4, .026, .012, -.007, RUB) shell(B, pcf, pn, seg=26, dz=.026, name='calf_shell') if st == 3: ps = Prof([K(zs + .012, ax2 * .8 + .012, ay2 * .78 + .012, n, 0, -.004), K(zs + .055, ax2 + .017, ay2 + .017, n, cx * .3, -.01), K(.25, (ax2 + bx2) / 2 + .016, (ay2 + by2) / 2 + .016, n, cx * .2, -.006), K(.345, bx2 + .016, by2 + .016, n)]) B.mat = RED shell(B, ps, [P(.12, .88, zs + .04, .32, .004, RED)] + slots(.34, .66, zs + .09, 4, .024, .006, -.0035), seg=14, dz=.024, span=(0, 150, 0, 100), thick=.009, rim=.003, zwarp=lambda phi, t, u: .02 * t * (1 - abs(2 * u - 1)), name='shin_plate') Rk = max(by + .014, (rd + .002) / .669 + .012) pk = Prof([K(-rd * 1.3, Rk * .82), K(-rd * .6, Rk), K(.02, Rk * 1.02), K(rd + .03, Rk * .9)]) B.mat = c['plate']; shell(B, pk, [P(.15, .85, -rd * 1.05, rd, .004, c['plate'])], seg=10, dz=.02, span=(0, 96, 0, 76), thick=.009, rim=.003, name='knee_cap') up = g['fh'] - 1 # taller boots: the cuff sits higher so it clears the boot top B.mat = GREY if st == 4 else STEEL; B.tube(LC - .064 - up * .02, LC - .038 - up * .025, bx2 * 1.12, seg=20, ch=.003, name='ankle_cuff') B.bone = ft; B.mat = STEEL B.ball((0, 0, LC), .03 * g['fh'], seg=14, rings=6, name='ankle_ball') foot(B, st, J) def foot(B, st, J): s = B.sfx; ft, bl = 'foot' + s, 'ball' + s; B.L = J['FFT']; c = SK[st] g = LEG[st]; w = g['fw']; hs = g['fh']; so = .012 B.bone = ft; B.mat = c['body'] pb = Prof([K(-.08, w * .55, .022 * hs, 3.2, 0, .022 * hs + so), K(-.05, w * .9, .037 * hs, 3.2, 0, .037 * hs + so), K(0, w, .041 * hs, 3.2, 0, .041 * hs + so), K(.07, w * 1.06, .033 * hs, 3.2, 0, .033 * hs + so), K(.14, w * 1.06, .026 * hs, 3.2, 0, .026 * hs + so)]) shell(B, pb, [P(-62, 62, -.02, .125, .004, c['plate'] if st >= 3 else None)], seg=20, dz=.022, name='boot') B.mat = RUB shell(B, Prof([K(-.084, w * .6, .009, 4, 0, .009), K(-.05, w * .95, .009, 4, 0, .009), K(.07, w * 1.1, .009, 4, 0, .009), K(.142, w * 1.1, .009, 4, 0, .009)]), seg=20, dz=.03, name='sole') B.mat = STEEL; B.cyl((-w * .95, so + .016, .1435), (w * .95, so + .016, .1435), .012 * hs, seg=10, ch=.002, name='toe_hinge_pin') with B.at(T(0, .085, 0)): for sg in (1, -1): B.mat = c['body']; B.rbox((sg * (w * .78), -.03, 0), (.012, .06, .044), name='ankle_lug') B.mat = STEEL; joint_disc(B, (sg * (w * .78 - .002), 0, 0), (sg, 0, 0), .024 * hs, .011, seg=16, name='ankle_disc') if st == 4: B.mat = GREY; B.rbox((0, .05, -.092), (w * 1.5, .07, .03), n=4, name='heel_spur') B.bone = bl; B.mat = c['body'] ptoe = Prof([K(.148, w * 1.05, .025 * hs, 3.2, 0, .025 * hs + so), K(.19, w * .98, .022 * hs, 3.2, 0, .022 * hs + so), K(.222, w * .8, .017 * hs, 3.0, 0, .017 * hs + so), K(.236, w * .5, .010 * hs, 2.6, 0, .010 * hs + so)]) shell(B, ptoe, [P(-70, 70, .16, .226, .004, c['plate'])] if st >= 3 else [], seg=20, dz=.02, name='toe') B.mat = RUB shell(B, Prof([K(.147, w * 1.1, .009, 4, 0, .009), K(.2, w * 1.0, .009, 4, 0, .009), K(.236, w * .6, .008, 3, 0, .008)]), seg=20, dz=.03, name='toe_sole') # ----------------------------------------------------------------------------------------------- torso def torso_prof(): return Prof([K(.905, .112, .084, 2.6), K(.935, .142, .098, 2.6), K(1.0, .134, .094, 2.5), K(1.07, .116, .084, 2.3), K(1.17, .132, .096, 2.4, 0, -.003), K(1.28, .150, .110, 2.5, 0, -.008), K(1.36, .156, .108, 2.5, 0, -.006), K(1.405, .152, .096, 2.6), K(1.432, .144, .086, 2.6), K(1.456, .104, .074, 2.3), K(1.478, .076, .072, 2.0), K(1.50, .068, .068, 2.0), K(1.565, .066, .066, 2.0)], front=-90, pdir=1) def core(B, J, tp): """The part of him that is still a man: torso and neck in an insulated suit. Always worn; every stage sits on it.""" B.L = I4; B.wfn = spine_w; B.mat = SUIT pn = [P(-180, 180, .905, .95, .006, DARK), P(-1.3, 1.3, .965, 1.44, -.0025, RUB), P(-180, 180, 1.252, 1.257, -.002, RUB), P(-180, 180, 1.47, 1.502, .004, DARK), P(-180, 180, 1.502, 1.565, 0, RUB)] pn += [P(58, 122, 1.0 + i * .03, 1.013 + i * .03, .003) for i in range(8)] pn += [P(-122, -58, 1.12 + i * .03, 1.133 + i * .03, .003) for i in range(4)] pn += [P(-180, 180, 1.506 + i * .012, 1.512 + i * .012, .004, RUB, eps=.002) for i in range(5)] # neck bellows: skinned neck to head, so it bends shell(B, tp, pn, seg=40, dz=.028, name='torso_suit') B.wfn = None p = tp.pt(-96, 1.078); n = tp.nrm(-96, 1.078); B.bone = 'spine_01' # the feeding port, in his right side with B.at(frame(p - n * .005, n, (0, 0, 1))): B.mat = STEEL; B.lathe([(0, 0), (0, .034), (.009, .034), (.012, .030), (.012, .023), (.005, .021), (.005, 0)], 20, 'feed_port_flange') B.mat = VIS; B.cyl((0, 0, .004), (0, 0, .0075), .0195, seg=16, name='feed_port_socket') B.mat = STEEL for k in range(4): a = pi / 4 + k * pi / 2; B.cyl((.011 * cos(a), .011 * sin(a), .007), (.011 * cos(a), .011 * sin(a), .0105), .0028, seg=6, name='feed_port_pin') B.mat = GLOW; B.cyl((0, .0285, .0085), (0, .0285, .0125), .0028, seg=6, name='feed_port_led') B.bone = 'pelvis'; B.mat = DARK B.rbox((0, 0, .872), (.056, .15, .08), n=4, t0=(.55, .7), name='crotch_gusset') def chest_light(B, tp, z, w, h, off=0.0, bone='spine_03', frame_mat=DARK): p = tp.pt(0, z, off); n = tp.nrm(0, z); B.bone = bone with B.at(frame(p - n * .004, n, (1, 0, 0))): B.mat = frame_mat; B.rbox((0, 0, .006), (w + .016, h + .016, .012), n=6, ch=.003, name='light_housing') B.mat = GLOW; B.rbox((0, 0, .0125), (w, h, .004), n=8, ch=.001, name='light_lens') def collar(B, z, r, h, mat): B.bone = 'spine_03'; B.mat = mat with B.at(T(0, 0, z)): B.lathe([(0, 0), (0, r), (h * .25, r * 1.05), (h * .85, r * .92), (h, r * .84), (h, 0)], 28, 'collar') def torso_s1(B, J, tp): B.L = I4; B.wfn = None; B.bone = 'spine_03'; B.mat = DARK shell(B, tp, [P(.08, .45, 1.31, 1.415, .003, sym=True)], seg=18, dz=.022, span=(0, 118, 0, 92), z0=1.215, z1=1.452, thick=.008, off=.011, rim=.003, zwarp=lambda phi, t, u: -.03 * (1 - t) * (1 - abs(2 * u - 1)), name='chest_plate') chest_light(B, tp, 1.34, .04, .022, off=.011) B.bone = 'spine_03'; B.mat = DARK shell(B, tp, [], seg=16, dz=.024, span=(180, 140, 180, 104), z0=1.2, z1=1.452, thick=.008, off=.011, rim=.003, name='back_plate') collar(B, 1.452, .09, .044, DARK) for i, bn in enumerate(('spine_01', 'spine_02')): B.bone = bn; B.mat = DARK shell(B, tp, [], seg=12, dz=.03, span=(0, 86 + 10 * i, 0, 92 + 10 * i), z0=1.07 + .042 * i, z1=1.103 + .042 * i, thick=.006, off=.009, rim=.0025, name='ab_plate') B.bone = 'spine_03'; B.mat = DARK; B.rbox((0, .126, 1.27), (.17, .024, .26), n=5, name='tank_plate') with B.at(T(0, .188, 1.07)): B.mat = STEEL; B.lathe([(0, 0), (.006, .028), (.02, .046), (.046, .055), (.28, .055), (.303, .048), (.32, .032), (.33, .019), (.352, .017), (.352, 0)], 20, 'air_tank') B.mat = DARK for z in (.075, .24): B.tube(z, z + .02, .058, seg=20, ch=.003, name='tank_band') B.mat = RED; B.tube(.35, .368, .022, seg=12, ch=.003, name='tank_valve') B.cyl((0, 0, .36), (-.04, 0, .36), .008, seg=8, ch=.002, name='tank_knob') B.mat = RUB B.hose([V((-.02, .188, 1.435)), V((-.09, .16, 1.50)), V((-.135, .04, 1.535)), V((-.118, -.045, 1.565)), V((-.07, -.086, 1.588))], .0105, seg=8, sub=5, rib=.12, bones=['spine_03', 'spine_03', 'spine_03', 'head', 'head'], name='regulator_hose') for sg in (1, -1): B.hose([tp.pt(sg * 54, 1.225, .013), tp.pt(sg * 72, 1.14, .03), tp.pt(sg * 80, 1.04, .03), tp.pt(sg * 74, .985, .018)], .0032, seg=6, sub=5, bones=['spine_03', 'spine_02', 'spine_01', 'pelvis'], name='side_cable') B.bone = 'pelvis'; B.mat = DARK; B.rbox(tp.pt(sg * 74, .972, .014), (.044, .03, .06), n=5, rot=RZ(sg * 74), name='belt_box') B.mat = RUB B.bone = 'pelvis'; B.mat = DARK; B.rbox((0, -.08, .888), (.066, .016, .09), n=4, t0=(.5, 1), name='groin_plate') def torso_s2(B, J, tp): B.L = I4; B.wfn = None; B.bone = 'spine_03'; B.mat = MATTE shell(B, tp, [P(.07, .44, 1.30, 1.42, .006, sym=True), P(.44, .56, 1.235, 1.262, 0, RED)], seg=20, dz=.022, span=(0, 128, 0, 96), z0=1.19, z1=1.452, thick=.012, off=.016, rim=.004, zwarp=lambda phi, t, u: -.035 * (1 - t) * (1 - abs(2 * u - 1)), name='chest_plate') B.mat = STEEL; bolts(B, tp, [(-50, 1.425), (50, 1.425), (-56, 1.25), (56, 1.25)], .016, .006, .004) chest_light(B, tp, 1.345, .04, .022, off=.016, frame_mat=MATTE) B.bone = 'spine_03'; B.mat = MATTE shell(B, tp, [P(.1, .9, 1.2, 1.42, .005)], seg=18, dz=.024, span=(180, 150, 180, 110), z0=1.16, z1=1.452, thick=.012, off=.016, rim=.004, name='back_plate') collar(B, 1.452, .098, .048, MATTE) for i, bn in enumerate(('spine_01', 'spine_01', 'spine_02')): B.bone = bn; B.mat = MATTE shell(B, tp, [], seg=14, dz=.03, span=(0, 96 + 8 * i, 0, 100 + 8 * i), z0=1.035 + .04 * i, z1=1.068 + .04 * i, thick=.008, off=.012, rim=.003, name='ab_plate') B.bone = 'pelvis' for sg in (1, -1): B.rbox(tp.pt(sg * 50, .985, .02), (.06, .036, .075), n=5, rot=RZ(sg * 50), name='hip_pouch') B.rbox((0, -.082, .888), (.074, .02, .1), n=4, t0=(.5, 1), name='groin_plate') B.mat = RED; B.rbox((0, -.093, .915), (.034, .006, .012), n=4, ch=.001, name='groin_mark') B.bone = 'spine_03'; B.mat = MATTE B.rbox((0, .15, 1.29), (.21, .075, .30), n=5, ch=.006, name='pack') for sg in (1, -1): with B.at(T(sg * .066, .205, 1.13)): B.mat = STEEL; B.lathe([(0, 0), (.006, .024), (.02, .04), (.04, .046), (.27, .046), (.29, .04), (.303, .024), (.31, 0)], 16, 'pack_tank') B.mat = RUB B.hose([V((sg * .06, .17, 1.445)), V((sg * .112, .12, 1.53)), V((sg * .114, .04, 1.61)), V((sg * .104, .012, 1.655))], .0115, seg=8, sub=5, rib=.12, bones=['spine_03', 'spine_03', 'head', 'head'], name='air_hose') for k in range(3): B.hose([V((sg * (.05 + .016 * k), .075, 1.488)), V((sg * (.062 + .018 * k), .105 - .01 * k, 1.545)), V((sg * (.05 + .02 * k), .09 - .012 * k, 1.61))], .0065, seg=6, sub=4, bones=['spine_03', 'spine_03', 'head'], name='neck_cable') def torso_s3(B, J, tp): B.L = I4; B.wfn = None for sg in (1, -1): B.bone = 'spine_03'; B.mat = RED shell(B, tp, [P(.12, .88, 1.295, 1.425, .004, RED)] + slots(.3, .7, 1.33, 3, .022, .006, -.003), seg=10, dz=.022, span=(sg * 34, 60, sg * 28, 46), z0=1.262, z1=1.452, thick=.012, off=.02, rim=.004, zwarp=lambda phi, t, u, sg=sg: -.03 * (1 - t) * (u if sg > 0 else 1 - u), name='pec_plate') for i in range(2): B.bone = 'spine_03' if i == 0 else 'spine_02'; B.mat = GREY shell(B, tp, [P(.12, .88, None, None, .003, RED)], seg=10, dz=.03, span=(sg * 40, 74 - 6 * i), z0=1.185 - .065 * i, z1=1.243 - .065 * i, thick=.009, off=.015, rim=.003, zwarp=lambda phi, t, u, sg=sg: -.022 * (u if sg > 0 else 1 - u), name='rib_plate') B.bone = 'spine_03'; B.mat = GREY shell(B, tp, [], seg=3, dz=.025, span=(0, 11, 0, 9), z0=1.20, z1=1.452, thick=.016, off=.024, rim=.003, name='sternum') chest_light(B, tp, 1.35, .03, .034, off=.022, frame_mat=GREY) B.bone = 'spine_03'; B.mat = GREY shell(B, tp, [P(.1, .9, 1.2, 1.43, .005, RED)], seg=18, dz=.024, span=(180, 150, 180, 110), z0=1.16, z1=1.452, thick=.012, off=.016, rim=.004, name='back_plate') for i in range(3): B.bone = 'spine_01'; B.mat = STEEL if i % 2 == 0 else GREY shell(B, tp, z0=1.012 + .03 * i, z1=1.035 + .03 * i, off=.007, seg=40, dz=.03, name='waist_ring') collar(B, 1.452, .1, .046, GREY) B.mat = RED shell(B, Prof([K(1.455, .108, .1), K(1.545, .112, .108)], front=-90, pdir=1, lin=True), [P(.1, .9, 1.47, 1.53, .003, RED)], seg=12, dz=.03, span=(180, 150, 180, 120), thick=.008, rim=.003, name='neck_guard') B.mat = GREY; B.rbox((0, .152, 1.28), (.22, .08, .32), n=5, ch=.006, t1=(.8, 1), name='pack') B.mat = RED; B.rbox((0, .196, 1.3), (.13, .014, .2), n=5, ch=.003, name='pack_cover') B.mat = RUB for i in range(4): B.rbox((0, .204, 1.24 + i * .04), (.09, .006, .012), n=4, ch=.001, name='pack_vent') for sg in (1, -1): with B.at(T(sg * .092, .2, 1.15)): B.mat = STEEL; B.lathe([(0, 0), (.005, .016), (.016, .028), (.19, .028), (.2, .016), (.206, 0)], 14, 'pack_tank') B.mat = RUB B.hose([V((sg * .07, .17, 1.44)), V((sg * .128, .13, 1.545)), V((sg * .118, .05, 1.62)), V((sg * .104, .012, 1.658))], .011, seg=8, sub=5, rib=.12, bones=['spine_03', 'spine_03', 'head', 'head'], name='air_hose') B.bone = 'pelvis' ph = Prof([K(.882, .178, .13, 2.6), K(.972, .178, .132, 2.6)], front=-90, pdir=1, lin=True) for sg in (1, -1): B.mat = RED; shell(B, ph, [P(.12, .88, .897, .96, .003, RED)], seg=10, dz=.03, span=(sg * 90, 84, sg * 90, 70), thick=.008, rim=.003, name='tasset') B.mat = RED; B.rbox((0, -.084, .888), (.07, .022, .1), n=4, t0=(.45, 1), name='groin_plate') def torso_s4(B, J, tp): B.L = I4; B.wfn = None; B.bone = 'spine_03'; B.mat = DARK shell(B, tp, [P(.05, .46, 1.275, 1.425, .012, GREY, sym=True), P(.12, .4, 1.305, 1.4, .006, GREY, sym=True), P(.47, .53, 1.19, 1.3, -.008, RUB)], seg=22, dz=.022, span=(0, 124, 0, 104), z0=1.175, z1=1.455, thick=.03, off=.042, rim=.006, zwarp=lambda phi, t, u: -.03 * (1 - t) * (1 - abs(2 * u - 1)), name='chest_block') B.mat = STEEL; bolts(B, tp, [(-42, 1.405), (42, 1.405), (-56, 1.26), (56, 1.26), (-30, 1.2), (30, 1.2)], .042, .007, .004) chest_light(B, tp, 1.35, .05, .028, off=.05, frame_mat=GREY) B.bone = 'spine_03'; B.mat = DARK shell(B, tp, [P(.08, .92, 1.19, 1.43, .008, GREY)], seg=18, dz=.024, span=(180, 150, 180, 116), z0=1.15, z1=1.455, thick=.02, off=.03, rim=.005, name='back_plate') with B.at(T(0, 0, 1.44)): B.mat = GREY; B.lathe([(0, 0), (0, .116), (.03, .132), (.108, .128), (.118, .12), (.118, .102), (.065, .098), (.065, 0)], 32, 'gorget') for sg in (1, -1): # yoke blocks between the gorget and the shoulder domes B.mat = GREY; B.rbox((sg * .108, .005, 1.488), (.07, .15, .05), n=5, ch=.006, rot=RY(sg * 18), name='yoke_block') B.mat = RUB for i in range(3): B.rbox((sg * .108, -.04 + i * .04, 1.5135), (.045, .012, .006), n=4, ch=.001, rot=RY(sg * 18), name='yoke_vent') for i, bn in enumerate(('spine_01', 'spine_01', 'spine_02')): B.bone = bn; B.mat = GREY if i == 1 else DARK shell(B, tp, [], seg=14, dz=.03, span=(0, 110 + 8 * i, 0, 114 + 8 * i), z0=1.03 + .038 * i, z1=1.064 + .038 * i, thick=.014, off=.022, rim=.004, name='ab_plate') B.bone = 'pelvis' for sg in (1, -1): B.mat = GREY; B.rbox(tp.pt(sg * 86, .962, .03), (.052, .11, .085), n=5, ch=.006, name='hip_block') B.mat = DARK; B.rbox((0, -.088, .885), (.08, .03, .11), n=4, t0=(.45, 1), name='groin_plate') B.bone = 'spine_03'; B.mat = DARK B.rbox((0, .2, 1.27), (.3, .13, .4), n=5, ch=.01, t1=(.86, .9), name='power_pack') B.mat = GREY; B.rbox((0, .27, 1.3), (.16, .016, .24), n=5, ch=.004, name='pack_cover') for sg in (1, -1): with B.at(T(sg * .1, .285, 1.07)): B.mat = STEEL; B.lathe([(0, 0), (0, .03), (.02, .046), (.05, .052), (.3, .052), (.33, .044), (.35, .026), (.35, 0)], 18, 'pack_cylinder') B.mat = GREY; B.rbox((sg * .1, .215, 1.5), (.085, .1, .06), n=5, ch=.006, name='intake_box') B.mat = RUB B.hose([V((sg * .1, .172, 1.5)), V((sg * .095, .145, 1.506)), V((sg * .078, .116, 1.497))], .014, seg=8, sub=5, rib=.12, name='collar_hose') TORSO = {1: torso_s1, 2: torso_s2, 3: torso_s3, 4: torso_s4} # ----------------------------------------------------------------------------------------------- head HM = Matrix(((0, 0, 1, 0), (-1, 0, 0, -.012), (0, -1, 0, 1.672), (0, 0, 0, 1))) # helmet frame: X front, Y down, Z his left def helmet_prof(W, rx, ry, n, p=2.3): ts = [-1, -.985, -.94, -.85, -.7, -.5, -.25, 0, .25, .5, .7, .85, .94, .985, 1] sc = lambda t: (1 - abs(t) ** p) ** (1 / p) if abs(t) < 1 else 0.0 return Prof([K(t * W, max(rx * sc(t), 1e-5), max(ry * sc(t), 1e-5), n) for t in ts], front=0, pdir=-1) def ear_caps(B, W, r, t): for sg in (1, -1): joint_disc(B, (-.005, .012, sg * (W - .012)), (0, 0, sg), r, t, name='ear_cap') def filters(B, hp, phi, z, r, t): """Breather cans low on the cheeks.""" for sg in (1, -1): joint_disc(B, hp.pt(phi, sg * z, -.004), hp.nrm(phi, sg * z), r, t, seg=14, name='filter_can') def head(B, st, J): """Helmet. Lofted ear to ear, so the two poles of the mesh sit under the ear caps. Angles: 0 = face, +90 = crown, -90 = chin.""" B.L = I4; B.wfn = None; B.bone = 'head' B.mat = STEEL; B.tube(1.54, 1.566, .08, seg=28, ch=.004, name='neck_ring') B.L = HM if st == 1: hp = helmet_prof(.094, .114, .122, 2.15) pn = [P(-30, 40, -.06, .06, -.003, VIS), P(46, 172, -.011, .011, .003), P(-76, -36, -.03, .03, .005)] B.mat = DARK; shell(B, hp, pn, seg=36, dz=.016, name='helmet') B.mat = STEEL; ear_caps(B, .094, .026, .011) B.cyl((.052, .062, -.062), (.072, .086, -.068), .014, seg=10, ch=.002, name='regulator_inlet') elif st == 2: hp = helmet_prof(.095, .115, .123, 2.4) pn = [P(-52, 76, -.064, .064, .006, CER), P(3, 9, -.052, .052, -.0045, VIS), P(36, 60, -.007, .007, 0, RED), P(-30, -27, -.04, .04, -.003, DARK)] B.mat = MATTE; shell(B, hp, pn, seg=36, dz=.016, name='helmet') ear_caps(B, .095, .04, .02) B.cyl((0, -.01, -.113), (.075, -.014, -.113), .0155, seg=12, ch=.003, name='sensor_pod') B.mat = GLOW; B.cyl((.074, -.014, -.113), (.078, -.014, -.113), .010, seg=10, name='sensor_lens') B.mat = STEEL; B.cyl((-.05, -.11, .05), (-.062, -.168, .05), .004, seg=6, name='antenna') B.mat = MATTE; filters(B, hp, -50, .05, .021, .014) elif st == 3: hp = helmet_prof(.095, .117, .123, 2.4) pn = [P(22, 165, -.022, .022, .009, RED), P(-50, 2, -.044, .044, .010, GREY), P(6, 11, .012, .05, -.003, GLOW), P(6, 11, -.05, -.012, -.003, GLOW), P(20, 118, .046, .08, .005, RED), P(20, 118, -.08, -.046, .005, RED), P(-28, -25, -.036, .036, -.003, DARK)] B.mat = GREY; shell(B, hp, pn, seg=36, dz=.016, name='helmet') B.mat = STEEL; ear_caps(B, .095, .032, .014) filters(B, hp, -52, .048, .02, .014) B.mat = RED for sg in (1, -1): with B.at(frame((-.012, -.035, sg * .085), (-.70, -.70, sg * .16), (.7, -.7, 0))): B.rbox((0, 0, .085), (.055, .009, .17), n=4, ch=.002, t1=(.22, .7), name='fin') else: hp = helmet_prof(.09, .108, .116, 2.3) pn = [P(16, 176, -.076, .076, 0, VIS), P(-56, 12, -.05, .05, .007, GREY), P(1, 6, -.04, .04, -.0035, GLOW)] pn += [P(-46, -20, zc - .002, zc + .002, -.004, DARK) for zc in (-.024, 0, .024)] B.mat = DARK; shell(B, hp, pn, seg=36, dz=.016, name='helmet') B.mat = GREY; ear_caps(B, .09, .036, .016) for sg in (1, -1): B.rbox((.04, .08, sg * .06), (.05, .03, .03), n=4, name='jaw_guard')