1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ximp3dscene.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmloff.hxx"
33 #include "ximp3dscene.hxx"
34 #include <xmloff/xmluconv.hxx>
35 #include "xexptran.hxx"
36 #include <xmloff/xmltoken.hxx>
37 #include "xmlnmspe.hxx"
38 #include <com/sun/star/drawing/Direction3D.hpp>
39 #include <com/sun/star/drawing/CameraGeometry.hpp>
40 #include "eventimp.hxx"
41 #include "descriptionimp.hxx"
43 using ::rtl::OUString
;
44 using ::rtl::OUStringBuffer
;
46 using namespace ::com::sun::star
;
47 using namespace ::xmloff::token
;
49 //////////////////////////////////////////////////////////////////////////////
50 // dr3d:3dlight context
52 SdXML3DLightContext::SdXML3DLightContext(
55 const rtl::OUString
& rLName
,
56 const com::sun::star::uno::Reference
< com::sun::star::xml::sax::XAttributeList
>& xAttrList
)
57 : SvXMLImportContext( rImport
, nPrfx
, rLName
),
58 maDiffuseColor(0x00000000),
59 maDirection(0.0, 0.0, 1.0),
63 // read attributes for the 3DScene
64 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
65 for(sal_Int16 i
=0; i
< nAttrCount
; i
++)
67 OUString sAttrName
= xAttrList
->getNameByIndex( i
);
69 sal_uInt16 nPrefix
= GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName
, &aLocalName
);
70 OUString sValue
= xAttrList
->getValueByIndex( i
);
71 const SvXMLTokenMap
& rAttrTokenMap
= GetImport().GetShapeImport()->Get3DLightAttrTokenMap();
73 switch(rAttrTokenMap
.Get(nPrefix
, aLocalName
))
75 case XML_TOK_3DLIGHT_DIFFUSE_COLOR
:
77 GetImport().GetMM100UnitConverter().convertColor(maDiffuseColor
, sValue
);
80 case XML_TOK_3DLIGHT_DIRECTION
:
82 GetImport().GetMM100UnitConverter().convertB3DVector(maDirection
, sValue
);
85 case XML_TOK_3DLIGHT_ENABLED
:
87 GetImport().GetMM100UnitConverter().convertBool(mbEnabled
, sValue
);
90 case XML_TOK_3DLIGHT_SPECULAR
:
92 GetImport().GetMM100UnitConverter().convertBool(mbSpecular
, sValue
);
99 SdXML3DLightContext::~SdXML3DLightContext()
103 //////////////////////////////////////////////////////////////////////////////
105 TYPEINIT1( SdXML3DSceneShapeContext
, SdXMLShapeContext
);
107 SdXML3DSceneShapeContext::SdXML3DSceneShapeContext(
108 SvXMLImport
& rImport
,
110 const OUString
& rLocalName
,
111 const com::sun::star::uno::Reference
< com::sun::star::xml::sax::XAttributeList
>& xAttrList
,
112 uno::Reference
< drawing::XShapes
>& rShapes
,
113 sal_Bool bTemporaryShapes
)
114 : SdXMLShapeContext( rImport
, nPrfx
, rLocalName
, xAttrList
, rShapes
, bTemporaryShapes
), SdXML3DSceneAttributesHelper( rImport
)
118 //////////////////////////////////////////////////////////////////////////////
120 SdXML3DSceneShapeContext::~SdXML3DSceneShapeContext()
124 //////////////////////////////////////////////////////////////////////////////
126 void SdXML3DSceneShapeContext::StartElement(const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
128 // create new 3DScene shape and add it to rShapes, use it
129 // as base for the new 3DScene import
130 AddShape( "com.sun.star.drawing.Shape3DSceneObject" );
135 mxChilds
= uno::Reference
< drawing::XShapes
>::query( mxShape
);
137 GetImport().GetShapeImport()->pushGroupForSorting( mxChilds
);
141 // set pos, size, shear and rotate
145 // read attributes for the 3DScene
146 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
147 for(sal_Int16 i
=0; i
< nAttrCount
; i
++)
149 OUString sAttrName
= xAttrList
->getNameByIndex( i
);
151 sal_uInt16 nPrefix
= GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName
, &aLocalName
);
152 OUString sValue
= xAttrList
->getValueByIndex( i
);
153 processSceneAttribute( nPrefix
, aLocalName
, sValue
);
156 // #91047# call parent function is missing here, added it
160 SdXMLShapeContext::StartElement(xAttrList
);
164 //////////////////////////////////////////////////////////////////////////////
166 void SdXML3DSceneShapeContext::EndElement()
170 uno::Reference
< beans::XPropertySet
> xPropSet(mxShape
, uno::UNO_QUERY
);
173 setSceneAttributes( xPropSet
);
177 GetImport().GetShapeImport()->popGroupAndSort();
180 SdXMLShapeContext::EndElement();
184 //////////////////////////////////////////////////////////////////////////////
186 SvXMLImportContext
* SdXML3DSceneShapeContext::CreateChildContext( USHORT nPrefix
,
187 const OUString
& rLocalName
,
188 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
190 SvXMLImportContext
* pContext
= 0L;
193 if( nPrefix
== XML_NAMESPACE_SVG
&&
194 (IsXMLToken( rLocalName
, XML_TITLE
) || IsXMLToken( rLocalName
, XML_DESC
) ) )
196 pContext
= new SdXMLDescriptionContext( GetImport(), nPrefix
, rLocalName
, xAttrList
, mxShape
);
198 else if( nPrefix
== XML_NAMESPACE_OFFICE
&& IsXMLToken( rLocalName
, XML_EVENT_LISTENERS
) )
200 pContext
= new SdXMLEventsContext( GetImport(), nPrefix
, rLocalName
, xAttrList
, mxShape
);
202 // look for local light context first
203 else if(nPrefix
== XML_NAMESPACE_DR3D
&& IsXMLToken( rLocalName
, XML_LIGHT
) )
205 // dr3d:light inside dr3d:scene context
206 pContext
= create3DLightContext( nPrefix
, rLocalName
, xAttrList
);
209 // call GroupChildContext function at common ShapeImport
212 pContext
= GetImport().GetShapeImport()->Create3DSceneChildContext(
213 GetImport(), nPrefix
, rLocalName
, xAttrList
, mxChilds
);
216 // call parent when no own context was created
219 pContext
= SvXMLImportContext::CreateChildContext(
220 nPrefix
, rLocalName
, xAttrList
);
226 //////////////////////////////////////////////////////////////////////////////
228 SdXML3DSceneAttributesHelper::SdXML3DSceneAttributesHelper( SvXMLImport
& rImporter
)
229 : mrImport( rImporter
),
230 mbSetTransform( FALSE
),
231 mxPrjMode(drawing::ProjectionMode_PERSPECTIVE
),
235 mxShadeMode(drawing::ShadeMode_SMOOTH
),
236 maAmbientColor(0x00666666),
237 mbLightingMode(FALSE
),
238 maVRP(0.0, 0.0, 1.0),
239 maVPN(0.0, 0.0, 1.0),
240 maVUP(0.0, 1.0, 0.0),
247 SdXML3DSceneAttributesHelper::~SdXML3DSceneAttributesHelper()
249 // release remembered light contexts, they are no longer needed
250 while(maList
.Count())
251 maList
.Remove(maList
.Count() - 1)->ReleaseRef();
254 /** creates a 3d ligth context and adds it to the internal list for later processing */
255 SvXMLImportContext
* SdXML3DSceneAttributesHelper::create3DLightContext( sal_uInt16 nPrfx
, const rtl::OUString
& rLName
, const com::sun::star::uno::Reference
< com::sun::star::xml::sax::XAttributeList
>& xAttrList
)
257 SvXMLImportContext
* pContext
= new SdXML3DLightContext(mrImport
, nPrfx
, rLName
, xAttrList
);
259 // remember SdXML3DLightContext for later evaluation
263 maList
.Insert((SdXML3DLightContext
*)pContext
, LIST_APPEND
);
269 /** this should be called for each scene attribute */
270 void SdXML3DSceneAttributesHelper::processSceneAttribute( sal_uInt16 nPrefix
, const ::rtl::OUString
& rLocalName
, const ::rtl::OUString
& rValue
)
272 if( XML_NAMESPACE_DR3D
== nPrefix
)
274 if( IsXMLToken( rLocalName
, XML_TRANSFORM
) )
276 SdXMLImExTransform3D
aTransform(rValue
, mrImport
.GetMM100UnitConverter());
277 if(aTransform
.NeedsAction())
278 mbSetTransform
= aTransform
.GetFullHomogenTransform(mxHomMat
);
281 else if( IsXMLToken( rLocalName
, XML_VRP
) )
283 ::basegfx::B3DVector aNewVec
;
284 mrImport
.GetMM100UnitConverter().convertB3DVector(aNewVec
, rValue
);
293 else if( IsXMLToken( rLocalName
, XML_VPN
) )
295 ::basegfx::B3DVector aNewVec
;
296 mrImport
.GetMM100UnitConverter().convertB3DVector(aNewVec
, rValue
);
305 else if( IsXMLToken( rLocalName
, XML_VUP
) )
307 ::basegfx::B3DVector aNewVec
;
308 mrImport
.GetMM100UnitConverter().convertB3DVector(aNewVec
, rValue
);
317 else if( IsXMLToken( rLocalName
, XML_PROJECTION
) )
319 if( IsXMLToken( rValue
, XML_PARALLEL
) )
320 mxPrjMode
= drawing::ProjectionMode_PARALLEL
;
322 mxPrjMode
= drawing::ProjectionMode_PERSPECTIVE
;
325 else if( IsXMLToken( rLocalName
, XML_DISTANCE
) )
327 mrImport
.GetMM100UnitConverter().convertMeasure(mnDistance
, rValue
);
330 else if( IsXMLToken( rLocalName
, XML_FOCAL_LENGTH
) )
332 mrImport
.GetMM100UnitConverter().convertMeasure(mnFocalLength
, rValue
);
335 else if( IsXMLToken( rLocalName
, XML_SHADOW_SLANT
) )
337 mrImport
.GetMM100UnitConverter().convertNumber(mnShadowSlant
, rValue
);
340 else if( IsXMLToken( rLocalName
, XML_SHADE_MODE
) )
342 if( IsXMLToken( rValue
, XML_FLAT
) )
343 mxShadeMode
= drawing::ShadeMode_FLAT
;
344 else if( IsXMLToken( rValue
, XML_PHONG
) )
345 mxShadeMode
= drawing::ShadeMode_PHONG
;
346 else if( IsXMLToken( rValue
, XML_GOURAUD
) )
347 mxShadeMode
= drawing::ShadeMode_SMOOTH
;
349 mxShadeMode
= drawing::ShadeMode_DRAFT
;
352 else if( IsXMLToken( rLocalName
, XML_AMBIENT_COLOR
) )
354 mrImport
.GetMM100UnitConverter().convertColor(maAmbientColor
, rValue
);
357 else if( IsXMLToken( rLocalName
, XML_LIGHTING_MODE
) )
359 mrImport
.GetMM100UnitConverter().convertBool(mbLightingMode
, rValue
);
365 /** this sets the scene attributes at this propertyset */
366 void SdXML3DSceneAttributesHelper::setSceneAttributes( const com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
>& xPropSet
)
370 // world transformation
374 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DTransformMatrix")), aAny
);
379 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneDistance")), aAny
);
382 aAny
<<= mnFocalLength
;
383 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneFocalLength")), aAny
);
386 aAny
<<= (sal_Int16
)mnShadowSlant
;
387 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneShadowSlant")), aAny
);
390 aAny
<<= mxShadeMode
;
391 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneShadeMode")), aAny
);
394 aAny
<<= maAmbientColor
.GetColor();
395 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneAmbientColor")), aAny
);
398 aAny
<<= mbLightingMode
;
399 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneTwoSidedLighting")), aAny
);
407 for(sal_uInt32
a(0L); a
< maList
.Count(); a
++)
409 SdXML3DLightContext
* pCtx
= (SdXML3DLightContext
*)maList
.GetObject(a
);
412 aAny
<<= pCtx
->GetDiffuseColor().GetColor();
413 drawing::Direction3D xLightDir
;
414 xLightDir
.DirectionX
= pCtx
->GetDirection().getX();
415 xLightDir
.DirectionY
= pCtx
->GetDirection().getY();
416 xLightDir
.DirectionZ
= pCtx
->GetDirection().getZ();
418 aAny3
<<= pCtx
->GetEnabled();
424 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor1")), aAny
);
425 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection1")), aAny2
);
426 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn1")), aAny3
);
431 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor2")), aAny
);
432 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection2")), aAny2
);
433 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn2")), aAny3
);
438 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor3")), aAny
);
439 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection3")), aAny2
);
440 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn3")), aAny3
);
445 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor4")), aAny
);
446 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection4")), aAny2
);
447 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn4")), aAny3
);
452 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor5")), aAny
);
453 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection5")), aAny2
);
454 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn5")), aAny3
);
459 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor6")), aAny
);
460 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection6")), aAny2
);
461 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn6")), aAny3
);
466 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor7")), aAny
);
467 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection7")), aAny2
);
468 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn7")), aAny3
);
473 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor8")), aAny
);
474 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection8")), aAny2
);
475 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn8")), aAny3
);
482 // CameraGeometry and camera settings
483 drawing::CameraGeometry aCamGeo
;
484 aCamGeo
.vrp
.PositionX
= maVRP
.getX();
485 aCamGeo
.vrp
.PositionY
= maVRP
.getY();
486 aCamGeo
.vrp
.PositionZ
= maVRP
.getZ();
487 aCamGeo
.vpn
.DirectionX
= maVPN
.getX();
488 aCamGeo
.vpn
.DirectionY
= maVPN
.getY();
489 aCamGeo
.vpn
.DirectionZ
= maVPN
.getZ();
490 aCamGeo
.vup
.DirectionX
= maVUP
.getX();
491 aCamGeo
.vup
.DirectionY
= maVUP
.getY();
492 aCamGeo
.vup
.DirectionZ
= maVUP
.getZ();
494 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DCameraGeometry")), aAny
);
496 // #91047# set drawing::ProjectionMode AFTER camera geometry is set
497 // projection "D3DScenePerspective" drawing::ProjectionMode
499 xPropSet
->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DScenePerspective")), aAny
);