Пример #1
0
void LightStage::Shadow::setKeylightFrustum(const ViewFrustum& viewFrustum, float nearDepth, float farDepth) {
    assert(nearDepth < farDepth);

    // Orient the keylight frustum
    const auto& direction = glm::normalize(_light->getDirection());
    glm::quat orientation;
    if (direction == IDENTITY_UP) {
        orientation = glm::quat(glm::mat3(-IDENTITY_RIGHT, IDENTITY_FRONT, -IDENTITY_UP));
    } else if (direction == -IDENTITY_UP) {
        orientation = glm::quat(glm::mat3(IDENTITY_RIGHT, IDENTITY_FRONT, IDENTITY_UP));
    } else {
        auto side = glm::normalize(glm::cross(direction, IDENTITY_UP));
        auto up = glm::normalize(glm::cross(side, direction));
        orientation = glm::quat_cast(glm::mat3(side, up, -direction));
    }
    _frustum->setOrientation(orientation);

    // Position the keylight frustum
    _frustum->setPosition(viewFrustum.getPosition() - (nearDepth + farDepth)*direction);

    const Transform view{ _frustum->getView()};
    const Transform viewInverse{ view.getInverseMatrix() };

    auto nearCorners = viewFrustum.getCorners(nearDepth);
    auto farCorners = viewFrustum.getCorners(farDepth);

    vec3 min{ viewInverse.transform(nearCorners.bottomLeft) };
    vec3 max{ min };
    // Expand keylight frustum  to fit view frustum
    auto fitFrustum = [&min, &max, &viewInverse](const vec3& viewCorner) {
        const auto corner = viewInverse.transform(viewCorner);

        min.x = glm::min(min.x, corner.x);
        min.y = glm::min(min.y, corner.y);
        min.z = glm::min(min.z, corner.z);

        max.x = glm::max(max.x, corner.x);
        max.y = glm::max(max.y, corner.y);
        max.z = glm::max(max.z, corner.z);
    };
    fitFrustum(nearCorners.bottomRight);
    fitFrustum(nearCorners.topLeft);
    fitFrustum(nearCorners.topRight);
    fitFrustum(farCorners.bottomLeft);
    fitFrustum(farCorners.bottomRight);
    fitFrustum(farCorners.topLeft);
    fitFrustum(farCorners.topRight);

    glm::mat4 ortho = glm::ortho<float>(min.x, max.x, min.y, max.y, -max.z, -min.z);
    _frustum->setProjection(ortho);

    // Calculate the frustum's internal state
    _frustum->calculate();

    // Update the buffer
    _schemaBuffer.edit<Schema>().projection = ortho;
    _schemaBuffer.edit<Schema>().viewInverse = viewInverse.getMatrix();
}
Пример #2
0
QVariantMap Camera::getViewFrustum() {
    ViewFrustum frustum;
    loadViewFrustum(frustum);

    QVariantMap result;
    result["position"].setValue(frustum.getPosition());
    result["orientation"].setValue(frustum.getOrientation());
    result["projection"].setValue(frustum.getProjection());
    result["centerRadius"].setValue(frustum.getCenterRadius());
    result["fieldOfView"].setValue(frustum.getFieldOfView());
    result["aspectRatio"].setValue(frustum.getAspectRatio());

    return result;
}
Пример #3
0
int ItemSpatialTree::selectCells(CellSelection& selection, const ViewFrustum& frustum, float lodAngle) const {
    auto worldPlanes = frustum.getPlanes();
    FrustumSelector selector;
    for (int i = 0; i < ViewFrustum::NUM_PLANES; i++) {
        ::Plane octPlane;
        octPlane.setNormalAndPoint(worldPlanes[i].getNormal(), evalCoordf(worldPlanes[i].getPoint(), ROOT_DEPTH));
        selector.frustum[i] = Coord4f(octPlane.getNormal(), octPlane.getDCoefficient());
    }

    selector.eyePos = evalCoordf(frustum.getPosition(), ROOT_DEPTH);
    selector.setAngle(glm::radians(lodAngle));

    return Octree::select(selection, selector);
}
Пример #4
0
void ConicalViewFrustum::set(const ViewFrustum& viewFrustum) {
    // The ConicalViewFrustum has two parts: a central sphere (same as ViewFrustum) and a circular cone that bounds the frustum part.
    // Why?  Because approximate intersection tests are much faster to compute for a cone than for a frustum.
    _position = viewFrustum.getPosition();
    _radius = viewFrustum.getCenterRadius();
    _farClip = viewFrustum.getFarClip();

    auto topLeft = viewFrustum.getNearTopLeft() - _position;
    auto topRight = viewFrustum.getNearTopRight() - _position;
    auto bottomLeft = viewFrustum.getNearBottomLeft() - _position;
    auto bottomRight = viewFrustum.getNearBottomRight() - _position;
    auto centerAxis = 0.25f * (topLeft + topRight + bottomLeft + bottomRight); // Take the average

    _direction = glm::normalize(centerAxis);
    _angle = std::max(std::max(angleBetween(_direction, topLeft),
                               angleBetween(_direction, topRight)),
                      std::max(angleBetween(_direction, bottomLeft),
                               angleBetween(_direction, bottomRight)));
}
Пример #5
0
float OctreeElement::distanceToCamera(const ViewFrustum& viewFrustum) const {
    glm::vec3 center = _cube.calcCenter();
    glm::vec3 temp = viewFrustum.getPosition() - center;
    float distanceToVoxelCenter = sqrtf(glm::dot(temp, temp));
    return distanceToVoxelCenter;
}
Пример #6
0
// Calculates the distance to the furthest point of the voxel to the camera
// does as much math as possible in voxel scale and then scales up to TREE_SCALE at end
float OctreeElement::furthestDistanceToCamera(const ViewFrustum& viewFrustum) const {
    glm::vec3 furthestPoint;
    viewFrustum.getFurthestPointFromCamera(_cube, furthestPoint);
    glm::vec3 temp = viewFrustum.getPosition() - furthestPoint;
    return sqrtf(glm::dot(temp, temp));
}