Beispiel #1
0
 def __init__(self, parent, data):
     self.parent = parent
     self.size = 12 * 4
     r11, r21, r31, r21, r22, r23, r31, r32, r33, x, y, z = unpack(
         'f' * 12, data)
     self.rot = [r11, r21, r31, r21, r22, r23, r31, r32, r33]
     self.center = Vec3(x, z, -y)
Beispiel #2
0
 def avg_tangent(self, faces):
     tangent = Vec3()
     for face in faces:
         tangent = tangent + face.tangent
     #tangent = tangent / float(len(faces))
     #return tangent.normalize()
     return tangent
    def position_at(self, true_anomaly: float) -> Vec3:
        if self.is_nearly_radial:
            raise ValueError("True anomaly is nonsensical for radial orbits")

        radius = self.semilatus_rectum / (
            1 + self.eccentricity * math.cos(true_anomaly))
        position = Vec3(radius * math.cos(true_anomaly),
                        radius * math.sin(true_anomaly), 0 * METERS)
        return self.rot.act_on(position)
    def from_cartesian(body: Body, pos: Vec3, vel: Vec3) -> Orbit:
        mu = body.mu
        r = pos.length()
        v = vel.length()

        energy = v * v / 2 - mu / r
        angmom = pos.cross(vel)

        # eccentricity vector = v x h / mu - r/|r|
        # = [(v.v)r - (r.v)v] - r/|r|
        # = [(v^2/mu - 1/r)] r - [(r.v)/mu] v
        ecc = vel.cross(angmom) / mu - pos / r

        # P = a (1 - e) = mu a (1-e)^2 / mu / (1+e) = h^2 / mu / (1+e)
        periapsis = angmom.dot(angmom) / mu / (1 + ecc.length())

        rot = Quaternion.from_xz_frame(ecc.norm(), angmom.norm())

        return Orbit(body, periapsis, energy, rot)
Beispiel #5
0
    def __init__(self, parent, data):
        self.parent = parent
        count = unpack('H', data[:2])[0]
        data = data[2:]
        self.vertices = []
        for i in range(count):
            x, y, z = unpack('fff', data[:3 * 4])
            data = data[3 * 4:]
            self.vertices.append(Vec3(x, z, -y))
        self.size = 2 + count * 3 * 4

        for i, v1 in enumerate(self.vertices):
            for j, v2 in list(enumerate(self.vertices))[i + 1:]:
                if v1.x == v2.x and v1.y == v2.y and v1.z == v2.z:
                    self.vertices[j] = v1
Beispiel #6
0
    def __init__(self, group, v1, v2, v3):
        self.group = group
        self.v1 = v1
        self.v2 = v2
        self.v3 = v3

        edge1 = self.v2.pos - self.v1.pos
        edge2 = self.v3.pos - self.v1.pos

        edgeuv1 = self.v2.uv - self.v1.uv
        edgeuv2 = self.v3.uv - self.v2.uv
        
        self.normal = edge1.cross(edge2).normalize()

        cp = edgeuv1.y*edgeuv2.x - edgeuv1.x*edgeuv2.y
        if cp != 0:
            self.tangent   = ((edge1 * -edgeuv2.y + edge2 * edgeuv1.y) / cp).normalize();
            self.bitangent = ((edge1 * -edgeuv2.x + edge2 * edgeuv1.x) / cp).normalize();
        else:
            self.tangent = self.normal.cross(Vec3(0.00001, 0.00001, 1.0)).normalize()
            self.bitangent = self.normal.cross(self.tangent).normalize()
Beispiel #7
0
    def open(filename, bones=None):
        infile = File3Ds.open(filename)
        objects = []
        objs = infile.main.children.editor.children.object

        if not isinstance(objs, list): #FIXME
            objs = [objs]

        for index, obj in enumerate(objs):
            name = obj.data.name
            mesh = obj.children.mesh
            faces = mesh.children.faces
            vertices = mesh.children.vertices
            texcoords = mesh.children.texcoords
            center = mesh.children.matrix.data.center
            groups = faces.children.smoothgroup.data.groups
            facelist = []
            for i, (i1, i2, i3, flags) in enumerate(faces.data.faces):
                group = groups[i]
                pos1 = vertices.data.vertices[i1]
                pos2 = vertices.data.vertices[i2]
                pos3 = vertices.data.vertices[i3]
                uv1 = texcoords.data.texcoords[i1]
                uv2 = texcoords.data.texcoords[i2]
                uv3 = texcoords.data.texcoords[i3]
                v1 = Vertex(i1, pos1, uv1)
                v2 = Vertex(i2, pos2, uv2)
                v3 = Vertex(i3, pos3, uv3)
                facelist.append(Face(group, v1, v2, v3))
            objects.append(Object(index, name, center, facelist))
        
        if bones:
            root = Model.walk(bones, objects)
        else:
            root = Object(0, 'root', Vec3(), [])
            for obj in objects:
                root.add_child(obj)

        return Model(root)
Beispiel #8
0
def main():
    img_width = 256
    img_height = 256
    max_val = 255

    ppm_h = f'P6 {img_width} {img_height} {max_val}\n'

    j = 0
    i = 0
    k = 0

    image = array.array('B', [0, 0, 63] * img_width * img_height)

    for j in range(img_height - 1, 0, -1):

        sys.stderr.write(f'\rScanlines remaining: {j}\n')
        sys.stderr.flush()
        if j < 255:
            k = k + 1

        for i in range(0, img_width, 1):
            index = 3 * (k * img_width + i)

            col = Vec3([i / (img_width - 1), j / (img_height - 1), 0.25])

            ncol = col.multiply_s(255)

            image[index] = int(ncol.r())
            image[index + 1] = int(ncol.g())
            image[index + 2] = int(ncol.b())
            print(f'{int(ncol.x())} {int(ncol.y())} {int(ncol.z())}\n')

    sys.stderr.write(f'\nDone.\n')

    with open("img.ppm", 'wb') as f:
        f.write(bytearray(ppm_h, 'ascii'))
        image.tofile(f)
Beispiel #9
0
    def get_triangle(self, index):
        triangle = self.triangles[index]

        v1 = self.vertices[triangle.v1]
        v1 = v1.x, v1.y, v1.z
        n1 = triangle.n1
        n1 = n1.x, n1.y, n1.z
        uv1 = triangle.s1, triangle.t1

        v2 = self.vertices[triangle.v2]
        v2 = v2.x, v2.y, v2.z
        n2 = triangle.n2
        n2 = n2.x, n2.y, n2.z
        uv2 = triangle.s2, triangle.t2

        v3 = self.vertices[triangle.v3]
        v3 = v3.x, v3.y, v3.z
        n3 = triangle.n3
        n3 = n3.x, n3.y, n3.z
        uv3 = triangle.s3, triangle.t3

        t1 = self.get_tangent(Vec3(*n1),
                              Vec3(*v2) - Vec3(*v1),
                              Vec3(*v3) - Vec3(*v1),
                              Vec2(*uv2) - Vec2(*uv1),
                              Vec2(*uv3) - Vec2(*uv1))
        t2 = self.get_tangent(Vec3(*n2),
                              Vec3(*v3) - Vec3(*v2),
                              Vec3(*v1) - Vec3(*v2),
                              Vec2(*uv3) - Vec2(*uv2),
                              Vec2(*uv1) - Vec2(*uv2))
        t3 = self.get_tangent(Vec3(*n3),
                              Vec3(*v1) - Vec3(*v3),
                              Vec3(*v2) - Vec3(*v3),
                              Vec2(*uv1) - Vec2(*uv3),
                              Vec2(*uv2) - Vec2(*uv3))

        return [
            (v1, n1, uv1, t1),
            (v2, n2, uv2, t2),
            (v3, n3, uv3, t3),
        ]
Beispiel #10
0
 def avg_normal(self, faces):
     normal = Vec3()
     for face in faces:
         normal = normal + face.normal
     normal = normal / float(len(faces))
     return normal.normalize()
Beispiel #11
0
 def get_local_offset(self):
     if self.parent:
         return (self.center - self.parent.center)*scale
     else:
         return Vec3(0.0, 0.0, 0.0)
Beispiel #12
0
def main():
    aspect_ratio = 16 / 9
    img_width = 400
    img_height = int(img_width / aspect_ratio)
    max_val = 255
    ppm_h = f'P6 {img_width} {img_height} {max_val}\n'
    image = array.array('B', [217, 232, 255] * img_width * img_height)

    vp_height = 2.0
    vp_width = round(aspect_ratio * vp_height)
    focal = 1.0

    origin = Vec3([0, 0, 0])
    horizontal = Vec3([vp_width, 0, 0])
    vertical = Vec3([0, vp_height, 0])
    hlc = horizontal.multiply_s(0.5)
    vlc = vertical.multiply_s(0.5)
    fl = Vec3([0, 0, focal])

    llc = origin.sub(
        hlc)  #origin - horizontal/2 - vertical/2 - vec3(0, 0, focal_length);
    llc = llc.sub(vlc)
    llc = llc.sub(fl)
    sphere = [255, 0, 0]
    print(f'P6 {img_width} {img_height} {max_val}\n')
    print(vp_width)
    k = 0
    for j in range(img_height - 1, 0, -1):

        sys.stderr.write(f'\rScanlines remaining: {j}\n')
        sys.stderr.flush()
        if j < 255:
            k = k + 1

        for i in range(0, img_width, 1):
            index = 3 * (k * img_width + i)
            col1 = [1.0, 1.0, 1.0]
            col2 = [0.5, 0.7, 1.0]
            u = i / (img_width - 1)
            v = j / (img_height - 1)

            r = llc.add(horizontal.multiply_s(u)).add(
                vertical.multiply_s(v)).sub(origin)

            center = Vec3([0, 0, -1])
            oc = origin.sub(center)
            da = r.dot_p(r)
            db = oc.dot_p(r)
            db = 2.0 * db
            dc = oc.dot_p(oc)
            dc = dc - 0.5 * 0.5
            discrim = (db**2) - 4 * da * dc

            if discrim < 0:
                t = -1.0

            else:
                t = (-db - math.sqrt(discrim)) / (2.0 * da)

            # Red Circle
            if t > 0:
                N = r.multiply_s(t)
                N = N.sub(center)
                N = N.unitvec()
                p = Vec3([1, 1, 1])

                rayN = N.add(p)
                rayN = rayN.multiply_s(0.5)
                image[index] = round(255.0 * rayN.x())
                image[index + 1] = round(255.0 * rayN.y())
                image[index + 2] = round(255.0 * rayN.z())

            else:
                unit_direction = r.unitvec()
                t = 0.5 * (unit_direction.y() + 1.0)
                l = 0

                for x in col1:
                    col1[l] = (1.0 - t) * x
                    l = l + 1

                m = 0

                for y in col2:
                    col2[m] = t * y
                    m = m + 1

                ray_color = [x + y for x, y in zip(col1, col2)]
                retray = Vec3(ray_color)
                rayr = round(255 * retray.x())
                rayg = round(255 * retray.y())
                rayb = round(255 * retray.z())
                image[index] = rayr
                image[index + 1] = rayg
                image[index + 2] = rayb

            print(image[index], image[index + 1], image[index + 2])

    sys.stderr.write(f'\nDone.\n')
    with open("rayimg.ppm", 'wb') as f:
        f.write(bytearray(ppm_h, 'ascii'))
        image.tofile(f)