1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "OGLTrans_TransitionImpl.hxx" 29 #include "OGLTrans_Shaders.hxx" 30 #include <GL/gl.h> 31 #include <math.h> 32 33 34 void OGLTransitionImpl::clear() 35 { 36 for(unsigned int i( 0 ); i < OverallOperations.size(); ++i) 37 delete OverallOperations[i]; 38 OverallOperations.clear(); 39 maLeavingSlidePrimitives.clear(); 40 maEnteringSlidePrimitives.clear(); 41 for(unsigned int i(0); i < maSceneObjects.size(); ++i) 42 delete maSceneObjects[i]; 43 maSceneObjects.clear(); 44 45 mbReflectSlides = false; 46 47 #ifdef GL_VERSION_2_0 48 if( mProgramObject ) { 49 OGLShaders::glDeleteProgram( mProgramObject ); 50 mProgramObject = 0; 51 } 52 53 if( mVertexObject ) { 54 OGLShaders::glDeleteShader( mVertexObject ); 55 mVertexObject = 0; 56 } 57 58 if( mFragmentObject ) { 59 OGLShaders::glDeleteShader( mFragmentObject ); 60 mFragmentObject = 0; 61 } 62 #endif 63 64 if( maHelperTexture ) { 65 glDeleteTextures( 1, &maHelperTexture ); 66 maHelperTexture = 0; 67 } 68 69 if( mmClearTransition ) 70 (this->*mmClearTransition)(); 71 } 72 73 OGLTransitionImpl::~OGLTransitionImpl() 74 { 75 clear(); 76 } 77 78 void OGLTransitionImpl::prepare( ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex ) 79 { 80 for(unsigned int i(0); i < maSceneObjects.size(); ++i) { 81 maSceneObjects[i]->prepare(); 82 } 83 84 if( mmPrepareTransition ) 85 (this->*mmPrepareTransition)( glLeavingSlideTex, glEnteringSlideTex ); 86 } 87 88 void OGLTransitionImpl::finish() 89 { 90 for(unsigned int i(0); i < maSceneObjects.size(); ++i) { 91 maSceneObjects[i]->finish(); 92 } 93 } 94 95 static void blendSlide( double depth ) 96 { 97 double showHeight = -1 + depth*2; 98 GLfloat reflectionColor[] = {0, 0, 0, 0.25}; 99 100 glDisable( GL_DEPTH_TEST ); 101 glBegin( GL_QUADS ); 102 glColor4fv( reflectionColor ); 103 glVertex3f( -1, -1, 0 ); 104 glColor4f( 0, 0, 0, 1 ); 105 glVertex3f(-1, showHeight, 0 ); 106 glVertex3f( 1, showHeight, 0 ); 107 glColor4fv( reflectionColor ); 108 glVertex3f( 1, -1, 0 ); 109 glEnd(); 110 111 glBegin( GL_QUADS ); 112 glColor4f( 0, 0, 0, 1 ); 113 glVertex3f( -1, showHeight, 0 ); 114 glVertex3f( -1, 1, 0 ); 115 glVertex3f( 1, 1, 0 ); 116 glVertex3f( 1, showHeight, 0 ); 117 glEnd(); 118 glEnable( GL_DEPTH_TEST ); 119 } 120 121 static void slideShadow( double nTime, Primitive& primitive, double sw, double sh ) 122 { 123 double reflectionDepth = 0.3; 124 125 glEnable(GL_BLEND); 126 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 127 glDisable(GL_LIGHTING); 128 129 glPushMatrix(); 130 primitive.applyOperations( nTime, sw, sh ); 131 blendSlide( reflectionDepth ); 132 glPopMatrix(); 133 134 glDisable(GL_BLEND); 135 glEnable(GL_LIGHTING); 136 } 137 138 void OGLTransitionImpl::display( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, 139 double SlideWidth, double SlideHeight, double DispWidth, double DispHeight ) 140 { 141 double SlideWidthScale, SlideHeightScale; 142 143 SlideWidthScale = SlideWidth/DispWidth; 144 SlideHeightScale = SlideHeight/DispHeight; 145 146 if( mmPrepare ) { 147 clear(); 148 (this->*mmPrepare)( nTime, SlideWidth, SlideHeight, DispWidth, DispHeight ); 149 } 150 151 glPushMatrix(); 152 displaySlides( nTime, glLeavingSlideTex, glEnteringSlideTex, SlideWidthScale, SlideHeightScale ); 153 displayScene( nTime, SlideWidth, SlideHeight, DispWidth, DispHeight ); 154 glPopMatrix(); 155 } 156 157 void OGLTransitionImpl::applyOverallOperations( double nTime, double SlideWidthScale, double SlideHeightScale ) 158 { 159 for(unsigned int i(0); i < OverallOperations.size(); ++i) 160 OverallOperations[i]->interpolate(nTime,SlideWidthScale,SlideHeightScale); 161 } 162 163 void OGLTransitionImpl::displaySlide( double nTime, ::sal_Int32 glSlideTex, std::vector<Primitive>& primitives, 164 double SlideWidthScale, double SlideHeightScale ) 165 { 166 //TODO change to foreach 167 glBindTexture(GL_TEXTURE_2D, glSlideTex); 168 169 // display slide reflection 170 // note that depth test is turned off while blending the shadow 171 // so the slides has to be rendered in right order, see rochade as example 172 if( mbReflectSlides ) { 173 double surfaceLevel = -0.04; 174 175 /* reflected slides */ 176 glPushMatrix(); 177 178 glScaled( 1, -1, 1 ); 179 glTranslated( 0, 2 - surfaceLevel, 0 ); 180 181 glCullFace(GL_FRONT); 182 for(unsigned int i(0); i < primitives.size(); ++i) 183 primitives[i].display(nTime, SlideWidthScale, SlideHeightScale); 184 glCullFace(GL_BACK); 185 186 slideShadow( nTime, primitives[0], SlideWidthScale, SlideHeightScale ); 187 188 glPopMatrix(); 189 } 190 191 for(unsigned int i(0); i < primitives.size(); ++i) 192 primitives[i].display(nTime, SlideWidthScale, SlideHeightScale); 193 } 194 195 void OGLTransitionImpl::displaySlides( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, 196 double SlideWidthScale, double SlideHeightScale ) 197 { 198 if( mmDisplaySlides ) 199 (this->*mmDisplaySlides)( nTime, glLeavingSlideTex, glEnteringSlideTex, SlideWidthScale, SlideHeightScale ); 200 else { 201 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale ); 202 203 glEnable(GL_TEXTURE_2D); 204 displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale ); 205 displaySlide( nTime, glEnteringSlideTex, maEnteringSlidePrimitives, SlideWidthScale, SlideHeightScale ); 206 } 207 } 208 209 void OGLTransitionImpl::displayScene( double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight ) 210 { 211 glEnable(GL_TEXTURE_2D); 212 for(unsigned int i(0); i < maSceneObjects.size(); ++i) 213 maSceneObjects[i]->display(nTime, SlideWidth, SlideHeight, DispWidth, DispHeight); 214 } 215 216 void Primitive::display(double nTime, double WidthScale, double HeightScale) 217 { 218 glPushMatrix(); 219 220 applyOperations( nTime, WidthScale, HeightScale ); 221 222 glEnableClientState( GL_VERTEX_ARRAY ); 223 if(!Normals.empty()) 224 { 225 glNormalPointer( GL_DOUBLE , 0 , &Normals[0] ); 226 glEnableClientState( GL_NORMAL_ARRAY ); 227 } 228 glEnableClientState( GL_TEXTURE_COORD_ARRAY ); 229 glTexCoordPointer( 2, GL_DOUBLE, 0, &TexCoords[0] ); 230 glVertexPointer( 3, GL_DOUBLE, 0, &Vertices[0] ); 231 glDrawArrays( GL_TRIANGLES, 0, Vertices.size() ); 232 glPopMatrix(); 233 } 234 235 void Primitive::applyOperations(double nTime, double WidthScale, double HeightScale) 236 { 237 for(unsigned int i(0); i < Operations.size(); ++i) 238 Operations[i]->interpolate( nTime ,WidthScale,HeightScale); 239 glScaled(WidthScale,HeightScale,1); 240 } 241 242 Primitive::~Primitive() 243 { 244 for(unsigned int i( 0 ); i < Operations.size(); ++i) 245 delete Operations[i]; 246 } 247 248 249 void SceneObject::display(double nTime, double /* SlideWidth */, double /* SlideHeight */, double DispWidth, double DispHeight ) 250 { 251 for(unsigned int i(0); i < maPrimitives.size(); ++i) { 252 // fixme: allow various model spaces, now we make it so that 253 // it is regular -1,-1 to 1,1, where the whole display fits in 254 glPushMatrix(); 255 if (DispHeight > DispWidth) 256 glScaled(DispHeight/DispWidth, 1, 1); 257 else 258 glScaled(1, DispWidth/DispHeight, 1); 259 maPrimitives[i].display(nTime, 1, 1); 260 glPopMatrix(); 261 } 262 } 263 264 void SceneObject::pushPrimitive(const Primitive &p) 265 { 266 maPrimitives.push_back(p); 267 } 268 269 SceneObject::SceneObject() 270 : maPrimitives() 271 { 272 } 273 274 Iris::Iris() 275 : SceneObject () 276 { 277 } 278 279 void Iris::display(double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight ) 280 { 281 glBindTexture(GL_TEXTURE_2D, maTexture); 282 SceneObject::display(nTime, SlideWidth, SlideHeight, DispWidth, DispHeight); 283 } 284 285 void Iris::prepare() 286 { 287 static GLubyte img[3] = { 80, 80, 80 }; 288 289 glGenTextures(1, &maTexture); 290 glBindTexture(GL_TEXTURE_2D, maTexture); 291 glTexImage2D(GL_TEXTURE_2D, 0, 3, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, img); 292 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); 293 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); 294 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 295 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 296 } 297 298 void Iris::finish() 299 { 300 glDeleteTextures(1, &maTexture); 301 } 302 303 void OGLTransitionImpl::makeOutsideCubeFaceToLeft() 304 { 305 clear(); 306 Primitive Slide; 307 308 Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1)); 309 Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1)); 310 311 maLeavingSlidePrimitives.push_back(Slide); 312 313 Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,-1),90,false,0.0,1.0)); 314 315 maEnteringSlidePrimitives.push_back(Slide); 316 317 OverallOperations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,-1),-90,true,0.0,1.0)); 318 } 319 320 void OGLTransitionImpl::makeInsideCubeFaceToLeft() 321 { 322 clear(); 323 Primitive Slide; 324 325 Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1)); 326 Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1)); 327 328 maLeavingSlidePrimitives.push_back(Slide); 329 330 Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,1),-90,false,0.0,1.0)); 331 332 maEnteringSlidePrimitives.push_back(Slide); 333 334 OverallOperations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,1),90,true,0.0,1.0)); 335 } 336 337 void OGLTransitionImpl::makeFallLeaving() 338 { 339 clear(); 340 Primitive Slide; 341 342 Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1)); 343 Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1)); 344 maEnteringSlidePrimitives.push_back(Slide); 345 346 Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(1,0,0),basegfx::B3DVector(0,-1,0), 90,true,0.0,1.0)); 347 maLeavingSlidePrimitives.push_back(Slide); 348 349 mbUseMipMapEntering = false; 350 } 351 352 void OGLTransitionImpl::makeTurnAround() 353 { 354 clear(); 355 Primitive Slide; 356 357 mbReflectSlides = true; 358 359 Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1)); 360 Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1)); 361 maLeavingSlidePrimitives.push_back(Slide); 362 363 Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,0),-180,false,0.0,1.0)); 364 maEnteringSlidePrimitives.push_back(Slide); 365 366 OverallOperations.push_back(new STranslate(basegfx::B3DVector(0, 0, -1.5),true, 0, 0.5)); 367 OverallOperations.push_back(new STranslate(basegfx::B3DVector(0, 0, 1.5), true, 0.5, 1)); 368 OverallOperations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0, 1, 0),basegfx::B3DVector(0, 0, 0), -180, true, 0.0, 1.0)); 369 } 370 371 void OGLTransitionImpl::makeTurnDown() 372 { 373 clear(); 374 Primitive Slide; 375 376 Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1)); 377 Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1)); 378 maLeavingSlidePrimitives.push_back(Slide); 379 380 Slide.Operations.push_back(new STranslate(basegfx::B3DVector(0, 0, 0.0001), false, -1.0, 0.0)); 381 Slide.Operations.push_back(new SRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(-1, 1, 0), -90, true, 0.0, 1.0)); 382 Slide.Operations.push_back(new SRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(-1, 1, 0), 90, false, -1.0, 0.0)); 383 maEnteringSlidePrimitives.push_back(Slide); 384 385 mbUseMipMapLeaving = false; 386 } 387 388 void OGLTransitionImpl::makeIris() 389 { 390 clear(); 391 Primitive Slide; 392 393 Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1)); 394 Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1)); 395 maEnteringSlidePrimitives.push_back (Slide); 396 397 Slide.Operations.push_back (new STranslate (basegfx::B3DVector (0, 0, 0.000001), false, -1, 0)); 398 Slide.Operations.push_back (new STranslate (basegfx::B3DVector (0, 0, -0.000002), false, 0.5, 1)); 399 maLeavingSlidePrimitives.push_back (Slide); 400 401 402 Primitive irisPart, part; 403 int i, nSteps = 24, nParts = 7; 404 double lt = 0, t = 1.0/nSteps, cx, cy, lcx, lcy, lx = 1, ly = 0, x, y, cxo, cyo, lcxo, lcyo, of=2.2, f=1.42; 405 406 for (i=1; i<=nSteps; i++) { 407 x = cos ((3*2*M_PI*t)/nParts); 408 y = -sin ((3*2*M_PI*t)/nParts); 409 cx = (f*x + 1)/2; 410 cy = (f*y + 1)/2; 411 lcx = (f*lx + 1)/2; 412 lcy = (f*ly + 1)/2; 413 cxo = (of*x + 1)/2; 414 cyo = (of*y + 1)/2; 415 lcxo = (of*lx + 1)/2; 416 lcyo = (of*ly + 1)/2; 417 irisPart.pushTriangle (basegfx::B2DVector (lcx, lcy), 418 basegfx::B2DVector (lcxo, lcyo), 419 basegfx::B2DVector (cx, cy)); 420 irisPart.pushTriangle (basegfx::B2DVector (cx, cy), 421 basegfx::B2DVector (lcxo, lcyo), 422 basegfx::B2DVector (cxo, cyo)); 423 lx = x; 424 ly = y; 425 lt = t; 426 t += 1.0/nSteps; 427 } 428 429 Iris* pIris = new Iris(); 430 double angle = 87; 431 432 for (i = 0; i < nParts; i++) { 433 irisPart.Operations.clear (); 434 double rx, ry; 435 436 rx = cos ((2*M_PI*i)/nParts); 437 ry = sin ((2*M_PI*i)/nParts); 438 irisPart.Operations.push_back (new SRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(rx, ry, 0), angle, true, 0.0, 0.5)); 439 irisPart.Operations.push_back (new SRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(rx, ry, 0), -angle, true, 0.5, 1)); 440 if (i > 0) { 441 irisPart.Operations.push_back (new STranslate (basegfx::B3DVector(rx, ry, 0), false, -1, 0)); 442 irisPart.Operations.push_back (new SRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(0, 0, 0), i*360.0/nParts, false, -1, 0)); 443 irisPart.Operations.push_back (new STranslate (basegfx::B3DVector(-1, 0, 0), false, -1, 0)); 444 } 445 irisPart.Operations.push_back(new STranslate(basegfx::B3DVector(0, 0, 1), false, -2, 0.0)); 446 irisPart.Operations.push_back (new SRotate (basegfx::B3DVector(1, .5, 0), basegfx::B3DVector(1, 0, 0), -30, false, -1, 0)); 447 pIris->pushPrimitive (irisPart); 448 } 449 450 maSceneObjects.push_back (pIris); 451 452 mbUseMipMapLeaving = mbUseMipMapEntering = false; 453 } 454 455 void OGLTransitionImpl::displaySlidesRochade( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, 456 double SlideWidthScale, double SlideHeightScale ) 457 { 458 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale ); 459 460 glEnable(GL_TEXTURE_2D); 461 462 if( nTime > .5) { 463 displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale ); 464 displaySlide( nTime, glEnteringSlideTex, maEnteringSlidePrimitives, SlideWidthScale, SlideHeightScale ); 465 } else { 466 displaySlide( nTime, glEnteringSlideTex, maEnteringSlidePrimitives, SlideWidthScale, SlideHeightScale ); 467 displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale ); 468 } 469 } 470 471 void OGLTransitionImpl::makeRochade() 472 { 473 clear(); 474 Primitive Slide; 475 476 mbReflectSlides = true; 477 mmDisplaySlides = &OGLTransitionImpl::displaySlidesRochade; 478 479 double w, h; 480 481 w = 2.2; 482 h = 10; 483 484 Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1)); 485 Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1)); 486 487 Slide.Operations.push_back(new SEllipseTranslate(w, h, 0.25, -0.25, true, 0, 1)); 488 Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,0), -45, true, 0, 1)); 489 maLeavingSlidePrimitives.push_back(Slide); 490 491 Slide.Operations.clear(); 492 Slide.Operations.push_back(new SEllipseTranslate(w, h, 0.75, 0.25, true, 0, 1)); 493 Slide.Operations.push_back(new STranslate(basegfx::B3DVector(0, 0, -h), false, -1, 0)); 494 Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,0), -45, true, 0, 1)); 495 Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,0), 45, false, -1, 0)); 496 maEnteringSlidePrimitives.push_back(Slide); 497 498 // OverallOperations.push_back(new SEllipseTranslate(0.5, 2, 0, 1, true, 0, 1)); 499 // push_back(new STranslate(basegfx::B3DVector(0, 0, -2), true, 0, 0.5)); 500 // OverallOperations.push_back(new STranslate(basegfx::B3DVector(0, 0, 2), true, 0.5, 1)); 501 } 502 503 // TODO(Q3): extract to basegfx 504 inline basegfx::B2DVector clamp(const basegfx::B2DVector& v) 505 { 506 return basegfx::B2DVector(min(max(v.getX(),-1.0),1.0), 507 min(max(v.getY(),-1.0),1.0)); 508 } 509 510 // TODO(Q3): extract to basegfx 511 inline basegfx::B3DVector clamp(const basegfx::B3DVector& v) 512 { 513 return basegfx::B3DVector(min(max(v.getX(),-1.0),1.0), 514 min(max(v.getY(),-1.0),1.0), 515 min(max(v.getZ(),-1.0),1.0)); 516 } 517 518 inline double randFromNeg1to1() 519 { 520 return ( ( static_cast<double>( rand() ) / static_cast<double>( RAND_MAX ) ) * 2.0 ) - 1.0; 521 } 522 523 // TODO(Q3): extract to basegfx 524 inline basegfx::B3DVector randNormVectorInXYPlane() 525 { 526 basegfx::B3DVector toReturn(randFromNeg1to1(),randFromNeg1to1(),0.0); 527 return toReturn/toReturn.getLength(); 528 } 529 530 void OGLTransitionImpl::makeRevolvingCircles( ::sal_uInt16 nCircles , ::sal_uInt16 nPointsOnCircles ) 531 { 532 clear(); 533 double dAngle(2*3.1415926/static_cast<double>( nPointsOnCircles )); 534 if(nCircles < 2 || nPointsOnCircles < 4) 535 { 536 makeNByMTileFlip(1,1); 537 return; 538 } 539 double Radius(1.0/static_cast<double>( nCircles )); 540 double dRadius(Radius); 541 double LastRadius(0.0); 542 double NextRadius(2*Radius); 543 544 /// now we know there is at least two circles 545 /// the first will always be a full circle 546 /// the last will always be the outer shell of the slide with a circle hole 547 548 //add the full circle 549 vector<basegfx::B2DVector> unScaledTexCoords; 550 double TempAngle(0.0); 551 for(unsigned int Point(0); Point < nPointsOnCircles; ++Point) 552 { 553 unScaledTexCoords.push_back( basegfx::B2DVector( cos(TempAngle - 3.1415926/2.0) , sin(TempAngle- 3.1415926/2.0) ) ); 554 555 TempAngle += dAngle; 556 } 557 558 { 559 //double angle(0.0); 560 Primitive EnteringSlide; 561 Primitive LeavingSlide; 562 for(int Point(0); Point + 1 < nPointsOnCircles; ++Point) 563 { 564 EnteringSlide.pushTriangle( basegfx::B2DVector( 0.5 , 0.5 ) , Radius * unScaledTexCoords[ Point + 1 ] / 2.0 + basegfx::B2DVector( 0.5 , 0.5 ) , Radius * unScaledTexCoords[ Point ] / 2.0 + basegfx::B2DVector( 0.5 , 0.5 ) ); 565 LeavingSlide.pushTriangle( basegfx::B2DVector( 0.5 , 0.5 ) , Radius * unScaledTexCoords[ Point + 1 ] / 2.0 + basegfx::B2DVector( 0.5 , 0.5 ) , Radius * unScaledTexCoords[ Point ] / 2.0 + basegfx::B2DVector( 0.5, 0.5) ); 566 } 567 EnteringSlide.pushTriangle( basegfx::B2DVector(0.5,0.5) , Radius * unScaledTexCoords[ 0 ] / 2.0 + basegfx::B2DVector( 0.5 , 0.5 ) , Radius * unScaledTexCoords[ nPointsOnCircles - 1 ] / 2.0 + basegfx::B2DVector( 0.5 , 0.5 ) ); 568 LeavingSlide.pushTriangle( basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); 569 570 basegfx::B3DVector axis(randNormVectorInXYPlane()); 571 EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) ); 572 LeavingSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) ); 573 EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , -180, false,0.0,1.0) ); 574 575 maEnteringSlidePrimitives.push_back(EnteringSlide); 576 maLeavingSlidePrimitives.push_back(LeavingSlide); 577 LastRadius = Radius; 578 Radius = NextRadius; 579 NextRadius += dRadius; 580 } 581 582 for(int i(1); i < nCircles - 1; ++i) 583 { 584 Primitive LeavingSlide; 585 Primitive EnteringSlide; 586 for(int Side(0); Side < nPointsOnCircles - 1; ++Side) 587 { 588 EnteringSlide.pushTriangle(Radius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); 589 EnteringSlide.pushTriangle(Radius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); 590 591 LeavingSlide.pushTriangle(Radius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); 592 LeavingSlide.pushTriangle(Radius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); 593 } 594 595 EnteringSlide.pushTriangle(Radius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); 596 EnteringSlide.pushTriangle(Radius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); 597 598 LeavingSlide.pushTriangle(Radius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); 599 LeavingSlide.pushTriangle(Radius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); 600 601 basegfx::B3DVector axis(randNormVectorInXYPlane()); 602 EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) ); 603 LeavingSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) ); 604 EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , -180, false,0.0,1.0) ); 605 606 maEnteringSlidePrimitives.push_back(EnteringSlide); 607 maLeavingSlidePrimitives.push_back(LeavingSlide); 608 609 LastRadius = Radius; 610 Radius = NextRadius; 611 NextRadius += dRadius; 612 } 613 { 614 Radius = sqrt(2.0); 615 Primitive LeavingSlide; 616 Primitive EnteringSlide; 617 for(int Side(0); Side < nPointsOnCircles - 1; ++Side) 618 { 619 620 EnteringSlide.pushTriangle(clamp(Radius*unScaledTexCoords[Side])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); 621 EnteringSlide.pushTriangle(clamp(Radius*unScaledTexCoords[Side])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) , clamp(Radius*unScaledTexCoords[Side + 1])/2.0 + basegfx::B2DVector(0.5,0.5) ); 622 623 LeavingSlide.pushTriangle(clamp(Radius*unScaledTexCoords[Side])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); 624 LeavingSlide.pushTriangle(clamp(Radius*unScaledTexCoords[Side])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) , clamp(Radius*unScaledTexCoords[Side + 1])/2.0 + basegfx::B2DVector(0.5,0.5) ); 625 } 626 627 EnteringSlide.pushTriangle(clamp(Radius*unScaledTexCoords[nPointsOnCircles - 1])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); 628 EnteringSlide.pushTriangle(clamp(Radius*unScaledTexCoords[nPointsOnCircles - 1])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) , clamp(Radius*unScaledTexCoords[0])/2.0 + basegfx::B2DVector(0.5,0.5) ); 629 630 LeavingSlide.pushTriangle(clamp(Radius*unScaledTexCoords[nPointsOnCircles - 1])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); 631 LeavingSlide.pushTriangle(clamp(Radius*unScaledTexCoords[nPointsOnCircles - 1])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) , clamp(Radius*unScaledTexCoords[0])/2.0 + basegfx::B2DVector(0.5,0.5) ); 632 633 basegfx::B3DVector axis(randNormVectorInXYPlane()); 634 EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, (LastRadius + dRadius)/2.0 , 1.0 ) ); 635 LeavingSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, (LastRadius + dRadius)/2.0 , 1.0 ) ); 636 EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , -180, false,0.0,1.0) ); 637 638 maEnteringSlidePrimitives.push_back(EnteringSlide); 639 maLeavingSlidePrimitives.push_back(LeavingSlide); 640 } 641 } 642 643 void OGLTransitionImpl::makeHelix( ::sal_uInt16 nRows ) 644 { 645 clear(); 646 double invN(1.0/static_cast<double>(nRows)); 647 double iDn = 0.0; 648 double iPDn = invN; 649 for(unsigned int i(0); i < nRows; ++i) 650 { 651 Primitive Tile; 652 653 Tile.pushTriangle(basegfx::B2DVector( 1.0 , iDn ) , basegfx::B2DVector( 0.0 , iDn ) , basegfx::B2DVector( 0.0 , iPDn )); 654 655 Tile.pushTriangle(basegfx::B2DVector( 1.0 , iPDn ) , basegfx::B2DVector( 1.0 , iDn ) , basegfx::B2DVector( 0.0 , iPDn )); 656 657 Tile.Operations.push_back( new SRotate( basegfx::B3DVector( 0 , 1 , 0 ) , ( Tile.getVertices()[1] + Tile.getVertices()[3] )/2.0 , 180 , 658 true,min(max(static_cast<double>(i - nRows/2.0)*invN/2.0,0.0),1.0), 659 min(max(static_cast<double>(i + nRows/2.0)*invN/2.0,0.0),1.0) ) ); 660 661 maLeavingSlidePrimitives.push_back(Tile); 662 663 Tile.Operations.push_back( new SRotate( basegfx::B3DVector( 0 , 1 , 0 ) , ( Tile.getVertices()[1] + Tile.getVertices()[3] )/2.0 , -180 , false,0.0,1.0) ); 664 665 maEnteringSlidePrimitives.push_back(Tile); 666 667 iDn += invN; 668 iPDn += invN; 669 } 670 } 671 672 void OGLTransitionImpl::makeNByMTileFlip( ::sal_uInt16 n, ::sal_uInt16 m ) 673 { 674 clear(); 675 double invN(1.0/static_cast<double>(n)); 676 double invM(1.0/static_cast<double>(m)); 677 double iDn = 0.0; 678 double iPDn = invN; 679 for(unsigned int i(0); i < n; ++i) 680 { 681 double jDm = 0.0; 682 double jPDm = invM; 683 for(unsigned int j(0); j < m; ++j) 684 { 685 Primitive Tile; 686 687 Tile.pushTriangle(basegfx::B2DVector( iPDn , jDm ) , basegfx::B2DVector( iDn , jDm ) , basegfx::B2DVector( iDn , jPDm )); 688 689 Tile.pushTriangle(basegfx::B2DVector( iPDn , jPDm ) , basegfx::B2DVector( iPDn , jDm ) , basegfx::B2DVector( iDn , jPDm ));//bottom left corner of tile 690 691 Tile.Operations.push_back( new SRotate( basegfx::B3DVector( 1 , 1 , 0 ) , ( Tile.getVertices()[1] + Tile.getVertices()[3] )/2.0 , 180 , true, iDn*jDm/2.0 , ((iPDn*jPDm)+1.0)/2.0 ) ); 692 maLeavingSlidePrimitives.push_back(Tile); 693 Tile.Operations.push_back( new SRotate( basegfx::B3DVector( 1 , 1 , 0 ) , ( Tile.getVertices()[1] + Tile.getVertices()[3] )/2.0 , -180, false, iDn*jDm/2.0 , ((iPDn*jPDm)+1.0)/2.0 ) ); 694 695 maEnteringSlidePrimitives.push_back(Tile); 696 697 jDm += invM; 698 jPDm += invM; 699 } 700 iDn += invN; 701 iPDn += invN; 702 } 703 } 704 705 SRotate::SRotate(const basegfx::B3DVector& Axis,const basegfx::B3DVector& Origin,double Angle, bool bInter, double T0, double T1):axis(Axis),origin(Origin),angle(Angle) 706 { 707 nT0 = T0; 708 nT1 = T1; 709 bInterpolate = bInter; 710 } 711 712 SScale::SScale(const basegfx::B3DVector& Scale,const basegfx::B3DVector& Origin, bool bInter, double T0, double T1):scale(Scale),origin(Origin) 713 { 714 nT0 = T0; 715 nT1 = T1; 716 bInterpolate = bInter; 717 } 718 719 RotateAndScaleDepthByWidth::RotateAndScaleDepthByWidth(const basegfx::B3DVector& Axis,const basegfx::B3DVector& Origin,double Angle, bool bInter, double T0, double T1):axis(Axis),origin(Origin),angle(Angle) 720 { 721 nT0 = T0; 722 nT1 = T1; 723 bInterpolate = bInter; 724 } 725 726 RotateAndScaleDepthByHeight::RotateAndScaleDepthByHeight(const basegfx::B3DVector& Axis,const basegfx::B3DVector& Origin,double Angle, bool bInter, double T0, double T1):axis(Axis),origin(Origin),angle(Angle) 727 { 728 nT0 = T0; 729 nT1 = T1; 730 bInterpolate = bInter; 731 } 732 733 734 STranslate::STranslate(const basegfx::B3DVector& Vector, bool bInter, double T0, double T1):vector(Vector) 735 { 736 nT0 = T0; 737 nT1 = T1; 738 bInterpolate = bInter; 739 } 740 741 inline double intervalInter(double t, double T0, double T1) 742 { 743 return ( t - T0 ) / ( T1 - T0 ); 744 } 745 746 void STranslate::interpolate(double t,double SlideWidthScale,double SlideHeightScale) 747 { 748 if(t <= nT0) 749 return; 750 if(!bInterpolate || t > nT1) 751 t = nT1; 752 t = intervalInter(t,nT0,nT1); 753 glTranslated(SlideWidthScale*t*vector.getX(),SlideHeightScale*t*vector.getY(),t*vector.getZ()); 754 } 755 756 void SRotate::interpolate(double t,double SlideWidthScale,double SlideHeightScale) 757 { 758 if(t <= nT0) 759 return; 760 if(!bInterpolate || t > nT1) 761 t = nT1; 762 t = intervalInter(t,nT0,nT1); 763 glTranslated(SlideWidthScale*origin.getX(),SlideHeightScale*origin.getY(),origin.getZ()); 764 glScaled(SlideWidthScale,SlideHeightScale,1); 765 glRotated(t*angle,axis.getX(),axis.getY(),axis.getZ()); 766 glScaled(1/SlideWidthScale,1/SlideHeightScale,1); 767 glTranslated(-SlideWidthScale*origin.getX(),-SlideHeightScale*origin.getY(),-origin.getZ()); 768 } 769 770 void SScale::interpolate(double t,double SlideWidthScale,double SlideHeightScale) 771 { 772 if(t <= nT0) 773 return; 774 if(!bInterpolate || t > nT1) 775 t = nT1; 776 t = intervalInter(t,nT0,nT1); 777 glTranslated(SlideWidthScale*origin.getX(),SlideHeightScale*origin.getY(),origin.getZ()); 778 glScaled((1-t) + t*scale.getX(),(1-t) + t*scale.getY(),(1-t) + t*scale.getZ()); 779 glTranslated(-SlideWidthScale*origin.getX(),-SlideHeightScale*origin.getY(),-origin.getZ()); 780 } 781 782 void RotateAndScaleDepthByWidth::interpolate(double t,double SlideWidthScale,double SlideHeightScale) 783 { 784 if(t <= nT0) 785 return; 786 if(!bInterpolate || t > nT1) 787 t = nT1; 788 t = intervalInter(t,nT0,nT1); 789 glTranslated(SlideWidthScale*origin.getX(),SlideHeightScale*origin.getY(),SlideWidthScale*origin.getZ()); 790 glRotated(t*angle,axis.getX(),axis.getY(),axis.getZ()); 791 glTranslated(-SlideWidthScale*origin.getX(),-SlideHeightScale*origin.getY(),-SlideWidthScale*origin.getZ()); 792 } 793 794 void RotateAndScaleDepthByHeight::interpolate(double t,double SlideWidthScale,double SlideHeightScale) 795 { 796 if(t <= nT0) 797 return; 798 if(!bInterpolate || t > nT1) 799 t = nT1; 800 t = intervalInter(t,nT0,nT1); 801 glTranslated(SlideWidthScale*origin.getX(),SlideHeightScale*origin.getY(),SlideHeightScale*origin.getZ()); 802 glRotated(t*angle,axis.getX(),axis.getY(),axis.getZ()); 803 glTranslated(-SlideWidthScale*origin.getX(),-SlideHeightScale*origin.getY(),-SlideHeightScale*origin.getZ()); 804 } 805 806 SEllipseTranslate::SEllipseTranslate(double dWidth, double dHeight, double dStartPosition, double dEndPosition, bool bInter, double T0, double T1) 807 { 808 nT0 = T0; 809 nT1 = T1; 810 bInterpolate = bInter; 811 width = dWidth; 812 height = dHeight; 813 startPosition = dStartPosition; 814 endPosition = dEndPosition; 815 } 816 817 void SEllipseTranslate::interpolate(double t,double /* SlideWidthScale */,double /* SlideHeightScale */) 818 { 819 if(t <= nT0) 820 return; 821 if(!bInterpolate || t > nT1) 822 t = nT1; 823 t = intervalInter(t,nT0,nT1); 824 825 double a1, a2, x, y; 826 a1 = startPosition*2*M_PI; 827 a2 = (startPosition + t*(endPosition - startPosition))*2*M_PI; 828 x = width*(cos (a2) - cos (a1))/2; 829 y = height*(sin (a2) - sin (a1))/2; 830 831 glTranslated(x, 0, y); 832 } 833 834 STranslate* STranslate::clone() 835 { 836 return new STranslate(*this); 837 } 838 SRotate* SRotate::clone() 839 { 840 return new SRotate(*this); 841 } 842 843 SScale* SScale::clone() 844 { 845 return new SScale(*this); 846 } 847 848 SEllipseTranslate* SEllipseTranslate::clone() 849 { 850 return new SEllipseTranslate(*this); 851 } 852 853 RotateAndScaleDepthByWidth* RotateAndScaleDepthByWidth::clone() 854 { 855 return new RotateAndScaleDepthByWidth(*this); 856 } 857 858 RotateAndScaleDepthByHeight* RotateAndScaleDepthByHeight::clone() 859 { 860 return new RotateAndScaleDepthByHeight(*this); 861 } 862 863 const Primitive& Primitive::operator=(const Primitive& rvalue) 864 { 865 for(unsigned int i( 0 ); i < rvalue.Operations.size(); ++i) 866 Operations.push_back(rvalue.Operations[i]->clone()); 867 for(unsigned int i( 0 ); i < rvalue.Vertices.size(); ++i)//SPEED! use copy or something. this is slow. 868 Vertices.push_back(rvalue.Vertices[i]); 869 for(unsigned int i( 0 ); i < rvalue.TexCoords.size(); ++i)//SPEED! use copy or something. this is slow. 870 TexCoords.push_back(rvalue.TexCoords[i]); 871 for(unsigned int i( 0 ); i < rvalue.Normals.size(); ++i)//SPEED! use copy or something. this is slow. 872 Normals.push_back(rvalue.Normals[i]); 873 return *this; 874 } 875 876 Primitive::Primitive(const Primitive& rvalue) 877 { 878 for(unsigned int i( 0 ); i < rvalue.Operations.size(); ++i) 879 Operations.push_back(rvalue.Operations[i]->clone()); 880 for(unsigned int i( 0 ); i < rvalue.Vertices.size(); ++i)//SPEED! use copy or something. this is slow. 881 Vertices.push_back(rvalue.Vertices[i]); 882 for(unsigned int i( 0 ); i < rvalue.TexCoords.size(); ++i)//SPEED! use copy or something. this is slow. 883 TexCoords.push_back(rvalue.TexCoords[i]); 884 for(unsigned int i( 0 ); i < rvalue.Normals.size(); ++i)//SPEED! use copy or something. this is slow. 885 Normals.push_back(rvalue.Normals[i]); 886 } 887 888 void Primitive::pushTriangle(const basegfx::B2DVector& SlideLocation0,const basegfx::B2DVector& SlideLocation1,const basegfx::B2DVector& SlideLocation2) 889 { 890 vector<basegfx::B3DVector> Verts; 891 vector<basegfx::B2DVector> Texs; 892 Verts.reserve(3); 893 Texs.reserve(3); 894 895 Verts.push_back(basegfx::B3DVector( 2*SlideLocation0.getX() - 1, -2*SlideLocation0.getY() + 1 , 0.0 )); 896 Verts.push_back(basegfx::B3DVector( 2*SlideLocation1.getX() - 1, -2*SlideLocation1.getY() + 1 , 0.0 )); 897 Verts.push_back(basegfx::B3DVector( 2*SlideLocation2.getX() - 1, -2*SlideLocation2.getY() + 1 , 0.0 )); 898 899 //figure out if they're facing the correct way, and make them face the correct way. 900 basegfx::B3DVector Normal( basegfx::cross( Verts[0] - Verts[1] , Verts[1] - Verts[2] ) ); 901 if(Normal.getZ() >= 0.0)//if the normal is facing us 902 { 903 Texs.push_back(SlideLocation0); 904 Texs.push_back(SlideLocation1); 905 Texs.push_back(SlideLocation2); 906 } 907 else // if the normal is facing away from us, make it face us 908 { 909 Texs.push_back(SlideLocation0); 910 Texs.push_back(SlideLocation2); 911 Texs.push_back(SlideLocation1); 912 Verts.clear(); 913 Verts.push_back(basegfx::B3DVector( 2*SlideLocation0.getX() - 1, -2*SlideLocation0.getY() + 1 , 0.0 )); 914 Verts.push_back(basegfx::B3DVector( 2*SlideLocation2.getX() - 1, -2*SlideLocation2.getY() + 1 , 0.0 )); 915 Verts.push_back(basegfx::B3DVector( 2*SlideLocation1.getX() - 1, -2*SlideLocation1.getY() + 1 , 0.0 )); 916 } 917 918 Vertices.push_back(Verts[0]); 919 Vertices.push_back(Verts[1]); 920 Vertices.push_back(Verts[2]); 921 922 TexCoords.push_back(Texs[0]); 923 TexCoords.push_back(Texs[1]); 924 TexCoords.push_back(Texs[2]); 925 926 Normals.push_back(basegfx::B3DVector(0,0,1));//all normals always face the screen when untransformed. 927 Normals.push_back(basegfx::B3DVector(0,0,1));//all normals always face the screen when untransformed. 928 Normals.push_back(basegfx::B3DVector(0,0,1));//all normals always face the screen when untransformed. 929 } 930 931 void OGLTransitionImpl::makeDiamond() 932 { 933 mmPrepare = &OGLTransitionImpl::prepareDiamond; 934 mbUseMipMapLeaving = mbUseMipMapEntering = false; 935 } 936 937 void OGLTransitionImpl::prepareDiamond( double nTime, double /* SlideWidth */, double /* SlideHeight */, double /* DispWidth */, double /* DispHeight */ ) 938 { 939 Primitive Slide1, Slide2; 940 941 Slide1.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1)); 942 Slide1.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1)); 943 maEnteringSlidePrimitives.push_back (Slide1); 944 945 946 if( nTime >= 0.5 ) { 947 double m = 1 - nTime; 948 949 Slide2.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (m,0), basegfx::B2DVector (0,m)); 950 Slide2.pushTriangle (basegfx::B2DVector (nTime,0), basegfx::B2DVector (1,0), basegfx::B2DVector (1,m)); 951 Slide2.pushTriangle (basegfx::B2DVector (1,nTime), basegfx::B2DVector (1,1), basegfx::B2DVector (nTime,1)); 952 Slide2.pushTriangle (basegfx::B2DVector (0,nTime), basegfx::B2DVector (m,1), basegfx::B2DVector (0,1)); 953 } else { 954 double l = 0.5 - nTime; 955 double h = 0.5 + nTime; 956 957 Slide2.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0.5,l)); 958 Slide2.pushTriangle (basegfx::B2DVector (0.5,l), basegfx::B2DVector (1,0), basegfx::B2DVector (h,0.5)); 959 Slide2.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (1,1), basegfx::B2DVector (h,0.5)); 960 Slide2.pushTriangle (basegfx::B2DVector (h,0.5), basegfx::B2DVector (1,1), basegfx::B2DVector (0.5,h)); 961 Slide2.pushTriangle (basegfx::B2DVector (0.5,h), basegfx::B2DVector (1,1), basegfx::B2DVector (0,1)); 962 Slide2.pushTriangle (basegfx::B2DVector (l,0.5), basegfx::B2DVector (0.5,h), basegfx::B2DVector (0,1)); 963 Slide2.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (l,0.5), basegfx::B2DVector (0,1)); 964 Slide2.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (0.5,l), basegfx::B2DVector (l,0.5)); 965 } 966 Slide2.Operations.push_back (new STranslate (basegfx::B3DVector (0, 0, 0.00000001), false, -1, 0)); 967 maLeavingSlidePrimitives.push_back (Slide2); 968 } 969 970 void OGLTransitionImpl::makeVenetianBlinds( bool vertical, int parts ) 971 { 972 static double t30 = tan( M_PI/6.0 ); 973 double n, ln = 0; 974 double p = 1.0/parts; 975 976 for( int i=0; i<parts; i++ ) { 977 Primitive Slide; 978 n = (i + 1)/(double)parts; 979 if( vertical ) { 980 Slide.pushTriangle (basegfx::B2DVector (ln,0), basegfx::B2DVector (n,0), basegfx::B2DVector (ln,1)); 981 Slide.pushTriangle (basegfx::B2DVector (n,0), basegfx::B2DVector (ln,1), basegfx::B2DVector (n,1)); 982 Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0, 1, 0), basegfx::B3DVector(n + ln - 1, 0, -t30*p), -120, true, 0.0, 1.0)); 983 } else { 984 Slide.pushTriangle (basegfx::B2DVector (0,ln), basegfx::B2DVector (1,ln), basegfx::B2DVector (0,n)); 985 Slide.pushTriangle (basegfx::B2DVector (1,ln), basegfx::B2DVector (0,n), basegfx::B2DVector (1,n)); 986 Slide.Operations.push_back(new RotateAndScaleDepthByHeight(basegfx::B3DVector(1, 0, 0), basegfx::B3DVector(0, 1 - n - ln, -t30*p), -120, true, 0.0, 1.0)); 987 } 988 maLeavingSlidePrimitives.push_back (Slide); 989 990 if( vertical ) { 991 Slide.Operations.push_back(new SRotate(basegfx::B3DVector(0, 1, 0), basegfx::B3DVector(2*n - 1, 0, 0), -60, false, -1, 0)); 992 Slide.Operations.push_back(new SRotate(basegfx::B3DVector(0, 1, 0), basegfx::B3DVector(n + ln - 1, 0, 0), 180, false, -1, 0)); 993 } else { 994 Slide.Operations.push_back(new SRotate(basegfx::B3DVector(1, 0, 0), basegfx::B3DVector(0, 1 - 2*n, 0), -60, false, -1, 0)); 995 Slide.Operations.push_back(new SRotate(basegfx::B3DVector(1, 0, 0), basegfx::B3DVector(0, 1 - n - ln, 0), 180, false, -1, 0)); 996 } 997 maEnteringSlidePrimitives.push_back (Slide); 998 ln = n; 999 } 1000 } 1001 1002 void OGLTransitionImpl::displaySlidesFadeSmoothly( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale ) 1003 { 1004 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale ); 1005 1006 glDisable(GL_DEPTH_TEST); 1007 1008 displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale ); 1009 1010 glDisable(GL_LIGHTING); 1011 glEnable(GL_BLEND); 1012 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1013 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 1014 glColor4f( 1, 1, 1, nTime ); 1015 displaySlide( nTime, glEnteringSlideTex, maEnteringSlidePrimitives, SlideWidthScale, SlideHeightScale ); 1016 glDisable(GL_BLEND); 1017 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1018 glEnable(GL_LIGHTING); 1019 1020 glEnable(GL_DEPTH_TEST); 1021 } 1022 1023 void OGLTransitionImpl::makeFadeSmoothly() 1024 { 1025 Primitive Slide; 1026 1027 Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1)); 1028 Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1)); 1029 maLeavingSlidePrimitives.push_back (Slide); 1030 maEnteringSlidePrimitives.push_back (Slide); 1031 1032 mmDisplaySlides = &OGLTransitionImpl::displaySlidesFadeSmoothly; 1033 mbUseMipMapLeaving = mbUseMipMapEntering = false; 1034 } 1035 1036 void OGLTransitionImpl::displaySlidesFadeThroughBlack( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale ) 1037 { 1038 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale ); 1039 1040 glDisable(GL_DEPTH_TEST); 1041 1042 glDisable(GL_LIGHTING); 1043 glEnable(GL_BLEND); 1044 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1045 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 1046 if( nTime < 0.5 ) { 1047 glColor4f( 1, 1, 1, 1 - nTime*2 ); 1048 displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale ); 1049 } else { 1050 glColor4f( 1, 1, 1, (nTime - 0.5)*2 ); 1051 displaySlide( nTime, glEnteringSlideTex, maEnteringSlidePrimitives, SlideWidthScale, SlideHeightScale ); 1052 } 1053 glDisable(GL_BLEND); 1054 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1055 glEnable(GL_LIGHTING); 1056 1057 glEnable(GL_DEPTH_TEST); 1058 } 1059 1060 void OGLTransitionImpl::makeFadeThroughBlack() 1061 { 1062 Primitive Slide; 1063 1064 Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1)); 1065 Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1)); 1066 maLeavingSlidePrimitives.push_back (Slide); 1067 maEnteringSlidePrimitives.push_back (Slide); 1068 1069 mmDisplaySlides = &OGLTransitionImpl::displaySlidesFadeThroughBlack; 1070 mbUseMipMapLeaving = mbUseMipMapEntering = false; 1071 } 1072 1073 static const char* basicVertexShader = "\n\ 1074 varying vec2 v_texturePosition;\n\ 1075 \n\ 1076 void main( void )\n\ 1077 {\n\ 1078 gl_Position = ftransform();\n\ 1079 v_texturePosition = gl_MultiTexCoord0.xy;\n\ 1080 }\n\ 1081 "; 1082 1083 static const char* staticFragmentShader = "\n\ 1084 uniform sampler2D leavingSlideTexture;\n\ 1085 uniform sampler2D enteringSlideTexture;\n\ 1086 uniform sampler2D permTexture;\n\ 1087 uniform float time;\n\ 1088 varying vec2 v_texturePosition;\n\ 1089 \n\ 1090 float snoise(vec2 P) {\n\ 1091 \n\ 1092 return texture2D(permTexture, P).r;\n\ 1093 }\n\ 1094 \n\ 1095 \n\ 1096 #define PART 0.5\n\ 1097 #define START 0.4\n\ 1098 #define END 0.9\n\ 1099 \n\ 1100 void main() {\n\ 1101 float sn = snoise(10.0*v_texturePosition+time*0.07);\n\ 1102 if( time < PART ) {\n\ 1103 float sn1 = snoise(vec2(time*15.0, 20.0*v_texturePosition.y));\n\ 1104 float sn2 = snoise(v_texturePosition);\n\ 1105 if (sn1 > 1.0 - time*time && sn2 < 2.0*time+0.1)\n\ 1106 gl_FragColor = vec4(sn, sn, sn, 1.0);\n\ 1107 else if (time > START )\n\ 1108 gl_FragColor = ((time-START)/(PART - START))*vec4(sn, sn, sn, 1.0) + (1.0 - (time - START)/(PART - START))*texture2D(leavingSlideTexture, v_texturePosition);\n\ 1109 else\n\ 1110 gl_FragColor = texture2D(leavingSlideTexture, v_texturePosition);\n\ 1111 } else if ( time < PART ) {\n\ 1112 gl_FragColor = texture2D(leavingSlideTexture, v_texturePosition);\n\ 1113 } else if ( time > END ) {\n\ 1114 gl_FragColor = ((1.0 - time)/(1.0 - END))*vec4(sn, sn, sn, 1.0) + ((time - END)/(1.0 - END))*texture2D(enteringSlideTexture, v_texturePosition);\n\ 1115 } else \n\ 1116 gl_FragColor = vec4(sn, sn, sn, 1.0);\n\ 1117 }\n\ 1118 "; 1119 1120 static const char* dissolveFragmentShader = "\n\ 1121 uniform sampler2D leavingSlideTexture;\n\ 1122 uniform sampler2D enteringSlideTexture;\n\ 1123 uniform sampler2D permTexture;\n\ 1124 uniform float time;\n\ 1125 varying vec2 v_texturePosition;\n\ 1126 \n\ 1127 float snoise(vec2 P) {\n\ 1128 \n\ 1129 return texture2D(permTexture, P).r;\n\ 1130 }\n\ 1131 \n\ 1132 void main() {\n\ 1133 float sn = snoise(10.0*v_texturePosition);\n\ 1134 if( sn < time)\n\ 1135 gl_FragColor = texture2D(enteringSlideTexture, v_texturePosition);\n\ 1136 else\n\ 1137 gl_FragColor = texture2D(leavingSlideTexture, v_texturePosition);\n\ 1138 }\n\ 1139 "; 1140 1141 int permutation256 [256]= { 1142 215, 100, 200, 204, 233, 50, 85, 196, 1143 71, 141, 122, 160, 93, 131, 243, 234, 1144 162, 183, 36, 155, 4, 62, 35, 205, 1145 40, 102, 33, 27, 255, 55, 214, 156, 1146 75, 163, 134, 126, 249, 74, 197, 228, 1147 72, 90, 206, 235, 17, 22, 49, 169, 1148 227, 89, 16, 5, 117, 60, 248, 230, 1149 217, 68, 138, 96, 194, 170, 136, 10, 1150 112, 238, 184, 189, 176, 42, 225, 212, 1151 84, 58, 175, 244, 150, 168, 219, 236, 1152 101, 208, 123, 37, 164, 110, 158, 201, 1153 78, 114, 57, 48, 70, 142, 106, 43, 1154 232, 26, 32, 252, 239, 98, 191, 94, 1155 59, 149, 39, 187, 203, 190, 19, 13, 1156 133, 45, 61, 247, 23, 34, 20, 52, 1157 118, 209, 146, 193, 222, 18, 1, 152, 1158 46, 41, 91, 148, 115, 25, 135, 77, 1159 254, 147, 224, 161, 9, 213, 223, 250, 1160 231, 251, 127, 166, 63, 179, 81, 130, 1161 139, 28, 120, 151, 241, 86, 111, 0, 1162 88, 153, 172, 182, 159, 105, 178, 47, 1163 51, 167, 65, 66, 92, 73, 198, 211, 1164 245, 195, 31, 220, 140, 76, 221, 186, 1165 154, 185, 56, 83, 38, 165, 109, 67, 1166 124, 226, 132, 53, 229, 29, 12, 181, 1167 121, 24, 207, 199, 177, 113, 30, 80, 1168 3, 97, 188, 79, 216, 173, 8, 145, 1169 87, 128, 180, 237, 240, 137, 125, 104, 1170 15, 242, 119, 246, 103, 143, 95, 144, 1171 2, 44, 69, 157, 192, 174, 14, 54, 1172 218, 82, 64, 210, 11, 6, 129, 21, 1173 116, 171, 99, 202, 7, 107, 253, 108 1174 }; 1175 1176 void initPermTexture(GLuint *texID) 1177 { 1178 glGenTextures(1, texID); 1179 glBindTexture(GL_TEXTURE_2D, *texID); 1180 1181 static bool initialized = false; 1182 static unsigned char permutation2D[256*256*4]; 1183 if( !initialized ) { 1184 int x, y; 1185 1186 for( y=0; y < 256; y++ ) 1187 for( x=0; x < 256; x++ ) 1188 permutation2D[x*4 + y*1024] = permutation256[(y + permutation256[x]) & 0xff]; 1189 1190 initialized = true; 1191 } 1192 1193 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, permutation2D ); 1194 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); 1195 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); 1196 } 1197 1198 void OGLTransitionImpl::preparePermShader() 1199 { 1200 #ifdef GL_VERSION_2_0 1201 if( mProgramObject ) { 1202 OGLShaders::glUseProgram( mProgramObject ); 1203 1204 GLint location = OGLShaders::glGetUniformLocation( mProgramObject, "leavingSlideTexture" ); 1205 if( location != -1 ) { 1206 OGLShaders::glUniform1i( location, 0 ); // texture unit 0 1207 } 1208 1209 glActiveTexture(GL_TEXTURE1); 1210 if( !maHelperTexture ) 1211 initPermTexture( &maHelperTexture ); 1212 glActiveTexture(GL_TEXTURE0); 1213 1214 location = OGLShaders::glGetUniformLocation( mProgramObject, "permTexture" ); 1215 if( location != -1 ) { 1216 OGLShaders::glUniform1i( location, 1 ); // texture unit 1 1217 } 1218 1219 location = OGLShaders::glGetUniformLocation( mProgramObject, "enteringSlideTexture" ); 1220 if( location != -1 ) { 1221 OGLShaders::glUniform1i( location, 2 ); // texture unit 2 1222 } 1223 } 1224 #endif 1225 } 1226 1227 void OGLTransitionImpl::prepareStatic( ::sal_Int32 /* glLeavingSlideTex */, ::sal_Int32 /* glEnteringSlideTex */ ) 1228 { 1229 mProgramObject = OGLShaders::LinkProgram( basicVertexShader, staticFragmentShader ); 1230 1231 preparePermShader(); 1232 } 1233 1234 void OGLTransitionImpl::displaySlidesShaders( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, 1235 double SlideWidthScale, double SlideHeightScale ) 1236 { 1237 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale ); 1238 1239 #ifdef GL_VERSION_2_0 1240 if( mProgramObject ) { 1241 GLint location = OGLShaders::glGetUniformLocation( mProgramObject, "time" ); 1242 if( location != -1 ) { 1243 OGLShaders::glUniform1f( location, nTime ); 1244 } 1245 } 1246 1247 glActiveTexture( GL_TEXTURE2 ); 1248 glBindTexture( GL_TEXTURE_2D, glEnteringSlideTex ); 1249 glActiveTexture( GL_TEXTURE0 ); 1250 #endif 1251 1252 displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale ); 1253 } 1254 1255 void OGLTransitionImpl::makeStatic() 1256 { 1257 Primitive Slide; 1258 1259 Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1)); 1260 Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1)); 1261 maLeavingSlidePrimitives.push_back (Slide); 1262 maEnteringSlidePrimitives.push_back (Slide); 1263 1264 mmDisplaySlides = &OGLTransitionImpl::displaySlidesShaders; 1265 mmPrepareTransition = &OGLTransitionImpl::prepareStatic; 1266 mbUseMipMapLeaving = mbUseMipMapEntering = false; 1267 1268 mnRequiredGLVersion = 2.0; 1269 } 1270 1271 void OGLTransitionImpl::prepareDissolve( ::sal_Int32 /* glLeavingSlideTex */, ::sal_Int32 /* glEnteringSlideTex */ ) 1272 { 1273 mProgramObject = OGLShaders::LinkProgram( basicVertexShader, dissolveFragmentShader ); 1274 1275 preparePermShader(); 1276 } 1277 1278 void OGLTransitionImpl::makeDissolve() 1279 { 1280 Primitive Slide; 1281 1282 Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1)); 1283 Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1)); 1284 maLeavingSlidePrimitives.push_back (Slide); 1285 maEnteringSlidePrimitives.push_back (Slide); 1286 1287 mmDisplaySlides = &OGLTransitionImpl::displaySlidesShaders; 1288 mmPrepareTransition = &OGLTransitionImpl::prepareDissolve; 1289 mbUseMipMapLeaving = mbUseMipMapEntering = false; 1290 1291 mnRequiredGLVersion = 2.0; 1292 } 1293 1294 void OGLTransitionImpl::makeNewsflash() 1295 { 1296 Primitive Slide; 1297 1298 Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1)); 1299 Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1)); 1300 Slide.Operations.push_back(new SRotate(basegfx::B3DVector(0,0,1),basegfx::B3DVector(0,0,0),3000,true,0,0.5)); 1301 Slide.Operations.push_back(new SScale(basegfx::B3DVector(0.01,0.01,0.01),basegfx::B3DVector(0,0,0),true,0,0.5)); 1302 Slide.Operations.push_back(new STranslate(basegfx::B3DVector(-10000, 0, 0),false, 0.5, 2)); 1303 maLeavingSlidePrimitives.push_back(Slide); 1304 1305 Slide.Operations.clear(); 1306 Slide.Operations.push_back(new SRotate(basegfx::B3DVector(0,0,1),basegfx::B3DVector(0,0,0),-3000,true,0.5,1)); 1307 Slide.Operations.push_back(new STranslate(basegfx::B3DVector(-100, 0, 0),false, -1, 1)); 1308 Slide.Operations.push_back(new STranslate(basegfx::B3DVector(100, 0, 0),false, 0.5, 1)); 1309 Slide.Operations.push_back(new SScale(basegfx::B3DVector(0.01,0.01,0.01),basegfx::B3DVector(0,0,0),false,-1,1)); 1310 Slide.Operations.push_back(new SScale(basegfx::B3DVector(100,100,100),basegfx::B3DVector(0,0,0),true,0.5,1)); 1311 maEnteringSlidePrimitives.push_back(Slide); 1312 1313 OverallOperations.push_back(new SRotate(basegfx::B3DVector(0,0,1),basegfx::B3DVector(0.2,0.2,0),1080,true,0,1)); 1314 } 1315 1316