ganeswidgets/src/hgtransformedquad.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 11 Jun 2010 14:43:11 +0300
changeset 5 4fa04caf0f43
parent 2 49c70dcc3f17
child 20 a60f8b6b1d32
permissions -rw-r--r--
Revision: 201021 Kit: 2010123

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:    
*
*/

#include "hgtransformedquad.h"
#include "hgquad.h"
#include "trace.h"
#include <QVector2D>
#include <QPolygon>
#include <QMatrix4x4>
#include <QPainter>

    HgTransformedQuad::HgTransformedQuad(qreal yDir) : mYDir(yDir)
    {
        
    }

    HgTransformedQuad::~HgTransformedQuad()
    {
        
    }

    int HgTransformedQuad::index() const
        {
        return mIndex;
        }

    bool HgTransformedQuad::isPointInside(const QPointF& point) const
    {    
        QPolygonF poly;
        getTransformedPoints(poly);
        QRectF rect = poly.boundingRect();
        if (rect.contains(point))
        {
            return true;
        }
        return false;
    }

    void HgTransformedQuad::transformQuad(int index, const QMatrix4x4& projView, HgQuad* quad, 
        qreal mirroringPlaneY, const QVector2D& translate, const QPointF& center, 
        const QSizeF& windowSize)
    {
        mIndex = index;
        mQuad = quad;
            
        QMatrix4x4 tm;
        tm.setToIdentity();
        tm.rotate(quad->outerRotation());

        if (mQuad->mirrorImageEnabled())
        {
            computeMirroredPoints(tm, projView, mirroringPlaneY, translate, center, windowSize);
        }
        
        tm.translate(quad->position());    
        tm.rotate(quad->rotation());    
        tm.scale(quad->scale().x(), quad->scale().y());

        tm = projView * tm;         
        
        perspectiveTransformPoints(mTransformedPoints, tm, center, windowSize);
        
        for (int i = 0; i < 4; i++)
            mTransformedPoints[i] += translate;
        
    }
    
    void HgTransformedQuad::getTransformedPoints(QPolygonF& poly) const
    {
        poly.clear();
        poly.append(mTransformedPoints[0].toPointF());
        poly.append(mTransformedPoints[1].toPointF());
        poly.append(mTransformedPoints[2].toPointF());
        poly.append(mTransformedPoints[3].toPointF());    
    }

    bool HgTransformedQuad::quadSorter(HgTransformedQuad* a, HgTransformedQuad* b)
    {
        return a->mQuad->position().z() < b->mQuad->position().z();
    }

    HgQuad* HgTransformedQuad::quad() const
    {
        return mQuad;
    }
    
    void HgTransformedQuad::computeMirroredPoints(const QMatrix4x4& trans, const QMatrix4x4& projView, 
        qreal mirroringPlaneY, const QVector2D& translate, const QPointF& center, 
        const QSizeF& windowSize)
    {
        HgQuad* quad = mQuad;

        QMatrix4x4 mirror = trans;

        qreal distToPlane = qAbs(quad->position().y() - mirroringPlaneY);
        
        mirror.translate(quad->position().x(), mirroringPlaneY - distToPlane/1, quad->position().z());
        mirror.scale(quad->scale().x(), -quad->scale().y()/1);
        mirror.rotate(quad->rotation());
            
        QMatrix4x4 modelViewProjMatrix = projView * mirror;
        
        perspectiveTransformPoints(mMirroredPoints, modelViewProjMatrix, center, windowSize);    
        
        for (int i = 0; i < 4; i++)
            mMirroredPoints[i] += translate;

    }

    void HgTransformedQuad::perspectiveTransformPoints(QVector2D* outPoints, const QMatrix4x4& matrix, 
        const QPointF& center, const QSizeF& windowSize)
    {
        const QVector4D points[] = 
        {
            QVector4D(-0.5f, -0.5f, 0.0f, 1.0f),
            QVector4D( 0.5f, -0.5f, 0.0f, 1.0f),
            QVector4D( 0.5f,  0.5f, 0.0f, 1.0f),
            QVector4D(-0.5f,  0.5f, 0.0f, 1.0f)
        };

        qreal hw = windowSize.width() * 0.5f;
        qreal hh = windowSize.height() * 0.5f;
        
        for (int i = 0; i < 4; i++)
        {
            QVector4D temp = matrix * points[i];
                                
            outPoints[i] = QVector2D(
                center.x() + temp.x() / temp.w() * hw, 
                center.y() + (temp.y() / temp.w() * hh) * mYDir);

        }
        
    }