void particlesUpdateBB(CompOutput *output, CompWindow *w) { ANIM_WINDOW(w); int i; for (i = 0; i < aw->numPs; i++) { ParticleSystem *ps = &aw->ps[i]; if (ps->active) { int j; for (j = 0; j < ps->numParticles; j++) { Particle *part = &ps->particles[j]; float w = part->width / 2; float h = part->height / 2; w += (w * part->w_mod) * part->life; h += (h * part->h_mod) * part->life; Box particleBox = {part->x - w, part->x + w, part->y - h, part->y + h}; expandBoxWithBox (&aw->BB, &particleBox); } } } if (aw->useDrawRegion) { int nClip = aw->drawRegion->numRects; Box *pClip = aw->drawRegion->rects; for (; nClip--; pClip++) expandBoxWithBox (&aw->BB, pClip); } else // drawing full window updateBBWindow (output, w); }
CompOptionValue * animGetPluginOptVal (CompWindow *w, ExtensionPluginInfo *pluginInfo, int optionId) { ANIM_WINDOW (w); ANIM_SCREEN (w->screen); OptionSet *os = &as->eventOptionSets[win2AnimEventMap[aw->com.curWindowEvent]]. sets[aw->curAnimSelectionRow]; IdValuePair *pair = os->pairs; int i; for (i = 0; i < os->nPairs; i++, pair++) if (pair->pluginInfo == pluginInfo && pair->optionId == optionId) return &pair->value; return &pluginInfo->effectOptions[optionId].value; }
Bool fxSidekickInit (CompWindow * w) { ANIM_WINDOW(w); // determine number of rotations randomly in [0.9, 1.1] range aw->numZoomRotations = animGetF (w, ANIM_SCREEN_OPTION_SIDEKICK_NUM_ROTATIONS) * (1.0f + 0.2f * rand() / RAND_MAX - 0.1f); float winCenterX = WIN_X(w) + WIN_W(w) / 2.0; float iconCenterX = aw->com.icon.x + aw->com.icon.width / 2.0; // if window is to the right of icon, rotate clockwise instead // to make rotation look more pleasant if (winCenterX > iconCenterX) aw->numZoomRotations *= -1; return fxZoomInit (w); }
static float fxZoomGetSpringiness (CompWindow *w) { ANIM_WINDOW (w); const BananaValue * option_zoom_springiness = bananaGetOption (bananaIndex, "zoom_springiness", w->screen->screenNum); const BananaValue * option_sidekick_springiness = bananaGetOption (bananaIndex, "sidekick_springiness", w->screen->screenNum); if (aw->com.curAnimEffect == AnimEffectZoom) return 2 * option_zoom_springiness->f; else if (aw->com.curAnimEffect == AnimEffectSidekick) return 1.6 * option_sidekick_springiness->f; else return 0.0f; }
void fxGlideUpdateWindowAttrib(AnimScreen *as, CompWindow *w, WindowPaintAttrib *wAttrib) { ANIM_WINDOW(w); if (fxGlideIsPolygonBased(as, aw)) return; // the effect is CompTransform-based if (fxGlideZoomToTaskBar(as, aw)) { fxZoomUpdateWindowAttrib(as, w, wAttrib); return; } float forwardProgress = fxGlideAnimProgress(aw); wAttrib->opacity = aw->storedOpacity * (1 - forwardProgress); }
void fxRollUpModelStep (CompWindow *w, float time) { defaultAnimStep (w, time); ANIM_WINDOW(w); Model *model = aw->com.model; float forwardProgress = sigmoidAnimProgress (w); Bool fixedInterior = animGetB (w, ANIM_SCREEN_OPTION_ROLLUP_FIXED_INTERIOR); Object *object = model->objects; int i; for (i = 0; i < model->numObjects; i++, object++) fxRollUpModelStepObject (w, model, object, forwardProgress, fixedInterior); }
void fxDodgeAnimStep (CompWindow *w, float time) { XRectangle dodgeBox; defaultAnimStep (w, time); ANIM_WINDOW(w); aw->com.transformProgress = 0; float forwardProgress = defaultAnimProgress (w); if (forwardProgress > aw->com.transformStartProgress) { aw->com.transformProgress = (forwardProgress - aw->com.transformStartProgress) / (1 - aw->com.transformStartProgress); } if (!aw->isDodgeSubject && aw->com.transformProgress <= 0.5f && fxDodgeFindDodgeBox (w, &dodgeBox)) { // Update dodge amount if subject window has moved during dodge float newDodgeAmount = DODGE_AMOUNT_BOX(dodgeBox, w, aw->dodgeDirection); // Only update if amount got larger if (((newDodgeAmount > 0 && aw->dodgeMaxAmount > 0) || (newDodgeAmount < 0 && aw->dodgeMaxAmount < 0)) && abs(newDodgeAmount) > abs(aw->dodgeMaxAmount)) { aw->dodgeMaxAmount = newDodgeAmount; } } matrixGetIdentity (&aw->com.transform); applyDodgeTransform (w, &aw->com.transform); }
Bool fxCurvedFoldModelStep(CompScreen *s, CompWindow *w, float time) { if (!defaultAnimStep(s, w, time)) return FALSE; ANIM_SCREEN(s); ANIM_WINDOW(w); Model *model = aw->model; float forwardProgress; if ((aw->curWindowEvent == WindowEventMinimize || aw->curWindowEvent == WindowEventUnminimize) && animGetB(as, aw, ANIM_SCREEN_OPTION_CURVED_FOLD_Z2TOM)) { float dummy; fxZoomAnimProgress(as, aw, &forwardProgress, &dummy, TRUE); } else forwardProgress = defaultAnimProgress(aw); float curveMaxAmp = animGetF(as, aw, ANIM_SCREEN_OPTION_CURVED_FOLD_AMP) * WIN_W(w) * pow(WIN_H(w) / (s->height * 1.2f), 0.7); int i; for (i = 0; i < model->numObjects; i++) fxCurvedFoldModelStepObject (w, model, &model->objects[i], forwardProgress, curveMaxAmp); return TRUE; }
void fxHorizontalFoldsModelStep(CompWindow * w, float time) { defaultAnimStep(w, time); ANIM_WINDOW(w); Model *model = aw->com.model; float winHeight = 0; if (aw->com.curWindowEvent == WindowEventShade || aw->com.curWindowEvent == WindowEventUnshade) { winHeight = (w)->height; } else { winHeight = BORDER_H(w); } int nHalfFolds = 2.0 * animGetI(w, ANIM_SCREEN_OPTION_HORIZONTAL_FOLDS_NUM_FOLDS); float foldMaxAmp = 0.3 * pow((winHeight / nHalfFolds) / w->screen->height, 0.3) * animGetF(w, ANIM_SCREEN_OPTION_HORIZONTAL_FOLDS_AMP_MULT); float forwardProgress = getProgressAndCenter(w, NULL); float sinForProg = sin(forwardProgress * M_PI / 2); Object *object = model->objects; int i; for (i = 0; i < model->numObjects; i++, object++) fxHorizontalFoldsModelStepObject(w, model, object, forwardProgress, sinForProg, foldMaxAmp, i / model->gridWidth); }
void fxZoomAnimProgress (CompWindow *w, float *moveProgress, float *scaleProgress, Bool neverSpringy) { ANIM_WINDOW(w); float forwardProgress = 1 - aw->com.animRemainingTime / (aw->com.animTotalTime - aw->com.timestep); forwardProgress = MIN(forwardProgress, 1); forwardProgress = MAX(forwardProgress, 0); float x = forwardProgress; Bool backwards = FALSE; int animProgressDir = 1; if (aw->com.curWindowEvent == WindowEventUnminimize || aw->com.curWindowEvent == WindowEventOpen) animProgressDir = 2; if (aw->com.animOverrideProgressDir != 0) animProgressDir = aw->com.animOverrideProgressDir; if ((animProgressDir == 1 && (aw->com.curWindowEvent == WindowEventUnminimize || aw->com.curWindowEvent == WindowEventOpen)) || (animProgressDir == 2 && (aw->com.curWindowEvent == WindowEventMinimize || aw->com.curWindowEvent == WindowEventClose))) backwards = TRUE; if (backwards) x = 1 - x; float dampBase = (pow(1-pow(x,1.2)*0.5,10)-pow(0.5,10))/(1-pow(0.5,10)); float nonSpringyProgress = 1 - pow(decelerateProgressCustom(1 - x, .5f, .8f), 1.7f); if (moveProgress && scaleProgress) { float damping = pow(dampBase, 0.5); float damping2 = ((pow(1-(pow(x,0.7)*0.5),10)-pow(0.5,10))/(1-pow(0.5,10))) * 0.7 + 0.3; float springiness = 0; // springy only when appearing if ((aw->com.curWindowEvent == WindowEventUnminimize || aw->com.curWindowEvent == WindowEventOpen) && !neverSpringy) { springiness = fxZoomGetSpringiness (w); } float springyMoveProgress = cos(2*M_PI*pow(x,1)*1.25) * damping * damping2; if (springiness > 1e-4f) { if (x > 0.2) { springyMoveProgress *= springiness; } else { // interpolate between (springyMoveProgress * springiness) // and springyMoveProgress for smooth transition at 0.2 // (where it crosses y=0) float progressUpto02 = x / 0.2f; springyMoveProgress = (1 - progressUpto02) * springyMoveProgress + progressUpto02 * springyMoveProgress * springiness; } *moveProgress = 1 - springyMoveProgress; } else { *moveProgress = nonSpringyProgress; } if (aw->com.curWindowEvent == WindowEventUnminimize || aw->com.curWindowEvent == WindowEventOpen) *moveProgress = 1 - *moveProgress; if (backwards) *moveProgress = 1 - *moveProgress; float scProgress = nonSpringyProgress; if (aw->com.curWindowEvent == WindowEventUnminimize || aw->com.curWindowEvent == WindowEventOpen) scProgress = 1 - scProgress; if (backwards) scProgress = 1 - scProgress; *scaleProgress = pow(scProgress, 1.25); } }
static void inline fxRollUpModelStepObject(CompWindow * w, Model * model, Object * object, float forwardProgress, Bool fixedInterior) { ANIM_WINDOW(w); float origx = WIN_X(w) + WIN_W(w) * object->gridPosition.x; if (aw->com.curWindowEvent == WindowEventShade || aw->com.curWindowEvent == WindowEventUnshade) { // Execute shade mode // find position in window contents // (window contents correspond to 0.0-1.0 range) float relPosInWinContents = (object->gridPosition.y * WIN_H(w) - model->topHeight) / w->height; if (object->gridPosition.y == 0) { object->position.x = origx; object->position.y = WIN_Y(w); } else if (object->gridPosition.y == 1) { object->position.x = origx; object->position.y = (1 - forwardProgress) * (WIN_Y(w) + WIN_H(w) * object->gridPosition.y) + forwardProgress * (WIN_Y(w) + model->topHeight + model->bottomHeight); } else { object->position.x = origx; if (relPosInWinContents > forwardProgress) { object->position.y = (1 - forwardProgress) * (WIN_Y(w) + WIN_H(w) * object->gridPosition.y) + forwardProgress * (WIN_Y(w) + model->topHeight); if (fixedInterior) object->offsetTexCoordForQuadBefore.y = -forwardProgress * w->height; } else { object->position.y = WIN_Y(w) + model->topHeight; if (!fixedInterior) object->offsetTexCoordForQuadAfter. y = (forwardProgress - relPosInWinContents) * w->height; } } } }
Bool fxAirplaneInit (CompWindow *w) { if (!polygonsAnimInit (w)) return FALSE; if (!tessellateIntoAirplane (w)) return FALSE; ANIM_WINDOW (w); const BananaValue * option_airplane_path_length = bananaGetOption (bananaIndex, "airplane_path_length", w->screen->screenNum); float airplanePathLength = option_airplane_path_length->f; PolygonSet *pset = aw->eng.polygonSet; PolygonObject *p = pset->polygons; float winLimitsW; // boundaries of polygon tessellation float winLimitsH; winLimitsW = BORDER_W (w); winLimitsH = BORDER_H (w); float H4 = (float)winLimitsH / 4; float H6 = (float)winLimitsH / 6; int i; for (i = 0; i < pset->nPolygons; i++, p++) { if (!p->effectParameters) { p->effectParameters = calloc (1, sizeof (AirplaneEffectParameters)); } if (!p->effectParameters) { compLogMessage ("animation", CompLogLevelError, "Not enough memory"); return FALSE; } AirplaneEffectParameters *aep = p->effectParameters; p->moveStartTime = 0.00; p->moveDuration = 0.19; aep->moveStartTime2 = 0.19; aep->moveDuration2 = 0.19; aep->moveStartTime3 = 0.38; aep->moveDuration3 = 0.19; aep->moveStartTime4 = 0.58; aep->moveDuration4 = 0.09; aep->moveDuration5 = 0.41; aep->flyFinalRotation.x = 90; aep->flyFinalRotation.y = 10; aep->flyTheta = 0; aep->centerPosFly.x = 0; aep->centerPosFly.y = 0; aep->centerPosFly.z = 0; aep->flyScale = 0; aep->flyFinalScale = 6 * (winLimitsW / (w->screen->width / 2)); switch (i) { case 0: p->rotAxisOffset.x = -H4; p->rotAxisOffset.y = H4; p->rotAxis.x = 1.00; p->rotAxis.y = 1.00; p->rotAxis.z = 0.00; p->finalRotAng = 179.5; aep->rotAxisOffsetA.x = 0; aep->rotAxisOffsetA.y = 0; aep->rotAxisA.x = 1.00; aep->rotAxisA.y = 0.00; aep->rotAxisA.z = 0.00; aep->finalRotAngA = 84; aep->rotAxisOffsetB.x = 0; aep->rotAxisOffsetB.y = 0; aep->rotAxisB.x = 0.00; aep->rotAxisB.y = 0.00; aep->rotAxisB.z = 0.00; aep->finalRotAngB = 0; break; case 1: p->rotAxisOffset.x = -H4; p->rotAxisOffset.y = H4; p->rotAxis.x = 1.00; p->rotAxis.y = 1.00; p->rotAxis.z = 0.00; p->finalRotAng = 179.5; aep->rotAxisOffsetA.x = 0; aep->rotAxisOffsetA.y = 0; aep->rotAxisA.x = 1.00; aep->rotAxisA.y = 0.00; aep->rotAxisA.z = 0.00; aep->finalRotAngA = 84; aep->rotAxisOffsetB.x = 0; aep->rotAxisOffsetB.y = H6; aep->rotAxisB.x = 1.00; aep->rotAxisB.y = 0.00; aep->rotAxisB.z = 0.00; aep->finalRotAngB = -84; break; case 2: p->moveDuration = 0.00; p->rotAxisOffset.x = 0; p->rotAxisOffset.y = 0; p->rotAxis.x = 0.00; p->rotAxis.y = 0.00; p->rotAxis.z = 0.00; p->finalRotAng = 0; aep->rotAxisOffsetA.x = 0; aep->rotAxisOffsetA.y = 0; aep->rotAxisA.x = 1.00; aep->rotAxisA.y = 0.00; aep->rotAxisA.z = 0.00; aep->finalRotAngA = 84; aep->rotAxisOffsetB.x = 0; aep->rotAxisOffsetB.y = H6; aep->rotAxisB.x = 1.00; aep->rotAxisB.y = 0.00; aep->rotAxisB.z = 0.00; aep->finalRotAngB = -84; break; case 3: p->moveDuration = 0.00; p->rotAxisOffset.x = 0; p->rotAxisOffset.y = 0; p->rotAxis.x = 0.00; p->rotAxis.y = 0.00; p->rotAxis.z = 0.00; p->finalRotAng = 0; aep->rotAxisOffsetA.x = 0; aep->rotAxisOffsetA.y = 0; aep->rotAxisA.x = 1.00; aep->rotAxisA.y = 0.00; aep->rotAxisA.z = 0.00; aep->finalRotAngA = 84; aep->moveDuration3 = 0.00; aep->rotAxisOffsetB.x = 0; aep->rotAxisOffsetB.y = 0; aep->rotAxisB.x = 0.00; aep->rotAxisB.y = 0.00; aep->rotAxisB.z = 0.00; aep->finalRotAngB = 0; break; case 4: p->moveDuration = 0.00; p->rotAxisOffset.x = 0; p->rotAxisOffset.y = 0; p->rotAxis.x = 0.00; p->rotAxis.y = 0.00; p->rotAxis.z = 0.00; p->finalRotAng = 0; aep->rotAxisOffsetA.x = 0; aep->rotAxisOffsetA.y = 0; aep->rotAxisA.x = 1.00; aep->rotAxisA.y = 0.00; aep->rotAxisA.z = 0.00; aep->finalRotAngA = -84; aep->moveDuration3 = 0.00; aep->rotAxisOffsetB.x = 0; aep->rotAxisOffsetB.y = 0; aep->rotAxisB.x = 0.00; aep->rotAxisB.y = 0.00; aep->rotAxisB.z = 0.00; aep->finalRotAngB = 0; break; case 5: p->moveDuration = 0.00; p->rotAxisOffset.x = 0; p->rotAxisOffset.y = 0; p->rotAxis.x = 0.00; p->rotAxis.y = 0.00; p->rotAxis.z = 0.00; p->finalRotAng = 0; aep->rotAxisOffsetA.x = 0; aep->rotAxisOffsetA.y = 0; aep->rotAxisA.x = 1.00; aep->rotAxisA.y = 0.00; aep->rotAxisA.z = 0.00; aep->finalRotAngA = -84; aep->rotAxisOffsetB.x = 0; aep->rotAxisOffsetB.y = -H6; aep->rotAxisB.x = 1.00; aep->rotAxisB.y = 0.00; aep->rotAxisB.z = 0.00; aep->finalRotAngB = 84; break; case 6: p->rotAxisOffset.x = -H4; p->rotAxisOffset.y = -H4; p->rotAxis.x = 1.00; p->rotAxis.y = -1.00; p->rotAxis.z = 0.00; p->finalRotAng = -179.5; aep->rotAxisOffsetA.x = 0; aep->rotAxisOffsetA.y = 0; aep->rotAxisA.x = 1.00; aep->rotAxisA.y = 0.00; aep->rotAxisA.z = 0.00; aep->finalRotAngA = -84; aep->rotAxisOffsetB.x = 0; aep->rotAxisOffsetB.y = -H6; aep->rotAxisB.x = 1.00; aep->rotAxisB.y = 0.00; aep->rotAxisB.z = 0.00; aep->finalRotAngB = 84; break; case 7: p->rotAxisOffset.x = -H4; p->rotAxisOffset.y = -H4; p->rotAxis.x = 1.00; p->rotAxis.y = -1.00; p->rotAxis.z = 0.00; p->finalRotAng = -179.5; aep->rotAxisOffsetA.x = 0; aep->rotAxisOffsetA.y = 0; aep->rotAxisA.x = 1.00; aep->rotAxisA.y = 0.00; aep->rotAxisA.z = 0.00; aep->finalRotAngA = -84; aep->rotAxisOffsetB.x = 0; aep->rotAxisOffsetB.y = 0; aep->rotAxisB.x = 0.00; aep->rotAxisB.y = 0.00; aep->rotAxisB.z = 0.00; aep->finalRotAngB = 0; break; } } if (airplanePathLength >= 1) pset->allFadeDuration = 0.30f / airplanePathLength; else pset->allFadeDuration = 0.30f; pset->doDepthTest = TRUE; pset->doLighting = TRUE; pset->correctPerspective = CorrectPerspectivePolygon; pset->extraPolygonTransformFunc = &AirplaneExtraPolygonTransformFunc; // Duration extension aw->com.animTotalTime *= 2 + airplanePathLength; aw->com.animRemainingTime = aw->com.animTotalTime; return TRUE; }
Bool fxSkewerInit (CompWindow *w) { if (!polygonsAnimInit (w)) return FALSE; CompScreen *s = w->screen; ANIM_WINDOW (w); aw->com.animTotalTime /= SKEWER_PERCEIVED_T; aw->com.animRemainingTime = aw->com.animTotalTime; const BananaValue * option_skewer_direction = bananaGetOption (bananaIndex, "skewer_direction", s->screenNum); const BananaValue * option_skewer_tessellation = bananaGetOption (bananaIndex, "skewer_tessellation", s->screenNum); const BananaValue * option_skewer_thickness = bananaGetOption (bananaIndex, "skewer_thickness", s->screenNum); const BananaValue * option_skewer_rotation = bananaGetOption (bananaIndex, "skewer_rotation", s->screenNum); const BananaValue * option_skewer_gridx = bananaGetOption (bananaIndex, "skewer_gridx", s->screenNum); const BananaValue * option_skewer_gridy = bananaGetOption (bananaIndex, "skewer_gridy", s->screenNum); float thickness = option_skewer_thickness->f; int rotation = option_skewer_rotation->i; int gridSizeX = option_skewer_gridx->i; int gridSizeY = option_skewer_gridy->i; int dir[2]; // directions array int c = 0; // number of directions getDirection (dir, &c, option_skewer_direction->i); if (option_skewer_tessellation->i == PolygonTessHex) { if (!tessellateIntoHexagons (w, gridSizeX, gridSizeY, thickness)) return FALSE; } else { if (!tessellateIntoRectangles (w, gridSizeX, gridSizeY, thickness)) return FALSE; } PolygonSet *pset = aw->eng.polygonSet; PolygonObject *p = pset->polygons; int times[pset->nPolygons]; int last_time = pset->nPolygons - 1; int i; for (i = 0; i < pset->nPolygons; i++) times[i] = i; for (i = 0; i < pset->nPolygons; i++, p++) { if (c > 0) { switch (dir[(int)floor (RAND_FLOAT () * c)]) { case 0: // left p->finalRelPos.x = -s->width; p->rotAxis.x = rotation; break; case 1: // right p->finalRelPos.x = s->width; p->rotAxis.x = rotation; break; case 2: // up p->finalRelPos.y = -s->height; p->rotAxis.y = rotation; break; case 3: // down p->finalRelPos.y = s->height; p->rotAxis.y = rotation; break; case 4: // in p->finalRelPos.z = -.8 * DEFAULT_Z_CAMERA * s->width; p->rotAxis.x = rotation; p->rotAxis.y = rotation; break; case 5: // out p->finalRelPos.z = .8 * DEFAULT_Z_CAMERA * s->width; p->rotAxis.x = rotation; p->rotAxis.y = rotation; break; } p->finalRotAng = rotation; } // if no direction is set - just fade // choose random start_time int rand_time = floor (RAND_FLOAT () * last_time); p->moveStartTime = 0.8 / (float)pset->nPolygons * times[rand_time]; p->moveDuration = 1 - p->moveStartTime; p->fadeStartTime = p->moveStartTime + 0.2; p->fadeDuration = 1 - p->fadeStartTime; times[rand_time] = times[last_time]; // copy last one over times[rand_time] last_time--; //descrease last_time } pset->doDepthTest = TRUE; pset->doLighting = TRUE; pset->correctPerspective = CorrectPerspectiveWindow; return TRUE; }
void fxSkewerInit(CompScreen *s, CompWindow *w) { ANIM_SCREEN (s); ANIM_WINDOW (w); aw->animTotalTime /= SKEWER_PERCEIVED_T; aw->animRemainingTime = aw->animTotalTime; float thickness = animGetF (as, aw, ANIM_SCREEN_OPTION_SKEWER_THICKNESS); int rotation = animGetI (as, aw, ANIM_SCREEN_OPTION_SKEWER_ROTATION); int gridSizeX = animGetI (as, aw, ANIM_SCREEN_OPTION_SKEWER_GRIDSIZE_X); int gridSizeY = animGetI (as, aw, ANIM_SCREEN_OPTION_SKEWER_GRIDSIZE_Y); int dir[2]; // directions array int c = 0; // number of directions getDirection (dir, &c, animGetI (as, aw, ANIM_SCREEN_OPTION_SKEWER_DIRECTION)); if (animGetI (as, aw, ANIM_SCREEN_OPTION_SKEWER_TESS) == PolygonTessHex) { if (!tessellateIntoHexagons (w, gridSizeX, gridSizeY, thickness)) return; } else { if (!tessellateIntoRectangles (w, gridSizeX, gridSizeY, thickness)) return; } PolygonSet *pset = aw->polygonSet; PolygonObject *p = pset->polygons; int times[pset->nPolygons]; int last_time = pset->nPolygons - 1; int i; for (i = 0; i < pset->nPolygons; i++) times[i] = i; for (i = 0; i < pset->nPolygons; i++, p++) { if (c > 0) { switch (dir[(int)floor (RAND_FLOAT () * c)]) { case 0: // left p->finalRelPos.x = -s->width; p->rotAxis.x = rotation; break; case 1: // right p->finalRelPos.x = s->width; p->rotAxis.x = rotation; break; case 2: // up p->finalRelPos.y = -s->height; p->rotAxis.y = rotation; break; case 3: // down p->finalRelPos.y = s->height; p->rotAxis.y = rotation; break; case 4: // in p->finalRelPos.z = -.8 * DEFAULT_Z_CAMERA * s->width; p->rotAxis.x = rotation; p->rotAxis.y = rotation; break; case 5: // out p->finalRelPos.z = .8 * DEFAULT_Z_CAMERA * s->width; p->rotAxis.x = rotation; p->rotAxis.y = rotation; break; } p->finalRotAng = rotation; } // if no direction is set - just fade // choose random start_time int rand_time = floor (RAND_FLOAT () * last_time); p->moveStartTime = 0.8 / (float)pset->nPolygons * times[rand_time]; p->moveDuration = 1 - p->moveStartTime; p->fadeStartTime = p->moveStartTime + 0.2; p->fadeDuration = 1 - p->fadeStartTime; times[rand_time] = times[last_time]; // copy last one over times[rand_time] last_time--; //descrease last_time } pset->doDepthTest = TRUE; pset->doLighting = TRUE; pset->correctPerspective = CorrectPerspectiveWindow; }
Bool fxLeafSpreadInit (CompWindow *w) { if (!polygonsAnimInit (w)) return FALSE; CompScreen *s = w->screen; ANIM_WINDOW (w); if (!tessellateIntoRectangles (w, 20, 14, 15.0f)) return FALSE; PolygonSet *pset = aw->eng.polygonSet; PolygonObject *p = pset->polygons; float fadeDuration = 0.26; float life = 0.4; float spreadFac = 3.5; float randYMax = 0.07; float winFacX = WIN_W (w) / 800.0; float winFacY = WIN_H (w) / 800.0; float winFacZ = (WIN_H (w) + WIN_W (w)) / 2.0 / 800.0; int i; for (i = 0; i < pset->nPolygons; i++, p++) { p->rotAxis.x = RAND_FLOAT (); p->rotAxis.y = RAND_FLOAT (); p->rotAxis.z = RAND_FLOAT (); float screenSizeFactor = (0.8 * DEFAULT_Z_CAMERA * s->width); float speed = screenSizeFactor / 10 * (0.2 + RAND_FLOAT ()); float xx = 2 * (p->centerRelPos.x - 0.5); float yy = 2 * (p->centerRelPos.y - 0.5); float x = speed * winFacX * spreadFac * (xx + 0.5 * (RAND_FLOAT () - 0.5)); float y = speed * winFacY * spreadFac * (yy + 0.5 * (RAND_FLOAT () - 0.5)); float z = speed * winFacZ * 7 * ((RAND_FLOAT () - 0.5) / 0.5); p->finalRelPos.x = x; p->finalRelPos.y = y; p->finalRelPos.z = z; p->moveStartTime = p->centerRelPos.y * (1 - fadeDuration - randYMax) + randYMax * RAND_FLOAT (); p->moveDuration = 1; p->fadeStartTime = p->moveStartTime + life; if (p->fadeStartTime > 1 - fadeDuration) p->fadeStartTime = 1 - fadeDuration; p->fadeDuration = fadeDuration; p->finalRotAng = 150; } pset->doDepthTest = TRUE; pset->doLighting = TRUE; pset->correctPerspective = CorrectPerspectivePolygon; aw->com.animTotalTime /= LEAFSPREAD_PERCEIVED_T; aw->com.animRemainingTime = aw->com.animTotalTime; return TRUE; }
Bool fxExplodeInit (CompWindow *w) { if (!polygonsAnimInit (w)) return FALSE; CompScreen *s = w->screen; ANIM_WINDOW (w); const BananaValue * option_explode_gridx = bananaGetOption (bananaIndex, "explode_gridx", s->screenNum); const BananaValue * option_explode_gridy = bananaGetOption (bananaIndex, "explode_gridy", s->screenNum); const BananaValue * option_explode_spokes = bananaGetOption (bananaIndex, "explode_spokes", s->screenNum); const BananaValue * option_explode_tiers = bananaGetOption (bananaIndex, "explode_tiers", s->screenNum); const BananaValue * option_explode_thickness = bananaGetOption (bananaIndex, "explode_thickness", s->screenNum); const BananaValue * option_explode_tessellation = bananaGetOption (bananaIndex, "explode_tessellation", s->screenNum); switch (option_explode_tessellation->i) { case PolygonTessRect: if (!tessellateIntoRectangles (w, option_explode_gridx->i, option_explode_gridy->i, option_explode_thickness->f)) return FALSE; break; case PolygonTessHex: if (!tessellateIntoHexagons (w, option_explode_gridx->i, option_explode_gridy->i, option_explode_thickness->f)) return FALSE; break; case PolygonTessGlass: if (!tessellateIntoGlass (w, option_explode_spokes->i, option_explode_tiers->i, option_explode_thickness->f)) return FALSE; break; default: return FALSE; } PolygonSet *pset = aw->eng.polygonSet; PolygonObject *p = pset->polygons; double sqrt2 = sqrt (2); int i; for (i = 0; i < pset->nPolygons; i++, p++) { p->rotAxis.x = RAND_FLOAT (); p->rotAxis.y = RAND_FLOAT (); p->rotAxis.z = RAND_FLOAT (); float screenSizeFactor = (0.8 * DEFAULT_Z_CAMERA * s->width); float speed = screenSizeFactor / 10 * (0.2 + RAND_FLOAT ()); float xx = 2 * (p->centerRelPos.x - 0.5); float yy = 2 * (p->centerRelPos.y - 0.5); float x = speed * 2 * (xx + 0.5 * (RAND_FLOAT () - 0.5)); float y = speed * 2 * (yy + 0.5 * (RAND_FLOAT () - 0.5)); float distToCenter = sqrt (xx * xx + yy * yy) / sqrt2; float moveMult = 1 - distToCenter; moveMult = moveMult < 0 ? 0 : moveMult; float zbias = 0.1; float z = speed * 10 * (zbias + RAND_FLOAT () * pow (moveMult, 0.5)); p->finalRelPos.x = x; p->finalRelPos.y = y; p->finalRelPos.z = z; p->finalRotAng = RAND_FLOAT () * 540 - 270; } pset->allFadeDuration = 0.3f; pset->doDepthTest = TRUE; pset->doLighting = TRUE; pset->correctPerspective = CorrectPerspectivePolygon; pset->backAndSidesFadeDur = 0.2f; aw->com.animTotalTime /= EXPLODE_PERCEIVED_T; aw->com.animRemainingTime = aw->com.animTotalTime; return TRUE; }
// Returns FALSE if the subject is destroyed or if there was an error when // calculating the dodge box static Bool fxDodgeFindDodgeBox (CompWindow *w, XRectangle *dodgeBox) { ANIM_SCREEN(w->screen); ANIM_WINDOW(w); if (!aw->dodgeSubjectWin) // if the subject is destroyed return FALSE; // Find the box to be dodged, it can contain multiple windows // when there are dialog/utility windows of subject windows // (stacked in the moreToBePaintedNext chain) // Then this would be a bounding box of the subject windows // intersecting with dodger. Region wRegion = XCreateRegion(); if (!wRegion) return FALSE; Region dodgeRegion = XCreateRegion(); if (!dodgeRegion) { XDestroyRegion (wRegion); return FALSE; } XRectangle rect; rect.x = WIN_X(w); rect.y = WIN_Y(w); rect.width = WIN_W(w); rect.height = WIN_H(w); int dodgeMaxAmount = (int)aw->dodgeMaxAmount; // to compute if subject(s) intersect with dodger w, // enlarge dodger window's box so that it encloses all of the covered // region during dodge movement. This corrects the animation when // there are >1 subjects (a window with its dialog/utility windows). switch (aw->dodgeDirection) { case 0: rect.y += dodgeMaxAmount; rect.height -= dodgeMaxAmount; break; case 1: rect.height += dodgeMaxAmount; break; case 2: rect.x += dodgeMaxAmount; rect.width -= dodgeMaxAmount; break; case 3: rect.width += dodgeMaxAmount; break; } XUnionRectWithRegion(&rect, &emptyRegion, wRegion); AnimWindow *awCur; CompWindow *wCur = aw->dodgeSubjectWin; for (; wCur; wCur = awCur->moreToBePaintedNext) { fxDodgeProcessSubject(wCur, wRegion, dodgeRegion, wCur == aw->dodgeSubjectWin); awCur = GET_ANIM_WINDOW(wCur, as); if (!awCur) break; } AnimWindow *awSubj = GET_ANIM_WINDOW(aw->dodgeSubjectWin, as); wCur = awSubj->moreToBePaintedPrev; for (; wCur; wCur = awCur->moreToBePaintedPrev) { fxDodgeProcessSubject(wCur, wRegion, dodgeRegion, FALSE); awCur = GET_ANIM_WINDOW(wCur, as); if (!awCur) break; } XClipBox(dodgeRegion, dodgeBox); XDestroyRegion (wRegion); XDestroyRegion (dodgeRegion); return TRUE; }
void fxDodgePostPreparePaintScreen (CompWindow *w) { ANIM_SCREEN(w->screen); ANIM_WINDOW(w); // Only dodge subjects should be processed here if (!aw->isDodgeSubject) return; if (!aw->restackInfo) return; if (aw->skipPostPrepareScreen) return; // Dodgy window CompWindow *dw; AnimWindow *adw = NULL; for (dw = aw->dodgeChainStart; dw; dw = adw->dodgeChainNext) { adw = GET_ANIM_WINDOW(dw, as); if (!adw) break; // find the first dodging window that hasn't yet // reached 50% progress yet. The subject window should be // painted right behind that one (or right in front of it if // the subject window is being lowered). if (!(adw->com.transformProgress > 0.5f)) break; } AnimWindow *awOldHost = NULL; if (aw->restackInfo->raised && dw != aw->winThisIsPaintedBefore) // w's host is changing { if (aw->winThisIsPaintedBefore) { // Clear old host awOldHost = GET_ANIM_WINDOW(aw->winThisIsPaintedBefore, as); awOldHost->winToBePaintedBeforeThis = NULL; } if (dw && adw) // if a dodgy win. is still at <0.5 progress { // Put subject right behind adw (new host) adw->winToBePaintedBeforeThis = w; } // otherwise all dodgy win.s have passed 0.5 progress CompWindow *wCur = w; while (wCur) { AnimWindow *awCur = GET_ANIM_WINDOW(wCur, as); awCur->winThisIsPaintedBefore = dw; // dw can be null, which is ok wCur = awCur->moreToBePaintedNext; } } else if (!aw->restackInfo->raised) { // Put subject right in front of dw // But we need to find the dodgy window above dw // (since we need to put subject *behind* another one) CompWindow *wDodgeChainAbove = NULL; if (dw && adw) // if a dodgy win. is still at <0.5 progress { if (adw->dodgeChainPrev) wDodgeChainAbove = adw->dodgeChainPrev; else wDodgeChainAbove = aw->restackInfo->wOldAbove; if (!wDodgeChainAbove) compLogMessage ("animation", CompLogLevelError, "%s: error at line %d", __FILE__, __LINE__); else if (aw->winThisIsPaintedBefore != wDodgeChainAbove) // w's host is changing { AnimWindow *adw2 = GET_ANIM_WINDOW(wDodgeChainAbove, as); // Put subject right behind adw2 (new host) adw2->winToBePaintedBeforeThis = w; } } if (aw->winThisIsPaintedBefore && aw->winThisIsPaintedBefore != wDodgeChainAbove) { awOldHost = GET_ANIM_WINDOW(aw->winThisIsPaintedBefore, as); // Clear old host awOldHost->winToBePaintedBeforeThis = NULL; } // otherwise all dodgy win.s have passed 0.5 progress // wDodgeChainAbove can be null, which is ok aw->winThisIsPaintedBefore = wDodgeChainAbove; } }
static void fxCurvedFoldModelStepObject(CompWindow *w, Model *model, Object *object, float forwardProgress, float curveMaxAmp) { ANIM_WINDOW(w); float origx = w->attrib.x + (WIN_W(w) * object->gridPosition.x - w->output.left) * model->scale.x; float origy = w->attrib.y + (WIN_H(w) * object->gridPosition.y - w->output.top) * model->scale.y; if (aw->curWindowEvent == WindowEventShade || aw->curWindowEvent == WindowEventUnshade) { // Execute shade mode // find position in window contents // (window contents correspond to 0.0-1.0 range) float relPosInWinContents = (object->gridPosition.y * WIN_H(w) - model->topHeight) / w->height; float relDistToCenter = fabs(relPosInWinContents - 0.5); if (object->gridPosition.y == 0) { object->position.x = origx; object->position.y = WIN_Y(w); } else if (object->gridPosition.y == 1) { object->position.x = origx; object->position.y = (1 - forwardProgress) * origy + forwardProgress * (WIN_Y(w) + model->topHeight + model->bottomHeight); } else { object->position.x = origx + sin(forwardProgress * M_PI / 2) * (0.5 - object->gridPosition.x) * 2 * model->scale.x * curveMaxAmp * (1 - pow (pow(2 * relDistToCenter, 1.3), 2)); object->position.y = (1 - forwardProgress) * origy + forwardProgress * (WIN_Y(w) + model->topHeight); } } else { // Execute normal mode // find position within window borders // (border contents correspond to 0.0-1.0 range) float relPosInWinBorders = (object->gridPosition.y * WIN_H(w) - (w->output.top - w->input.top)) / BORDER_H(w); float relDistToCenter = fabs(relPosInWinBorders - 0.5); // prevent top & bottom shadows from extending too much if (relDistToCenter > 0.5) relDistToCenter = 0.5; object->position.x = origx + sin(forwardProgress * M_PI / 2) * (0.5 - object->gridPosition.x) * 2 * model->scale.x * curveMaxAmp * (1 - pow (pow(2 * relDistToCenter, 1.3), 2)); object->position.y = (1 - forwardProgress) * origy + forwardProgress * (BORDER_Y(w) + BORDER_H(w) / 2.0); } }
void applyZoomTransform (CompWindow * w) { ANIM_WINDOW(w); CompTransform *transform = &aw->com.transform; Point curCenter; Point curScale; Point winCenter; Point iconCenter; float rotateProgress; getZoomCenterScaleFull (w, &curCenter, &curScale, &winCenter, &iconCenter, &rotateProgress); if (fxZoomGetSpringiness (w) == 0.0f && (aw->com.curAnimEffect == AnimEffectZoom || aw->com.curAnimEffect == AnimEffectSidekick) && (aw->com.curWindowEvent == WindowEventOpen || aw->com.curWindowEvent == WindowEventClose)) { matrixTranslate (transform, iconCenter.x, iconCenter.y, 0); matrixScale (transform, curScale.x, curScale.y, curScale.y); matrixTranslate (transform, -iconCenter.x, -iconCenter.y, 0); if (aw->com.curAnimEffect == AnimEffectSidekick) { matrixTranslate (transform, winCenter.x, winCenter.y, 0); matrixRotate (transform, rotateProgress * 360 * aw->numZoomRotations, 0.0f, 0.0f, 1.0f); matrixTranslate (transform, -winCenter.x, -winCenter.y, 0); } } else { matrixTranslate (transform, winCenter.x, winCenter.y, 0); float tx, ty; if (aw->com.curAnimEffect != AnimEffectZoom) { // avoid parallelogram look float maxScale = MAX(curScale.x, curScale.y); matrixScale (transform, maxScale, maxScale, maxScale); tx = (curCenter.x - winCenter.x) / maxScale; ty = (curCenter.y - winCenter.y) / maxScale; } else { matrixScale (transform, curScale.x, curScale.y, curScale.y); tx = (curCenter.x - winCenter.x) / curScale.x; ty = (curCenter.y - winCenter.y) / curScale.y; } matrixTranslate (transform, tx, ty, 0); if (aw->com.curAnimEffect == AnimEffectSidekick) { matrixRotate (transform, rotateProgress * 360 * aw->numZoomRotations, 0.0f, 0.0f, 1.0f); } matrixTranslate (transform, -winCenter.x, -winCenter.y, 0); } }
static void getZoomCenterScaleFull (CompWindow *w, Point *pCurCenter, Point *pCurScale, Point *pWinCenter, Point *pIconCenter, float *pRotateProgress) { ANIM_WINDOW (w); Point winCenter = {(WIN_X (w) + WIN_W (w) / 2.0), (WIN_Y (w) + WIN_H (w) / 2.0)}; Point iconCenter = {aw->com.icon.x + aw->com.icon.width / 2.0, aw->com.icon.y + aw->com.icon.height / 2.0}; Point winSize = {WIN_W (w), WIN_H (w)}; winSize.x = (winSize.x == 0 ? 1 : winSize.x); winSize.y = (winSize.y == 0 ? 1 : winSize.y); float scaleProgress; float moveProgress; float rotateProgress = 0; if (aw->com.curAnimEffect == AnimEffectSidekick) { fxZoomAnimProgress (w, &moveProgress, &scaleProgress, FALSE); rotateProgress = moveProgress; } else if (aw->com.curAnimEffect == AnimEffectZoom) { fxZoomAnimProgress (w, &moveProgress, &scaleProgress, FALSE); } else { // other effects use this for minimization fxZoomAnimProgress (w, &moveProgress, &scaleProgress, TRUE); } Point curCenter = {(1 - moveProgress) * winCenter.x + moveProgress * iconCenter.x, (1 - moveProgress) * winCenter.y + moveProgress * iconCenter.y}; Point curScale = {((1 - scaleProgress) * winSize.x + scaleProgress * aw->com.icon.width) / winSize.x, ((1 - scaleProgress) * winSize.y + scaleProgress * aw->com.icon.height) / winSize.y}; // Copy calculated variables if (pCurCenter) *pCurCenter = curCenter; if (pCurScale) *pCurScale = curScale; if (pWinCenter) *pWinCenter = winCenter; if (pIconCenter) *pIconCenter = iconCenter; if (pRotateProgress) *pRotateProgress = rotateProgress; }
// Divide the window in 8 polygons (6 quadrilaters and 2 triangles (all of them draw as quadrilaters)) // Based on tessellateIntoRectangles and tessellateIntoHexagons. Improperly called tessellation. static Bool tessellateIntoAirplane (CompWindow *w) { ANIM_WINDOW (w); PolygonSet *pset = aw->eng.polygonSet; if (!pset) return FALSE; float winLimitsX; // boundaries of polygon tessellation float winLimitsY; float winLimitsW; float winLimitsH; winLimitsX = BORDER_X (w); winLimitsY = BORDER_Y (w); winLimitsW = BORDER_W (w); winLimitsH = BORDER_H (w); int numpol = 8; if (pset->nPolygons != numpol) { if (pset->nPolygons > 0) freePolygonObjects (pset); pset->nPolygons = numpol; pset->polygons = calloc (pset->nPolygons, sizeof (PolygonObject)); if (!pset->polygons) { compLogMessage ("animation", CompLogLevelError, "Not enough memory"); pset->nPolygons = 0; return FALSE; } } float thickness = 0; thickness /= w->screen->width; pset->thickness = thickness; pset->nTotalFrontVertices = 0; float W = (float)winLimitsW; float H2 = (float)winLimitsH / 2; float H3 = (float)winLimitsH / 3; float H6 = (float)winLimitsH / 6; float halfThick = pset->thickness / 2; /** * * These correspond to the polygons: * based on GLUT sample origami.c code by Mark J. Kilgard * * |- W -| * |- H2 -| * * - -- +----+--------+------------------+ * | | | / | * | | 6 / | * | 7 | / 5 | * H2 | | + | * | +--------+------------------+ * | / 4 | * H __ |/____________.__________________| * |\ center | * | \ 3 | * | +--------+------------------+ * | | + | * | 0 | \ | * | | 1 \ 2 | * | | | \ | * - +----+--------+------------------+ * * */ PolygonObject *p = pset->polygons; int i; for (i = 0; i < 8; i++, p++) { float topRightY, topLeftY, bottomLeftY, bottomRightY; float topLeftX, topRightX, bottomLeftX, bottomRightX; p->centerPos.x = p->centerPosStart.x = winLimitsX + H2; p->centerPos.y = p->centerPosStart.y = winLimitsY + H2; p->centerPos.z = p->centerPosStart.z = -halfThick; p->rotAngle = p->rotAngleStart = 0; p->nSides = 4; p->nVertices = 2 * 4; pset->nTotalFrontVertices += 4; switch (i) { case 0: topLeftX = -H2; topLeftY = 0; bottomLeftX = -H2; bottomLeftY = H2; bottomRightX = -H3; bottomRightY = H2; topRightX = -H3; topRightY = H6; break; case 1: topLeftX = -H3; topLeftY = H6; bottomLeftX = -H3; bottomLeftY = H2; bottomRightX = 0; bottomRightY = H2; topRightX = 0; topRightY = H2; break; case 2: topLeftX = -H3; topLeftY = H6; bottomLeftX = 0; bottomLeftY = H2; bottomRightX = W - H2; bottomRightY = H2; topRightX = W - H2; topRightY = H6; break; case 3: topLeftX = -H2; topLeftY = 0; bottomLeftX = -H3; bottomLeftY = H6; bottomRightX = W - H2; bottomRightY = H6; topRightX = W - H2; topRightY = 0; break; case 4: topLeftX = -H3; topLeftY = -H6; bottomLeftX = -H2; bottomLeftY = 0; bottomRightX = W - H2; bottomRightY = 0; topRightX = W - H2; topRightY = -H6; break; case 5: topLeftX = 0; topLeftY = -H2; bottomLeftX = -H3; bottomLeftY = -H6; bottomRightX = W - H2; bottomRightY = -H6; topRightX = W - H2; topRightY = -H2; break; case 6: topLeftX = -H3; topLeftY = -H2; bottomLeftX = -H3; bottomLeftY = -H6; bottomRightX = -H3; bottomRightY = -H6; topRightX = 0; topRightY = -H2; break; default: topLeftX = -H2; topLeftY = -H2; bottomLeftX = -H2; bottomLeftY = 0; bottomRightX = -H3; bottomRightY = -H6; topRightX = -H3; topRightY = -H2; break; } // 4 front, 4 back vertices if (!p->vertices) { p->vertices = calloc (8 * 3, sizeof (GLfloat)); } if (!p->vertices) { compLogMessage ("animation", CompLogLevelError, "Not enough memory"); freePolygonObjects (pset); return FALSE; } GLfloat *pv = p->vertices; // Determine 4 front vertices in ccw direction pv[0] = topLeftX; pv[1] = topLeftY; pv[2] = halfThick; pv[3] = bottomLeftX; pv[4] = bottomLeftY; pv[5] = halfThick; pv[6] = bottomRightX; pv[7] = bottomRightY; pv[8] = halfThick; pv[9] = topRightX; pv[10] = topRightY; pv[11] = halfThick; // Determine 4 back vertices in cw direction pv[12] = topRightX; pv[13] = topRightY; pv[14] = -halfThick; pv[15] = bottomRightX; pv[16] = bottomRightY; pv[17] = -halfThick; pv[18] = bottomLeftX; pv[19] = bottomLeftY; pv[20] = -halfThick; pv[21] = topLeftX; pv[22] = topLeftY; pv[23] = -halfThick; // 16 indices for 4 sides (for quad strip) if (!p->sideIndices) { p->sideIndices = calloc (4 * 4, sizeof (GLushort)); } if (!p->sideIndices) { compLogMessage ("animation", CompLogLevelError, "Not enough memory"); freePolygonObjects (pset); return FALSE; } GLushort *ind = p->sideIndices; int id = 0; ind[id++] = 0; ind[id++] = 7; ind[id++] = 6; ind[id++] = 1; ind[id++] = 1; ind[id++] = 6; ind[id++] = 5; ind[id++] = 2; ind[id++] = 2; ind[id++] = 5; ind[id++] = 4; ind[id++] = 3; ind[id++] = 3; ind[id++] = 4; ind[id++] = 7; ind[id++] = 0; if (i < 4) { p->boundingBox.x1 = p->centerPos.x + topLeftX; p->boundingBox.y1 = p->centerPos.y + topLeftY; p->boundingBox.x2 = ceil (p->centerPos.x + bottomRightX); p->boundingBox.y2 = ceil (p->centerPos.y + bottomRightY); } else { p->boundingBox.x1 = p->centerPos.x + bottomLeftX; p->boundingBox.y1 = p->centerPos.y + topLeftY; p->boundingBox.x2 = ceil (p->centerPos.x + bottomRightX); p->boundingBox.y2 = ceil (p->centerPos.y + bottomLeftY); } } return TRUE; }
void fxAirplaneLinearAnimStepPolygon (CompWindow *w, PolygonObject *p, float forwardProgress) { ANIM_WINDOW (w); const BananaValue * option_airplane_path_length = bananaGetOption (bananaIndex, "airplane_path_length", w->screen->screenNum); const BananaValue * option_airplane_fly_to_taskbar = bananaGetOption (bananaIndex, "airplane_fly_to_taskbar", w->screen->screenNum); float airplanePathLength = option_airplane_path_length->f; Bool airplaneFly2TaskBar = option_airplane_fly_to_taskbar->b; AirplaneEffectParameters *aep = p->effectParameters; if (!aep) return; /* Phase1: folding: flaps, folding center, folding wings. * Phase2: rotate and fly. */ if (forwardProgress > p->moveStartTime && forwardProgress < aep->moveStartTime4) // Phase1: folding: flaps, center, wings. { float moveProgress1 = forwardProgress - p->moveStartTime; if (p->moveDuration > 0) moveProgress1 /= p->moveDuration; else moveProgress1 = 0; if (moveProgress1 < 0) moveProgress1 = 0; else if (moveProgress1 > 1) moveProgress1 = 1; float moveProgress2 = forwardProgress - aep->moveStartTime2; if (aep->moveDuration2 > 0) moveProgress2 /= aep->moveDuration2; else moveProgress2 = 0; if (moveProgress2 < 0) moveProgress2 = 0; else if (moveProgress2 > 1) moveProgress2 = 1; float moveProgress3 = forwardProgress - aep->moveStartTime3; if (aep->moveDuration3 > 0) moveProgress3 /= aep->moveDuration3; else moveProgress3 = 0; if (moveProgress3 < 0) moveProgress3 = 0; else if (moveProgress3 > 1) moveProgress3 = 1; p->centerPos.x = p->centerPosStart.x; p->centerPos.y = p->centerPosStart.y; p->centerPos.z = p->centerPosStart.z; p->rotAngle = moveProgress1 * p->finalRotAng; aep->rotAngleA = moveProgress2 * aep->finalRotAngA; aep->rotAngleB = moveProgress3 * aep->finalRotAngB; aep->flyRotation.x = 0; aep->flyRotation.y = 0; aep->flyRotation.z = 0; aep->flyScale = 0; } else if (forwardProgress >= aep->moveStartTime4) // Phase2: rotate and fly { float moveProgress4 = forwardProgress - aep->moveStartTime4; if (aep->moveDuration4 > 0) moveProgress4 /= aep->moveDuration4; if (moveProgress4 < 0) moveProgress4 = 0; else if (moveProgress4 > 1) moveProgress4 = 1; float moveProgress5 = forwardProgress - (aep->moveStartTime4 + .01); if (aep->moveDuration5 > 0) moveProgress5 /= aep->moveDuration5; if (moveProgress5 < 0) moveProgress5 = 0; else if (moveProgress5 > 1) moveProgress5 = 1; p->rotAngle = p->finalRotAng; aep->rotAngleA = aep->finalRotAngA; aep->rotAngleB = aep->finalRotAngB; aep->flyRotation.x = moveProgress4 * aep->flyFinalRotation.x; aep->flyRotation.y = moveProgress4 * aep->flyFinalRotation.y; // flying path float icondiffx = 0; aep->flyTheta = moveProgress5 * -M_PI_2 * airplanePathLength; aep->centerPosFly.x = w->screen->width * .4 * sin (2 * aep->flyTheta); if (((aw->com.curWindowEvent == WindowEventMinimize || aw->com.curWindowEvent == WindowEventUnminimize) && airplaneFly2TaskBar) || aw->com.curWindowEvent == WindowEventOpen || aw->com.curWindowEvent == WindowEventClose) { // flying path ends at icon/pointer int sign = 1; if (aw->com.curWindowEvent == WindowEventUnminimize || aw->com.curWindowEvent == WindowEventOpen) sign = -1; icondiffx = (((aw->com.icon.x + aw->com.icon.width / 2) - (p->centerPosStart.x + sign * w->screen->width * .4 * sin (2 * -M_PI_2 * airplanePathLength))) * moveProgress5); aep->centerPosFly.y = ((aw->com.icon.y + aw->com.icon.height / 2) - p->centerPosStart.y) * -sin (aep->flyTheta / airplanePathLength); } else { if (p->centerPosStart.y < w->screen->height * .33 || p->centerPosStart.y > w->screen->height * .66) aep->centerPosFly.y = w->screen->height * .6 * sin (aep->flyTheta / 3.4); else aep->centerPosFly.y = w->screen->height * .4 * sin (aep->flyTheta / 3.4); if (p->centerPosStart.y < w->screen->height * .33) aep->centerPosFly.y *= -1; } aep->flyFinalRotation.z = ((atan (2.0) + M_PI_2) * sin (aep->flyTheta) - M_PI_2) * 180 / M_PI; aep->flyFinalRotation.z += 90; if (aw->com.curWindowEvent == WindowEventMinimize || aw->com.curWindowEvent == WindowEventClose) { aep->flyFinalRotation.z *= -1; } else if (aw->com.curWindowEvent == WindowEventUnminimize || aw->com.curWindowEvent == WindowEventOpen) { aep->centerPosFly.x *= -1; } aep->flyRotation.z = aep->flyFinalRotation.z; p->centerPos.x = p->centerPosStart.x + aep->centerPosFly.x + icondiffx; p->centerPos.y = p->centerPosStart.y + aep->centerPosFly.y; p->centerPos.z = p->centerPosStart.z + aep->centerPosFly.z; aep->flyScale = moveProgress5 * aep->flyFinalScale; } }
Bool fxZoomInit (CompWindow *w) { ANIM_WINDOW (w); const BananaValue * option_sidekick_zoom_from_center = bananaGetOption (bananaIndex, "sidekick_zoom_from_center", w->screen->screenNum); if ((aw->com.curAnimEffect == AnimEffectSidekick && (option_sidekick_zoom_from_center->i == 3 || ((aw->com.curWindowEvent == WindowEventMinimize || aw->com.curWindowEvent == WindowEventUnminimize) && option_sidekick_zoom_from_center->i == 1) || ((aw->com.curWindowEvent == WindowEventOpen || aw->com.curWindowEvent == WindowEventClose) && option_sidekick_zoom_from_center->i == 2))) || (aw->com.curAnimEffect == AnimEffectZoom && (option_sidekick_zoom_from_center->i == 3 || ((aw->com.curWindowEvent == WindowEventMinimize || aw->com.curWindowEvent == WindowEventUnminimize) && option_sidekick_zoom_from_center->i == 1) || ((aw->com.curWindowEvent == WindowEventOpen || aw->com.curWindowEvent == WindowEventClose) && option_sidekick_zoom_from_center->i == 2)))) { aw->com.icon.x = WIN_X (w) + WIN_W (w) / 2 - aw->com.icon.width / 2; aw->com.icon.y = WIN_Y (w) + WIN_H (w) / 2 - aw->com.icon.height / 2; } // allow extra time for spring damping / deceleration if ((aw->com.curWindowEvent == WindowEventUnminimize || aw->com.curWindowEvent == WindowEventOpen) && fxZoomGetSpringiness (w) > 1e-4) { aw->com.animTotalTime /= SPRINGY_ZOOM_PERCEIVED_T; } else if ((aw->com.curAnimEffect == AnimEffectZoom || aw->com.curAnimEffect == AnimEffectSidekick) && (aw->com.curWindowEvent == WindowEventOpen || aw->com.curWindowEvent == WindowEventClose)) { aw->com.animTotalTime /= NONSPRINGY_ZOOM_PERCEIVED_T; } else { aw->com.animTotalTime /= ZOOM_PERCEIVED_T; } aw->com.animRemainingTime = aw->com.animTotalTime; aw->com.usingTransform = TRUE; return defaultAnimInit (w); }
Bool fxFoldInit (CompWindow *w) { if (!polygonsAnimInit (w)) return FALSE; ANIM_WINDOW (w); aw->com.animTotalTime /= FOLD_PERCEIVED_T; aw->com.animRemainingTime = aw->com.animTotalTime; const BananaValue * option_fold_gridx = bananaGetOption (bananaIndex, "fold_gridx", w->screen->screenNum); const BananaValue * option_fold_gridy = bananaGetOption (bananaIndex, "fold_gridy", w->screen->screenNum); const BananaValue * option_fold_dir = bananaGetOption (bananaIndex, "fold_dir", w->screen->screenNum); int gridSizeX = option_fold_gridx->i; int gridSizeY = option_fold_gridy->i; if (!tessellateIntoRectangles (w, gridSizeX, gridSizeY, 1.0f)) return FALSE; PolygonSet *pset = aw->eng.polygonSet; PolygonObject *p = pset->polygons; // handle other non-zero values int fold_in = option_fold_dir->i == 0 ? 1 : 0; float rows_duration; float fduration; if (gridSizeY == 1) { fduration = 1.0f / (float) (gridSizeY + 2 * ceil (gridSizeX / 2)); rows_duration = 0; } else { fduration = 1.0f / (float) (gridSizeY + 2 * ceil (gridSizeX / 2) + 1 + fold_in); rows_duration = (gridSizeY - 1 + fold_in) * fduration; } float duration = fduration * 2; float start; int i; int j = 0; int k = 0; for (i = 0; i < pset->nPolygons; i++, p++) { if (i > pset->nPolygons - gridSizeX - 1) { // bottom row polygons if (j < gridSizeX / 2) { // the left ones start = rows_duration + duration * j++; p->rotAxis.y = -180; p->finalRotAng = 180; p->fadeStartTime = start + fduration; p->fadeDuration = fduration; } else if (j == gridSizeX / 2) { // the middle one start = rows_duration + j * duration; p->rotAxis.y = 90; p->finalRotAng = 90; p->fadeStartTime = start + fduration; p->fadeDuration = fduration; j++; } else { // the right ones start = rows_duration + (j - 2) * duration + duration * k--; p->rotAxis.y = 180; p->finalRotAng = 180; p->fadeStartTime = start + fduration; p->fadeDuration = fduration; } } else { // main rows int row = i / gridSizeX; // [0; gridSizeY-1] start = row * fduration; p->rotAxis.x = 180; p->finalRelPos.y = row; // number of row, not finalRelPos!! p->finalRotAng = 180; p->fadeDuration = fduration; p->fadeStartTime = start; if (row < gridSizeY - 2 || fold_in) p->fadeStartTime += fduration; } p->moveStartTime = start; p->moveDuration = duration; } pset->doDepthTest = TRUE; pset->doLighting = TRUE; pset->correctPerspective = CorrectPerspectiveWindow; return TRUE; }