def mandelboxSDF(pos, scale):
    orbitTrap = glm.vec4(10000)
    iterations = 17  #0 to 300
    colorIterations = 3  #0 to 300
    minRad2 = 0.25  #0.0 to 2.0
    scale = glm.vec4(scale, scale, scale, abs(scale)) / minRad2
    rotVector = glm.vec3(1, 1, 1)  #(0, 0, 0) to (1, 1, 1)
    rotAngle = 0  #0 to 180(?)
    rot = rotationMatrix3(glm.normalize(rotVector), rotAngle)
    absScalem1 = abs(scale - 1)
    absScaleRaisedTo1mIters = pow(abs(scale), float(1 - iterations))
    p = pos
    w = 1
    p0 = p
    w0 = w
    for i in range(iterations):
        p *= rot
        p = glm.clamp(p, -1, 1) * 2 - p
        r2 = glm.dot(p, p)
        if i < colorIterations:
            orbitTrap = glm.min(orbitTrap, abs(glm.vec4(p, r2)))
        p *= glm.clamp(glm.max(minRad2 / r2, minRad2), 0, 1)
        w *= glm.clamp(glm.max(minRad2 / r2, minRad2), 0, 1)
        p = p * glm.vec3(scale[0], scale[1], scale[2]) + p0
        w = w * scale[3] + w0
        if r2 > 1000:
            break
    return (glm.length(p) - absScalem1[3]) / w - absScaleRaisedTo1mIters[3]
def cylinderSDF(p, h, r):
    inOutRadius = glm.length(p.xy) - r
    inOutHeight = glm.abs(p.z) - h / 2.0
    insideDistance = glm.min(glm.max(inOutRadius, inOutHeight), 0.0)
    outsideDistance = glm.length(
        glm.max(glm.vec2(inOutRadius, inOutHeight), 0.0))
    return insideDistance + outsideDistance
Example #3
0
 def union_update(self, other) -> 'self':
     ''' extend the volume of the current box to bound the given point or box '''
     if isinstance(other, (dvec3, fvec3)):
         self.min = glm.min(self.min, other)
         self.max = glm.max(self.max, other)
     elif isinstance(other, Box):
         self.min = glm.min(self.min, other.min)
         self.max = glm.max(self.max, other.max)
     else:
         raise TypeError('unable to integrate {}'.format(type(other)))
     return self
Example #4
0
 def intersection_update(self, other) -> 'self':
     ''' reduce the volume of the current box to the intersection between the 2 boxes '''
     if isinstance(other, Box):
         self.min = glm.max(self.min, other.min)
         self.max = glm.min(self.max, other.max)
     else:
         raise TypeError('expected a Box'.format(type(other)))
     return self
Example #5
0
 def intersection(self, other):
     ''' intersection area between the 2 boxes '''
     if isinstance(other, Box):
         self.min = glm.max(self.min, other.min)
         self.max = glm.min(self.max, other.max)
     else:
         raise TypeError('expected a Box'.format(type(other)))
     return self
Example #6
0
def compute_plane_minmax(position, far_screen, split):
    
    pm = glm.mat4(position, position, position, position)
    s0 = (far_screen - pm) * split + pm
    
    min0 = glm.min(s0[0], s0[1], s0[2], s0[3])
    max0 = glm.max(s0[0], s0[1], s0[2], s0[3])
    
    return min0, max0
Example #7
0
    def union(self, other) -> 'Box':
        ''' return a box containing the current and the given box (or point) 
		
			Example:
				
				>>> Box(vec2(1,2), vec2(2,3)) .union(vec3(1,4))
				Box(vec2(1,2), vec2(2,4))
				
				>>> Box(vec2(1,2), vec2(2,3)) .union(Box(vec3(1,-4), vec3(2,8)))
				Box(vec2(1,-4), vec3(2,8))
		
		'''
        if isinstance(other, (dvec3, fvec3)):
            return Box(glm.min(self.min, other), glm.max(self.max, other))
        elif isinstance(other, Box):
            return Box(glm.min(self.min, other.min),
                       glm.max(self.max, other.max))
        else:
            raise TypeError('unable to integrate {}'.format(type(other)))
Example #8
0
    def intersection(self, other) -> 'Box':
        ''' return a box for the volume common to the current and the given box 
		
			Example:
			
				>>> Box(vec2(-1,2), vec2(2,3)) .intersection(Box(vec3(1,-4), vec3(2,8)))
				Box(vec2(1,2), vec3(2,3))
		
		'''
        if isinstance(other, Box):
            return Box(glm.max(self.min, other.min),
                       glm.min(self.max, other.max))
        else:
            raise TypeError('expected a Box'.format(type(other)))
    def update(self):
        w = self.window
        LEFT = glfw.get_key(w, glfw.KEY_A) or glfw.get_key(w, glfw.KEY_LEFT)
        FORWARD = glfw.get_key(w, glfw.KEY_W) or glfw.get_key(w, glfw.KEY_UP)
        RIGHT = glfw.get_key(w, glfw.KEY_D) or glfw.get_key(w, glfw.KEY_RIGHT)
        BACK = glfw.get_key(w, glfw.KEY_S) or glfw.get_key(w, glfw.KEY_DOWN)
        UP = glfw.get_key(w, glfw.KEY_E) or glfw.get_key(w, glfw.KEY_PAGE_UP)
        DOWN = glfw.get_key(w, glfw.KEY_Q) or glfw.get_key(
            w, glfw.KEY_PAGE_DOWN)

        SPEED = 0.1
        LEFT *= glm.vec3(-1.0, +0.0, +0.0) * SPEED
        FORWARD *= glm.vec3(+0.0, -1.0, +0.0) * SPEED
        RIGHT *= glm.vec3(+1.0, +0.0, +0.0) * SPEED
        BACK *= glm.vec3(+0.0, +1.0, +0.0) * SPEED
        UP *= glm.vec3(+0.0, +0.0, +1.0) * SPEED
        DOWN *= glm.vec3(+0.0, +0.0, -1.0) * SPEED

        self.movement += LEFT + FORWARD + RIGHT + BACK + UP + DOWN
        self.movement.y = glm.max(glm.min(self.movement.y, 100.0), -100.0)
        self.movement.z = glm.max(glm.min(self.movement.z, 30.0), -300.0)
        self.update_uniforms({
            "u_movement": (self.movement.x, self.movement.y, self.movement.z)
        })
def boxSDF(p, size):
    d = glm.abs(p) - (size / 2.0)
    insideDistance = glm.min(glm.max(d.x, glm.max(d.y, d.z)), 0.0)
    outsideDistance = glm.length(glm.max(d, 0.0))
    return insideDistance + outsideDistance
def differenceSDF(distA, distB):
    return glm.max(distA, -distB)
def intersectSDF(distA, distB):
    return glm.max(distA, distB)
Example #13
0
 def intersection(self, other):
     return AABB(glm.min(self.max, other.max), glm.max(self.min, other.min))
Example #14
0
 def merge(self, other):
     return AABB(glm.min(self.min, other.min), glm.max(self.max, other.max))
Example #15
0
    def prepare_render_shadowmap(
        self, 
        shadowmap_index, 
        shadowmap_layer, 
        shader, 
        camera_position, 
        camera_screen
    ):
        
        si = shadowmap_index

        prefix = self.get_uniform_name('')

        view = glm.lookAt(self.position, self.position - self.front, self.up)

        if self.type == 'directional':
            
            position = view * camera_position
            screen = view * camera_screen

            min0, max0 = compute_plane_minmax(
                position, screen, self.shadowmaps_depths[si]
            )

            min1, max1 = compute_plane_minmax(
                position, screen, self.shadowmaps_depths[si+1]
            )

            min2 = glm.min(min0, min1)
            max2 = glm.max(max0, max1)

            projection = glm.ortho(
                round(min2.x), 
                round(max2.x), 
                round(min2.y), 
                round(max2.y), 
                self.snear, 
                self.sfar
            )
            
            scale = max(max2.x - min2.x, max2.y - min2.y)
            shader._members[prefix + 'scale'].value = scale

        elif self.type == 'point':
            projection = glm.perspective(
                math.pi / 2, 
                1., 
                self.snear, 
                self.sfar
            )

        else:
            projection = glm.perspective(
                2 * self.outer_cone, 
                1., 
                self.snear, 
                self.sfar
            )
        
        self._view = view
        self._proj = projection
        
        pv = projection * view

        shader._members[prefix + 'shadowmap_textures[%s].layer' % si].value = shadowmap_layer
        shader._members[prefix + 'shadowmap_textures[%s].depth' % si].value = self.shadowmaps_depths[si]
        shader._members[prefix + 'shadowmap_textures[%s].projection' % si].write(pv)
        shader._members[prefix + 'shadowmap_projection'].write(pv)