diff options
Diffstat (limited to 'svx/source/sdr/contact/viewcontactofe3d.cxx')
-rw-r--r-- | svx/source/sdr/contact/viewcontactofe3d.cxx | 113 |
1 files changed, 83 insertions, 30 deletions
diff --git a/svx/source/sdr/contact/viewcontactofe3d.cxx b/svx/source/sdr/contact/viewcontactofe3d.cxx index d916a5fe6b..783a008866 100644 --- a/svx/source/sdr/contact/viewcontactofe3d.cxx +++ b/svx/source/sdr/contact/viewcontactofe3d.cxx @@ -8,7 +8,7 @@ * * $RCSfile: viewcontactofe3d.cxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.2.18.1 $ * * This file is part of OpenOffice.org. * @@ -39,6 +39,45 @@ #include <svx/sdr/contact/viewcontactofe3dscene.hxx> #include <drawinglayer/attribute/sdrattribute.hxx> #include <drawinglayer/attribute/sdrattribute3d.hxx> +#include <svx/scene3d.hxx> +#include <drawinglayer/primitive3d/transformprimitive3d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + const sdr::contact::ViewContactOfE3dScene* tryToFindVCOfE3DScene( + const sdr::contact::ViewContact& rCandidate, + basegfx::B3DHomMatrix& o_rInBetweenObjectTransform) + { + const sdr::contact::ViewContactOfE3dScene* pSceneParent = + dynamic_cast< const sdr::contact::ViewContactOfE3dScene* >(rCandidate.GetParentContact()); + + if(pSceneParent) + { + // each 3d object (including in-between scenes) should have a scene as parent + const sdr::contact::ViewContactOfE3dScene* pSceneParentParent = + dynamic_cast< const sdr::contact::ViewContactOfE3dScene* >(pSceneParent->GetParentContact()); + + if(pSceneParentParent) + { + // the parent scene of rCandidate is a in-between scene, call recursively and collect + // the in-between scene's object transformation part in o_rInBetweenObjectTransform + const basegfx::B3DHomMatrix& rSceneParentTransform = pSceneParent->GetE3dScene().GetTransform(); + o_rInBetweenObjectTransform = rSceneParentTransform * o_rInBetweenObjectTransform; + return tryToFindVCOfE3DScene(*pSceneParent, o_rInBetweenObjectTransform); + } + else + { + // the parent scene is the outmost scene + return pSceneParent; + } + } + + // object hierarchy structure is incorrect; no result + return 0; + } +} // end of anonymous namespace ////////////////////////////////////////////////////////////////////////////// @@ -53,14 +92,19 @@ namespace sdr if(rxContent3D.hasElements()) { - // try to get the ViewObjectContactOfE3dScene for this single 3d object - const ViewContactOfE3dScene* pVCOfE3DScene = tryToFindVCOfE3DScene(); + // try to get the outmost ViewObjectContactOfE3dScene for this single 3d object, + // the ones on the way there are grouping scenes. Collect the in-between scene's + // transformations to build a correct object transformation for the embedded + // object + basegfx::B3DHomMatrix aInBetweenObjectTransform; + const ViewContactOfE3dScene* pVCOfE3DScene = tryToFindVCOfE3DScene(*this, aInBetweenObjectTransform); if(pVCOfE3DScene) { basegfx::B3DVector aLightNormal; const double fShadowSlant(pVCOfE3DScene->getSdrSceneAttribute().getShadowSlant()); const basegfx::B3DRange& rAllContentRange = pVCOfE3DScene->getAllContentRange3D(); + drawinglayer::geometry::ViewInformation3D aViewInformation3D(pVCOfE3DScene->getViewInformation3D()); if(pVCOfE3DScene->getSdrLightingAttribute().getLightVector().size()) { @@ -69,12 +113,25 @@ namespace sdr aLightNormal.normalize(); } + if(!aInBetweenObjectTransform.isIdentity()) + { + // if aInBetweenObjectTransform is used, create combined ViewInformation3D which + // contains the correct object transformation for the embedded 3d object + aViewInformation3D = drawinglayer::geometry::ViewInformation3D( + aViewInformation3D.getObjectTransformation() * aInBetweenObjectTransform, + aViewInformation3D.getOrientation(), + aViewInformation3D.getProjection(), + aViewInformation3D.getDeviceToView(), + aViewInformation3D.getViewTime(), + aViewInformation3D.getExtendedInformationSequence()); + } + // create embedded 2d primitive and add. LightNormal and ShadowSlant are needed for evtl. // 3D shadow extraction for correct B2DRange calculation (shadow is part of the object) const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::Embedded3DPrimitive2D( rxContent3D, pVCOfE3DScene->getObjectTransformation(), - pVCOfE3DScene->getViewInformation3D(), + aViewInformation3D, aLightNormal, fShadowSlant, rAllContentRange)); @@ -95,10 +152,10 @@ namespace sdr { } - drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3d::getViewIndependentPrimitive3DSequence() const + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3d::getVIP3DSWithoutObjectTransform() const { // local up-to-date checks. Create new list and compare. - const drawinglayer::primitive3d::Primitive3DSequence xNew(createViewIndependentPrimitive3DSequence()); + drawinglayer::primitive3d::Primitive3DSequence xNew(createViewIndependentPrimitive3DSequence()); if(!drawinglayer::primitive3d::arePrimitive3DSequencesEqual(mxViewIndependentPrimitive3DSequence, xNew)) { @@ -110,38 +167,34 @@ namespace sdr return mxViewIndependentPrimitive3DSequence; } - drawinglayer::primitive2d::Primitive2DSequence ViewContactOfE3d::createViewIndependentPrimitive2DSequence() const - { - // also need to create a 2D embedding when the view-independent part is requested, - // see view-dependent part in ViewObjectContactOfE3d::createPrimitive2DSequence - // get 3d primitive vector, isPrimitiveVisible() is done in 3d creator - return impCreateWithGivenPrimitive3DSequence(getViewIndependentPrimitive3DSequence()); - } - - const ViewContactOfE3dScene* ViewContactOfE3d::tryToFindVCOfE3DScene() const + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3d::getViewIndependentPrimitive3DSequence() const { - const ViewContact* pParent = GetParentContact(); + // get sequence without object transform + drawinglayer::primitive3d::Primitive3DSequence xRetval(getVIP3DSWithoutObjectTransform()); - if(pParent) + if(xRetval.hasElements()) { - const ViewContactOfE3dScene* pSceneParent = dynamic_cast< const ViewContactOfE3dScene* >(pParent); + // add object transform if it's used + const basegfx::B3DHomMatrix& rObjectTransform(GetE3dObject().GetTransform()); - if(pSceneParent) + if(!rObjectTransform.isIdentity()) { - return pSceneParent; - } - else - { - const ViewContactOfE3d* p3dParent = dynamic_cast< const ViewContactOfE3d* >(pParent); - - if(p3dParent) - { - return p3dParent->tryToFindVCOfE3DScene(); - } + const drawinglayer::primitive3d::Primitive3DReference xReference(new drawinglayer::primitive3d::TransformPrimitive3D( + rObjectTransform, xRetval)); + return drawinglayer::primitive3d::Primitive3DSequence(&xReference, 1); } } + + // return current Primitive2DSequence + return xRetval; + } - return 0L; + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfE3d::createViewIndependentPrimitive2DSequence() const + { + // also need to create a 2D embedding when the view-independent part is requested, + // see view-dependent part in ViewObjectContactOfE3d::createPrimitive2DSequence + // get 3d primitive vector, isPrimitiveVisible() is done in 3d creator + return impCreateWithGivenPrimitive3DSequence(getViewIndependentPrimitive3DSequence()); } ViewObjectContact& ViewContactOfE3d::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) |