def save_map(map_filename, cube_map): nolms = True with gzip.open(map_filename, 'w') as f: f.write(struct.pack('4s', "OCTA")) writeint(f, MAPVERSION) writeint(f, 40) #header size writeint(f, cube_map.meta_data['wordsize']) #world size writeint(f, 0) #num ents writeint(f, 0) #num pvs writeint(f, 0) #light maps writeint(f, 0) #blend map writeint(f, 1) #num vars writeint(f, len(cube_map.vslots)) #num vslots writechar(f, cs_id_types.ID_SVAR) writeushort(f, len('skybox')) f.write('skybox') writeushort(f, len('skyboxes/remus/sky01')) f.write('skyboxes/remus/sky01') writechar(f, 3) f.write("fps\x00") # Extra data writeushort(f, 0) # texmru writeushort(f, 0) savevslots(f, cube_map.vslots) savec(f, cube_map, cube_map.octants, ivec(0, 0, 0), cube_map.meta_data['wordsize']>>1, nolms)
def save_map(map_filename, cube_map): nolms = True with gzip.open(map_filename, 'w') as f: f.write(struct.pack('4s', "OCTA")) writeint(f, MAPVERSION) writeint(f, 40) #header size writeint(f, cube_map.meta_data['wordsize']) #world size writeint(f, 0) #num ents writeint(f, 0) #num pvs writeint(f, 0) #light maps writeint(f, 0) #blend map writeint(f, 1) #num vars writeint(f, len(cube_map.vslots)) #num vslots writechar(f, cs_id_types.ID_SVAR) writeushort(f, len('skybox')) f.write('skybox') writeushort(f, len('skyboxes/remus/sky01')) f.write('skyboxes/remus/sky01') writechar(f, 3) f.write("fps\x00") # Extra data writeushort(f, 0) # texmru writeushort(f, 0) savevslots(f, cube_map.vslots) savec(f, cube_map, cube_map.octants, ivec(0, 0, 0), cube_map.meta_data['wordsize'] >> 1, nolms)
def faceconvexity(*args): if len(args) == 1 and isinstance(args[0], (list, tuple)): v = args[0] n = ivec() n.cross(ivec(v[1]).sub(v[0]), ivec(v[2]).sub(v[0])); return ivec(v[0]).sub(v[3]).dot(n); # 1 if convex, -1 if concave, 0 if flat elif len(args) == 2 and isinstance(args[0], Cube): c, orient = args if flataxisface(c, orient): return 0 v = [None]*4 genfaceverts(c, orient, v) return faceconvexity(v)
def genedgespanvert(p, cube, v): p1 = ivec(8 - p.x, p.y, p.z); p2 = ivec(p.x, 8 - p.y, p.z); p3 = ivec(p.x, p.y, 8 - p.z); plane1 = Plane() plane2 = Plane() plane3 = Plane() genvertp(cube, p, p1, p2, plane1); genvertp(cube, p, p2, p3, plane2); genvertp(cube, p, p3, p1, plane3); if(plane1 == plane2): genvertp(cube, p, p1, p2, plane1, True) if(plane1 == plane3): genvertp(cube, p, p1, p2, plane1, True) if(plane2 == plane3): genvertp(cube, p, p2, p3, plane2, True) assert(threeplaneintersect(plane1, plane2, plane3, v)); v.x = max(0.0, min(8.0, v.x)) v.y = max(0.0, min(8.0, v.y)) v.z = max(0.0, min(8.0, v.z))
def neighbourcube(c, cube_map, orient, x, y, z, size, ro, rsize): worldsize = cube_map.meta_data['wordsize'] n = ivec(x, y, z) dim = dimension(orient); diff = n[dim]; if dimcoord(orient): n[dim] += size else: n[dim] -= size diff ^= n[dim]; if diff >= uint(worldsize): ro = n rsize = size return c scale = worldscale nc = cube_map.octants if neighbourdepth >= 0: scale -= neighbourdepth + 1 diff >>= scale while 1: scale += 1 dif >>= 1 if diff == 0: break nc = neighbourstack[worldscale - scale] scale -= 1 nc = nc[octastep(n.x, n.y, n.z, scale)] if (size>>scale == 0) and nc.children is not None: while 1: scale -= 1 nc = nc[0].children[octastep(n.x, n.y, n.z, scale)] if (size>>scale == 0) and nc.children is not None: break ro = n.mask(~0<<scale) rsize = 1<<scale return nc[0]
def neighbourcube(c, cube_map, orient, x, y, z, size, ro, rsize): worldsize = cube_map.meta_data['wordsize'] n = ivec(x, y, z) dim = dimension(orient) diff = n[dim] if dimcoord(orient): n[dim] += size else: n[dim] -= size diff ^= n[dim] if diff >= uint(worldsize): ro = n rsize = size return c scale = worldscale nc = cube_map.octants if neighbourdepth >= 0: scale -= neighbourdepth + 1 diff >>= scale while 1: scale += 1 dif >>= 1 if diff == 0: break nc = neighbourstack[worldscale - scale] scale -= 1 nc = nc[octastep(n.x, n.y, n.z, scale)] if (size >> scale == 0) and nc.children is not None: while 1: scale -= 1 nc = nc[0].children[octastep(n.x, n.y, n.z, scale)] if (size >> scale == 0) and nc.children is not None: break ro = n.mask(~0 << scale) rsize = 1 << scale return nc[0]
def edgespan2vectorcube(self): if self.isentirelysolid() or self.isempty(): return for x in xrange(2): for y in xrange(2): for z in xrange(2): p = ivec(8 * x, 8 * y, 8 * z) v = vec(0, 0, 0) o = self.copy() genedgespanvert(p, o, v) self.setcubeedge(0, y, z, edgeval(self.getcubeedge(0, y, z), x, int(v.x + 0.49))) self.setcubeedge(1, z, x, edgeval(self.getcubeedge(1, z, x), y, int(v.y + 0.49))) self.setcubeedge(2, x, y, edgeval(self.getcubeedge(2, x, y), z, int(v.z + 0.49)))
def edgespan2vectorcube(self): if self.isentirelysolid() or self.isempty(): return for x in range(2): for y in range(2): for z in range(2): p = ivec(8 * x, 8 * y, 8 * z) v = vec(0, 0, 0) o = self.copy() genedgespanvert(p, o, v) self.setcubeedge(0, y, z, edgeval(self.getcubeedge(0, y, z), x, int(v.x + 0.49))) self.setcubeedge(1, z, x, edgeval(self.getcubeedge(1, z, x), y, int(v.y + 0.49))) self.setcubeedge(2, x, y, edgeval(self.getcubeedge(2, x, y), z, int(v.z + 0.49)))
def occludesface(c, orient, o, size, vo, vsize, vmat, nmat, matmask, vf, numv): dim = dimension(orient) if c.children == 0: if nmat != empty_material_types.MAT_AIR and (c.material & matmask) == nmat: nf = [facevec() for _ in range(8)] return clipfacevecs(vf, numv, o[C[dim]], o[R[dim]], size, nf) < 3 if c.isentirelysolid(): return True if vmat != empty_material_types.MAT_AIR and ( (c.material & matmask) == vmat or (isliquid(vmat) and isclipped(c.material & material_types.MATF_VOLUME))): return True if touchingface(c, orient) and faceedges(c, orient) == F_SOLID: return True cf = [facevec() for _ in range(8)] numc = clipfacevecs(vf, numv, o[C[dim]], o[R[dim]], size, cf) if numc < 3: return True if c.isempty() or notouchingface(c, orient): return False of = [facevec() for _ in range(4)] numo = genfacevecs(c, orient, o, size, False, of) return numo >= 3 and insideface(cf, numc, of, numo) size >>= 1 coord = dimcoord(orient) for i in range(8): if octacoord(dim, i) == coord: if occludesface(c.children[i], orient, ivec(i, o.x, o.y, o.z, size), size, vo, vsize, vmat, nmat, matmask, vf, numv) == 0: return False return True
def occludesface(c, orient, o, size, vo, vsize, vmat, nmat, matmask, vf, numv): dim = dimension(orient) if c.children == 0: if nmat != empty_material_types.MAT_AIR and (c.material & matmask) == nmat: nf = [facevec() for _ in xrange(8)] return clipfacevecs(vf, numv, o[C[dim]], o[R[dim]], size, nf) < 3; if c.isentirelysolid(): return True if vmat != empty_material_types.MAT_AIR and ((c.material & matmask) == vmat or (isliquid(vmat) and isclipped(c.material & material_types.MATF_VOLUME))): return True if touchingface(c, orient) and faceedges(c, orient) == F_SOLID: return True cf = [facevec() for _ in xrange(8)] numc = clipfacevecs(vf, numv, o[C[dim]], o[R[dim]], size, cf) if numc < 3: return True if c.isempty() or notouchingface(c, orient): return False of = [facevec() for _ in xrange(4)] numo = genfacevecs(c, orient, o, size, False, of) return numo >= 3 and insideface(cf, numc, of, numo) size >>= 1 coord = dimcoord(orient) for i in xrange(8): if octacoord(dim, i) == coord: if occludesface(c.children[i], orient, ivec(i, o.x, o.y, o.z, size), size, vo, vsize, vmat, nmat, matmask, vf, numv) == 0: return False; return True;
def loadchildren(version, f, co, size): cubes = newcubes() for i in xrange(len(cubes)): loadc(version, f, cubes[i], ivec(i, co.x, co.y, co.z, size), size) return cubes
def visibletris(c, cube_map, orient, x, y, z, size, nmat, matmask): vis = 3 touching = 0xF e1, e2, e3, n = [ivec() for _ in range(4)] v = [None] * 4 genfaceverts(c, orient, v) e1 = v[1] e2 = v[2] e3 = v[0] n.cross((e1).sub(v[0]), (e2).sub(v[0])) convex = (e3).sub(v[3]).dot(n) if convex == 0: if ivec().cross(e3, e2).iszero(): if n.iszero(): return 0 vis = 1 touching = 0xF & ~(1 << 3) elif n.iszero(): vis = 2 touching = 0xF & ~(1 << 1) dim = dimension(orient) coord = dimcoord(orient) if v[0][dim] != coord * 8: touching &= ~(1 << 0) if v[1][dim] != coord * 8: touching &= ~(1 << 1) if v[2][dim] != coord * 8: touching &= ~(1 << 2) if v[3][dim] != coord * 8: touching &= ~(1 << 3) # mask of triangles not touching notouchmasks = [ # order 0: flat or convex # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 1, 3, 0], # order 1: concave [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 2, 0], ] order = 1 if convex < 0 else 0 notouch = notouchmasks[order][touching] if (vis & notouch) == vis: return vis no = ivec() nsize = 0 o = neighbourcube(c, cube_map, orient, x, y, z, size, no, nsize) if o is c: return 0 if c.material & matmask == nmat: nmat = empty_material_types.MAT_AIR vo = ivec(x, y, z) vo.mask(0xFFF) no.mask(0xFFF) cf = [facevec() for _ in range(4)] of = [facevec() for _ in range(4)] opp = opposite(orient) numo = 0 numc = 0 if nsize > size or (nsize == size and o.children == 0): if o.isempty() or notouchingface(o, opp): return vis if nmat != empty_material_types.MAT_AIR and (o.material & matmask) == nmat: return vis if o.isentirelysolid() or (touchingface(o, opp) and faceedges(o, opp) == F_SOLID): return vis & notouch numc = genfacevecs(c, orient, vo, size, False, cf, v) numo = genfacevecs(o, opp, no, nsize, False, of) if numo < 3: return vis if insideface(cf, numc, of, numo): return vis & notouch else: numc = genfacevecs(c, orient, vo, size, False, cf, v) if occludesface(o, opp, no, nsize, vo, size, empty_material_types.MAT_AIR, nmat, matmask, cf, numc): return vis & notouch if vis != 3 or notouch: return vis triverts = [ # order [ # coord [[1, 2, 3], [0, 1, 3]], # verts [[0, 1, 2], [0, 2, 3]] ], [ # coord [[0, 1, 2], [3, 0, 2]], # verts [[1, 2, 3], [1, 3, 0]] ] ] while 1: for i in range(2): verts = triverts[order][coord][i] tf = [cf[verts[0]], cf[verts[1]], cf[verts[2]]] if numo > 0: if insideface(tf, 3, of, numo) == 0: continue elif occludesface(o, opp, no, nsize, vo, size, empty_material_types.MAT_AIR, nmat, matmask, tf, 3) == 0: continue return vis & ~(1 << i) vis |= 4 order += 1 if order <= 1: break return 3
def genfaceverts(c, orient, v): if orient == 0: v[0] = ivec(edgeget(c.getcubeedge(0, 1, 1), 0), edgeget(c.getcubeedge(1, 1, 0), 1), edgeget(c.getcubeedge(2, 0, 1), 1)); v[1] = ivec(edgeget(c.getcubeedge(0, 1, 0), 0), edgeget(c.getcubeedge(1, 0, 0), 1), edgeget(c.getcubeedge(2, 0, 1), 0)); v[2] = ivec(edgeget(c.getcubeedge(0, 0, 0), 0), edgeget(c.getcubeedge(1, 0, 0), 0), edgeget(c.getcubeedge(2, 0, 0), 0)); v[3] = ivec(edgeget(c.getcubeedge(0, 0, 1), 0), edgeget(c.getcubeedge(1, 1, 0), 0), edgeget(c.getcubeedge(2, 0, 0), 1)); elif orient == 1: v[0] = ivec(edgeget(c.getcubeedge(0, 1, 1), 1), edgeget(c.getcubeedge(1, 1, 1), 1), edgeget(c.getcubeedge(2, 1, 1), 1)); v[1] = ivec(edgeget(c.getcubeedge(0, 0, 1), 1), edgeget(c.getcubeedge(1, 1, 1), 0), edgeget(c.getcubeedge(2, 1, 0), 1)); v[2] = ivec(edgeget(c.getcubeedge(0, 0, 0), 1), edgeget(c.getcubeedge(1, 0, 1), 0), edgeget(c.getcubeedge(2, 1, 0), 0)); v[3] = ivec(edgeget(c.getcubeedge(0, 1, 0), 1), edgeget(c.getcubeedge(1, 0, 1), 1), edgeget(c.getcubeedge(2, 1, 1), 0)); elif orient == 2: v[0] = ivec(edgeget(c.getcubeedge(0, 0, 1), 1), edgeget(c.getcubeedge(1, 1, 1), 0), edgeget(c.getcubeedge(2, 1, 0), 1)); v[1] = ivec(edgeget(c.getcubeedge(0, 0, 1), 0), edgeget(c.getcubeedge(1, 1, 0), 0), edgeget(c.getcubeedge(2, 0, 0), 1)); v[2] = ivec(edgeget(c.getcubeedge(0, 0, 0), 0), edgeget(c.getcubeedge(1, 0, 0), 0), edgeget(c.getcubeedge(2, 0, 0), 0)); v[3] = ivec(edgeget(c.getcubeedge(0, 0, 0), 1), edgeget(c.getcubeedge(1, 0, 1), 0), edgeget(c.getcubeedge(2, 1, 0), 0)); elif orient == 3: v[0] = ivec(edgeget(c.getcubeedge(0, 1, 0), 0), edgeget(c.getcubeedge(1, 0, 0), 1), edgeget(c.getcubeedge(2, 0, 1), 0)); v[1] = ivec(edgeget(c.getcubeedge(0, 1, 1), 0), edgeget(c.getcubeedge(1, 1, 0), 1), edgeget(c.getcubeedge(2, 0, 1), 1)); v[2] = ivec(edgeget(c.getcubeedge(0, 1, 1), 1), edgeget(c.getcubeedge(1, 1, 1), 1), edgeget(c.getcubeedge(2, 1, 1), 1)); v[3] = ivec(edgeget(c.getcubeedge(0, 1, 0), 1), edgeget(c.getcubeedge(1, 0, 1), 1), edgeget(c.getcubeedge(2, 1, 1), 0)); elif orient == 4: v[0] = ivec(edgeget(c.getcubeedge(0, 0, 0), 0), edgeget(c.getcubeedge(1, 0, 0), 0), edgeget(c.getcubeedge(2, 0, 0), 0)); v[1] = ivec(edgeget(c.getcubeedge(0, 1, 0), 0), edgeget(c.getcubeedge(1, 0, 0), 1), edgeget(c.getcubeedge(2, 0, 1), 0)); v[2] = ivec(edgeget(c.getcubeedge(0, 1, 0), 1), edgeget(c.getcubeedge(1, 0, 1), 1), edgeget(c.getcubeedge(2, 1, 1), 0)); v[3] = ivec(edgeget(c.getcubeedge(0, 0, 0), 1), edgeget(c.getcubeedge(1, 0, 1), 0), edgeget(c.getcubeedge(2, 1, 0), 0)); elif orient == 5: v[0] = ivec(edgeget(c.getcubeedge(0, 0, 1), 0), edgeget(c.getcubeedge(1, 1, 0), 0), edgeget(c.getcubeedge(2, 0, 0), 1)); v[1] = ivec(edgeget(c.getcubeedge(0, 0, 1), 1), edgeget(c.getcubeedge(1, 1, 1), 0), edgeget(c.getcubeedge(2, 1, 0), 1)); v[2] = ivec(edgeget(c.getcubeedge(0, 1, 1), 1), edgeget(c.getcubeedge(1, 1, 1), 1), edgeget(c.getcubeedge(2, 1, 1), 1)); v[3] = ivec(edgeget(c.getcubeedge(0, 1, 1), 0), edgeget(c.getcubeedge(1, 1, 0), 1), edgeget(c.getcubeedge(2, 0, 1), 1));
def savec(f, cube_map, c, o, size, nolms): for i in xrange(8): co = ivec(i, o.x, o.y, o.z, size) if len(c[i].children) > 0: writechar(f, octa_save_types.OCTSAV_CHILDREN) savec(f, cube_map, c[i].children, co, size>>1, nolms) else: oflags = 0 surfmask = 0 totalverts = 0 if c[i].material != empty_material_types.MAT_AIR: oflags |= 0x40 if not nolms: if c[i].merged: oflags |= 0x80 if c[i].ext: for j in xrange(6): surf = c[i].ext.surfaces[j] if not surf.used: continue oflags |= 0x20 surfmask |= 1<<j totalverts += surf.totalverts() if c[i].children: writechar(f, oflags | octa_save_types.OCTSAV_LODCUBE) elif c[i].isempty(): writechar(f, oflags | octa_save_types.OCTSAV_EMPTY) elif c[i].isentirelysolid(): writechar(f, oflags | octa_save_types.OCTSAV_SOLID) else: writechar(f, oflags | octa_save_types.OCTSAV_NORMAL) f.write(c[i].data) for j in xrange(6): writeushort(f, c[i].texture_walls[j]) if oflags&0x40: writeushort(f, c[i].material); if oflags&0x80: writechar(f, c[i].merged) if oflags&0x20: writechar(f, surfmask) writechar(f, totalverts) for j in xrange(6): if surfmask & (1<<j): surf = c[i].ext.surfaces[j] verts = c[i].ext.verts() + surf.verts; layerverts = surf.numverts & layer_types.MAXFACEVERTS numverts = surf.totalverts() vertmask = 0 vertorder = 0 uvorder = 0 dim = dimension(j) vc = C[dim] vr = R[dim] if numverts: if c[i].merged & (1<<j): vertmask |= 0x04; if layerverts == 4: v = [verts[0].getxyz(), verts[1].getxyz(), verts[2].getxyz(), verts[3].getxyz()] for k in xrange(4): v0 = v[k] v1 = v[(k+1) & 3] v2 = v[(k+2) & 3] v3 = v[(k+3) & 3] if v1[vc] == v0[vc] and v1[vr] == v2[vr] and v3[vc] == v2[vc] and v3[vr] == v0[vr]: vertmask |= 0x01 vertorder = k break else: vis = visibletris(c[i], cube_map, j, co.x, co.y, co.z, size) if vis & 4 or faceconvexity(c[i], j) < 0: vertmask |= 0x01 if layerverts < 4 and vis & 2: vertmask |= 0x02 matchnorm = True for k in xrange(numverts): v = verts[k] if v.u or v.v: vertmask |= 0x40 if v.norm: vertmask |= 0x80 if v.norm != verts[0].norm: matchnorm = False if matchnorm: vertmask |= 0x08 if vertmask & 0x40 and layerverts == 4: for k in xrange(4): v0 = verts[k] v1 = verts[(k+1)&3] v2 = verts[(k+2)&3] v3 = verts[(k+3)&3] if v1.u == v0.u and v1.v == v2.v and v3.u == v2.u and v3.v == v0.v: if surf.numverts & layer_types.LAYER_DUP: b0 = verts[4+k] b1 = verts[4+((k+1)&3)] b2 = verts[4+((k+2)&3)] b3 = verts[4+((k+3)&3)] if b1.u != b0.u or b1.v != b2.v or b3.u != b2.u or b3.v != b0.v: continue uvorder = k vertmask |= 0x02 | (((k+4-vertorder)&3)<<4) break surf.verts = vertmask f.write(surf, sizeof(surfaceinfo)) hasxyz = (vertmask & 0x04)!=0 hasuv = (vertmask & 0x40)!=0 hasnorm = (vertmask & 0x80)!=0 if layerverts == 4: if hasxyz and vertmask & 0x01: v0 = verts[vertorder].getxyz() v2 = verts[(vertorder+2)&3].getxyz() writeushort(f, v0[vc]) writeushort(f, v0[vr]) writeushort(f, v2[vc]) writeushort(f, v2[vr]) hasxyz = False if hasuv and vertmask & 0x02: v0 = verts[uvorder] v2 = verts[(uvorder+2)&3] writeushort(f, v0.u) writeushort(f, v0.v) writeushort(f, v2.u) writeushort(f, v2.v) if surf.numverts & layer_types.LAYER_DUP: b0 = verts[4+uvorder] b2 = verts[4+((uvorder+2)&3)] writeushort(f, b0.u) writeushort(f, b0.v) writeushort(f, b2.u) writeushort(f, b2.v) hasuv = False; if hasnorm and vertmask&0x08: writeushort(f, verts[0].norm) hasnorm = False if hasxyz or hasuv or hasnorm: for k in xrange(layerverts): v = verts[(k+vertorder)%layerverts] if hasxyz: xyz = v.getxyz() writeushort(f, xyz[vc]) writeushort(f, xyz[vr]) if hasuv: writeushort(f, v.u) writeushort(f, v.v) if hasnorm: writeushort(f, v.norm) if surf.numverts & layer_types.LAYER_DUP: for k in xrange(layerverts): v = verts[layerverts + (k+vertorder)%layerverts] if hasuv: writeushort(f, v.u) writeushort(f, v.v) if c[i].children: savec(f, cube_map, c[i].children, co, size>>1, nolms)
def loadc(version, f, cube, co, size): haschildren = False octsav = readchar(f) val = octsav & 0x7 if val == octa_save_types.OCTSAV_CHILDREN: cube.children = loadchildren(version, f, co, size >> 1) return elif val == octa_save_types.OCTSAV_LODCUBE: haschildren = True elif val == octa_save_types.OCTSAV_EMPTY: cube.setfaces(F_EMPTY) elif val == octa_save_types.OCTSAV_SOLID: cube.setfaces(F_SOLID) elif val == octa_save_types.OCTSAV_NORMAL: cube.data = bytearray(f.read(12)) else: raise OctaError() if version < 14: cube.texture = struct.unpack("6b", f.read(6)) else: cube.texture = struct.unpack("6H", f.read(12)) if version < 7: f.read(3) elif version <= 31: mask = readchar(f) if mask & 0x80: mat = readchar(f) if version < 27: matconv = [ empty_material_types.MAT_AIR, empty_material_types.MAT_WATER, empty_material_types.MAT_CLIP, empty_material_types.MAT_GLASS | empty_material_types.MAT_CLIP, empty_material_types.MAT_NOCLIP, empty_material_types.MAT_LAVA | empty_material_types.MAT_DEATH, empty_material_types.MAT_GAMECLIP, empty_material_types.MAT_DEATH ] cube.material = matconv[mat] if mat < len( matconv) else empty_material_types.MAT_AIR else: cube.material = convertoldmaterial(mat) surfaces = [SurfaceCompat() for _ in range(12)] normals = [NormalsCompat() for _ in range(6)] merges = [MergesCompat() for _ in range(6)] hassurfs = 0 hasnorms = 0 hasmerges = 0 if mask & 0x3F: numsurfs = 6 i = 0 while i < numsurfs: if i >= 6 or mask & (1 << i): surfaces[i] = SurfaceCompat.read(f) if version < 10: surfaces[i].lmid += 1 if version < 18: if surfaces[i].lmid >= lighting_types.LMID_AMBIENT1: surfaces[i].lmid += 1 if surfaces[i].lmid >= lighting_types.LMID_BRIGHT1: surfaces[i].lmid += 1 if version < 19: if surfaces[i].lmid >= lighting_types.LMID_DARK: surfaces[i].lmid += 2 if i < 6: if mask & 0x40: hasnorms |= 1 << i normals[i] = NormalsCompat.read(f) if surfaces[i].layer != 0 or surfaces[ i] != lighting_types.LMID_AMBIENT: hassurfs |= 1 << i if surfaces[i].layer & 2: numsurfs += 1 if version <= 8: cube.edgespan2vectorcube() if version <= 11: cube.faces[0], cube.faces[2] = cube.faces[2], cube.faces[0] cube.texture[0], cube.texture[4] = cube.texture[4], cube.texture[0] cube.texture[1], cube.texture[5] = cube.texture[5], cube.texture[1] if hassurfs & 0x33: cube.surfaces[0], cube.surfaces[4] = cube.surfaces[ 4], cube.surfaces[0] cube.surfaces[1], cube.surfaces[5] = cube.surfaces[ 5], cube.surfaces[1] hassurfs = (hassurfs & ~0x33) | ((hassurfs & 0x30) >> 4) | ( (hassurfs & 0x03) << 4) if version >= 20: if octsav & 0x80: merged = readchar(f) cube.merged = merged & 0x3F if merged & 0x80: mask = readchar(f) if mask: hasmerges = mask & 0x3F for i in range(6): if mask & (1 << i): merges[i] = MergesCompat.read(f) m = merges[i] if version <= 25: uorigin = m.u1 & 0xE000 vorigin = m.v1 & 0xE000 m.u1 = (m.u1 - uorigin) << 2 m.u2 = (m.u2 - uorigin) << 2 m.v1 = (m.v1 - vorigin) << 2 m.v2 = (m.v2 - vorigin) << 2 if hassurfs or hasnorms or hasmerges: convertoldsurfaces(cube, co, size, surfaces, hassurfs, normals, hasnorms, merges, hasmerges) else: if octsav & 0x40: if version <= 32: mat = readchar(f) cube.material = convertoldmaterial(mat) else: cube.material = readuchar(f) if octsav & 0x80: cube.merged = readchar(f) if octsav & 0x20: surfmask = readchar(f) totalverts = readchar(f) newcubeext(cube, totalverts, False) cube.ext.surfaces = [SurfaceInfo() for _ in range(6)] cube.ext.verts = [VertInfo() for _ in range(cube.ext.maxverts)] offset = 0 for i in range(6): if surfmask & (1 << i): cube.ext.surfaces[i] = SurfaceInfo.read(f) surf = cube.ext.surfaces[i] vertmask = surf.verts numverts = surf.totalverts if numverts == 0: surf.verts = 0 continue surf.verts = offset verts = cube.ext.verts verts = cube.ext.verts[offset / 12:] offset += numverts v = [ivec() for _ in range(4)] n = 0 layerverts = surf.numverts & layer_types.MAXFACEVERTS dim = dimension(i) vc = C[dim] vr = R[dim] bias = 0 genfaceverts(cube, i, v) hasxyz = (vertmask & 0x04) != 0 hasuv = (vertmask & 0x40) != 0 hasnorm = (vertmask & 0x80) != 0 if hasxyz: e1, e2, e3 = ivec(), ivec(), ivec() e1 = v[1] e2 = v[2] n.cross((e1).sub(v[0]), (e2).sub(v[0])) if n.iszero(): e3 = v[3] n.cross(e2, (e3).sub(v[0])) bias = -n.dot( ivec(v[0]).mul(size).add( ivec(co).mask(0xFFF).shl(3))) else: if layerverts < 4: vis = 2 if vertmask & 0x02 else 1 else: vis = 3 if vertmask & 0x01: order = 1 else: order = 0 k = 0 vo = ivec(co).mask(0xFFF).shl(3) verts[k].setxyz(v[order].mul(size).add(vo)) k += 1 if vis & 1: verts[k].setxyz(v[order + 1].mul(size).add(vo)) k += 1 verts[k].setxyz(v[order + 2].mul(size).add(vo)) k += 1 if vis & 2: verts[k].setxyz(v[(order + 3) & 3].mul(size).add(vo)) k += 1 if layerverts == 4: if hasxyz and vertmask & 0x01: c1, r1, c2, r2 = struct.unpack("4H", f.read(8)) xyz = ivec() xyz[vc] = c1 xyz[vr] = r1 xyz[dim] = -(bias + n[vc] * xyz[vc] + n[vr] * xyz[vr]) / n[dim] verts[0].setxyz(xyz) xyz[vc] = c1 xyz[vr] = r2 xyz[dim] = -(bias + n[vc] * xyz[vc] + n[vr] * xyz[vr]) / n[dim] verts[1].setxyz(xyz) xyz[vc] = c2 xyz[vr] = r2 xyz[dim] = -(bias + n[vc] * xyz[vc] + n[vr] * xyz[vr]) / n[dim] verts[2].setxyz(xyz) xyz[vc] = c2 xyz[vr] = r1 xyz[dim] = -(bias + n[vc] * xyz[vc] + n[vr] * xyz[vr]) / n[dim] verts[3].setxyz(xyz) hasxyz = False if hasuv and vertmask & 0x02: uvorder = (vertmask & 0x30) >> 4 v0 = verts[uvorder] v1 = verts[(uvorder + 1) & 3] v2 = verts[(uvorder + 2) & 3] v3 = verts[(uvorder + 3) & 3] v0.u, v0.v = struct.unpack("2H", f.read(4)) v2.u, v2.v = struct.unpack("2H", f.read(4)) v1.u = v0.u v1.v = v2.v v3.u = v2.u v3.v = v0.v if surf.numverts & layer_types.LAYER_DUP: b0 = verts[4 + uvorder] b1 = verts[4 + ((uvorder + 1) & 3)] b2 = verts[4 + ((uvorder + 2) & 3)] b3 = verts[4 + ((uvorder + 3) & 3)] b0.u, b0.v = struct.unpack("2H", f.read(4)) b2.u, b2.v = struct.unpack("2H", f.read(4)) b1.u = b0.u b1.v = b2.v b3.u = b2.u b3.v = b0.v hasuv = False if hasnorm and vertmask & 0x08: norm = readushort(f) for k in range(layerverts): verts[k].norm = norm hasnorm = False if hasxyz or hasuv or hasnorm: for k in range(layerverts): v = verts[k] if hasxyz: xyz = ivec() xyz[vc], xyz[vr] = struct.unpack( "2H", f.read(4)) xyz[dim] = -(bias + n[vc] * xyz[vc] + n[vr] * xyz[vr]) / n[dim] v.setxyz(xyz) if hasuv: v.u, v.v = struct.unpack("2H", f.read(4)) if hasnorm: v.norm = readushort(f) if surf.numverts & layer_types.LAYER_DUP: for k in range(layerverts): v = verts[k + layerverts] t = verts[k] v.setxyz(t.x, t.y, t.z) if hasuv: v.u, v.v = struct.unpack("2H", f.read(4)) v.norm = t.norm if haschildren: cube.children = loadchildren(version, f, co, size >> 1) else: cube.children = None return cube
def visibletris(c, cube_map, orient, x, y, z, size, nmat, matmask): vis = 3 touching = 0xF e1, e2, e3, n = [ivec() for _ in xrange(4)] v = [None]*4 genfaceverts(c, orient, v) e1 = v[1] e2 = v[2] e3 = v[0] n.cross((e1).sub(v[0]), (e2).sub(v[0])) convex = (e3).sub(v[3]).dot(n) if convex == 0: if ivec().cross(e3, e2).iszero(): if n.iszero(): return 0 vis = 1 touching = 0xF & ~(1<<3) elif n.iszero(): vis = 2 touching = 0xF&~(1<<1) dim = dimension(orient) coord = dimcoord(orient) if v[0][dim] != coord*8: touching &= ~(1<<0) if v[1][dim] != coord*8: touching &= ~(1<<1) if v[2][dim] != coord*8: touching &= ~(1<<2) if v[3][dim] != coord*8: touching &= ~(1<<3) # mask of triangles not touching notouchmasks = [ # order 0: flat or convex # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [ 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 1, 3, 0 ], # order 1: concave [ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 2, 0 ], ] order = 1 if convex < 0 else 0 notouch = notouchmasks[order][touching] if (vis¬ouch)==vis: return vis no = ivec() nsize = 0 o = neighbourcube(c, cube_map, orient, x, y, z, size, no, nsize) if o is c: return 0 if c.material & matmask == nmat: nmat = empty_material_types.MAT_AIR vo = ivec(x, y, z) vo.mask(0xFFF) no.mask(0xFFF) cf = [facevec() for _ in xrange(4)] of = [facevec() for _ in xrange(4)] opp = opposite(orient) numo = 0 numc = 0 if nsize > size or (nsize == size and o.children == 0): if o.isempty() or notouchingface(o, opp): return vis if nmat != empty_material_types.MAT_AIR and (o.material & matmask) == nmat: return vis if o.isentirelysolid() or (touchingface(o, opp) and faceedges(o, opp) == F_SOLID): return vis & notouch numc = genfacevecs(c, orient, vo, size, False, cf, v) numo = genfacevecs(o, opp, no, nsize, False, of) if numo < 3: return vis if insideface(cf, numc, of, numo): return vis & notouch else: numc = genfacevecs(c, orient, vo, size, False, cf, v) if occludesface(o, opp, no, nsize, vo, size, empty_material_types.MAT_AIR, nmat, matmask, cf, numc): return vis & notouch if vis != 3 or notouch: return vis triverts = [ # order [ # coord [ [ 1, 2, 3 ], [ 0, 1, 3 ] ], # verts [ [ 0, 1, 2 ], [ 0, 2, 3 ] ] ], [ # coord [ [ 0, 1, 2 ], [ 3, 0, 2 ] ], # verts [ [ 1, 2, 3 ], [ 1, 3, 0 ] ] ] ] while 1: for i in xrange(2): verts = triverts[order][coord][i] tf = [cf[verts[0]], cf[verts[1]], cf[verts[2]]] if numo > 0: if insideface(tf, 3, of, numo) == 0: continue elif occludesface(o, opp, no, nsize, vo, size, empty_material_types.MAT_AIR, nmat, matmask, tf, 3) == 0: continue return vis & ~(1<<i) vis |= 4; order += 1 if order <= 1: break return 3;
def convertoldsurfaces(c, co, size, srcsurfs, hassurfs, normals, hasnorms, merges, hasmerges): dstsurfs = [SurfaceInfo() for _ in range(6)] verts = [VertInfo() for _ in range(6 * 2 * layer_types.MAXFACEVERTS)] totalverts = 0 numsurfs = 6 for i in range(6): if (hassurfs | hasnorms | hasmerges) & (1 << i): dst = dstsurfs[i] curverts = None numverts = 0 src = None blend = None if hassurfs & (1 << i): src = srcsurfs[i] if src.layer & 2: blend = srcsurfs[numsurfs] numsurfs += 1 dst.lmid[0] = src.lmid dst.lmid[1] = blend.lmid dst.numverts |= layer_types.LAYER_BLEND if blend.lmid >= lighting_types.LMID_RESERVED: if src.x != blend.x or src.y != blend.y or src.w != blend.w or src.h != blend.h or ( not src.compare_textcoords(blend)): dst.numverts |= layer_types.LAYER_DUP elif src.layer == 1: dst.lmid[1] = src.lmid dst.numverts |= layer_types.LAYER_BOTTOM else: dst.lmid[0] = src.lmid dst.numverts |= layer_types.LAYER_TOP else: dst.numverts |= layer_types.LAYER_TOP uselms = hassurfs & (1 << i) and ( dst.lmid[0] >= lighting_types.LMID_RESERVED or dst.lmid[1] >= lighting_types.LMID_RESERVED or dst.numverts & ~layer_types.LAYER_TOP) usemerges = hasmerges & (1 << i) and merges[i].u1 < merges[ i].u2 and merges[i].v1 < merges[i].v2 usenorms = hasnorms & (1 << i) and normals[i].normals[0] != bvec( 128, 128, 128) if uselms or usemerges or usenorms: v = [ivec() for _ in range(4)] pos = [ivec() for _ in range(4)] e1 = ivec() e2 = ivec() e3 = ivec() n = ivec() vo = ivec(co).mask(0xFFF).shl(3) genfaceverts(c, i, v) e1 = v[1] e2 = v[2] n.cross((e1).sub(v[0]), (e2).sub(v[0])) if usemerges: m = merges[i] offset = -n.dot(v[0].mul(size).add(vo)), dim = dimension(i) vc = C[dim] vr = R[dim] for k in range(4): coords = facecoords[i][k] if coords[vc]: cc = m.u2 else: cc = m.u1 if coords[vr]: rc = m.v2 else: rc = m.v1 dc = -(offset + n[vc] * cc + n[vr] * rc) / n[dim] mv = pos[k] mv[vc] = cc mv[vr] = rc mv[dim] = dc else: e3 = v[0] convex = (e3).sub(v[3]).dot(n) vis = 3 if convex == 0: if ivec(0, 0, 0).cross(e3, e2).iszero(): if not n.iszero(): vis = 1 elif n.iszero(): vis = 2 if convex < 0: order = 1 else: order = 0 pos[0] = v[order].mul(size).add(vo) if vis & 1: pos[1] = v[order + 1].mul(size).add(vo) else: pos[1] = pos[0] pos[2] = v[order + 2].mul(size).add(vo) if vis & 2: pos[3] = v[(order + 3) & 3].mul(size).add(vo) else: pos[3] = pos[0] curverts = verts + totalverts for k in range(4): if k > 0 and (pos[k] == pos[0] or pos[k] == pos[k - 1]): continue dv = curverts[numverts] numverts += 1 dv.setxyz(pos[k]) if uselms: u = src.x + (src.texcoords[k * 2] / 255.0) * (src.w - 1) v = src.y + (src.texcoords[k * 2 + 1] / 255.0) * (src.h - 1) dv.u = ushort( floor( clamp((u) * float(USHRT_MAX + 1) / LM_PACKW + 0.5, 0.0, float(USHRT_MAX)))) dv.v = ushort( floor( clamp((v) * float(USHRT_MAX + 1) / LM_PACKH + 0.5, 0.0, float(USHRT_MAX)))) else: dv.u = 0 dv.v = 0 if usenorms and normals[i].normals[k] != bvec( 128, 128, 128): dv.norm = encodenormal( normals[i].normals[k].tovec().normalize()) else: dv.norm = 0 dst.verts = totalverts dst.numverts |= numverts totalverts += numverts if dst.numverts & layer_types.LAYER_DUP: for k in range(4): if k > 0 and (pos[k] == pos[0] or pos[k] == pos[k - 1]): continue bv = verts[totalverts] totalverts += 1 bv.setxyz(pos[k]) bv.u = ushort( floor( clamp((blend.x + (blend.texcoords[k * 2] / 255.0) * (blend.w - 1)) * float(USHRT_MAX + 1) / LM_PACKW, 0.0, float(USHRT_MAX)))) bv.v = ushort( floor( clamp((blend.y + (blend.texcoords[k * 2 + 1] / 255.0) * (blend.h - 1)) * float(USHRT_MAX + 1) / LM_PACKH, 0.0, float(USHRT_MAX)))) if usenorms and normals[i].normals[k] != bvec( 128, 128, 128): bv.norm = encodenormal( normals[i].normals[k].tovec().normalize()) else: bv.norm = 0 setsurfaces(c, dstsurfs, verts, totalverts)
''' This file may be in part a direct translation of the original Cube 2 sources into python. Please see readme_source.txt for the license that may apply. ''' from cube2common.ivec import ivec facecoords = ( ( ivec(0,8,8), ivec(0,8,0), ivec(0,0,0), ivec(0,0,8) ) , ( ivec(8,8,8), ivec(8,0,8), ivec(8,0,0), ivec(8,8,0) ) , ( ivec(8,0,8), ivec(0,0,8), ivec(0,0,0), ivec(8,0,0) ) , ( ivec(0,8,0), ivec(0,8,8), ivec(8,8,8), ivec(8,8,0) ) , ( ivec(0,0,0), ivec(0,8,0), ivec(8,8,0), ivec(8,0,0) ) , ( ivec(0,0,8), ivec(8,0,8), ivec(8,8,8), ivec(0,8,8) ))
def loadchildren(version, f, co, size): cubes = newcubes() for i in range(len(cubes)): loadc(version, f, cubes[i], ivec(i, co.x, co.y, co.z, size), size) return cubes
def savec(f, cube_map, c, o, size, nolms): for i in range(8): co = ivec(i, o.x, o.y, o.z, size) if len(c[i].children) > 0: writechar(f, octa_save_types.OCTSAV_CHILDREN) savec(f, cube_map, c[i].children, co, size >> 1, nolms) else: oflags = 0 surfmask = 0 totalverts = 0 if c[i].material != empty_material_types.MAT_AIR: oflags |= 0x40 if not nolms: if c[i].merged: oflags |= 0x80 if c[i].ext: for j in range(6): surf = c[i].ext.surfaces[j] if not surf.used: continue oflags |= 0x20 surfmask |= 1 << j totalverts += surf.totalverts() if c[i].children: writechar(f, oflags | octa_save_types.OCTSAV_LODCUBE) elif c[i].isempty(): writechar(f, oflags | octa_save_types.OCTSAV_EMPTY) elif c[i].isentirelysolid(): writechar(f, oflags | octa_save_types.OCTSAV_SOLID) else: writechar(f, oflags | octa_save_types.OCTSAV_NORMAL) f.write(c[i].data) for j in range(6): writeushort(f, c[i].texture_walls[j]) if oflags & 0x40: writeushort(f, c[i].material) if oflags & 0x80: writechar(f, c[i].merged) if oflags & 0x20: writechar(f, surfmask) writechar(f, totalverts) for j in range(6): if surfmask & (1 << j): surf = c[i].ext.surfaces[j] verts = c[i].ext.verts() + surf.verts layerverts = surf.numverts & layer_types.MAXFACEVERTS numverts = surf.totalverts() vertmask = 0 vertorder = 0 uvorder = 0 dim = dimension(j) vc = C[dim] vr = R[dim] if numverts: if c[i].merged & (1 << j): vertmask |= 0x04 if layerverts == 4: v = [ verts[0].getxyz(), verts[1].getxyz(), verts[2].getxyz(), verts[3].getxyz() ] for k in range(4): v0 = v[k] v1 = v[(k + 1) & 3] v2 = v[(k + 2) & 3] v3 = v[(k + 3) & 3] if v1[vc] == v0[vc] and v1[vr] == v2[ vr] and v3[vc] == v2[ vc] and v3[vr] == v0[vr]: vertmask |= 0x01 vertorder = k break else: vis = visibletris(c[i], cube_map, j, co.x, co.y, co.z, size) if vis & 4 or faceconvexity(c[i], j) < 0: vertmask |= 0x01 if layerverts < 4 and vis & 2: vertmask |= 0x02 matchnorm = True for k in range(numverts): v = verts[k] if v.u or v.v: vertmask |= 0x40 if v.norm: vertmask |= 0x80 if v.norm != verts[0].norm: matchnorm = False if matchnorm: vertmask |= 0x08 if vertmask & 0x40 and layerverts == 4: for k in range(4): v0 = verts[k] v1 = verts[(k + 1) & 3] v2 = verts[(k + 2) & 3] v3 = verts[(k + 3) & 3] if v1.u == v0.u and v1.v == v2.v and v3.u == v2.u and v3.v == v0.v: if surf.numverts & layer_types.LAYER_DUP: b0 = verts[4 + k] b1 = verts[4 + ((k + 1) & 3)] b2 = verts[4 + ((k + 2) & 3)] b3 = verts[4 + ((k + 3) & 3)] if b1.u != b0.u or b1.v != b2.v or b3.u != b2.u or b3.v != b0.v: continue uvorder = k vertmask |= 0x02 | (( (k + 4 - vertorder) & 3) << 4) break surf.verts = vertmask f.write(surf, sizeof(surfaceinfo)) hasxyz = (vertmask & 0x04) != 0 hasuv = (vertmask & 0x40) != 0 hasnorm = (vertmask & 0x80) != 0 if layerverts == 4: if hasxyz and vertmask & 0x01: v0 = verts[vertorder].getxyz() v2 = verts[(vertorder + 2) & 3].getxyz() writeushort(f, v0[vc]) writeushort(f, v0[vr]) writeushort(f, v2[vc]) writeushort(f, v2[vr]) hasxyz = False if hasuv and vertmask & 0x02: v0 = verts[uvorder] v2 = verts[(uvorder + 2) & 3] writeushort(f, v0.u) writeushort(f, v0.v) writeushort(f, v2.u) writeushort(f, v2.v) if surf.numverts & layer_types.LAYER_DUP: b0 = verts[4 + uvorder] b2 = verts[4 + ((uvorder + 2) & 3)] writeushort(f, b0.u) writeushort(f, b0.v) writeushort(f, b2.u) writeushort(f, b2.v) hasuv = False if hasnorm and vertmask & 0x08: writeushort(f, verts[0].norm) hasnorm = False if hasxyz or hasuv or hasnorm: for k in range(layerverts): v = verts[(k + vertorder) % layerverts] if hasxyz: xyz = v.getxyz() writeushort(f, xyz[vc]) writeushort(f, xyz[vr]) if hasuv: writeushort(f, v.u) writeushort(f, v.v) if hasnorm: writeushort(f, v.norm) if surf.numverts & layer_types.LAYER_DUP: for k in range(layerverts): v = verts[layerverts + (k + vertorder) % layerverts] if hasuv: writeushort(f, v.u) writeushort(f, v.v) if c[i].children: savec(f, cube_map, c[i].children, co, size >> 1, nolms)
def write_physics_state(cds, physics_state): d = physics_state # TODO: replace this with an actual lookup for which material is at a particular position lookupmaterial = dummy_air_material_lookup # 3 bits phys state, 1 bit life sequence, 2 bits move, 2 bits strafe physstate = d.physstate | ((d.lifesequence & 1) << 3) | ((d.move & 3) << 4) | ((d.strafe & 3) << 6) cds.putbyte(physstate) o = ivec(vec(d.o.x, d.o.y, d.o.z - d.eyeheight)) vel = min(int(d.vel.magnitude() * DVELF), 0xFFFF) fall = min(int(d.falling.magnitude() * DVELF), 0xFFFF) # 3 bits position, 1 bit velocity, 3 bits falling, 1 bit material flags = 0; if (o.x < 0 or o.x > 0xFFFF): flags |= 1 << 0 if (o.y < 0 or o.y > 0xFFFF): flags |= 1 << 1 if (o.z < 0 or o.z > 0xFFFF): flags |= 1 << 2 if (vel > 0xFF): flags |= 1 << 3 if fall > 0: flags |= 1 << 4 if fall > 0xFF: flags |= 1 << 5 if d.falling.x or d.falling.y or d.falling.z > 0: flags |= 1 << 6 if lookupmaterial(d.feetpos()) & material_types.MATF_CLIP == empty_material_types.MAT_GAMECLIP: flags |= 1 << 7 cds.putuint(flags) for k in xrange(3): cds.putbyte(o[k] & 0xFF) cds.putbyte((o[k] >> 8) & 0xFF) if o[k] < 0 or o[k] > 0xFFFF: cds.putbyte((o[k] >> 16) & 0xFF) if d.yaw < 0: dir = 360 + int(d.yaw) % 360 else: dir = int(d.yaw) % 360 dir += clamp(int(d.pitch + 90), 0, 180) * 360 cds.putbyte(dir & 0xFF) cds.putbyte((dir >> 8) & 0xFF) cds.putbyte(clamp(int(d.roll + 90), 0, 180)) cds.putbyte(vel & 0xFF) if vel > 0xFF: cds.putbyte((vel >> 8) & 0xFF) velyaw, velpitch = vectoyawpitch(d.vel) if velyaw < 0: veldir = 360 + int(velyaw) % 360 else: veldir = int(velyaw) % 360 veldir += clamp(int(velpitch + 90), 0, 180) * 360 cds.putbyte(veldir & 0xFF) cds.putbyte((veldir >> 8) & 0xFF) if fall > 0: cds.putbyte(fall & 0xFF) if fall > 0xFF: cds.putbyte((fall >> 8) & 0xFF) if d.falling.x or d.falling.y or d.falling.z > 0: fallyaw, fallpitch = vectoyawpitch(d.falling) if fallyaw < 0: falldir = 360 + int(fallyaw) % 360 else: falldir = int(fallyaw) % 360 falldir += clamp(int(fallpitch + 90), 0, 180) * 360 cds.putbyte(falldir & 0xFF) cds.putbyte((falldir >> 8) & 0xFF)
def convertoldsurfaces(c, co, size, srcsurfs, hassurfs, normals, hasnorms, merges, hasmerges): dstsurfs = map(lambda _: SurfaceInfo(), xrange(6)) verts = map(lambda _: VertInfo(), xrange(6*2*layer_types.MAXFACEVERTS)) totalverts = 0 numsurfs = 6 for i in xrange(6): if (hassurfs|hasnorms|hasmerges)&(1<<i): dst = dstsurfs[i] curverts = None numverts = 0 src = None blend = None if hassurfs & (1<<i): src = srcsurfs[i] if src.layer & 2: blend = srcsurfs[numsurfs] numsurfs += 1 dst.lmid[0] = src.lmid; dst.lmid[1] = blend.lmid; dst.numverts |= layer_types.LAYER_BLEND; if blend.lmid >= lighting_types.LMID_RESERVED: if src.x != blend.x or src.y != blend.y or src.w != blend.w or src.h != blend.h or (not src.compare_textcoords(blend)): dst.numverts |= layer_types.LAYER_DUP elif src.layer == 1: dst.lmid[1] = src.lmid dst.numverts |= layer_types.LAYER_BOTTOM else: dst.lmid[0] = src.lmid dst.numverts |= layer_types.LAYER_TOP else: dst.numverts |= layer_types.LAYER_TOP uselms = hassurfs & (1<<i) and (dst.lmid[0] >= lighting_types.LMID_RESERVED or dst.lmid[1] >= lighting_types.LMID_RESERVED or dst.numverts & ~layer_types.LAYER_TOP) usemerges = hasmerges&(1<<i) and merges[i].u1 < merges[i].u2 and merges[i].v1 < merges[i].v2 usenorms = hasnorms & (1<<i) and normals[i].normals[0] != bvec(128, 128, 128) if uselms or usemerges or usenorms: v = map(lambda _: ivec(), xrange(4)) pos = map(lambda _: ivec(), xrange(4)) e1 = ivec() e2 = ivec() e3 = ivec() n = ivec() vo = ivec(co).mask(0xFFF).shl(3) genfaceverts(c, i, v); e1 = v[1] e2 = v[2] n.cross((e1).sub(v[0]), (e2).sub(v[0])); if usemerges: m = merges[i] offset = -n.dot(v[0].mul(size).add(vo)), dim = dimension(i) vc = C[dim] vr = R[dim] for k in xrange(4): coords = facecoords[i][k] if coords[vc]: cc = m.u2 else: cc = m.u1 if coords[vr]: rc = m.v2 else: rc = m.v1 dc = -(offset + n[vc]*cc + n[vr]*rc)/n[dim] mv = pos[k] mv[vc] = cc mv[vr] = rc mv[dim] = dc else: e3 = v[0] convex = (e3).sub(v[3]).dot(n) vis = 3; if convex == 0: if ivec(0, 0, 0).cross(e3, e2).iszero(): if not n.iszero(): vis = 1 elif n.iszero(): vis = 2 if convex < 0: order = 1 else: order = 0 pos[0] = v[order].mul(size).add(vo); if vis & 1: pos[1] = v[order+1].mul(size).add(vo) else: pos[1] = pos[0] pos[2] = v[order+2].mul(size).add(vo); if vis & 2: pos[3] = v[(order+3)&3].mul(size).add(vo) else: pos[3] = pos[0]; curverts = verts + totalverts; for k in xrange(4): if k > 0 and (pos[k] == pos[0] or pos[k] == pos[k-1]): continue dv = curverts[numverts] numverts += 1 dv.setxyz(pos[k]) if uselms: u = src.x + (src.texcoords[k*2] / 255.0) * (src.w - 1) v = src.y + (src.texcoords[k*2+1] / 255.0) * (src.h - 1) dv.u = ushort(floor(clamp((u) * float(USHRT_MAX+1)/LM_PACKW + 0.5, 0.0, float(USHRT_MAX)))) dv.v = ushort(floor(clamp((v) * float(USHRT_MAX+1)/LM_PACKH + 0.5, 0.0, float(USHRT_MAX)))) else: dv.u = 0 dv.v = 0 if usenorms and normals[i].normals[k] != bvec(128, 128, 128): dv.norm = encodenormal(normals[i].normals[k].tovec().normalize()) else: dv.norm = 0 dst.verts = totalverts; dst.numverts |= numverts; totalverts += numverts; if dst.numverts & layer_types.LAYER_DUP: for k in xrange(4): if k > 0 and (pos[k] == pos[0] or pos[k] == pos[k-1]): continue bv = verts[totalverts] totalverts += 1 bv.setxyz(pos[k]) bv.u = ushort(floor(clamp((blend.x + (blend.texcoords[k*2] / 255.0) * (blend.w - 1)) * float(USHRT_MAX+1)/LM_PACKW, 0.0, float(USHRT_MAX)))) bv.v = ushort(floor(clamp((blend.y + (blend.texcoords[k*2+1] / 255.0) * (blend.h - 1)) * float(USHRT_MAX+1)/LM_PACKH, 0.0, float(USHRT_MAX)))) if usenorms and normals[i].normals[k] != bvec(128, 128, 128): bv.norm = encodenormal(normals[i].normals[k].tovec().normalize()) else: bv.norm = 0 setsurfaces(c, dstsurfs, verts, totalverts)
''' This file may be in part a direct translation of the original Cube 2 sources into python. Please see readme_source.txt for the license that may apply. ''' from cube2common.ivec import ivec facecoords = ((ivec(0, 8, 8), ivec(0, 8, 0), ivec(0, 0, 0), ivec(0, 0, 8)), (ivec(8, 8, 8), ivec(8, 0, 8), ivec(8, 0, 0), ivec(8, 8, 0)), (ivec(8, 0, 8), ivec(0, 0, 8), ivec(0, 0, 0), ivec(8, 0, 0)), (ivec(0, 8, 0), ivec(0, 8, 8), ivec(8, 8, 8), ivec(8, 8, 0)), (ivec(0, 0, 0), ivec(0, 8, 0), ivec(8, 8, 0), ivec(8, 0, 0)), (ivec(0, 0, 8), ivec(8, 0, 8), ivec(8, 8, 8), ivec(0, 8, 8)))
def write_physics_state(cds, physics_state): d = physics_state # TODO: replace this with an actual lookup for which material is at a particular position lookupmaterial = dummy_air_material_lookup # 3 bits phys state, 1 bit life sequence, 2 bits move, 2 bits strafe physstate = d.physstate | ((d.lifesequence & 1) << 3) | ((d.move & 3) << 4) | ((d.strafe & 3) << 6) cds.putbyte(physstate) o = ivec(vec(d.o.x, d.o.y, d.o.z - d.eyeheight)) vel = min(int(d.vel.magnitude() * DVELF), 0xFFFF) fall = min(int(d.falling.magnitude() * DVELF), 0xFFFF) # 3 bits position, 1 bit velocity, 3 bits falling, 1 bit material flags = 0; if (o.x < 0 or o.x > 0xFFFF): flags |= 1 << 0 if (o.y < 0 or o.y > 0xFFFF): flags |= 1 << 1 if (o.z < 0 or o.z > 0xFFFF): flags |= 1 << 2 if (vel > 0xFF): flags |= 1 << 3 if fall > 0: flags |= 1 << 4 if fall > 0xFF: flags |= 1 << 5 if d.falling.x or d.falling.y or d.falling.z > 0: flags |= 1 << 6 if lookupmaterial(d.feetpos()) & material_types.MATF_CLIP == empty_material_types.MAT_GAMECLIP: flags |= 1 << 7 cds.putuint(flags) for k in range(3): cds.putbyte(o[k] & 0xFF) cds.putbyte((o[k] >> 8) & 0xFF) if o[k] < 0 or o[k] > 0xFFFF: cds.putbyte((o[k] >> 16) & 0xFF) if d.yaw < 0: dir = 360 + int(d.yaw) % 360 else: dir = int(d.yaw) % 360 dir += clamp(int(d.pitch + 90), 0, 180) * 360 cds.putbyte(dir & 0xFF) cds.putbyte((dir >> 8) & 0xFF) cds.putbyte(clamp(int(d.roll + 90), 0, 180)) cds.putbyte(vel & 0xFF) if vel > 0xFF: cds.putbyte((vel >> 8) & 0xFF) velyaw, velpitch = vectoyawpitch(d.vel) if velyaw < 0: veldir = 360 + int(velyaw) % 360 else: veldir = int(velyaw) % 360 veldir += clamp(int(velpitch + 90), 0, 180) * 360 cds.putbyte(veldir & 0xFF) cds.putbyte((veldir >> 8) & 0xFF) if fall > 0: cds.putbyte(fall & 0xFF) if fall > 0xFF: cds.putbyte((fall >> 8) & 0xFF) if d.falling.x or d.falling.y or d.falling.z > 0: fallyaw, fallpitch = vectoyawpitch(d.falling) if fallyaw < 0: falldir = 360 + int(fallyaw) % 360 else: falldir = int(fallyaw) % 360 falldir += clamp(int(fallpitch + 90), 0, 180) * 360 cds.putbyte(falldir & 0xFF) cds.putbyte((falldir >> 8) & 0xFF)
def genfacevecs(cu, orient, pos, size, solid, fvecs, v=None): i = 0 if solid: if orient == 0: if dimcoord(0): f = fvecs[i] f.y = ((pos.y + size) << 3) f.x = ((pos.z + size) << 3) i += 1 f = fvecs[i] f.y = ((pos.y + size) << 3) f.x = ((pos.z) << 3) i += 1 f = fvecs[i] f.y = ((pos.y) << 3) f.x = ((pos.z) << 3) i += 1 f = fvecs[i] f.y = ((pos.y) << 3) f.x = ((pos.z + size) << 3) i += 1 else: f = fvecs[i] f.y = ((pos.y) << 3) f.x = ((pos.z + size) << 3) i += 1 f = fvecs[i] f.y = ((pos.y) << 3) f.x = ((pos.z) << 3) i += 1 f = fvecs[i] f.y = ((pos.y + size) << 3) f.x = ((pos.z) << 3) i += 1 f = fvecs[i] f.y = ((pos.y + size) << 3) f.x = ((pos.z + size) << 3) i += 1 elif orient == 1: if dimcoord(1): f = fvecs[i] f.y = ((pos.y + size) << 3) f.x = ((pos.z + size) << 3) i += 1 f = fvecs[i] f.y = ((pos.y) << 3) f.x = ((pos.z + size) << 3) i += 1 f = fvecs[i] f.y = ((pos.y) << 3) f.x = ((pos.z) << 3) i += 1 f = fvecs[i] f.y = ((pos.y + size) << 3) f.x = ((pos.z) << 3) i += 1 else: f = fvecs[i] f.y = ((pos.y + size) << 3) f.x = ((pos.z) << 3) i += 1 f = fvecs[i] f.y = ((pos.y) << 3) f.x = ((pos.z) << 3) i += 1 f = fvecs[i] f.y = ((pos.y) << 3) f.x = ((pos.z + size) << 3) i += 1 f = fvecs[i] f.y = ((pos.y + size) << 3) f.x = ((pos.z + size) << 3) i += 1 elif orient == 2: if dimcoord(2): f = fvecs[i] f.x = ((pos.x + size) << 3) f.y = ((pos.z + size) << 3) i += 1 f = fvecs[i] f.x = ((pos.x) << 3) f.y = ((pos.z + size) << 3) i += 1 f = fvecs[i] f.x = ((pos.x) << 3) f.y = ((pos.z) << 3) i += 1 f = fvecs[i] f.x = ((pos.x + size) << 3) f.y = ((pos.z) << 3) i += 1 else: f = fvecs[i] f.x = ((pos.x + size) << 3) f.y = ((pos.z) << 3) i += 1 f = fvecs[i] f.x = ((pos.x) << 3) f.y = ((pos.z) << 3) i += 1 f = fvecs[i] f.x = ((pos.x) << 3) f.y = ((pos.z + size) << 3) i += 1 f = fvecs[i] f.x = ((pos.x + size) << 3) f.y = ((pos.z + size) << 3) i += 1 elif orient == 3: if dimcoord(3): f = fvecs[i] f.x = ((pos.x) << 3) f.y = ((pos.z) << 3) i += 1 f = fvecs[i] f.x = ((pos.x) << 3) f.y = ((pos.z + size) << 3) i += 1 f = fvecs[i] f.x = ((pos.x + size) << 3) f.y = ((pos.z + size) << 3) i += 1 f = fvecs[i] f.x = ((pos.x + size) << 3) f.y = ((pos.z) << 3) i += 1 else: f = fvecs[i] f.x = ((pos.x + size) << 3) f.y = ((pos.z) << 3) i += 1 f = fvecs[i] f.x = ((pos.x + size) << 3) f.y = ((pos.z + size) << 3) i += 1 f = fvecs[i] f.x = ((pos.x) << 3) f.y = ((pos.z + size) << 3) i += 1 f = fvecs[i] f.x = ((pos.x) << 3) f.y = ((pos.z) << 3) i += 1 elif orient == 4: if dimcoord(4): f = fvecs[i] f.y = ((pos.x) << 3) f.x = ((pos.y) << 3) i += 1 f = fvecs[i] f.y = ((pos.x) << 3) f.x = ((pos.y + size) << 3) i += 1 f = fvecs[i] f.y = ((pos.x + size) << 3) f.x = ((pos.y + size) << 3) i += 1 f = fvecs[i] f.y = ((pos.x + size) << 3) f.x = ((pos.y) << 3) i += 1 else: f = fvecs[i] f.y = ((pos.x + size) << 3) f.x = ((pos.y) << 3) i += 1 f = fvecs[i] f.y = ((pos.x + size) << 3) f.x = ((pos.y + size) << 3) i += 1 f = fvecs[i] f.y = ((pos.x) << 3) f.x = ((pos.y + size) << 3) i += 1 f = fvecs[i] f.y = ((pos.x) << 3) f.x = ((pos.y) << 3) i += 1 elif orient == 5: if dimcoord(5): f = fvecs[i] f.y = ((pos.x) << 3) f.x = ((pos.y) << 3) i += 1 f = fvecs[i] f.y = ((pos.x + size) << 3) f.x = ((pos.y) << 3) i += 1 f = fvecs[i] f.y = ((pos.x + size) << 3) f.x = ((pos.y + size) << 3) i += 1 f = fvecs[i] f.y = ((pos.x) << 3) f.x = ((pos.y + size) << 3) i += 1 else: f = fvecs[i] f.y = ((pos.x) << 3) f.x = ((pos.y + size) << 3) i += 1 f = fvecs[i] f.y = ((pos.x + size) << 3) f.x = ((pos.y + size) << 3) i += 1 f = fvecs[i] f.y = ((pos.x + size) << 3) f.x = ((pos.y) << 3) i += 1 f = fvecs[i] f.y = ((pos.x) << 3) f.x = ((pos.y) << 3) i += 1 return 4 buf = [ivec() for _ in range(4)] if v is None: genfaceverts(cu, orient, buf) v = buf prev = facevec(INT_MAX, INT_MAX) if orient == 0: if dimcoord(0): e = v[0] ef = ivec() ef.z = e.x ef.y = e.y ef.x = e.z if ef.z == dimcoord(0) * 8: f = fvecs[i] pf = ivec() pf.z = pos.x pf.y = pos.y pf.x = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[1] ef = ivec() ef.z = e.x ef.y = e.y ef.x = e.z if ef.z == dimcoord(0) * 8: f = fvecs[i] pf = ivec() pf.z = pos.x pf.y = pos.y pf.x = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[2] ef = ivec() ef.z = e.x ef.y = e.y ef.x = e.z if ef.z == dimcoord(0) * 8: f = fvecs[i] pf = ivec() pf.z = pos.x pf.y = pos.y pf.x = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[3] ef = ivec() ef.z = e.x ef.y = e.y ef.x = e.z if ef.z == dimcoord(0) * 8: f = fvecs[i] pf = ivec() pf.z = pos.x pf.y = pos.y pf.x = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 else: e = v[3] ef = ivec() ef.z = e.x ef.y = e.y ef.x = e.z if ef.z == dimcoord(0) * 8: f = fvecs[i] pf = ivec() pf.z = pos.x pf.y = pos.y pf.x = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[2] ef = ivec() ef.z = e.x ef.y = e.y ef.x = e.z if ef.z == dimcoord(0) * 8: f = fvecs[i] pf = ivec() pf.z = pos.x pf.y = pos.y pf.x = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[1] ef = ivec() ef.z = e.x ef.y = e.y ef.x = e.z if ef.z == dimcoord(0) * 8: f = fvecs[i] pf = ivec() pf.z = pos.x pf.y = pos.y pf.x = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[0] ef = ivec() ef.z = e.x ef.y = e.y ef.x = e.z if ef.z == dimcoord(0) * 8: f = fvecs[i] pf = ivec() pf.z = pos.x pf.y = pos.y pf.x = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 elif orient == 1: if dimcoord(1): e = v[0] ef = ivec() ef.z = e.x ef.y = e.y ef.x = e.z if ef.z == dimcoord(1) * 8: f = fvecs[i] pf = ivec() pf.z = pos.x pf.y = pos.y pf.x = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[1] ef = ivec() ef.z = e.x ef.y = e.y ef.x = e.z if ef.z == dimcoord(1) * 8: f = fvecs[i] pf = ivec() pf.z = pos.x pf.y = pos.y pf.x = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[2] ef = ivec() ef.z = e.x ef.y = e.y ef.x = e.z if ef.z == dimcoord(1) * 8: f = fvecs[i] pf = ivec() pf.z = pos.x pf.y = pos.y pf.x = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[3] ef = ivec() ef.z = e.x ef.y = e.y ef.x = e.z if ef.z == dimcoord(1) * 8: f = fvecs[i] pf = ivec() pf.z = pos.x pf.y = pos.y pf.x = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 else: e = v[3] ef = ivec() ef.z = e.x ef.y = e.y ef.x = e.z if ef.z == dimcoord(1) * 8: f = fvecs[i] pf = ivec() pf.z = pos.x pf.y = pos.y pf.x = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[2] ef = ivec() ef.z = e.x ef.y = e.y ef.x = e.z if ef.z == dimcoord(1) * 8: f = fvecs[i] pf = ivec() pf.z = pos.x pf.y = pos.y pf.x = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[1] ef = ivec() ef.z = e.x ef.y = e.y ef.x = e.z if ef.z == dimcoord(1) * 8: f = fvecs[i] pf = ivec() pf.z = pos.x pf.y = pos.y pf.x = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[0] ef = ivec() ef.z = e.x ef.y = e.y ef.x = e.z if ef.z == dimcoord(1) * 8: f = fvecs[i] pf = ivec() pf.z = pos.x pf.y = pos.y pf.x = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 elif orient == 2: if dimcoord(2): e = v[0] ef = ivec() ef.x = e.x ef.z = e.y ef.y = e.z if ef.z == dimcoord(2) * 8: f = fvecs[i] pf = ivec() pf.x = pos.x pf.z = pos.y pf.y = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[1] ef = ivec() ef.x = e.x ef.z = e.y ef.y = e.z if ef.z == dimcoord(2) * 8: f = fvecs[i] pf = ivec() pf.x = pos.x pf.z = pos.y pf.y = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[2] ef = ivec() ef.x = e.x ef.z = e.y ef.y = e.z if ef.z == dimcoord(2) * 8: f = fvecs[i] pf = ivec() pf.x = pos.x pf.z = pos.y pf.y = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[3] ef = ivec() ef.x = e.x ef.z = e.y ef.y = e.z if ef.z == dimcoord(2) * 8: f = fvecs[i] pf = ivec() pf.x = pos.x pf.z = pos.y pf.y = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 else: e = v[3] ef = ivec() ef.x = e.x ef.z = e.y ef.y = e.z if ef.z == dimcoord(2) * 8: f = fvecs[i] pf = ivec() pf.x = pos.x pf.z = pos.y pf.y = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[2] ef = ivec() ef.x = e.x ef.z = e.y ef.y = e.z if ef.z == dimcoord(2) * 8: f = fvecs[i] pf = ivec() pf.x = pos.x pf.z = pos.y pf.y = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[1] ef = ivec() ef.x = e.x ef.z = e.y ef.y = e.z if ef.z == dimcoord(2) * 8: f = fvecs[i] pf = ivec() pf.x = pos.x pf.z = pos.y pf.y = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[0] ef = ivec() ef.x = e.x ef.z = e.y ef.y = e.z if ef.z == dimcoord(2) * 8: f = fvecs[i] pf = ivec() pf.x = pos.x pf.z = pos.y pf.y = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 elif orient == 3: if dimcoord(3): e = v[0] ef = ivec() ef.x = e.x ef.z = e.y ef.y = e.z if ef.z == dimcoord(3) * 8: f = fvecs[i] pf = ivec() pf.x = pos.x pf.z = pos.y pf.y = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[1] ef = ivec() ef.x = e.x ef.z = e.y ef.y = e.z if ef.z == dimcoord(3) * 8: f = fvecs[i] pf = ivec() pf.x = pos.x pf.z = pos.y pf.y = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[2] ef = ivec() ef.x = e.x ef.z = e.y ef.y = e.z if ef.z == dimcoord(3) * 8: f = fvecs[i] pf = ivec() pf.x = pos.x pf.z = pos.y pf.y = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[3] ef = ivec() ef.x = e.x ef.z = e.y ef.y = e.z if ef.z == dimcoord(3) * 8: f = fvecs[i] pf = ivec() pf.x = pos.x pf.z = pos.y pf.y = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 else: e = v[3] ef = ivec() ef.x = e.x ef.z = e.y ef.y = e.z if ef.z == dimcoord(3) * 8: f = fvecs[i] pf = ivec() pf.x = pos.x pf.z = pos.y pf.y = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[2] ef = ivec() ef.x = e.x ef.z = e.y ef.y = e.z if ef.z == dimcoord(3) * 8: f = fvecs[i] pf = ivec() pf.x = pos.x pf.z = pos.y pf.y = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[1] ef = ivec() ef.x = e.x ef.z = e.y ef.y = e.z if ef.z == dimcoord(3) * 8: f = fvecs[i] pf = ivec() pf.x = pos.x pf.z = pos.y pf.y = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[0] ef = ivec() ef.x = e.x ef.z = e.y ef.y = e.z if ef.z == dimcoord(3) * 8: f = fvecs[i] pf = ivec() pf.x = pos.x pf.z = pos.y pf.y = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 elif orient == 4: if dimcoord(4): e = v[0] ef = ivec() ef.y = e.x ef.x = e.y ef.z = e.z if ef.z == dimcoord(4) * 8: f = fvecs[i] pf = ivec() pf.y = pos.x pf.x = pos.y pf.z = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[1] ef = ivec() ef.y = e.x ef.x = e.y ef.z = e.z if ef.z == dimcoord(4) * 8: f = fvecs[i] pf = ivec() pf.y = pos.x pf.x = pos.y pf.z = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[2] ef = ivec() ef.y = e.x ef.x = e.y ef.z = e.z if ef.z == dimcoord(4) * 8: f = fvecs[i] pf = ivec() pf.y = pos.x pf.x = pos.y pf.z = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[3] ef = ivec() ef.y = e.x ef.x = e.y ef.z = e.z if ef.z == dimcoord(4) * 8: f = fvecs[i] pf = ivec() pf.y = pos.x pf.x = pos.y pf.z = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 else: e = v[3] ef = ivec() ef.y = e.x ef.x = e.y ef.z = e.z if ef.z == dimcoord(4) * 8: f = fvecs[i] pf = ivec() pf.y = pos.x pf.x = pos.y pf.z = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[2] ef = ivec() ef.y = e.x ef.x = e.y ef.z = e.z if ef.z == dimcoord(4) * 8: f = fvecs[i] pf = ivec() pf.y = pos.x pf.x = pos.y pf.z = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[1] ef = ivec() ef.y = e.x ef.x = e.y ef.z = e.z if ef.z == dimcoord(4) * 8: f = fvecs[i] pf = ivec() pf.y = pos.x pf.x = pos.y pf.z = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[0] ef = ivec() ef.y = e.x ef.x = e.y ef.z = e.z if ef.z == dimcoord(4) * 8: f = fvecs[i] pf = ivec() pf.y = pos.x pf.x = pos.y pf.z = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 elif orient == 5: if dimcoord(5): e = v[0] ef = ivec() ef.y = e.x ef.x = e.y ef.z = e.z if ef.z == dimcoord(5) * 8: f = fvecs[i] pf = ivec() pf.y = pos.x pf.x = pos.y pf.z = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[1] ef = ivec() ef.y = e.x ef.x = e.y ef.z = e.z if ef.z == dimcoord(5) * 8: f = fvecs[i] pf = ivec() pf.y = pos.x pf.x = pos.y pf.z = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[2] ef = ivec() ef.y = e.x ef.x = e.y ef.z = e.z if ef.z == dimcoord(5) * 8: f = fvecs[i] pf = ivec() pf.y = pos.x pf.x = pos.y pf.z = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[3] ef = ivec() ef.y = e.x ef.x = e.y ef.z = e.z if ef.z == dimcoord(5) * 8: f = fvecs[i] pf = ivec() pf.y = pos.x pf.x = pos.y pf.z = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 else: e = v[3] ef = ivec() ef.y = e.x ef.x = e.y ef.z = e.z if ef.z == dimcoord(5) * 8: f = fvecs[i] pf = ivec() pf.y = pos.x pf.x = pos.y pf.z = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[2] ef = ivec() ef.y = e.x ef.x = e.y ef.z = e.z if ef.z == dimcoord(5) * 8: f = fvecs[i] pf = ivec() pf.y = pos.x pf.x = pos.y pf.z = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[1] ef = ivec() ef.y = e.x ef.x = e.y ef.z = e.z if ef.z == dimcoord(5) * 8: f = fvecs[i] pf = ivec() pf.y = pos.x pf.x = pos.y pf.z = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 e = v[0] ef = ivec() ef.y = e.x ef.x = e.y ef.z = e.z if ef.z == dimcoord(5) * 8: f = fvecs[i] pf = ivec() pf.y = pos.x pf.x = pos.y pf.z = pos.z f = facevec(ef.x * size + (pf.x << 3), ef.y * size + (pf.y << 3)) if f != prev: prev = f i += 1 if fvecs[0] == prev: i -= 1 return i
def loadc(version, f, cube, co, size): haschildren = False octsav = readchar(f) val = octsav & 0x7 if val == octa_save_types.OCTSAV_CHILDREN: cube.children = loadchildren(version, f, co, size>>1) return elif val == octa_save_types.OCTSAV_LODCUBE: haschildren = True elif val == octa_save_types.OCTSAV_EMPTY: cube.setfaces(F_EMPTY) elif val == octa_save_types.OCTSAV_SOLID: cube.setfaces(F_SOLID) elif val == octa_save_types.OCTSAV_NORMAL: cube.data = bytearray(f.read(12)) else: raise OctaError() if version < 14: cube.texture = struct.unpack("6b", f.read(6)) else: cube.texture = struct.unpack("6H", f.read(12)) if version < 7: f.read(3) elif version <= 31: mask = readchar(f) if mask & 0x80: mat = readchar(f) if version < 27: matconv = [empty_material_types.MAT_AIR, empty_material_types.MAT_WATER, empty_material_types.MAT_CLIP, empty_material_types.MAT_GLASS|empty_material_types.MAT_CLIP, empty_material_types.MAT_NOCLIP, empty_material_types.MAT_LAVA|empty_material_types.MAT_DEATH, empty_material_types.MAT_GAMECLIP, empty_material_types.MAT_DEATH] cube.material = matconv[mat] if mat < len(matconv) else empty_material_types.MAT_AIR else: cube.material = convertoldmaterial(mat) surfaces = map(lambda _: SurfaceCompat(), xrange(12)) normals = map(lambda _: NormalsCompat(), xrange(6)) merges = map(lambda _: MergesCompat(), xrange(6)) hassurfs = 0 hasnorms = 0 hasmerges = 0 if mask & 0x3F: numsurfs = 6 i = 0 while i < numsurfs: if i >= 6 or mask & (1 << i): surfaces[i] = SurfaceCompat.read(f) if version < 10: surfaces[i].lmid += 1 if version < 18: if surfaces[i].lmid >= lighting_types.LMID_AMBIENT1: surfaces[i].lmid += 1 if surfaces[i].lmid >= lighting_types.LMID_BRIGHT1: surfaces[i].lmid += 1 if version < 19: if surfaces[i].lmid >= lighting_types.LMID_DARK: surfaces[i].lmid += 2 if i < 6: if mask & 0x40: hasnorms |= 1<<i normals[i] = NormalsCompat.read(f) if surfaces[i].layer != 0 or surfaces[i] != lighting_types.LMID_AMBIENT: hassurfs |= 1<<i if surfaces[i].layer & 2: numsurfs += 1 if version <= 8: cube.edgespan2vectorcube() if version <= 11: cube.faces[0], cube.faces[2] = cube.faces[2], cube.faces[0] cube.texture[0], cube.texture[4] = cube.texture[4], cube.texture[0] cube.texture[1], cube.texture[5] = cube.texture[5], cube.texture[1] if hassurfs & 0x33: cube.surfaces[0], cube.surfaces[4] = cube.surfaces[4], cube.surfaces[0] cube.surfaces[1], cube.surfaces[5] = cube.surfaces[5], cube.surfaces[1] hassurfs = (hassurfs&~0x33) | ((hassurfs&0x30)>>4) | ((hassurfs&0x03)<<4) if version >= 20: if octsav&0x80: merged = readchar(f) cube.merged = merged&0x3F if merged&0x80: mask = readchar(f) if mask: hasmerges = mask&0x3F for i in xrange(6): if mask&(1<<i): merges[i] = MergesCompat.read(f) m = merges[i] if version <= 25: uorigin = m.u1 & 0xE000 vorigin = m.v1 & 0xE000 m.u1 = (m.u1 - uorigin) << 2 m.u2 = (m.u2 - uorigin) << 2 m.v1 = (m.v1 - vorigin) << 2 m.v2 = (m.v2 - vorigin) << 2 if hassurfs or hasnorms or hasmerges: convertoldsurfaces(cube, co, size, surfaces, hassurfs, normals, hasnorms, merges, hasmerges) else: if octsav&0x40: if version <= 32: mat = readchar(f) cube.material = convertoldmaterial(mat) else: cube.material = readuchar(f) if octsav & 0x80: cube.merged = readchar(f) if octsav & 0x20: surfmask = readchar(f) totalverts = readchar(f) newcubeext(cube, totalverts, False) cube.ext.surfaces = map(lambda _: SurfaceInfo(), xrange(6)) cube.ext.verts = map(lambda _: VertInfo(), xrange(cube.ext.maxverts)) offset = 0 for i in xrange(6): if surfmask & (1<<i): cube.ext.surfaces[i] = SurfaceInfo.read(f) surf = cube.ext.surfaces[i] vertmask = surf.verts numverts = surf.totalverts; if numverts == 0: surf.verts = 0 continue surf.verts = offset verts = cube.ext.verts verts = cube.ext.verts[offset/12:] offset += numverts v = map(lambda _: ivec(), xrange(4)) n = 0 layerverts = surf.numverts & layer_types.MAXFACEVERTS dim = dimension(i) vc = C[dim] vr = R[dim] bias = 0 genfaceverts(cube, i, v) hasxyz = (vertmask&0x04)!=0 hasuv = (vertmask&0x40)!=0 hasnorm = (vertmask&0x80)!=0 if hasxyz: e1, e2, e3 = ivec(), ivec(), ivec() e1 = v[1] e2 = v[2] n.cross((e1).sub(v[0]), (e2).sub(v[0])) if n.iszero(): e3 = v[3] n.cross(e2, (e3).sub(v[0])) bias = -n.dot(ivec(v[0]).mul(size).add(ivec(co).mask(0xFFF).shl(3))); else: if layerverts < 4: vis = 2 if vertmask&0x02 else 1 else: vis = 3 if vertmask&0x01: order = 1 else: order = 0 k = 0 vo = ivec(co).mask(0xFFF).shl(3) verts[k].setxyz(v[order].mul(size).add(vo)) k += 1 if vis & 1: verts[k].setxyz(v[order+1].mul(size).add(vo)) k += 1 verts[k].setxyz(v[order+2].mul(size).add(vo)); k += 1 if vis & 2: verts[k].setxyz(v[(order+3)&3].mul(size).add(vo)) k += 1 if layerverts == 4: if hasxyz and vertmask & 0x01: c1, r1, c2, r2 = struct.unpack("4H", f.read(8)) xyz = ivec() xyz[vc] = c1; xyz[vr] = r1 xyz[dim] = -(bias + n[vc]*xyz[vc] + n[vr]*xyz[vr])/n[dim] verts[0].setxyz(xyz) xyz[vc] = c1; xyz[vr] = r2 xyz[dim] = -(bias + n[vc]*xyz[vc] + n[vr]*xyz[vr])/n[dim] verts[1].setxyz(xyz) xyz[vc] = c2; xyz[vr] = r2 xyz[dim] = -(bias + n[vc]*xyz[vc] + n[vr]*xyz[vr])/n[dim] verts[2].setxyz(xyz) xyz[vc] = c2; xyz[vr] = r1 xyz[dim] = -(bias + n[vc]*xyz[vc] + n[vr]*xyz[vr])/n[dim] verts[3].setxyz(xyz) hasxyz = False; if hasuv and vertmask & 0x02: uvorder = (vertmask & 0x30)>>4 v0 = verts[uvorder] v1 = verts[(uvorder+1)&3] v2 = verts[(uvorder+2)&3] v3 = verts[(uvorder+3)&3] v0.u, v0.v = struct.unpack("2H", f.read(4)) v2.u, v2.v = struct.unpack("2H", f.read(4)) v1.u = v0.u v1.v = v2.v v3.u = v2.u v3.v = v0.v if surf.numverts & layer_types.LAYER_DUP: b0 = verts[4+uvorder] b1 = verts[4+((uvorder+1)&3)] b2 = verts[4+((uvorder+2)&3)] b3 = verts[4+((uvorder+3)&3)] b0.u, b0.v = struct.unpack("2H", f.read(4)) b2.u, b2.v = struct.unpack("2H", f.read(4)) b1.u = b0.u; b1.v = b2.v; b3.u = b2.u; b3.v = b0.v; hasuv = False if hasnorm and vertmask & 0x08: norm = readushort(f) for k in xrange(layerverts): verts[k].norm = norm hasnorm = False if hasxyz or hasuv or hasnorm: for k in xrange(layerverts): v = verts[k] if hasxyz: xyz = ivec() xyz[vc], xyz[vr] = struct.unpack("2H", f.read(4)) xyz[dim] = -(bias + n[vc]*xyz[vc] + n[vr]*xyz[vr])/n[dim]; v.setxyz(xyz); if hasuv: v.u, v.v = struct.unpack("2H", f.read(4)) if hasnorm: v.norm = readushort(f) if surf.numverts & layer_types.LAYER_DUP: for k in xrange(layerverts): v = verts[k+layerverts] t = verts[k] v.setxyz(t.x, t.y, t.z) if hasuv: v.u, v.v = struct.unpack("2H", f.read(4)) v.norm = t.norm if haschildren: cube.children = loadchildren(version, f, co, size>>1) else: cube.children = None return cube