def Sample2(self, p: Point3d, u: (float, float), Ns: Normal) -> Point3d: # Compute coordinate system for sphere sampling Pcenter = Point3d(0, 0, 0) * self.objectToWorld wc = (Pcenter - p).get_normalized() wcX, wcY = Transform.create_coordinateSystem(wc) # Sample uniformly on sphere if $\pt{}$ is inside it if (p - Pcenter).get_length_squared() - self.radius * self.radius < 1e-40: return self.Sample1(u, Ns) # Sample sphere uniformly inside subtended cone sinThetaMax2 = self.radius * self.radius / (p - Pcenter).get_length_squared() cosThetaMax = math.sqrt(max(0.0, 1.0 - sinThetaMax2)) dgSphere = DifferentialGeometry() thit = 1.0 r = Ray(p, UniformSampleCone2(u, cosThetaMax, wcX, wcY, wc), 1e-3) b, t = self.get_intersection(r, dgSphere) # if not b: #bug thit = Vector3d.dot(Pcenter - p, r.direction.get_normalized()) ps = r.get_at(thit) nn = (ps - Pcenter).get_normalized() Ns.Set(nn) # if (ReverseOrientation) *ns *= -1.f; return ps
def __init__(self, dg: DifferentialGeometry, ngeom: Normal): self.bxdfs = list() self.dgShading = dg self.ng = ngeom self.nn = self.dgShading.normal # self.sn = self.dgShading.normal # self.tn = Vector3d.cross(self.nn, self.sn) self.sn, self.tn = Transform.create_coordinateSystem(self.nn)
def create_spotLight(paramSet: ParamSet, light2world: Transform) -> PointLight: from maths.matrix44 import Matrix44 from maths.vector4d import Vector4d I = paramSet.find_spectrum("I", Spectrum(1.0)) sc = paramSet.find_spectrum("scale", Spectrum(1.0)) coneangle = paramSet.find_float("coneangle", 30.0) conedelta = paramSet.find_float("conedeltaangle", 5.0) # Compute spotlight world to light transformation frome = paramSet.find_point("from", Point3d(0.0, 0.0, 0.0)) to = paramSet.find_point("to", Point3d(0.0, 0.0, 1.0)) direction = (to - frome).get_normalized() du, dv = Transform.create_coordinateSystem(dir) m = Matrix44.create_from_vector4d( Vector4d(du.x, du.y, du.z, 0.0), Vector4d(dv.x, dv.y, dv.z, 0.0), Vector4d(direction.x, direction.y, direction.z, 0.0), Vector4d(0.0, 0.0, 0.0, 1.0)) dirToZ = Transform(m) light2world = light2world * Transform.create_translate(frome.ex, frome.ey, frome.ez) * dirToZ.get_invert() return SpotLight(light2world, I * sc, coneangle, coneangle - conedelta)