Plan 9 from Bell Labs’s /usr/web/sources/contrib/maht/inferno/appl/cmd/MiniLight/minilight/python/triangle.py

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#  MiniLight Python : minimal global illumination renderer
#
#  Copyright (c) 2007-2008, Harrison Ainsworth / HXA7241 and Juraj Sukop.
#  http://www.hxa7241.org/


from math import sqrt
from random import random
from vector3f import Vector3f, ZERO, ONE, MAX

import re
SEARCH = re.compile('(\(.+\))\s*(\(.+\))\s*(\(.+\))\s*(\(.+\))\s*(\(.+\))').search

TOLERANCE = 1.0 / 1024.0

class Triangle(object):

    def __init__(self, in_stream):
        for line in in_stream:
            if not line.isspace():
                v0, v1, v2, r, e = SEARCH(line).groups()
                self.vertexs = map(Vector3f, [v0, v1, v2])
                self.edge0 = Vector3f(v1) - Vector3f(v0)
                self.edge3 = Vector3f(v2) - Vector3f(v0)
                self.reflectivity = Vector3f(r).clamped(ZERO, ONE)
                self.emitivity = Vector3f(e).clamped(ZERO, MAX)
                edge1 = Vector3f(v2) - Vector3f(v1)
                self.tangent = self.edge0.unitize()
                self.normal = self.tangent.cross(edge1).unitize()
                pa2 = self.edge0.cross(edge1)
                self.area = sqrt(pa2.dot(pa2)) * 0.5
                return
        raise StopIteration

    def get_bound(self):
        v2 = self.vertexs[2]
        bound = [v2.x, v2.y, v2.z, v2.x, v2.y, v2.z]
        for j in range(3):
            v0 = self.vertexs[0][j]
            v1 = self.vertexs[1][j]
            if v0 < v1:
                if v0 < bound[j]:
                    bound[j] = v0
                if v1 > bound[j + 3]:
                    bound[j + 3] = v1
            else:
                if v1 < bound[j]:
                    bound[j] = v1
                if v0 > bound[j + 3]:
                    bound[j + 3] = v0
            bound[j] -= (abs(bound[j]) + 1.0) * TOLERANCE
            bound[j + 3] += (abs(bound[j + 3]) + 1.0) * TOLERANCE
        return bound

    def get_intersection(self, ray_origin, ray_direction):
        e1x = self.edge0.x; e1y = self.edge0.y; e1z = self.edge0.z
        e2x = self.edge3.x; e2y = self.edge3.y; e2z = self.edge3.z
        pvx = ray_direction.y * e2z - ray_direction.z * e2y
        pvy = ray_direction.z * e2x - ray_direction.x * e2z
        pvz = ray_direction.x * e2y - ray_direction.y * e2x
        det = e1x * pvx + e1y * pvy + e1z * pvz
        if -0.000001 < det < 0.000001:
            return None
        inv_det = 1.0 / det
        v0 = self.vertexs[0]
        tvx = ray_origin.x - v0.x
        tvy = ray_origin.y - v0.y
        tvz = ray_origin.z - v0.z
        u = (tvx * pvx + tvy * pvy + tvz * pvz) * inv_det
        if u < 0.0 or u > 1.0:
            return None
        qvx = tvy * e1z - tvz * e1y
        qvy = tvz * e1x - tvx * e1z
        qvz = tvx * e1y - tvy * e1x
        v = (ray_direction.x * qvx + ray_direction.y * qvy + ray_direction.z * qvz) * inv_det
        if v < 0.0 or u + v > 1.0:
            return None
        t = (e2x * qvx + e2y * qvy + e2z * qvz) * inv_det
        if t < 0.0:
            return None
        return t

    def get_sample_point(self):
        sqr1 = sqrt(random())
        r2 = random()
        a = 1.0 - sqr1
        b = (1.0 - r2) * sqr1
        return self.edge0 * a + self.edge3 * b + self.vertexs[0]

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].