def _writeElement(self, pbrtwriter: PbrtWriter, ele, material): from_pt = ele["from"] to_pt = ele["to"] cube = minus(to_pt, from_pt) mid = mult(plus(from_pt, to_pt), .5) with pbrtwriter.attribute(): pbrtwriter.translate(mid) if "rotation" in ele: import math rot = ele["rotation"] axis = rot["axis"] org = minus(mid, mult(rot["origin"], 1. / 16)) ang = rot["angle"] rxyz = {"x": (1, 0, 0), "y": (0, 1, 0), "z": (0, 0, 1)} sxyz = {"x": (0, 1, 1), "y": (1, 0, 1), "z": (1, 1, 0)} pbrtwriter.translate(mult(org, -1)) pbrtwriter.rotate(ang, rxyz[axis]) if "rescale" in rot and rot["rescale"]: scale = 1 / math.cos(ang / 180. * math.pi) pbrtwriter.scale(plus(mult(sxyz[axis], scale), rxyz[axis])) pbrtwriter.translate(org) for facename in ele["faces"]: face = ele["faces"][facename] tex = face["texture"] uv = face["uv"] delta_f, l_f, dir_, shape = pt_map[facename] delta = delta_f(cube) l1, l2 = l_f(cube) with pbrtwriter.attribute(): if "rotation" in face: rxyz = {"x": (1, 0, 0), "y": (0, 1, 0), "z": (0, 0, 1)} # shape[-1] should be "x", "y" or "z" pbrtwriter.rotate(face["rotation"] * dir_, rxyz[shape[-1]]) if material: material.write(pbrtwriter, face) pbrtwriter.translate(delta) params = [ "float l1", [l1], "float l2", [l2], "float dir", [dir_], "float u0", uv[0], "float v0", uv[1], "float u1", uv[2], "float v1", uv[3] ] if ResourceManager().hasAlpha(tex + ".png"): params.append("texture alpha") params.append("%s-alpha" % tex) pbrtwriter.shape(shape, *params)
def _writeScale(self, pbrtwriter: PbrtWriter, axis, s): org = (.5, .5, .5) pbrtwriter.translate(org) axis_v = {"x": (1, 0, 0), "y": (0, 1, 0), "z": (0, 0, 1)} sixa_v = {"x": (0, 1, 1), "y": (1, 0, 1), "z": (1, 1, 0)} pbrtwriter.scale(plus(mult(axis_v[axis], s), sixa_v[axis])) pbrtwriter.translate(mult(org, -1))
def build(self): self.addModel("torch") # Hard-code fire part face = {"uv": (0, 0, 1, 1), "texture": "block/sea_lantern"} eps = tuple([.001] * 3) fire = { "elements": [{ "from": minus((7 / 16, 8 / 16, 7 / 16), eps), "to": plus((9 / 16, 10 / 16, 9 / 16), eps), "faces": { key: face for key in ["up", "down", "west", "east", "north", "south"] } }] } self.models.append((fire, [], Light(self)))
def _getColor(biome_id: int, elevation: int, corner): """Calculate biome color by traingle lerp. Args: biome_id: Biome ID evelation: height of block corner: Color of 3 corners of triangle. Returns: (r, g, b) """ b = BIOMES[biome_id] temp = clamp(b[1] - elevation*0.00166667) rain = clamp(b[2])*temp alpha = [temp-rain, 1-temp, rain] ret_color = (0., 0., 0.) for i in range(3): ret_color = plus(ret_color, mult(corner[i], alpha[i])) ret_color = mult(ret_color, 1./255) ret_color = tuple(map(clamp, ret_color)) return ret_color
def build(self): self.addModel("wall_torch") # Hard-code fire part face = {"uv": (0, 0, 1, 1), "texture": "block/sea_lantern"} eps = tuple([.001] * 3) fire = { "elements": [{ "from": minus((-1 / 16, 11.5 / 16, 7 / 16), eps), "to": plus((1 / 16, 13.5 / 16, 9 / 16), eps), "rotation": { "origin": [0, 3.5, 8], "axis": "z", "angle": -22.5 }, "faces": { key: face for key in ["up", "down", "west", "east", "north", "south"] } }] } self.models.append((fire, [], Light(self)))
def _write(self, pbrtwriter: PbrtWriter): print("Writing liquid blocks...") for x, y, z in tqdmpos(range(self.X), range(self.Y), range(self.Z)): if self.level[y][z][x] == None: continue pt = (x, y, z) with pbrtwriter.attribute(): pbrtwriter.translate(plus(pt, (.5, 0, .5))) if self.getLevel((x, y + 1, z)) != None: # When a water block is on current block, the water should be full. ps = [1] * 9 else: dt = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 0), (0, 1), (1, -1), (1, 0), (1, 1)] hs = [None] * 9 for i in range(9): hs[i] = self.getHeight((x + dt[i][1], y, z + dt[i][0])) ps = [[0, 1, 3, 4], [1, 4], [1, 2, 4, 5], [3, 4], [4], [4, 5], [3, 4, 6, 7], [4, 7], [4, 5, 7, 8]] ps = [self.calAvg(map(lambda x: hs[x], p)) for p in ps] if self.getLevel((x, y + 1, z)) is None: from math import pi with pbrtwriter.attribute(): pbrtwriter.translate((-.5, 0, -.5)) pbrtwriter.shape("heightfield", "integer nv", [3], "integer nu", [3], "float Py", ps) if self.getLevel((x, y - 1, z)) is None: pbrtwriter.shape("quady") def flat(xs): ret = [] for x in xs: ret += list(x) return ret def trimesh(mv, pts, inds): with pbrtwriter.attribute(): pbrtwriter.translate(mv) pbrtwriter.shape("trianglemesh", "point P", flat(pts), "integer indices", flat(inds)) def rev(inds): ret = list(inds) for i in range(len(ret)): tri = ret[i] ret[i] = (tri[0], tri[2], tri[1]) return ret indx = [(0, 1, 2), (1, 3, 2), (2, 3, 4), (3, 5, 4)] if self.getLevel((x - 1, y, z)) is None: pts = [ (0, 0, -.5), (0, ps[0], -.5), (0, 0, 0), (0, ps[3], 0), (0, 0, .5), (0, ps[6], .5), ] trimesh((-.5, 0, 0), pts, rev(indx)) if self.getLevel((x + 1, y, z)) is None: pts = [ (0, 0, -.5), (0, ps[2], -.5), (0, 0, 0), (0, ps[5], 0), (0, 0, .5), (0, ps[8], .5), ] trimesh((.5, 0, 0), pts, indx) if self.getLevel((x, y, z - 1)) is None: pts = [ (-.5, 0, 0), (-.5, ps[0], 0), (0, 0, 0), (0, ps[1], 0), (.5, 0, 0), (.5, ps[2], 0), ] trimesh((0, 0, -.5), pts, indx) if self.getLevel((x, y, z + 1)) is None: pts = [ (-.5, 0, 0), (-.5, ps[6], 0), (0, 0, 0), (0, ps[7], 0), (.5, 0, 0), (.5, ps[8], 0), ] trimesh((0, 0, .5), pts, rev(indx))