Beispiel #1
0
def calcFrustumLineObject(invViewProjMatrix):
    # get frustum points
    frustum = [
        core.Vector3(-1.0, -1.0, -1.0),
        core.Vector3(1.0, -1.0, -1.0),
        core.Vector3(1.0, 1.0, -1.0),
        core.Vector3(-1.0, 1.0, -1.0),
        core.Vector3(-1.0, -1.0, 1.0),
        core.Vector3(1.0, -1.0, 1.0),
        core.Vector3(1.0, 1.0, 1.0),
        core.Vector3(-1.0, 1.0, 1.0)
    ]

    # camera to world-space
    for v in frustum:
        v.transform(invViewProjMatrix)

    obj = [None] * 6
    obj[0] = frustum[0:4]  # near poly ccw
    obj[1] = frustum[4:]  # far poly ccw
    obj[2] = [frustum[0], frustum[3], frustum[7], frustum[4]]  # left poly ccw
    obj[3] = [frustum[1], frustum[5], frustum[6], frustum[2]]  # right poly ccw
    obj[4] = [frustum[4], frustum[5], frustum[1],
              frustum[0]]  # bottom poly ccw
    obj[5] = [frustum[6], frustum[7], frustum[3], frustum[2]]  # top poly ccw
    return obj
Beispiel #2
0
 def __init__(self,
              type=TYPE_DIRECTIONAL,
              pos=core.Vector3(0, 1, 0),
              color=core.Color(1, 1, 1, 1)):
     core.Light.__init__(self, type, pos, color)
     self.constAttenuation = 1
     self.linearAttenuation = 0
     self.quadraticAttenuation = 0
Beispiel #3
0
 def interpolate(self, t, type):
     x = Spline.splineInterpolate(self.p0.x, self.p1.x, self.p2.x,
                                  self.p3.x, t, type)
     y = Spline.splineInterpolate(self.p0.y, self.p1.y, self.p2.y,
                                  self.p3.y, t, type)
     z = Spline.splineInterpolate(self.p0.z, self.p1.z, self.p2.z,
                                  self.p3.z, t, type)
     return core.Vector3(x, y, z)
Beispiel #4
0
def lineObjectFromAABB(aabb):
    aabbMin = aabb.min
    aabbMax = aabb.max
    box = [
        core.Vector3(aabbMin.x, aabbMin.y, aabbMin.z),
        core.Vector3(aabbMax.x, aabbMin.y, aabbMin.z),
        core.Vector3(aabbMax.x, aabbMax.y, aabbMin.z),
        core.Vector3(aabbMin.x, aabbMax.y, aabbMin.z),
        core.Vector3(aabbMin.x, aabbMin.y, aabbMax.z),
        core.Vector3(aabbMax.x, aabbMin.y, aabbMax.z),
        core.Vector3(aabbMax.x, aabbMax.y, aabbMax.z),
        core.Vector3(aabbMin.x, aabbMax.y, aabbMax.z)
    ]
    obj = [None] * 6
    obj[0] = box[0:4]
    obj[1] = box[4:]
    obj[2] = [box[0], box[3], box[7], box[4]]
    obj[3] = [box[1], box[5], box[6], box[2]]
    obj[4] = [box[4], box[5], box[1], box[0]]
    obj[5] = [box[6], box[7], box[3], box[2]]
    return obj
Beispiel #5
0
def calcFocusedLightVolumePoints(invViewProj, lightDir, aabb):
    obj = calcFrustumLineObject(invViewProj)
    if aabb:
        obj = clipObjectByAABB(obj, aabb)
    else:
        points = [
            core.Vector3(-1.0, -1.0, -1.0),
            core.Vector3(1.0, -1.0, -1.0),
            core.Vector3(1.0, 1.0, -1.0),
            core.Vector3(-1.0, 1.0, -1.0),
            core.Vector3(-1.0, -1.0, 1.0),
            core.Vector3(1.0, -1.0, 1.0),
            core.Vector3(1.0, 1.0, 1.0),
            core.Vector3(-1.0, 1.0, 1.0)
        ]

        # camera to world-space
        for v in points:
            v.transform(invViewProj)
        aabb = aabbFromPoints(points)

    return includeObjectLightVolume(obj, lightDir, aabb)
Beispiel #6
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.fixedFrameRate = 0.0
     self.setGravity(core.Vector3(0, -10, 0))
Beispiel #7
0
 def setDirection(self, dir):
     assert self.type is TYPE_DIRECTIONAL
     pos = -core.Vector3(dir)
     pos.normalize()
     self.position = pos
Beispiel #8
0
 def direction(self):
     if self.type is TYPE_DIRECTIONAL:
         dir = -core.Vector3(self.position)
         dir.normalize()
         return dir
Beispiel #9
0
 def setView(self, pos, dir, up=core.Vector3(0.0, 1.0, 0.0)):
     super().setView(pos, dir, up)
Beispiel #10
0
def lispSMMatrices(camera, lightDir, sceneAABB, useBodyVector=True):
    invViewProj = camera.viewProjectionMatrix()
    invViewProj.inverse()

    points = calcFocusedLightVolumePoints(invViewProj, lightDir, sceneAABB)

    cameraPos = camera.position()
    viewDir = camera.direction()
    dp = _dot(viewDir, lightDir)
    sinGamma = math.sqrt(1.0 - dp * dp)

    # calc up-vector
    if useBodyVector:
        newDir = calcBodyVector(points, cameraPos)
        left = _cross(lightDir, newDir)
    else:
        left = _cross(lightDir, viewDir)
    upVector = _normalize(_cross(left, lightDir))

    # temporal light View
    # look from position (cameraPos)
    # into direction (lightDir)
    # with up vector (upVector)
    viewMatrix = calcViewMatrix(cameraPos, lightDir, upVector)

    # transform the light volume points from world into light space
    numPoints = len(points)
    pointsCopy = [None] * numPoints
    for i in range(numPoints):
        v = points[i]
        points[i] = _coreVector(v)
        pointsCopy[i] = _coreVector(v)
        points[i].transform(viewMatrix)

    # calculate cubic hull (AABB)
    aabb = aabbFromPoints(points) if numPoints > 0 else _frustumAabb
    points = pointsCopy
    del pointsCopy

    nearPt = core.Vector3(0, 0, -1)  # frustum near-center
    nearPt.transform(invViewProj)  # camera space to world space
    nearDist = (nearPt - cameraPos).length()  # get camera near distance

    # LiSPSM formulas of the paper to get n (and f)
    factor = 1.0 / sinGamma
    z_n = factor * nearDist  # often 1
    d = abs(aabb.max.y -
            aabb.min.y)  # perspective transform depth # light space y extents
    z_f = z_n + d * sinGamma
    n = (z_n + math.sqrt(z_f * z_n)) / sinGamma
    f = n + d

    # new observer point n-1 behind eye position
    # pos = eyePos-up*(n-nearDist)
    pos = _linear(cameraPos, upVector, -(n - nearDist))
    viewMatrix = calcViewMatrix(pos, lightDir, upVector)

    # one possibility for a simple perspective transformation matrix
    # with the two parameters n(near) and f(far) in y direction
    # [ 1 0 0 0]    a = (f+n)/(f-n)
    # [ 0 a 0 1]    b = -2*f*n/(f-n)
    # [ 0 0 1 0]
    # [ 0 b 0 0]
    lispMatrix = core.Matrix4(1.0, 0.0, 0.0, 0.0, 0.0, (f + n) / (f - n), 0.0,
                              1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
                              -2.0 * f * n / (f - n), 0.0, 0.0)

    # temporal arrangement for the transformation of the points to post-perspective space
    lightProjection = viewMatrix * lispMatrix

    # transform the light volume points from world into the distorted light space
    for v in points:
        v.transform(lightProjection)

    # calculate the cubic hull (an AABB)
    aabb = aabbFromPoints(points) if numPoints > 0 else _frustumAabb

    # refit to unit cube
    projectionMatrix = calcProjectionMatrixForRHToFitAABB(aabb)
    return viewMatrix, lispMatrix * projectionMatrix
Beispiel #11
0
                             * b.y - a.y * b.x)
_add = lambda a, b: Vector(a.x + b.x, a.y + b.y, a.z + b.z)
_subtract = lambda a, b: Vector(a.x - b.x, a.y - b.y, a.z - b.z)
_linear = lambda a, b, t: Vector(a.x + b.x * t, a.y + b.y * t, a.z + b.z * t)
_lengthSq = lambda a: a.x * a.x + a.y * a.y + a.z * a.z
_length = lambda a: math.sqrt(_lengthSq(a))
_mulScalar = lambda a, b: Vector(a.x * b, a.y * b, a.z * b)


def _normalize(a):
    length = _length(a)
    return _mulScalar(a, 1.0 / length) if length > 0.0 else a


_copyVector = lambda a: Vector(a.x, a.y, a.z)
_coreVector = lambda a: core.Vector3(a.x, a.y, a.z)

_epsilon = 0.001
_inf = float('inf')
_fltMin = 1.175494351e-38
_fltMax = 3.402823466e+38
_dblMin = 2.2250738585072014e-308
_dblMax = 1.7976931348623158e+308
_isEqual = lambda a, b: abs(a.x - b.x) < _epsilon and abs(
    a.y - b.y) < _epsilon and abs(a.z - b.z) < _epsilon

_frustumAabb = AABB(core.Vector3(-1.0, -1.0, -1.0),
                    core.Vector3(1.0, 1.0, 1.0))


def calcFrustumLineObject(invViewProjMatrix):