def create_translate(x=None, y=None, z=None): from maths.matrix44 import Matrix44 from maths.vector3d import Vector3d from maths.vector4d import Vector4d if type(x) == Vector3d: m = Matrix44.create_from_vector4d(Vector4d(1.0, 0.0, 0.0, 0.0), Vector4d(0.0, 1.0, 0.0, 0.0), Vector4d(0.0, 0.0, 1.0, 0.0), Vector4d(x.x, x.y, x.z, 1.0)) m_inv = Matrix44.create_from_vector4d(Vector4d(1.0, 0.0, 0.0, 0.0), Vector4d(0.0, 1.0, 0.0, 0.0), Vector4d(0.0, 0.0, 1.0, 0.0), Vector4d(-x.x, -x.y, -x.z, 1.0)) else: m = Matrix44.create_from_vector4d(Vector4d(1.0, 0.0, 0.0, 0.0), Vector4d(0.0, 1.0, 0.0, 0.0), Vector4d(0.0, 0.0, 1.0, 0.0), Vector4d(x, y, z, 1.0)) m_inv = Matrix44.create_from_vector4d(Vector4d(1.0, 0.0, 0.0, 0.0), Vector4d(0.0, 1.0, 0.0, 0.0), Vector4d(0.0, 0.0, 1.0, 0.0), Vector4d(-x, -y, -z, 1.0)) return Transform(m, m_inv)
def create_identity(): from maths.matrix44 import Matrix44 from maths.vector4d import Vector4d m = Matrix44.create_from_vector4d(Vector4d(1.0, 0.0, 0.0, 0.0), Vector4d(0.0, 1.0, 0.0, 0.0), Vector4d(0.0, 0.0, 1.0, 0.0), Vector4d(0.0, 0.0, 0.0, 1.0)) return Transform(m, m)
def create_look_at(eye, at, up): from maths.vector4d import Vector4d from maths.vector3d import Vector3d # Initialize first three columns of viewing matrix z_axis = (at - eye).get_normalized() x_axis = maths.vector3d.Vector3d.cross(up, z_axis).get_normalized() y_axis = maths.vector3d.Vector3d.cross(z_axis, x_axis) # m = Matrix44.create_from_vector4d( # Vector4d.create_from_vector3d(x_axis, -maths.vector3d.Vector3d.dot(x_axis, eye)), # Vector4d.create_from_vector3d(y_axis, -maths.vector3d.Vector3d.dot(y_axis, eye)), # Vector4d.create_from_vector3d(z_axis, -maths.vector3d.Vector3d.dot(z_axis, eye)), # Vector4d(0.0, 0.0, 0.0, 1.0) # ) # m = Matrix44.create_from_vector4d( # Vector4d.create_from_vector3d(x_axis, 0.0), # Vector4d.create_from_vector3d(y_axis, 0.0), # Vector4d.create_from_vector3d(z_axis, 0.0), # Vector4d( # -maths.vector3d.Vector3d.dot(x_axis, eye), # -maths.vector3d.Vector3d.dot(y_axis, eye), # -maths.vector3d.Vector3d.dot(z_axis, eye), 1.0) # ) m = Matrix44.create_from_vector4d( Vector4d(x_axis.x, y_axis.x, z_axis.x, 0.0), Vector4d(x_axis.y, y_axis.y, z_axis.y, 0.0), Vector4d(x_axis.z, y_axis.z, z_axis.z, 0.0), Vector4d( -maths.vector3d.Vector3d.dot(x_axis, eye), -maths.vector3d.Vector3d.dot(y_axis, eye), -maths.vector3d.Vector3d.dot(z_axis, eye), 1.0) ) return Transform(m.get_invert(), m)
def create_rot_z(angle): from maths.matrix44 import Matrix44 from maths.vector4d import Vector4d c = math.cos(angle) s = math.sin(angle) m = Matrix44.create_from_vector4d(Vector4d(c, s, 0.0, 0.0), Vector4d(-s, c, 0.0, 0.0), Vector4d(0.0, 0.0, 1.0, 0.0), Vector4d(0.0, 0.0, 0.0, 1.0)) return Transform(m, m.get_transpose())
def create_rotate(angle: float, axis): from maths.matrix44 import Matrix44 from maths.vector4d import Vector4d a = axis.get_normalized() s = math.sin(angle) c = math.cos(angle) m = Matrix44.create_from_vector4d(Vector4d(a.x * a.x + (1.0 - a.x * a.x) * c, a.x * a.y * (1.0 - c) - a.z * s, a.x * a.z * (1.0 - c) + a.y * s, 0.0), Vector4d(a.x * a.y * (1.0 - c) + a.z * s, a.y * a.y + (1.0 - a.y * a.y) * c, a.y * a.z * (1.0 - c) - a.x * s, 0.0), Vector4d(a.x * a.z * (1.0 - c) - a.y * s, a.y * a.z * (1.0 - c) + a.x * s, a.z * a.z + (1.0 - a.z * a.z) * c, 0.0), Vector4d(0.0, 0.0, 0.0, 1.0)) return Transform(m, m.get_transpose())
def create_scale(x=None, y=None, z=None): from maths.matrix44 import Matrix44 from maths.vector3d import Vector3d from maths.vector4d import Vector4d if type(x) == Vector3d: m = Matrix44.create_from_vector4d(Vector4d(x.x, 0.0, 0.0, 0.0), Vector4d(0.0, x.y, 0.0, 0.0), Vector4d(0.0, 0.0, x.z, 0.0), Vector4d(0.0, 0.0, 0.0, 1.0)) m_inv = Matrix44.create_from_vector4d(Vector4d(1.0 / x.x, 0.0, 0.0, 0.0), Vector4d(0.0, 1.0 / x.y, 0.0, 0.0), Vector4d(0.0, 0.0, 1.0 / x.z, 0.0), Vector4d(0.0, 0.0, 0.0, 1.0)) else: m = Matrix44.create_from_vector4d(Vector4d(x, 0.0, 0.0, 0.0), Vector4d(0.0, y, 0.0, 0.0), Vector4d(0.0, 0.0, z, 0.0), Vector4d(0.0, 0.0, 0.0, 1.0)) m_inv = Matrix44.create_from_vector4d(Vector4d(1.0 / x, 0.0, 0.0, 0.0), Vector4d(0.0, 1.0 / y, 0.0, 0.0), Vector4d(0.0, 0.0, 1.0 / z, 0.0), Vector4d(0.0, 0.0, 0.0, 1.0)) return Transform(m, m_inv)
def create_perspective(fov: float=90, z_near: float=0.0, z_far: float=1.0): from maths.vector4d import Vector4d inv = 1.0 / (z_far - z_near) # Perform projective divide perspective_matrix = Matrix44.create_from_vector4d( Vector4d(1.0, 0.0, 0.0, 0.0), Vector4d(0.0, 1.0, 0.0, 0.0), Vector4d(0.0, 0.0, z_far * inv, 1.0), Vector4d(0.0, 0.0, -z_far * z_near * inv, 0.0) ) # Scale to canonical viewing volume inv_tan = 1.0 / math.tan(math.radians(fov) * 0.5) return Transform(perspective_matrix) * Transform.create_scale(inv_tan, inv_tan, 1.0)
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)
def __init__(self, mat: Matrix44, mat_inv: Matrix44=None): self.mat = mat if mat_inv is None: self.mat_inv = mat.get_invert() else: self.mat_inv = mat_inv