Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  dragmt3d.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */



#include <dragmt3d.hxx>
#include <o3tl/numeric.hxx>
#include <svx/svdpagv.hxx>
#include <svx/dialmgr.hxx>
#include <svx/svddrgmt.hxx>
#include <svx/svdtrans.hxx>
#include <svx/obj3d.hxx>
#include <svx/e3dundo.hxx>
#include <svx/strings.hrc>
#include <svx/sdr/overlay/overlaypolypolygon.hxx>
#include <svx/sdr/overlay/overlaymanager.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <svx/sdr/contact/viewcontactofe3dscene.hxx>
#include <drawinglayer/geometry/viewinformation3d.hxx>
#include <svx/e3dsceneupdater.hxx>
#include <svx/view3d.hxx>
#include <vcl/ptrstyle.hxx>
#include <comphelper/lok.hxx>


E3dDragMethod::E3dDragMethod (
    SdrDragView &_rView,
    const SdrMarkList& rMark,
    E3dDragConstraint eConstr,
    bool bFull)
:   SdrDragMethod(_rView),
    meConstraint(eConstr),
    mbMoveFull(bFull),
    mbMovedAtAll(false)
{
    // Create a unit for all the 3D objects present in the selection
    const size_t nCnt(rMark.GetMarkCount());

    if(mbMoveFull)
    {
        // for non-visible 3D objects fallback to wireframe interaction
        for(size_t nObjs = 0; nObjs < nCnt; ++nObjs)
        {
            E3dObject* pE3dObj = DynCastE3dObject(rMark.GetMark(nObjs)->GetMarkedSdrObj());

            if(pE3dObj)
            {
                if(!pE3dObj->HasFillStyle() && !pE3dObj->HasLineStyle())
                {
                    mbMoveFull = false;
                    break;
                }
            }
        }
    }

    for(size_t nObjs = 0; nObjs < nCnt; ++nObjs)
    {
        E3dObject* pE3dObj = DynCastE3dObject(rMark.GetMark(nObjs)->GetMarkedSdrObj());

        if(pE3dObj)
        {
            // fill new interaction unit
            E3dDragMethodUnit aNewUnit(*pE3dObj);

            // get transformations
            aNewUnit.maInitTransform = aNewUnit.maTransform = pE3dObj->GetTransform();

            if(nullptr != pE3dObj->getParentE3dSceneFromE3dObject())
            {
                // get transform between object and world, normally scene transform
                aNewUnit.maInvDisplayTransform = aNewUnit.maDisplayTransform = pE3dObj->getParentE3dSceneFromE3dObject()->GetFullTransform();
                aNewUnit.maInvDisplayTransform.invert();
            }

            if(!mbMoveFull)
            {
                // create wireframe visualisation for parent coordinate system
                aNewUnit.maWireframePoly.clear();
                aNewUnit.maWireframePoly = pE3dObj->CreateWireframe();
                aNewUnit.maWireframePoly.transform(aNewUnit.maTransform);
            }

            // Determine FullBound
            maFullBound.Union(pE3dObj->GetSnapRect());

            // Insert Unit
            maGrp.push_back(aNewUnit);
        }
    }
}

OUString E3dDragMethod::GetSdrDragComment() const
{
    return OUString();
}

// Create the wireframe model for all actions

bool E3dDragMethod::BeginSdrDrag()
{
    if(E3dDragConstraint::Z == meConstraint)
    {
        const sal_uInt32 nCnt(maGrp.size());
        DragStat().SetRef1( maFullBound.Center() );

        for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
        {
            E3dDragMethodUnit& rCandidate = maGrp[nOb];
            rCandidate.mnStartAngle = GetAngle(DragStat().GetStart() - DragStat().GetRef1());
            rCandidate.mnLastAngle = 0_deg100;
        }
    }
    else
    {
        maLastPos = DragStat().GetStart();
    }

    if(!mbMoveFull)
    {
        Show();
    }

    return true;
}

bool E3dDragMethod::EndSdrDrag(bool /*bCopy*/)
{
    const sal_uInt32 nCnt(maGrp.size());

    if(!mbMoveFull)
    {
        // Hide wireframe
        Hide();
    }

    // Apply all transformations and create undo's
    if(mbMovedAtAll)
    {
        const bool bUndo = getSdrDragView().IsUndoEnabled();
        if( bUndo )
            getSdrDragView().BegUndo(SvxResId(RID_SVX_3D_UNDO_ROTATE));
        sal_uInt32 nOb(0);

        for(nOb=0;nOb<nCnt;nOb++)
        {
            E3dDragMethodUnit& rCandidate = maGrp[nOb];
            E3DModifySceneSnapRectUpdater aUpdater(&rCandidate.mr3DObj);
            rCandidate.mr3DObj.SetTransform(rCandidate.maTransform);
            if( bUndo )
            {
                getSdrDragView().AddUndo(
                    std::make_unique<E3dRotateUndoAction>(
                        rCandidate.mr3DObj,
                        rCandidate.maInitTransform,
                        rCandidate.maTransform));
            }
        }
        if( bUndo )
            getSdrDragView().EndUndo();
    }

    return true;
}

void E3dDragMethod::CancelSdrDrag()
{
    if(mbMoveFull)
    {
        if(mbMovedAtAll)
        {
            const sal_uInt32 nCnt(maGrp.size());

            for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
            {
                // Restore transformation
                E3dDragMethodUnit& rCandidate = maGrp[nOb];
                E3DModifySceneSnapRectUpdater aUpdater(&rCandidate.mr3DObj);
                rCandidate.mr3DObj.SetTransform(rCandidate.maInitTransform);
            }
        }
    }
    else
    {
        // Hide WireFrame
        Hide();
    }
}

// Common MoveSdrDrag()

void E3dDragMethod::MoveSdrDrag(const Point& /*rPnt*/)
{
    mbMovedAtAll = true;
}

// Draw the wire frame model

// for migration from XOR to overlay
void E3dDragMethod::CreateOverlayGeometry(
    sdr::overlay::OverlayManager& rOverlayManager,
    const sdr::contact::ObjectContact& rObjectContact, bool /* bIsGeometrySizeValid */)
{
    // We do client-side object manipulation with the Kit API
    if (comphelper::LibreOfficeKit::isActive())
        return;

    const sal_uInt32 nCnt(maGrp.size());
    basegfx::B2DPolyPolygon aResult;

    for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
    {
        E3dDragMethodUnit& rCandidate = maGrp[nOb];
        SdrPageView* pPV = getSdrDragView().GetSdrPageView();

        if(pPV && pPV->HasMarkedObjPageView())
        {
            const basegfx::B3DPolyPolygon aCandidate(rCandidate.maWireframePoly);
            const sal_uInt32 nPlyCnt(aCandidate.count());

            if(nPlyCnt)
            {
                const E3dScene* pScene(rCandidate.mr3DObj.getRootE3dSceneFromE3dObject());

                if(nullptr != pScene)
                {
                    const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
                    const drawinglayer::geometry::ViewInformation3D& aViewInfo3D(rVCScene.getViewInformation3D());
                    const basegfx::B3DHomMatrix aWorldToView(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection() * aViewInfo3D.getOrientation());
                    const basegfx::B3DHomMatrix aTransform(aWorldToView * rCandidate.maDisplayTransform);

                    // transform to relative scene coordinates
                    basegfx::B2DPolyPolygon aPolyPolygon(basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(aCandidate, aTransform));

                    // transform to 2D view coordinates
                    aPolyPolygon.transform(rVCScene.getObjectTransformation());

                    aResult.append(aPolyPolygon);
                }
            }
        }
    }

    if(aResult.count())
    {
        std::unique_ptr<sdr::overlay::OverlayPolyPolygonStripedAndFilled> pNew(
            new sdr::overlay::OverlayPolyPolygonStripedAndFilled(
                std::move(aResult)));

        insertNewlyCreatedOverlayObjectForSdrDragMethod(
            std::move(pNew),
            rObjectContact,
            rOverlayManager);
    }
}


E3dDragRotate::E3dDragRotate(SdrDragView &_rView,
    const SdrMarkList& rMark,
    E3dDragConstraint eConstr,
    bool bFull)
:   E3dDragMethod(_rView, rMark, eConstr, bFull)
{
    // Get center of all selected objects in eye coordinates
    const sal_uInt32 nCnt(maGrp.size());

    if(!nCnt)
        return;

    const E3dScene* pScene(maGrp[0].mr3DObj.getRootE3dSceneFromE3dObject());

    if(nullptr == pScene)
        return;

    const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
    const drawinglayer::geometry::ViewInformation3D& aViewInfo3D(rVCScene.getViewInformation3D());

    for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
    {
        E3dDragMethodUnit& rCandidate = maGrp[nOb];
        basegfx::B3DPoint aObjCenter = rCandidate.mr3DObj.GetBoundVolume().getCenter();
        const basegfx::B3DHomMatrix aTransform(aViewInfo3D.getOrientation() * rCandidate.maDisplayTransform * rCandidate.maInitTransform);

        aObjCenter = aTransform * aObjCenter;
        maGlobalCenter += aObjCenter;
    }

    // Divide by the number
    if(nCnt > 1)
    {
        maGlobalCenter /= static_cast<double>(nCnt);
    }

    // get rotate center and transform to 3D eye coordinates
    basegfx::B2DPoint aRotCenter2D(Ref1().X(), Ref1().Y());

    // from world to relative scene using inverse getObjectTransformation()
    basegfx::B2DHomMatrix aInverseObjectTransform(rVCScene.getObjectTransformation());
    aInverseObjectTransform.invert();
    aRotCenter2D = aInverseObjectTransform * aRotCenter2D;

    // from 3D view to 3D eye
    basegfx::B3DPoint aRotCenter3D(aRotCenter2D.getX(), aRotCenter2D.getY(), 0.0);
    basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection());
    aInverseViewToEye.invert();
    aRotCenter3D = aInverseViewToEye * aRotCenter3D;

// Use X,Y of the RotCenter and depth of the common object centre
// as rotation point in the space
    maGlobalCenter.setX(aRotCenter3D.getX());
    maGlobalCenter.setY(aRotCenter3D.getY());
}


//The object is moved, determine the angle

void E3dDragRotate::MoveSdrDrag(const Point& rPnt)
{
    // call parent
    E3dDragMethod::MoveSdrDrag(rPnt);

    if(!DragStat().CheckMinMoved(rPnt))
        return;

    // Get modifier
    sal_uInt16 nModifier = 0;
    if(auto pDragView = dynamic_cast<const E3dView*>(&getSdrDragView()))
    {
        const MouseEvent& rLastMouse = pDragView->GetMouseEvent();
        nModifier = rLastMouse.GetModifier();
    }

    // Rotate all objects
    const sal_uInt32 nCnt(maGrp.size());

    for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
    {
        // Determine rotation angle
        double fWAngle, fHAngle;
        E3dDragMethodUnit& rCandidate = maGrp[nOb];

        if(E3dDragConstraint::Z == meConstraint)
        {
            Degree100 lastAngle = NormAngle36000(GetAngle(rPnt - DragStat().GetRef1()) -
                rCandidate.mnStartAngle) - rCandidate.mnLastAngle;
            rCandidate.mnLastAngle = lastAngle + rCandidate.mnLastAngle;
            fWAngle = toDegrees(lastAngle);
            fHAngle = 0.0;
        }
        else
        {
            if ((maFullBound.GetWidth() == 0) || (maFullBound.GetHeight() == 0))
                throw o3tl::divide_by_zero();
            fWAngle = 90.0 * static_cast<double>(rPnt.X() - maLastPos.X())
                / static_cast<double>(maFullBound.GetWidth());
            fHAngle = 90.0 * static_cast<double>(rPnt.Y() - maLastPos.Y())
                / static_cast<double>(maFullBound.GetHeight());
        }
        tools::Long nSnap = 0;

        if(!getSdrDragView().IsRotateAllowed())
            nSnap = 90;

        if(nSnap != 0)
        {
            fWAngle = static_cast<double>((static_cast<tools::Long>(fWAngle) + nSnap/2) / nSnap * nSnap);
            fHAngle = static_cast<double>((static_cast<tools::Long>(fHAngle) + nSnap/2) / nSnap * nSnap);
        }

        // to radians
        fWAngle = basegfx::deg2rad(fWAngle);
        fHAngle = basegfx::deg2rad(fHAngle);

        // Determine transformation
        basegfx::B3DHomMatrix aRotMat;
        if(E3dDragConstraint::Y & meConstraint)
        {
            if(nModifier & KEY_MOD2)
                aRotMat.rotate(0.0, 0.0, fWAngle);
            else
                aRotMat.rotate(0.0, fWAngle, 0.0);
        }
        else if(E3dDragConstraint::Z & meConstraint)
        {
            if(nModifier & KEY_MOD2)
                aRotMat.rotate(0.0, fWAngle, 0.0);
            else
                aRotMat.rotate(0.0, 0.0, fWAngle);
        }
        if(E3dDragConstraint::X & meConstraint)
        {
            aRotMat.rotate(fHAngle, 0.0, 0.0);
        }

        const E3dScene* pScene(rCandidate.mr3DObj.getRootE3dSceneFromE3dObject());

        if(nullptr != pScene)
        {
            // Transformation in eye coordinates, there rotate then and back
            const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
            const drawinglayer::geometry::ViewInformation3D& aViewInfo3D(rVCScene.getViewInformation3D());
            basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
            aInverseOrientation.invert();

            basegfx::B3DHomMatrix aTransMat(rCandidate.maDisplayTransform);
            aTransMat *= aViewInfo3D.getOrientation();
            aTransMat.translate(-maGlobalCenter.getX(), -maGlobalCenter.getY(), -maGlobalCenter.getZ());
            aTransMat *= aRotMat;
            aTransMat.translate(maGlobalCenter.getX(), maGlobalCenter.getY(), maGlobalCenter.getZ());
            aTransMat *= aInverseOrientation;
            aTransMat *= rCandidate.maInvDisplayTransform;

            // ...and apply
            rCandidate.maTransform *= aTransMat;

            if(mbMoveFull)
            {
                E3DModifySceneSnapRectUpdater aUpdater(&rCandidate.mr3DObj);
                rCandidate.mr3DObj.SetTransform(rCandidate.maTransform);
            }
            else
            {
                Hide();
                rCandidate.maWireframePoly.transform(aTransMat);
                Show();
            }
        }
    }
    maLastPos = rPnt;
    DragStat().NextMove(rPnt);
}

PointerStyle E3dDragRotate::GetSdrDragPointer() const
{
    return PointerStyle::Rotate;
}

// E3dDragMove. This drag method is only required for translations inside
// 3D scenes. If a 3D-scene itself moved, then this drag method will drag
// not be used.


E3dDragMove::E3dDragMove(SdrDragView &_rView,
    const SdrMarkList& rMark,
    SdrHdlKind eDrgHdl,
    E3dDragConstraint eConstr,
    bool bFull)
:   E3dDragMethod(_rView, rMark, eConstr, bFull),
    meWhatDragHdl(eDrgHdl)
{
    switch(meWhatDragHdl)
    {
        case SdrHdlKind::Left:
            maScaleFixPos = maFullBound.RightCenter();
            break;
        case SdrHdlKind::Right:
            maScaleFixPos = maFullBound.LeftCenter();
            break;
        case SdrHdlKind::Upper:
            maScaleFixPos = maFullBound.BottomCenter();
            break;
        case SdrHdlKind::Lower:
            maScaleFixPos = maFullBound.TopCenter();
            break;
        case SdrHdlKind::UpperLeft:
            maScaleFixPos = maFullBound.BottomRight();
            break;
        case SdrHdlKind::UpperRight:
            maScaleFixPos = maFullBound.BottomLeft();
            break;
        case SdrHdlKind::LowerLeft:
            maScaleFixPos = maFullBound.TopRight();
            break;
        case SdrHdlKind::LowerRight:
            maScaleFixPos = maFullBound.TopLeft();
            break;
        default:
            // Moving the object, SdrHdlKind::Move
            break;
    }

    // Override when IsResizeAtCenter()
    if(getSdrDragView().IsResizeAtCenter())
    {
        meWhatDragHdl = SdrHdlKind::User;
        maScaleFixPos = maFullBound.Center();
    }
}

// The object is moved, determine the translations

void E3dDragMove::MoveSdrDrag(const Point& rPnt)
{
    // call parent
    E3dDragMethod::MoveSdrDrag(rPnt);

    if(!DragStat().CheckMinMoved(rPnt))
        return;

    if(SdrHdlKind::Move == meWhatDragHdl)
    {
        // Translation
        // Determine the motion vector
        const sal_uInt32 nCnt(maGrp.size());

        // Get modifier
        sal_uInt16 nModifier(0);

        if(auto pDragView = dynamic_cast<const E3dView*>(&getSdrDragView()))
        {
            const MouseEvent& rLastMouse = pDragView->GetMouseEvent();
            nModifier = rLastMouse.GetModifier();
        }

        for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
        {
            E3dDragMethodUnit& rCandidate = maGrp[nOb];
            const E3dScene* pScene(rCandidate.mr3DObj.getRootE3dSceneFromE3dObject());

            if(nullptr != pScene)
            {
                const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
                const drawinglayer::geometry::ViewInformation3D& aViewInfo3D(rVCScene.getViewInformation3D());

                // move coor from 2d world to 3d Eye
                basegfx::B2DPoint aGlobalMoveHead2D(static_cast<double>(rPnt.X() - maLastPos.X()), static_cast<double>(rPnt.Y() - maLastPos.Y()));
                basegfx::B2DPoint aGlobalMoveTail2D(0.0, 0.0);
                basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation());

                aInverseSceneTransform.invert();
                aGlobalMoveHead2D = aInverseSceneTransform * aGlobalMoveHead2D;
                aGlobalMoveTail2D = aInverseSceneTransform * aGlobalMoveTail2D;

                basegfx::B3DPoint aMoveHead3D(aGlobalMoveHead2D.getX(), aGlobalMoveHead2D.getY(), 0.5);
                basegfx::B3DPoint aMoveTail3D(aGlobalMoveTail2D.getX(), aGlobalMoveTail2D.getY(), 0.5);
                basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection());
                aInverseViewToEye.invert();

                aMoveHead3D = aInverseViewToEye * aMoveHead3D;
                aMoveTail3D = aInverseViewToEye * aMoveTail3D;

                // eventually switch movement from XY to XZ plane
                if(nModifier & KEY_MOD2)
                {
                    double fZwi = aMoveHead3D.getY();
                    aMoveHead3D.setY(aMoveHead3D.getZ());
                    aMoveHead3D.setZ(fZwi);

                    fZwi = aMoveTail3D.getY();
                    aMoveTail3D.setY(aMoveTail3D.getZ());
                    aMoveTail3D.setZ(fZwi);
                }

                // Motion vector from eye coordinates to parent coordinates
                basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
                aInverseOrientation.invert();
                basegfx::B3DHomMatrix aCompleteTrans(rCandidate.maInvDisplayTransform * aInverseOrientation);

                aMoveHead3D = aCompleteTrans * aMoveHead3D;
                aMoveTail3D = aCompleteTrans* aMoveTail3D;

                // build transformation
                basegfx::B3DHomMatrix aTransMat;
                basegfx::B3DPoint aTranslate(aMoveHead3D - aMoveTail3D);
                aTransMat.translate(aTranslate.getX(), aTranslate.getY(), aTranslate.getZ());

                // ...and apply
                rCandidate.maTransform *= aTransMat;

                if(mbMoveFull)
                {
                    E3DModifySceneSnapRectUpdater aUpdater(&rCandidate.mr3DObj);
                    rCandidate.mr3DObj.SetTransform(rCandidate.maTransform);
                }
                else
                {
                    Hide();
                    rCandidate.maWireframePoly.transform(aTransMat);
                    Show();
                }
            }
        }
    }
    else
    {
        // Scaling
        // Determine scaling vector
        Point aStartPos = DragStat().GetStart();
        const sal_uInt32 nCnt(maGrp.size());

        for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
        {
            E3dDragMethodUnit& rCandidate = maGrp[nOb];
            const basegfx::B3DPoint aObjectCenter(rCandidate.mr3DObj.GetBoundVolume().getCenter());
            const E3dScene* pScene(rCandidate.mr3DObj.getRootE3dSceneFromE3dObject());

            if(nullptr != pScene)
            {
                // transform from 2D world view to 3D eye
                const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
                const drawinglayer::geometry::ViewInformation3D& aViewInfo3D(rVCScene.getViewInformation3D());

                basegfx::B2DPoint aGlobalScaleStart2D(static_cast<double>(aStartPos.X()), static_cast<double>(aStartPos.Y()));
                basegfx::B2DPoint aGlobalScaleNext2D(static_cast<double>(rPnt.X()), static_cast<double>(rPnt.Y()));
                basegfx::B2DPoint aGlobalScaleFixPos2D(static_cast<double>(maScaleFixPos.X()), static_cast<double>(maScaleFixPos.Y()));
                basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation());

                aInverseSceneTransform.invert();
                aGlobalScaleStart2D = aInverseSceneTransform * aGlobalScaleStart2D;
                aGlobalScaleNext2D = aInverseSceneTransform * aGlobalScaleNext2D;
                aGlobalScaleFixPos2D = aInverseSceneTransform * aGlobalScaleFixPos2D;

                basegfx::B3DPoint aGlobalScaleStart3D(aGlobalScaleStart2D.getX(), aGlobalScaleStart2D.getY(), aObjectCenter.getZ());
                basegfx::B3DPoint aGlobalScaleNext3D(aGlobalScaleNext2D.getX(), aGlobalScaleNext2D.getY(), aObjectCenter.getZ());
                basegfx::B3DPoint aGlobalScaleFixPos3D(aGlobalScaleFixPos2D.getX(), aGlobalScaleFixPos2D.getY(), aObjectCenter.getZ());
                basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection());

                aInverseViewToEye.invert();
                basegfx::B3DPoint aScStart(aInverseViewToEye * aGlobalScaleStart3D);
                basegfx::B3DPoint aScNext(aInverseViewToEye * aGlobalScaleNext3D);
                basegfx::B3DPoint aScFixPos(aInverseViewToEye * aGlobalScaleFixPos3D);

                // constraints?
                switch(meWhatDragHdl)
                {
                    case SdrHdlKind::Left:
                    case SdrHdlKind::Right:
                        // to constrain on X -> Y equal
                        aScNext.setY(aScFixPos.getY());
                        break;
                    case SdrHdlKind::Upper:
                    case SdrHdlKind::Lower:
                        // constrain to Y -> X equal
                        aScNext.setX(aScFixPos.getX());
                        break;
                    default:
                        break;
                }

                // get scale vector in eye coordinates
                basegfx::B3DPoint aScaleVec(aScStart - aScFixPos);
                aScaleVec.setZ(1.0);

                if(aScaleVec.getX() != 0.0)
                {
                    aScaleVec.setX((aScNext.getX() - aScFixPos.getX()) / aScaleVec.getX());
                }
                else
                {
                    aScaleVec.setX(1.0);
                }

                if(aScaleVec.getY() != 0.0)
                {
                    aScaleVec.setY((aScNext.getY() - aScFixPos.getY()) / aScaleVec.getY());
                }
                else
                {
                    aScaleVec.setY(1.0);
                }

                // SHIFT-key used?
                if(getSdrDragView().IsOrtho())
                {
                    if(fabs(aScaleVec.getX()) > fabs(aScaleVec.getY()))
                    {
                        // X is biggest
                        aScaleVec.setY(aScaleVec.getX());
                    }
                    else
                    {
                        // Y is biggest
                        aScaleVec.setX(aScaleVec.getY());
                    }
                }

                // build transformation
                basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
                aInverseOrientation.invert();

                basegfx::B3DHomMatrix aNewTrans = rCandidate.maInitTransform;
                aNewTrans *= rCandidate.maDisplayTransform;
                aNewTrans *= aViewInfo3D.getOrientation();
                aNewTrans.translate(-aScFixPos.getX(), -aScFixPos.getY(), -aScFixPos.getZ());
                aNewTrans.scale(aScaleVec.getX(), aScaleVec.getY(), aScaleVec.getZ());
                aNewTrans.translate(aScFixPos.getX(), aScFixPos.getY(), aScFixPos.getZ());
                aNewTrans *= aInverseOrientation;
                aNewTrans *= rCandidate.maInvDisplayTransform;

                // ...and apply
                rCandidate.maTransform = std::move(aNewTrans);

                if(mbMoveFull)
                {
                    E3DModifySceneSnapRectUpdater aUpdater(&rCandidate.mr3DObj);
                    rCandidate.mr3DObj.SetTransform(rCandidate.maTransform);
                }
                else
                {
                    Hide();
                    rCandidate.maWireframePoly.clear();
                    rCandidate.maWireframePoly = rCandidate.mr3DObj.CreateWireframe();
                    rCandidate.maWireframePoly.transform(rCandidate.maTransform);
                    Show();
                }
            }
        }
    }
    maLastPos = rPnt;
    DragStat().NextMove(rPnt);
}

PointerStyle E3dDragMove::GetSdrDragPointer() const
{
    return PointerStyle::Move;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=92 H=98 G=94

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge