예제 #1
0
const Matrix3x4& Light::GetVolumeTransform(Camera* camera)
{
    if (!node_)
        return Matrix3x4::IDENTITY;

    switch (lightType_)
    {
    case LIGHT_DIRECTIONAL:
        {
            Matrix3x4 quadTransform;
            Vector3 near, far;
            // Position the directional light quad in halfway between far & near planes to prevent depth clipping
            camera->GetFrustumSize(near, far);
            quadTransform.SetTranslation(Vector3(0.0f, 0.0f, (camera->GetNearClip() + camera->GetFarClip()) * 0.5f));
            quadTransform.SetScale(Vector3(far.x_, far.y_, 1.0f)); // Will be oversized, but doesn't matter (gets frustum clipped)
            volumeTransform_ = camera->GetEffectiveWorldTransform() * quadTransform;
            break;
        }

    case LIGHT_SPOT:
        {
            float yScale = tanf(fov_ * M_DEGTORAD * 0.5f) * range_;
            float xScale = aspectRatio_ * yScale;
            volumeTransform_ = Matrix3x4(node_->GetWorldPosition(), node_->GetWorldRotation(), Vector3(xScale, yScale, range_));
        }
        break;

    case LIGHT_POINT:
        volumeTransform_ = Matrix3x4(node_->GetWorldPosition(), Quaternion::IDENTITY, range_);
        break;
    }

    return volumeTransform_;
}
예제 #2
0
void NavArea::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
{
    if (debug && IsEnabledEffective())
    {
        Matrix3x4 mat;
        mat.SetTranslation(node_->GetWorldPosition());
        debug->AddBoundingBox(boundingBox_, mat, Color::GREEN, depthTest);
    }
}
예제 #3
0
Matrix3x4 Light::GetFullscreenQuadTransform(Camera* camera)
{
    Matrix3x4 quadTransform;
    Vector3 near, far;
    // Position the directional light quad in halfway between far & near planes to prevent depth clipping
    camera->GetFrustumSize(near, far);
    quadTransform.SetTranslation(Vector3(0.0f, 0.0f, (camera->GetNearClip() + camera->GetFarClip()) * 0.5f));
    quadTransform.SetScale(Vector3(far.x_, far.y_, 1.0f)); // Will be oversized, but doesn't matter (gets frustum clipped)
    return camera->GetEffectiveWorldTransform() * quadTransform;
}
예제 #4
0
파일: Skybox.cpp 프로젝트: Boshin/Urho3D
void Skybox::UpdateBatches(const FrameInfo& frame)
{
    distance_ = 0.0f;

    if (frame.frameNumber_ != lastFrame_)
    {
        customWorldTransforms_.Clear();
        lastFrame_ = frame.frameNumber_;
    }

    // Add camera position to fix the skybox in space. Use effective world transform to take reflection into account
    Matrix3x4 customWorldTransform = node_->GetWorldTransform();
    customWorldTransform.SetTranslation(node_->GetWorldPosition() + frame.camera_->GetEffectiveWorldTransform().Translation());
    HashMap<Camera*, Matrix3x4>::Iterator it = customWorldTransforms_.Insert(MakePair(frame.camera_, customWorldTransform));

    for (unsigned i = 0; i < batches_.Size(); ++i)
    {
        batches_[i].worldTransform_ = &it->second_;
        batches_[i].distance_ = 0.0f;
    }
}
예제 #5
0
BoundingBox NavArea::GetWorldBoundingBox() const
{
    Matrix3x4 mat;
    mat.SetTranslation(node_->GetWorldPosition());
    return boundingBox_.Transformed(mat);
}
예제 #6
0
const Matrix3x4& Sprite::GetTransform() const
{
    if (positionDirty_)
    {
        Vector2 pos = floatPosition_;

        Matrix3x4 parentTransform;

        if (parent_)
        {
            Sprite* parentSprite = dynamic_cast<Sprite*>(parent_);
            if (parentSprite)
                parentTransform = parentSprite->GetTransform();
            else
            {
                const IntVector2& parentScreenPos = parent_->GetScreenPosition() + parent_->GetChildOffset();
                parentTransform = Matrix3x4::IDENTITY;
                parentTransform.SetTranslation(Vector3((float)parentScreenPos.x_, (float)parentScreenPos.y_, 0.0f));
            }

            switch (GetHorizontalAlignment())
            {
            case HA_LEFT:
                break;

            case HA_CENTER:
                pos.x_ += (float)(parent_->GetSize().x_ / 2);
                break;

            case HA_RIGHT:
                pos.x_ += (float)parent_->GetSize().x_;
                break;
            }
            switch (GetVerticalAlignment())
            {
            case VA_TOP:
                break;

            case VA_CENTER:
                pos.y_ += (float)(parent_->GetSize().y_ / 2);
                break;

            case VA_BOTTOM:
                pos.y_ += (float)(parent_->GetSize().y_);
                break;
            }
        }
        else
            parentTransform = Matrix3x4::IDENTITY;

        Matrix3x4 hotspotAdjust(Matrix3x4::IDENTITY);
        hotspotAdjust.SetTranslation(Vector3((float)-hotSpot_.x_, (float)-hotSpot_.y_, 0.0f));

        Matrix3x4 mainTransform(Vector3(pos, 0.0f), Quaternion(rotation_, Vector3::FORWARD), Vector3(scale_, 1.0f));

        transform_ = parentTransform * mainTransform * hotspotAdjust;
        positionDirty_ = false;

        // Calculate an approximate screen position for GetElementAt(), or pixel-perfect child elements
        Vector3 topLeftCorner = transform_ * Vector3::ZERO;
        screenPosition_ = IntVector2((int)topLeftCorner.x_, (int)topLeftCorner.y_);
    }

    return transform_;
}