Exemplo n.º 1
0
    def center_and_normalize(self, scale=1.0):
        '''
        Scales down the object to fit in world space, 
        defaulting to a box from (1, 1, 1) to
        (-1, -1, -1)

        :param scale: Applies a scalar to the final result.
        '''
        count = 0
        center = glm.vec3(0., 0., 0.)
        farthest = 0.
        for shape in self.shapes:
            for point in shape.points:
                count += 1
                center += point.vertex
        center = center / float(count)

        # center the object
        for shape in self.shapes:
            for point in shape.points:
                point.vertex = point.vertex - center
                farthest = max([
                    glm.sqrt(point.vertex.x**2 + point.vertex.y**2 +
                             point.vertex.z**2), farthest
                ])
        # scale the objects verticies in relation to the furthest point from
        # the center
        scale = scale / farthest
        for shape in self.shapes:
            for point in shape.points:
                point.vertex = point.vertex * scale
Exemplo n.º 2
0
    def icoso_vertex(x, y, z):
        'Return vertex coordinates fixed to the unit sphere'
        length = glm.sqrt(x * x + y * y + z * z)

        return Point3D(
            x * radius / length,
            y * radius / length,
            z * radius / length,
        )
Exemplo n.º 3
0
 def remove_child(self, child):
     self.children.remove(child)
     child_center = glm.vec3(self.M * glm.vec4(child.center, 1))
     child_radius = child.radius * glm.length(self.M * glm.vec4(1, 1, 1, 0)) / glm.sqrt(3)
     if len(self.children) > 1:
         centers = [self.M * glm.vec4(child.center, 1) for child in self.children]
         self.min_x = min([center[0] for center in centers])
         self.max_x = max([center[0] for center in centers])
         self.min_y = min([center[1] for center in centers])
         self.max_y = max([center[1] for center in centers])
         self.min_z = min([center[2] for center in centers])
         self.max_z = max([center[2] for center in centers])
         self.center = glm.vec3((self.min_x + self.max_x) / 2, (self.min_y + self.max_y) / 2, (self.min_z + self.max_z) / 2)
         self.radius = max([glm.length(self.center - child.center) + child.radius for child in self.children])
Exemplo n.º 4
0
 def cull(self, C, cull_planes):
     if len(cull_planes) > 0:
         # Recalculate center and radius based on scene graph traversal
         center = glm.vec3(C * glm.vec4(self.center, 1))
         radius = self.radius * glm.length(
             C * glm.vec4(1, 1, 1, 0)) / glm.sqrt(3)
         for point, normal in cull_planes:
             dist = glm.dot(center - point, normal)
             if dist > radius:
                 # Cull if beyond plane
                 if self.name == None:
                     print(
                         'name:{} point:{!r} norm:{!r} dist:{} r:{} center:{!r} prev_center:{!r}'
                         .format(self.name, point, normal, dist, radius,
                                 center, self.center))
                 return True
         return False
Exemplo n.º 5
0
    def calc_collide_rays(self, numViewDirections, length):
        directions=[]

        goldenRatio = (1 + glm.sqrt(5)) / 2;
        angleIncrement = glm.pi() * 2 * goldenRatio;

        i=0 
        while i < (numViewDirections):
            t =  i / numViewDirections;
            inclination = glm.acos(1 - 2 * t); 
            azimuth = angleIncrement * i;
            x = glm.sin(inclination) * glm.cos(azimuth);
            y = glm.sin (inclination) * glm.sin(azimuth);
            z = glm.cos (inclination); 
            directions.append(glm.vec3(x, y, z)*length)
            i+=1

        return directions 
Exemplo n.º 6
0
 def add_child(self, child: Node):
     child_center = glm.vec3(self.M * glm.vec4(child.center, 1))
     child_radius = child.radius * glm.length(self.M * glm.vec4(1, 1, 1, 0)) / glm.sqrt(3)
     if len(self.children) == 0:
         self.center = child_center
         self.radius = child_radius
         self.min_x = self.max_x = self.center[0]
         self.min_y = self.max_y = self.center[1]
         self.min_z = self.max_z = self.center[2]
     else:
         self.min_x = min(self.min_x, child_center[0])
         self.max_x = max(self.max_x, child_center[0])
         self.min_y = min(self.min_y, child_center[1])
         self.max_y = max(self.max_y, child_center[1])
         self.min_z = min(self.min_z, child_center[2])
         self.max_z = max(self.max_z, child_center[2])
         new_center = glm.vec3((self.min_x + self.max_x) / 2, (self.min_y + self.max_y) / 2, (self.min_z + self.max_z) / 2)
         self.radius += glm.length(self.center - new_center)
         self.center = new_center
         self.radius = max(self.radius, glm.length(child_center - self.center) + child_radius)
         
     self.children.append(child)
Exemplo n.º 7
0
 def apply_matrix(self, M):
     self.center = glm.vec3(M * glm.vec4(self.center, 1))
     self.radius = self.radius * glm.length(M * glm.vec4(1, 1, 1, 0)) / glm.sqrt(3)
     self.M = M * self.M
Exemplo n.º 8
0
def sphere(radius, first_point, detail=2, color=None):
    def middle_point(point_1, point_2):
        """ Find a middle point and project to the unit sphere """

        # We check if we have already cut this edge first
        # to avoid duplicated verts
        smaller_index = min(point_1, point_2)
        greater_index = max(point_1, point_2)

        key = '{0}-{1}'.format(smaller_index, greater_index)

        if key in middle_point_cache:
            return middle_point_cache[key]

        # If it's not in cache, then we can cut it
        vert_1 = verts[point_1]
        vert_2 = verts[point_2]
        middle = [sum(i) / 2 for i in zip(vert_1.vertex, vert_2.vertex)]

        verts.append(icoso_vertex(*middle))

        index = len(verts) - 1
        middle_point_cache[key] = index

        return index

    def icoso_vertex(x, y, z):
        'Return vertex coordinates fixed to the unit sphere'
        length = glm.sqrt(x * x + y * y + z * z)

        return Point3D(
            x * radius / length,
            y * radius / length,
            z * radius / length,
        )

    middle_point_cache = {}
    PHI = (1 + glm.sqrt(5)) / 2
    verts = [
        icoso_vertex(-1, PHI, 0),
        icoso_vertex(1, PHI, 0),
        icoso_vertex(-1, -PHI, 0),
        icoso_vertex(1, -PHI, 0),
        icoso_vertex(0, -1, PHI),
        icoso_vertex(0, 1, PHI),
        icoso_vertex(0, -1, -PHI),
        icoso_vertex(0, 1, -PHI),
        icoso_vertex(PHI, 0, -1),
        icoso_vertex(PHI, 0, 1),
        icoso_vertex(-PHI, 0, -1),
        icoso_vertex(-PHI, 0, 1),
    ]

    faces = [
        # 5 faces around point 0
        [0, 11, 5],
        [0, 5, 1],
        [0, 1, 7],
        [0, 7, 10],
        [0, 10, 11],

        # Adjacent faces
        [1, 5, 9],
        [5, 11, 4],
        [11, 10, 2],
        [10, 7, 6],
        [7, 1, 8],

        # 5 faces around 3
        [3, 9, 4],
        [3, 4, 2],
        [3, 2, 6],
        [3, 6, 8],
        [3, 8, 9],

        # Adjacent faces
        [4, 9, 5],
        [2, 4, 11],
        [6, 2, 10],
        [8, 6, 7],
        [9, 8, 1]
    ]

    for i in range(detail):
        faces_subdiv = []

        for tri in faces:
            v1 = middle_point(tri[0], tri[1])
            v2 = middle_point(tri[1], tri[2])
            v3 = middle_point(tri[2], tri[0])

            faces_subdiv.append([tri[0], v1, v3])
            faces_subdiv.append([tri[1], v2, v1])
            faces_subdiv.append([tri[2], v3, v2])
            faces_subdiv.append([v1, v2, v3])

        faces = faces_subdiv

    for i, face in enumerate(faces):
        # reuse faces to save a bit of memory here
        faces[i] = Shape2D([verts[point] for point in face])

    sphere = Shape3D(faces)
    sphere.gen_normals()
    # sphere.offset = glm.vec4(first_point.vertex, 1)
    return sphere