def get_intensity(self, pos): q = sub(self.pos, pos) dsq = dot(q, q) invlend = 1 / math.sqrt(dsq) cosangle = -dot(q, self.d) * invlend if cosangle < self.coscutoff: return (0.0, 0.0, 0.0) i = pow(dot(self.d, mul(d, -invlend)), self.exp) return mul(self.color, i * 100.0 / (99.0 + dsq))
def intersect(self, raypos, raydir): tr = self.transform raydir = tr.inv_transform_vector(raydir) scale = 1.0 / length(raydir) raydir = mul(raydir, scale) # normalize raypos = tr.inv_transform_point(raypos) s = dot(neg(raypos), raydir) lsq = dot(raypos, raypos) if s < 0.0 and lsq > 1.0: return [] msq = lsq - s * s if msq > 1.0: return [] q = math.sqrt(1.0 - msq) t1 = s + q t2 = s - q if t1 > t2: t1, t2 = t2, t1 ts = [] if t1 > 0.0: ts.append( Intersection(scale, t1, raypos, raydir, self, Intersection.ENTRY, 0)) if t2 > 0.0: ts.append( Intersection(scale, t2, raypos, raydir, self, Intersection.EXIT, 0)) return ts
def intersect(self, raypos, raydir): tr = self.transform raydir = tr.inv_transform_vector(raydir) scale = 1.0 / length(raydir) raydir = mul(raydir, scale) # normalize raypos = tr.inv_transform_point(raypos) eps = 1e-7 px, py, pz = raypos dx, dy, dz = raydir tsc = self._solveCone(px, py, pz, dx, dy, dz) if not tsc: return [] tcmin, tcmax = tsc ts = [] cminy = py + tcmin[0] * dy cmaxy = py + tcmax[0] * dy if 0.0 <= cminy <= 1.0: ts.append(tcmin) if 0.0 <= cmaxy <= 1.0: ts.append(tcmax) if len(ts) == 0: return [] if len(ts) == 2: tr = [] if ts[0][0] > 0.0: tr.append( Intersection(scale, ts[0][0], raypos, raydir, self, Intersection.ENTRY, ts[0][1])) if ts[1][0] > 0.0: tr.append( Intersection(scale, ts[1][0], raypos, raydir, self, Intersection.EXIT, ts[1][1])) return tr # check plane # since we know there is only one intersection with the cone, # there must be an intersection in the base tp = (-py + 1.0) / dy ts.append((tp, 1)) ts.sort() tr = [] if ts[0][0] > 0.0: tr.append( Intersection(scale, ts[0][0], raypos, raydir, self, Intersection.ENTRY, ts[0][1])) if ts[1][0] > 0.0: tr.append( Intersection(scale, ts[1][0], raypos, raydir, self, Intersection.EXIT, ts[1][1])) return tr
def intersect(self, raypos, raydir): tr = self.transform raydir = tr.inv_transform_vector(raydir) scale = 1.0 / length(raydir) raydir = mul(raydir, scale) # normalize raypos = tr.inv_transform_point(raypos) eps = 1e-15 tmin = None tmax = None p = sub((0.5, 0.5, 0.5), raypos) for i in range(3): face1, face2 = self.slabs[i] e = p[i] f = raydir[i] if abs(f) > eps: t1 = (e + 0.5) / f t2 = (e - 0.5) / f if t1 > t2: t1, t2 = t2, t1 face1, face2 = face2, face1 if tmin is None or t1 > tmin[0]: tmin = (t1, face1) if tmax is None or t2 < tmax[0]: tmax = (t2, face2) if tmin[0] > tmax[0]: return [] if tmax[0] < 0.0: return [] elif -e - 0.5 > 0.0 or -e + 0.5 < 0.0: return [] ts = [] if tmin[0] > 0.0: ts.append( Intersection(scale, tmin[0], raypos, raydir, self, Intersection.ENTRY, tmin[1])) if tmax[0] > 0.0: ts.append( Intersection(scale, tmax[0], raypos, raydir, self, Intersection.EXIT, tmax[1])) return ts
def trace(amb, lights, scene, depth, raypos, raydir): i = scene.intersect(raypos, raydir) if i: #for ic in i: # print ic #print isect = i[0] if isect.t == Intersection.EXIT: return (0.0, 0.0, 0.0) sc, kd, ks, n = isect.primitive.get_surface(isect) c = get_ambient(sc, amb, kd) diffuse = (0.0, 0.0, 0.0) specular = (0.0, 0.0, 0.0) pos = isect.wpos normal = isect.normal for light in lights: lightdir, lightdistance = light.get_direction(pos) df = dot(normal, lightdir) if df > 0.0: poseps = add(pos, mul(lightdir, 1e-7)) i = scene.intersect(poseps, lightdir) if not i or (lightdistance and (lightdistance < i[0].distance)): ic = cmul(sc, light.get_intensity(pos)) if kd > 0.0: diffuse = add(diffuse, mul(ic, df)) if ks > 0.0: specular = add( specular, get_specular(ic, lightdir, normal, pos, raypos, n)) c = add(c, add(mul(diffuse, kd), mul(specular, ks))) if ks > 0.0 and depth > 0: refl_raydir = normalize( sub(raydir, mul(normal, 2 * dot(raydir, normal)))) poseps = add(pos, mul(refl_raydir, 1e-7)) rc = trace(amb, lights, scene, depth - 1, poseps, refl_raydir) return add(c, mul(cmul(rc, sc), ks)) else: return c else: return (0.0, 0.0, 0.0)
def intersect(self, raypos, raydir): tr = self.transform raydir = tr.inv_transform_vector(raydir) scale = 1.0 / length(raydir) raydir = mul(raydir, scale) # normalize raypos = tr.inv_transform_point(raypos) np = self.np denom = dot(np, raydir) if abs(denom) < 1e-7: return [] t = -dot(np, raypos) / denom if t < 0.0: return [] if denom > 0.0: return [ Intersection(scale, t, raypos, raydir, self, Intersection.EXIT, 0) ] else: return [ Intersection(scale, t, raypos, raydir, self, Intersection.ENTRY, 0) ]
def get_ambient(c, ia, kd): return mul(cmul(ia, c), kd)
def get_specular(ic, lightdir, sn, pos, raypos, n): halfway = normalize(add(lightdir, normalize(sub(raypos, pos)))) sp = dot(sn, halfway) if sp > 0.0: return mul(ic, pow(sp, n)) return (0.0, 0.0, 0.0)
def get_direction(self, pos): d = sub(self.pos, pos) dl = length(d) return mul(d, 1.0 / dl), length(d)
def get_intensity(self, pos): d = sub(self.pos, pos) dsq = dot(d, d) return mul(self.color, 100.0 / (99.0 + dsq))
def fget(self): if not self._opos: self._opos = add(self.rp, mul(self.rd, self.odistance)) return self._opos
def intersect(self, raypos, raydir): tr = self.transform raydir = tr.inv_transform_vector(raydir) scale = 1.0 / length(raydir) raydir = mul(raydir, scale) # normalize raypos = tr.inv_transform_point(raypos) eps = 1e-7 px, py, pz = raypos dx, dy, dz = raydir ts = [] if abs(dy) + eps >= 1.0: # ray is parallel to the cylinder axis frsd = 1.0 - px * px - pz * pz if frsd < 0.0: # outside cylinder return [] ts = list(self._solvePlane(py, dy)) elif abs(dy) < eps: # ray is orthogonal to the cylinder axis # check planes if py < 0.0 or py > 1.0: return [] # check cylinder res = self._solveCyl(px, pz, dx, dz) if not res: return [] ts = list(res) else: # general case # check cylinder res = self._solveCyl(px, pz, dx, dz) if not res: #print "baz" return [] tc1, tc2 = res # check planes tp1, tp2 = self._solvePlane(py, dy) # same min-max strategy as for cubes # Check max of mins tmin = tp1 tmax = tp2 if tc1 > tmin: tmin = tc1 if tc2 < tmax: tmax = tc2 if tmin[0] > tmax[0]: return [] if tmax[0] < 0.0: return [] ts = [tmin, tmax] tmin, tmax = ts ts = [] if tmin[0] > 0.0: ts.append( Intersection(scale, tmin[0], raypos, raydir, self, Intersection.ENTRY, tmin[1])) if tmax[0] > 0.0: ts.append( Intersection(scale, tmax[0], raypos, raydir, self, Intersection.EXIT, tmax[1])) return ts