summaryrefslogtreecommitdiff
path: root/svx/source/sdr/contact/viewcontactofe3d.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/sdr/contact/viewcontactofe3d.cxx')
-rw-r--r--svx/source/sdr/contact/viewcontactofe3d.cxx113
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)