void calculateWallOffset (const CompRect &output, const CompPoint &offsetInScreenCoords, const CompPoint &vpSize, const CompSize &screenSize, float &offsetInWorldX, float &offsetInWorldY, float &worldScaleFactorX, float &worldScaleFactorY, float animationProgress) { const float sx = screenSize.width () / static_cast <float> (output.width ()); const float sy = screenSize.height () / static_cast <float> (output.height ()); offsetInWorldX = 0.0; offsetInWorldY = 0.0; worldScaleFactorX = 1.0f; worldScaleFactorY = 1.0f; if (output.left () == 0) { offsetInWorldX = ((vpSize.x () * sx) / ((float) output.width ()) * (offsetInScreenCoords.x ()) * animationProgress); worldScaleFactorX = 1.0f - ((float) (offsetInScreenCoords.x ()) / (float) (output.width ())) * animationProgress; } if (output.top () == 0) { offsetInWorldY = ((vpSize.y () * sy) / ((float) output.height ()) * (offsetInScreenCoords.y ()) * animationProgress); worldScaleFactorY = 1.0f - ((float) (offsetInScreenCoords.y ()) / (float) output.height ()) * animationProgress; } }
void ResizeWindow::getStretchScale (BoxPtr pBox, float *xScale, float *yScale) { CompRect rect (window->borderRect ()); *xScale = (rect.width ()) ? (pBox->x2 - pBox->x1) / (float) rect.width () : 1.0f; *yScale = (rect.height ()) ? (pBox->y2 - pBox->y1) / (float) rect.height () : 1.0f; }
void LeafSpreadAnim::init () { if (!tessellateIntoRectangles (20, 14, 15.0f)) return; CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); float fadeDuration = 0.26; float life = 0.4; float spreadFac = 3.5; float randYMax = 0.07; float winFacX = outRect.width () / 800.0; float winFacY = outRect.height () / 800.0; float winFacZ = (outRect.height () + outRect.width ()) / 2.0 / 800.0; float screenSizeFactor = (0.8 * DEFAULT_Z_CAMERA * ::screen->width ()); foreach (PolygonObject *p, mPolygons) { p->rotAxis.set (RAND_FLOAT (), RAND_FLOAT (), RAND_FLOAT ()); 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.set (x, y, 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; }
Point ZoomAnim::getCenter () { Point center; if (zoomToIcon ()) { getCenterScale (¢er, 0); } else { float forwardProgress = progressLinear (); CompRect inRect (mAWindow->savedRectsValid () ? mAWindow->savedInRect () : mWindow->borderRect ()); center.setX (inRect.x () + inRect.width () / 2.0); if (mCurWindowEvent == WindowEventShade || mCurWindowEvent == WindowEventUnshade) { float origCenterY = (inRect.y () + inRect.height () / 2.0); center.setY ((1 - forwardProgress) * origCenterY + forwardProgress * (inRect.y () + mDecorTopHeight)); } else // i.e. (un)minimizing without zooming { center.setY (inRect.y () + inRect.height () / 2.0); } } return center; }
SidekickAnim::SidekickAnim (CompWindow *w, WindowEvent curWindowEvent, float duration, const AnimEffect info, const CompRect &icon) : Animation::Animation (w, curWindowEvent, duration, info, icon), TransformAnim::TransformAnim (w, curWindowEvent, duration, info, icon), ZoomAnim::ZoomAnim (w, curWindowEvent, duration, info, icon) { // determine number of rotations randomly in [0.9, 1.1] range mNumRotations = optValF (AnimationOptions::SidekickNumRotations) * (1.0f + 0.2f * rand () / RAND_MAX - 0.1f); CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); float winCenterX = outRect.x () + outRect.width () / 2.0; float iconCenterX = mIcon.x () + mIcon.width () / 2.0; // if window is to the right of icon, rotate clockwise instead // to make rotation look more pleasant if (winCenterX > iconCenterX) mNumRotations *= -1; }
bool CompRegion::intersects (const CompRect &r) const { int result; result = XRectInRegion (handle (), r.x (), r.y (), r.width (), r.height ()); return result != RectangleOut; }
bool CompRegion::contains (const CompRect &r) const { int result; result = XRectInRegion (handle (), r.x (), r.y (), r.width (), r.height ()); return result == RectangleIn; }
void ZoomAnim::getCenterScaleFull (Point *pCurCenter, Point *pCurScale, Point *pWinCenter, Point *pIconCenter, float *pMoveProgress) { CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); Point winCenter ((outRect.x () + outRect.width () / 2.0), (outRect.y () + outRect.height () / 2.0)); Point iconCenter (mIcon.x () + mIcon.width () / 2.0, mIcon.y () + mIcon.height () / 2.0); Point winSize (outRect.width (), outRect.height ()); winSize.setX (winSize.x () == 0 ? 1 : winSize.x ()); winSize.setY (winSize.y () == 0 ? 1 : winSize.y ()); float scaleProgress; float moveProgress; getZoomProgress (&moveProgress, &scaleProgress, neverSpringy ()); Point curCenter ((1 - moveProgress) * winCenter.x () + moveProgress * iconCenter.x (), (1 - moveProgress) * winCenter.y () + moveProgress * iconCenter.y ()); Point curScale (((1 - scaleProgress) * winSize.x () + scaleProgress * mIcon.width ()) / winSize.x (), ((1 - scaleProgress) * winSize.y () + scaleProgress * mIcon.height ()) / winSize.y ()); // Copy calculated variables if (pCurCenter) *pCurCenter = curCenter; if (pCurScale) *pCurScale = curScale; if (pWinCenter) *pWinCenter = winCenter; if (pIconCenter) *pIconCenter = iconCenter; if (pMoveProgress) *pMoveProgress = moveProgress; }
void SvgWindow::updateSvgMatrix () { SvgTexture *texture; GLTexture::Matrix *m; unsigned int i; CompRect rect; rect = context->box.boundingRect (); texture = &context->texture[0]; if (texture->matrices.size () != texture->textures.size ()) texture->matrices.resize (texture->textures.size ()); for (i = 0; i < texture->textures.size (); i++) { m = &texture->matrices[i]; *m = texture->textures[i]->matrix (); m->xx *= (float) texture->size.width () / rect.width (); m->yy *= (float) texture->size.height () / rect.height (); m->x0 -= (rect.x () * m->xx); m->y0 -= (rect.y () * m->yy); } texture = &context->texture[1]; if (texture->matrices.size () != texture->textures.size ()) texture->matrices.resize (texture->textures.size ()); for (i = 0; i < texture->textures.size (); i++) { m = &texture->matrices[i]; *m = texture->textures[i]->matrix (); m->xx *= (float) texture->size.width () / context->rect.width (); m->yy *= (float) texture->size.height () / context->rect.height (); m->x0 -= (context->rect.x () * m->xx); m->y0 -= (context->rect.y () * m->yy); } }
ZoomAnim::ZoomAnim (CompWindow *w, WindowEvent curWindowEvent, float duration, const AnimEffect info, const CompRect &icon) : Animation::Animation (w, curWindowEvent, duration, info, icon), TransformAnim::TransformAnim (w, curWindowEvent, duration, info, icon), FadeAnim::FadeAnim (w, curWindowEvent, duration, info, icon) { CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); if (isZoomFromCenter ()) { mIcon.setX (outRect.x () + outRect.width () / 2 - mIcon.width () / 2); mIcon.setY (outRect.y () + outRect.height () / 2 - mIcon.height () / 2); } }
void CompositeWindow::addDamageRect (const CompRect &rect) { if (priv->cScreen->damageMask () & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) return; if (!damageRect (false, rect)) { int x, y; x = rect.x (); y = rect.y (); const CompWindow::Geometry &geom = priv->window->geometry (); x += geom.x () + geom.border (); y += geom.y () + geom.border (); priv->cScreen->damageRegion (CompRegion (CompRect (x, y, rect.width (), rect.height ()))); } }
void HorizontalFoldsAnim::step () { GridZoomAnim::step (); CompRect winRect (mAWindow->savedRectsValid () ? mAWindow->saveWinRect () : mWindow->geometry ()); CompRect inRect (mAWindow->savedRectsValid () ? mAWindow->savedInRect () : mWindow->inputRect ()); CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); CompWindowExtents outExtents (mAWindow->savedRectsValid () ? mAWindow->savedOutExtents () : mWindow->output ()); int wx = winRect.x (); int wy = winRect.y (); int oy = outRect.y (); int owidth = outRect.width (); int oheight = outRect.height (); float winHeight = 0; if (mCurWindowEvent == WindowEventShade || mCurWindowEvent == WindowEventUnshade) { winHeight = winRect.height (); } else { winHeight = inRect.height (); } int nHalfFolds = 2.0 * optValI (AnimationOptions::HorizontalFoldsNumFolds); float foldMaxAmp = 0.3 * pow ((winHeight / nHalfFolds) / ::screen->height (), 0.3) * optValF (AnimationOptions::HorizontalFoldsAmpMult); float forwardProgress = getActualProgress (); float sinForProg = sin (forwardProgress * M_PI / 2); GridModel::GridObject *object = mModel->objects (); unsigned int n = mModel->numObjects (); for (unsigned int i = 0; i < n; ++i, ++object) { Point3d &objPos = object->position (); if (i % 2 == 0) // object is at the left side { float objGridY = object->gridPosition ().y (); int rowNo = (int)i / mGridWidth; float origy = (wy + (oheight * objGridY - outExtents.top) * mModel->scale ().y ()); if (mCurWindowEvent == WindowEventShade || mCurWindowEvent == WindowEventUnshade) { // Execute shade mode if (objGridY == 0) { objPos.setY (oy); objPos.setZ (0); } else if (objGridY == 1) { objPos.setY ( (1 - forwardProgress) * origy + forwardProgress * (oy + mDecorTopHeight + mDecorBottomHeight)); objPos.setZ (0); } else { float relDistToFoldCenter = (rowNo % 2 == 1 ? 0.5 : 0); objPos.setY ( (1 - forwardProgress) * origy + forwardProgress * (oy + mDecorTopHeight)); objPos.setZ ( getObjectZ (mModel, forwardProgress, sinForProg, relDistToFoldCenter, foldMaxAmp)); } } else { // Execute normal mode float relDistToFoldCenter = (rowNo % 2 == 0 ? 0.5 : 0); objPos.setY ( (1 - forwardProgress) * origy + forwardProgress * (inRect.y () + inRect.height () / 2.0)); objPos.setZ ( getObjectZ (mModel, forwardProgress, sinForProg, relDistToFoldCenter, foldMaxAmp)); } } else // object is at the right side { // Set y/z position to the y/z position of the object at the left // on the same row (previous object) Point3d &leftObjPos = (object - 1)->position (); objPos.setY (leftObjPos.y ()); objPos.setZ (leftObjPos.z ()); } float origx = (wx + (owidth * object->gridPosition ().x () - outExtents.left) * mModel->scale ().x ()); objPos.setX (origx); } }
void DominoAnim::init () { bool isRazr = (typeid (*this) == typeid (RazrAnim)); int fallDir; if (isRazr) fallDir = getActualAnimDirection ((AnimDirection) optValI (AnimationaddonOptions::RazrDirection), true); else fallDir = getActualAnimDirection ((AnimDirection) optValI (AnimationaddonOptions::DominoDirection), true); int defaultGridSize = 20; float minCellSize = 30; int gridSizeX; int gridSizeY; int fallDirGridSize; float minDistStartEdge; // half piece size in [0,1] range float gridCellW; float gridCellH; float cellAspectRatio = 1.25; if (isRazr) cellAspectRatio = 1; CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); // Determine sensible domino piece sizes if (fallDir == AnimDirectionDown || fallDir == AnimDirectionUp) { if (minCellSize > outRect.width ()) minCellSize = outRect.width (); if (outRect.width () / defaultGridSize < minCellSize) gridSizeX = (int)(outRect.width () / minCellSize); else gridSizeX = defaultGridSize; gridCellW = outRect.width () / gridSizeX; gridSizeY = (int)(outRect.height () / (gridCellW * cellAspectRatio)); if (gridSizeY == 0) gridSizeY = 1; gridCellH = outRect.height () / gridSizeY; fallDirGridSize = gridSizeY; } else { if (minCellSize > outRect.height ()) minCellSize = outRect.height (); if (outRect.height () / defaultGridSize < minCellSize) gridSizeY = (int)(outRect.height () / minCellSize); else gridSizeY = defaultGridSize; gridCellH = outRect.height () / gridSizeY; gridSizeX = (int)(outRect.width () / (gridCellH * cellAspectRatio)); if (gridSizeX == 0) gridSizeX = 1; gridCellW = outRect.width () / gridSizeX; fallDirGridSize = gridSizeX; } minDistStartEdge = (1.0 / fallDirGridSize) / 2; float thickness = MIN (gridCellW, gridCellH) / 3.5; if (!tessellateIntoRectangles (gridSizeX, gridSizeY, thickness)) return; float rotAxisX = 0; float rotAxisY = 0; Point3d rotAxisOff (0, 0, thickness / 2); float posX = 0; // position of standing piece float posY = 0; float posZ = 0; int nFallingColumns = gridSizeX; float gridCellHalfW = gridCellW / 2; float gridCellHalfH = gridCellH / 2; switch (fallDir) { case AnimDirectionDown: rotAxisX = -1; if (isRazr) rotAxisOff.setY (-gridCellHalfH); else { posY = -(gridCellHalfH + thickness); posZ = gridCellHalfH - thickness / 2; } break; case AnimDirectionLeft: rotAxisY = -1; if (isRazr) rotAxisOff.setX (gridCellHalfW); else { posX = gridCellHalfW + thickness; posZ = gridCellHalfW - thickness / 2; } nFallingColumns = gridSizeY; break; case AnimDirectionUp: rotAxisX = 1; if (isRazr) rotAxisOff.setY (gridCellHalfH); else { posY = gridCellHalfH + thickness; posZ = gridCellHalfH - thickness / 2; } break; case AnimDirectionRight: rotAxisY = 1; if (isRazr) rotAxisOff.setX (-gridCellHalfW); else { posX = -(gridCellHalfW + thickness); posZ = gridCellHalfW - thickness / 2; } nFallingColumns = gridSizeY; break; } float fadeDuration; float riseDuration; float riseTimeRandMax = 0.2; if (isRazr) { riseDuration = (1 - riseTimeRandMax) / fallDirGridSize; fadeDuration = riseDuration / 2; } else { fadeDuration = 0.18; riseDuration = 0.2; } float riseTimeRandSeed[nFallingColumns]; for (int i = 0; i < nFallingColumns; i++) riseTimeRandSeed[i] = RAND_FLOAT (); foreach (PolygonObject *p, mPolygons) { p->rotAxis.set (rotAxisX, rotAxisY, 0); p->finalRelPos.set (posX, posY, posZ); // dist. from rise-start / fall-end edge in window ([0,1] range) float distStartEdge = 0; // dist. from edge perpendicular to movement (for move start time) // so that same the blocks in same row/col. appear to knock down // the next one float distPerpEdge = 0; switch (fallDir) { case AnimDirectionUp: distStartEdge = p->centerRelPos.y (); distPerpEdge = p->centerRelPos.x (); break; case AnimDirectionRight: distStartEdge = 1 - p->centerRelPos.x (); distPerpEdge = p->centerRelPos.y (); break; case AnimDirectionDown: distStartEdge = 1 - p->centerRelPos.y (); distPerpEdge = p->centerRelPos.x (); break; case AnimDirectionLeft: distStartEdge = p->centerRelPos.x (); distPerpEdge = p->centerRelPos.y (); break; } float riseTimeRand = riseTimeRandSeed[(int)(distPerpEdge * nFallingColumns)] * riseTimeRandMax; p->moveDuration = riseDuration; float mult = 1; if (fallDirGridSize > 1) mult = ((distStartEdge - minDistStartEdge) / (1 - 2 * minDistStartEdge)); if (isRazr) { p->moveStartTime = mult * (1 - riseDuration - riseTimeRandMax) + riseTimeRand; p->fadeStartTime = p->moveStartTime + riseDuration / 2; p->finalRotAng = -180; p->rotAxisOffset = rotAxisOff; } else { p->moveStartTime = mult * (1 - riseDuration - riseTimeRandMax) + riseTimeRand; p->fadeStartTime = p->moveStartTime + riseDuration - riseTimeRand + 0.03; p->finalRotAng = -90; } if (p->fadeStartTime > 1 - fadeDuration) p->fadeStartTime = 1 - fadeDuration; p->fadeDuration = fadeDuration; }
void RaindropAnim::step () { float t = 1. - progressLinear (); if (mCurWindowEvent == WindowEventClose) t = 1. - t; CompRect winRect (mAWindow->savedRectsValid () ? mAWindow->saveWinRect () : mWindow->geometry ()); CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); CompWindowExtents outExtents (mAWindow->savedRectsValid () ? mAWindow->savedOutExtents () : mWindow->output ()); int wx = winRect.x (); int wy = winRect.y (); int owidth = outRect.width (); int oheight = outRect.height (); AnimJCScreen *ajs = AnimJCScreen::get (screen); float waveLength = ajs->optionGetRaindropWavelength (); int numWaves = ajs->optionGetRaindropNumWaves (); float waveAmp = (pow ((float)oheight / ::screen->height (), 0.4) * 0.08) * ajs->optionGetRaindropAmplitude (); float wavePosition = -waveLength * numWaves + (1. + waveLength * numWaves) * t; GridModel::GridObject *object = mModel->objects (); unsigned int n = mModel->numObjects (); for (unsigned int i = 0; i < n; i++, object++) { Point3d &objPos = object->position (); float origx = wx + mModel->scale ().x () * (owidth * object->gridPosition ().x () - outExtents.left); objPos.setX (origx); float origy = wy + mModel->scale ().y () * (oheight * object->gridPosition ().y () - outExtents.top); objPos.setY (origy); // find distance to center in grid terms float gridDistance = sqrt (pow (object->gridPosition ().x ()-0.5, 2) + pow (object->gridPosition ().y ()-0.5, 2)) * sqrt (2); float distFromWave = gridDistance - wavePosition; if (distFromWave < waveLength*numWaves && distFromWave > 0) objPos.setZ (waveAmp * sin (3.14159265 * distFromWave / waveLength / numWaves) * pow (sin (3.14159265 * distFromWave / waveLength), 2)); else objPos.setZ (0); } }
void RollUpAnim::step () { float forwardProgress = progressEaseInEaseOut (); bool fixedInterior = optValB (AnimationOptions::RollupFixedInterior); CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); int ox = outRect.x (); int oy = outRect.y (); int owidth = outRect.width (); int oheight = outRect.height (); GridModel::GridObject *object = mModel->objects (); unsigned int n = mModel->numObjects (); for (unsigned int i = 0; i < n; i++, object++) { // Executing shade mode Point3d &objPos = object->position (); if (i % 2 == 0) // object is at the left side { float objGridY = object->gridPosition ().y (); if (objGridY == 0) { objPos.setY (oy); } else if (objGridY == 1) { objPos.setY ( (1 - forwardProgress) * (oy + oheight * objGridY) + forwardProgress * (oy + mDecorTopHeight + mDecorBottomHeight)); } else { // find position in window contents // (window contents correspond to 0.0-1.0 range) float relPosInWinContents = (objGridY * oheight - mDecorTopHeight) / mWindow->height (); if (relPosInWinContents > forwardProgress) { objPos.setY ( (1 - forwardProgress) * (oy + oheight * objGridY) + forwardProgress * (oy + mDecorTopHeight)); if (fixedInterior) object->offsetTexCoordForQuadBefore (). setY (-forwardProgress * mWindow->height ()); } else { objPos.setY (oy + mDecorTopHeight); if (!fixedInterior) object->offsetTexCoordForQuadAfter (). setY ((forwardProgress - relPosInWinContents) * mWindow->height ()); } } } else // object is at the right side { // Set y position to the y position of the object at the left // on the same row (previous object) objPos.setY ((object - 1)->position ().y ()); // Also copy offset texture y coordinates object->offsetTexCoordForQuadBefore (). setY ((object - 1)->offsetTexCoordForQuadBefore ().y ()); object->offsetTexCoordForQuadAfter (). setY ((object - 1)->offsetTexCoordForQuadAfter ().y ()); } float origx = ox + owidth * object->gridPosition ().x (); objPos.setX (origx); } }
void FlickerSingleAnim::step () { int layer = MultiAnim <FlickerSingleAnim,5>::getCurrAnimNumber (mAWindow); CompRect winRect (mAWindow->savedRectsValid () ? mAWindow->saveWinRect () : mWindow->geometry ()); CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); CompWindowExtents outExtents (mAWindow->savedRectsValid () ? mAWindow->savedOutExtents () : mWindow->output ()); int wx = winRect.x (); int wy = winRect.y (); int owidth = outRect.width (); int oheight = outRect.height (); float t = 1 - progressLinear (); if (mCurWindowEvent == WindowEventClose) t = 1 - t; float amplitude = AnimJCScreen::get (screen)->optionGetFlickerAmplitude (); float waveLength = 0.4; float wavePosition = -waveLength + (1. + waveLength) * t; float displacement = 0; GridModel::GridObject *object = mModel->objects (); unsigned int n = mModel->numObjects (); for (unsigned int i = 0; i < n; i++, object++) { Point3d &objPos = object->position (); if (i % 2 == 0) // left side; reuse old displacement on right side { float distFromWave = object->gridPosition ().y () - wavePosition; if (distFromWave > 0 && distFromWave <= waveLength) { displacement = amplitude * sin (distFromWave/waveLength * M_PI); } else { displacement = 0; } } float x = wx + mModel->scale ().x () * (owidth * object->gridPosition ().x () - outExtents.left); float y = wy + mModel->scale ().y () * (oheight * object->gridPosition ().y () - outExtents.top); switch (layer) { case 1: x -= displacement; break; case 2: x += displacement; break; case 3: y -= displacement; break; case 4: y += displacement; break; default: break; } objPos.setX (x); objPos.setY (y); objPos.setZ (0); } }
bool SvgWindow::glDraw (const GLMatrix &transform, const GLWindowPaintAttrib &attrib, const CompRegion ®ion, unsigned int mask) { bool status = gWindow->glDraw (transform, attrib, region, mask); if (!status) return status; const CompRegion ® = (mask & PAINT_WINDOW_TRANSFORMED_MASK) ? infiniteRegion : region; if (context && reg.numRects ()) { GLTexture::MatrixList matrix (1); int x1, y1, x2, y2; CompRect rect = context->box.boundingRect (); x1 = MIN (rect.x1 (), sScreen->zoom.x1 ()); y1 = MIN (rect.y1 (), sScreen->zoom.y1 ()); x2 = MAX (rect.x2 (), sScreen->zoom.x2 ()); y2 = MAX (rect.y2 (), sScreen->zoom.y2 ()); rect.setGeometry (x1, y1, x2 - x1, y2 - y1); for (unsigned int i = 0; i < context->texture[0].textures.size (); i++) { matrix[0] = context->texture[0].matrices[i]; gWindow->vertexBuffer ()->begin (); gWindow->glAddGeometry (matrix, context->box, reg); gWindow->vertexBuffer ()->end (); if (mask & PAINT_WINDOW_TRANSLUCENT_MASK) mask |= PAINT_WINDOW_BLEND_MASK; gWindow->glDrawTexture (context->texture[0].textures[i], transform, attrib, mask); if (rect.width () > 0 && rect.height () > 0) { float xScale, yScale; float dx, dy; int width, height; rect.setGeometry (rect.x1 () - 1, rect.y1 () - 1, rect.width () + 1, rect.height () + 1); xScale = screen->width () / (float) (sScreen->zoom.width ()); yScale = screen->height () / (float) (sScreen->zoom.height ()); dx = rect.width (); dy = rect.height (); width = dx * xScale + 0.5f; height = dy * yScale + 0.5f; if (rect != context->rect || width != context->size.width () || height != context->size.height ()) { float x1, y1, x2, y2; context->rect = rect; context->size.setWidth (width); context->size.setHeight (height); dx = context->box.boundingRect ().width (); dy = context->box.boundingRect ().height (); x1 = (rect.x1 () - context->box.boundingRect ().x ()) / dx; y1 = (rect.y1 () - context->box.boundingRect ().y ()) / dy; x2 = (rect.x2 () - context->box.boundingRect ().x ()) / dx; y2 = (rect.y2 () - context->box.boundingRect ().y ()) / dy; finiTexture (context->texture[1]); if (initTexture (context->source, context->texture[1], context->size)) { renderSvg (context->source, context->texture[1], context->size, x1, y1, x2, y2); updateSvgMatrix (); } } for (unsigned int j = 0; j < context->texture[1].textures.size (); j++) { GLTexture::Filter saveFilter; CompRegion r (rect); matrix[0] = context->texture[1].matrices[j]; saveFilter = gScreen->filter (SCREEN_TRANS_FILTER); gScreen->setFilter (SCREEN_TRANS_FILTER, GLTexture::Good); gWindow->vertexBuffer ()->begin (); gWindow->glAddGeometry (matrix, r, reg); gWindow->vertexBuffer ()->end (); gWindow->glDrawTexture (context->texture[1].textures[j], transform, attrib, mask); gScreen->setFilter (SCREEN_TRANS_FILTER, saveFilter); } } else if (context->texture[1].size.width ()) { finiTexture (context->texture[1]); initTexture (source, context->texture[1], CompSize ()); memset (&context->rect, 0, sizeof (BoxRec)); context->size.setWidth (0); context->size.setHeight (0); } } } return status; }
void GridAnim::addGeometry (const GLTexture::MatrixList &matrix, const CompRegion ®ion, const CompRegion &clip, unsigned int maxGridWidth, unsigned int maxGridHeight) { if (region.isEmpty ()) // nothing to do return; GLfloat *v, *vMax; bool notUsing3dCoords = !using3D (); CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); CompWindowExtents outExtents (mAWindow->savedRectsValid () ? mAWindow->savedOutExtents () : mWindow->output ()); // window output (contents + decorations + shadows) coordinates and size int ox = outRect.x (); int oy = outRect.y (); int owidth = outRect.width (); int oheight = outRect.height (); // to be used if event is shade/unshade float winContentsY = oy + outExtents.top; float winContentsHeight = oheight - outExtents.top - outExtents.bottom; GLWindow *gWindow = GLWindow::get (mWindow); GLVertexBuffer *vertexBuffer = gWindow->vertexBuffer (); int vSize = vertexBuffer->getVertexStride (); // Indentation kept to provide a clean diff with the old code, for now... { int y1 = outRect.y1 (); int x2 = outRect.x2 (); int y2 = outRect.y2 (); float gridW = (float)owidth / (mGridWidth - 1); float gridH; if (mCurWindowEvent == WindowEventShade || mCurWindowEvent == WindowEventUnshade) { if (y1 < winContentsY) // if at top part gridH = mDecorTopHeight; else if (y2 > winContentsY + winContentsHeight) // if at bottom gridH = mDecorBottomHeight; else // in window contents (only in Y coords) { float winContentsHeight = oheight - (mDecorTopHeight + mDecorBottomHeight); gridH = winContentsHeight / (mGridHeight - 3); } } else gridH = (float)oheight / (mGridHeight - 1); int oldCount = vertexBuffer->countVertices (); gWindow->glAddGeometry (matrix, region, clip, gridW, gridH); int newCount = vertexBuffer->countVertices (); v = vertexBuffer->getVertices () + (oldCount * vSize); vMax = vertexBuffer->getVertices () + (newCount * vSize); float x, y, topiyFloat; // For each vertex for (; v < vMax; v += vSize) { x = v[0]; y = v[1]; if (y > y2) y = y2; if (mCurWindowEvent == WindowEventShade || mCurWindowEvent == WindowEventUnshade) { if (y1 < winContentsY) // if at top part { topiyFloat = (y - oy) / mDecorTopHeight; topiyFloat = MIN (topiyFloat, 0.999); // avoid 1.0 } else if (y2 > winContentsY + winContentsHeight) // if at bottom topiyFloat = (mGridHeight - 2) + (mDecorBottomHeight ? (y - winContentsY - winContentsHeight) / mDecorBottomHeight : 0); else // in window contents (only in Y coords) topiyFloat = (mGridHeight - 3) * (y - winContentsY) / winContentsHeight + 1; } else topiyFloat = (mGridHeight - 1) * (y - oy) / oheight; // topiy should be at most (mGridHeight - 2) int topiy = (int)(topiyFloat + 1e-4); if (topiy == mGridHeight - 1) --topiy; int bottomiy = topiy + 1; float iny = topiyFloat - topiy; float inyRest = 1 - iny; // End of calculations for y // Indentation kept to provide a clean diff with the old code... { if (x > x2) x = x2; // find containing grid cell (leftix rightix) x (topiy bottomiy) float leftixFloat = (mGridWidth - 1) * (x - ox) / owidth; int leftix = (int)(leftixFloat + 1e-4); if (leftix == mGridWidth - 1) --leftix; int rightix = leftix + 1; // GridModel::GridObjects that are at top, bottom, left, right corners of quad GridModel::GridObject *objToTopLeft = &(mModel->mObjects[topiy * mGridWidth + leftix]); GridModel::GridObject *objToTopRight = &(mModel->mObjects[topiy * mGridWidth + rightix]); GridModel::GridObject *objToBottomLeft = &(mModel->mObjects[bottomiy * mGridWidth + leftix]); GridModel::GridObject *objToBottomRight = &(mModel->mObjects[bottomiy * mGridWidth + rightix]); Point3d &objToTopLeftPos = objToTopLeft->mPosition; Point3d &objToTopRightPos = objToTopRight->mPosition; Point3d &objToBottomLeftPos = objToBottomLeft->mPosition; Point3d &objToBottomRightPos = objToBottomRight->mPosition; // find position in cell by taking remainder of flooring float inx = leftixFloat - leftix; float inxRest = 1 - inx; // Interpolate to find deformed coordinates float hor1x = (inxRest * objToTopLeftPos.x () + inx * objToTopRightPos.x ()); float hor1y = (inxRest * objToTopLeftPos.y () + inx * objToTopRightPos.y ()); float hor1z = (notUsing3dCoords ? 0 : inxRest * objToTopLeftPos.z () + inx * objToTopRightPos.z ()); float hor2x = (inxRest * objToBottomLeftPos.x () + inx * objToBottomRightPos.x ()); float hor2y = (inxRest * objToBottomLeftPos.y () + inx * objToBottomRightPos.y ()); float hor2z = (notUsing3dCoords ? 0 : inxRest * objToBottomLeftPos.z () + inx * objToBottomRightPos.z ()); float deformedX = inyRest * hor1x + iny * hor2x; float deformedY = inyRest * hor1y + iny * hor2y; float deformedZ = inyRest * hor1z + iny * hor2z; v[0] = deformedX; v[1] = deformedY; v[2] = deformedZ; } } } }
void GhostAnim::step () { float t = 1. - progressLinear (); if (mCurWindowEvent == WindowEventClose) t = 1. - t; CompRect winRect (mAWindow->savedRectsValid () ? mAWindow->saveWinRect () : mWindow->geometry ()); CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); CompWindowExtents outExtents (mAWindow->savedRectsValid () ? mAWindow->savedOutExtents () : mWindow->output ()); int wx = winRect.x (); int wy = winRect.y (); int owidth = outRect.width (); int oheight = outRect.height (); AnimJCScreen *ajs = AnimJCScreen::get (screen); float waveAmp = 3 * ajs->optionGetGhostAmplitude (); float waveLengthX1 = 0.4; float waveLengthX2 = 0.3; float waveLengthY1 = 0.45; float waveLengthY2 = 0.35; float wavePositionX1 = 0.25 * t * ajs->optionGetGhostWaveSpeed (); float wavePositionX2 = -0.25 * t * ajs->optionGetGhostWaveSpeed (); float wavePositionY1 = 0.25 * t * ajs->optionGetGhostWaveSpeed (); float wavePositionY2 = -0.25 * t * ajs->optionGetGhostWaveSpeed (); GridModel::GridObject *object = mModel->objects (); unsigned int n = mModel->numObjects (); for (unsigned int i = 0; i < n; i++, object++) { Point3d &objPos = object->position (); float origx = wx + mModel->scale ().x () * (owidth * object->gridPosition ().x () - outExtents.left); float origy = wy + mModel->scale ().y () * (oheight * object->gridPosition ().y () - outExtents.top); float x = object->gridPosition ().x (); float y = object->gridPosition ().y (); float distFromWaveX1 = x - wavePositionX1; float distFromWaveX2 = x - wavePositionX2; float distFromWaveY1 = y - wavePositionY1; float distFromWaveY2 = y - wavePositionY2; objPos.setX (origx + waveAmp * sin (distFromWaveX1 / waveLengthX1 * 2 * M_PI) + waveAmp * sin (distFromWaveX2 / waveLengthX2 * 2 * M_PI)); objPos.setY (origy + waveAmp * sin (distFromWaveY1 / waveLengthY1 * 2 * M_PI) + waveAmp * sin (distFromWaveY2 / waveLengthY2 * 2 * M_PI)); objPos.setZ (0); } }
void GridAnim::addGeometry (const GLTexture::MatrixList &matrix, const CompRegion ®ion, const CompRegion &clip, unsigned int maxGridWidth, unsigned int maxGridHeight) { unsigned int nMatrix = matrix.size (); int nVertices, nIndices; GLushort *i; GLfloat *v; int x1, y1, x2, y2; float winContentsY, winContentsHeight; float deformedX, deformedY; float deformedZ = 0; int nVertX, nVertY; int vSize; float gridW, gridH; bool rect = true; bool notUsing3dCoords = !using3D (); if (region.isEmpty ()) // nothing to do return; GLWindow::Geometry &geometry = GLWindow::get (mWindow)->geometry (); for (unsigned int it = 0; it < nMatrix; it++) { if (matrix[it].xy != 0.0f || matrix[it].yx != 0.0f) { rect = false; break; } } CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); CompWindowExtents outExtents (mAWindow->savedRectsValid () ? mAWindow->savedOutExtents () : mWindow->output ()); // window output (contents + decorations + shadows) coordinates and size int ox = outRect.x (); int oy = outRect.y (); int owidth = outRect.width (); int oheight = outRect.height (); // to be used if event is shade/unshade winContentsY = oy + outExtents.top; winContentsHeight = oheight - outExtents.top - outExtents.bottom; geometry.texUnits = (int)nMatrix; if (geometry.vCount == 0) { // reset geometry.indexCount = 0; geometry.texCoordSize = 4; } geometry.vertexStride = 3 + geometry.texUnits * geometry.texCoordSize; vSize = geometry.vertexStride; nVertices = geometry.vCount; nIndices = geometry.indexCount; v = geometry.vertices + (nVertices * vSize); i = geometry.indices + nIndices; // For each clip passed to this function foreach (const CompRect &pClip, region.rects ()) { x1 = pClip.x1 (); y1 = pClip.y1 (); x2 = pClip.x2 (); y2 = pClip.y2 (); gridW = (float)owidth / (mGridWidth - 1); if (mCurWindowEvent == WindowEventShade || mCurWindowEvent == WindowEventUnshade) { if (y1 < winContentsY) // if at top part { gridH = mDecorTopHeight; } else if (y2 > winContentsY + winContentsHeight) // if at bottom { gridH = mDecorBottomHeight; } else // in window contents (only in Y coords) { float winContentsHeight = oheight - (mDecorTopHeight + mDecorBottomHeight); gridH = winContentsHeight / (mGridHeight - 3); } } else gridH = (float)oheight / (mGridHeight - 1); // nVertX, nVertY: number of vertices for this clip in x and y dimensions // + 2 to avoid running short of vertices in some cases nVertX = ceil ((x2 - x1) / gridW) + 2; nVertY = (gridH ? ceil ((y2 - y1) / gridH) : 0) + 2; // Allocate 4 indices for each quad int newIndexSize = nIndices + ((nVertX - 1) * (nVertY - 1) * 4); if (newIndexSize > geometry.indexSize) { if (!geometry.moreIndices (newIndexSize)) return; i = geometry.indices + nIndices; } // Assign quad vertices to indices for (int jy = 0; jy < nVertY - 1; jy++) { for (int jx = 0; jx < nVertX - 1; jx++) { *i++ = nVertices + nVertX * (2 * jy + 1) + jx; *i++ = nVertices + nVertX * (2 * jy + 1) + jx + 1; *i++ = nVertices + nVertX * 2 * jy + jx + 1; *i++ = nVertices + nVertX * 2 * jy + jx; nIndices += 4; } } // Allocate vertices int newVertexSize = (nVertices + nVertX * (2 * nVertY - 2)) * vSize; if (newVertexSize > geometry.vertexSize) { if (!geometry.moreVertices (newVertexSize)) return; v = geometry.vertices + (nVertices * vSize); } float rowTexCoordQ = 1; float prevRowCellWidth = 0; // this initial value won't be used float rowCellWidth = 0; int clipRowSize = nVertX * vSize; // For each vertex float y = y1; for (int jy = 0; jy < nVertY; jy++) { float topiyFloat; bool applyOffsets = true; if (y > y2) y = y2; // Do calculations for y here to avoid repeating // them unnecessarily in the x loop if (mCurWindowEvent == WindowEventShade || mCurWindowEvent == WindowEventUnshade) { if (y1 < winContentsY) // if at top part { topiyFloat = (y - oy) / mDecorTopHeight; topiyFloat = MIN (topiyFloat, 0.999); // avoid 1.0 applyOffsets = false; } else if (y2 > winContentsY + winContentsHeight) // if at bottom { topiyFloat = (mGridHeight - 2) + (mDecorBottomHeight ? (y - winContentsY - winContentsHeight) / mDecorBottomHeight : 0); applyOffsets = false; } else // in window contents (only in Y coords) { topiyFloat = (mGridHeight - 3) * (y - winContentsY) / winContentsHeight + 1; } } else { topiyFloat = (mGridHeight - 1) * (y - oy) / oheight; } // topiy should be at most (mGridHeight - 2) int topiy = (int)(topiyFloat + 1e-4); if (topiy == mGridHeight - 1) topiy--; int bottomiy = topiy + 1; float iny = topiyFloat - topiy; float inyRest = 1 - iny; // End of calculations for y float x = x1; for (int jx = 0; jx < nVertX; jx++) { if (x > x2) x = x2; // find containing grid cell (leftix rightix) x (topiy bottomiy) float leftixFloat = (mGridWidth - 1) * (x - ox) / owidth; int leftix = (int)(leftixFloat + 1e-4); if (leftix == mGridWidth - 1) leftix--; int rightix = leftix + 1; // GridModel::GridObjects that are at top, bottom, left, right corners of quad GridModel::GridObject *objToTopLeft = &(mModel->mObjects[topiy * mGridWidth + leftix]); GridModel::GridObject *objToTopRight = &(mModel->mObjects[topiy * mGridWidth + rightix]); GridModel::GridObject *objToBottomLeft = &(mModel->mObjects[bottomiy * mGridWidth + leftix]); GridModel::GridObject *objToBottomRight = &(mModel->mObjects[bottomiy * mGridWidth + rightix]); Point3d &objToTopLeftPos = objToTopLeft->mPosition; Point3d &objToTopRightPos = objToTopRight->mPosition; Point3d &objToBottomLeftPos = objToBottomLeft->mPosition; Point3d &objToBottomRightPos = objToBottomRight->mPosition; // find position in cell by taking remainder of flooring float inx = leftixFloat - leftix; float inxRest = 1 - inx; // Interpolate to find deformed coordinates float hor1x = (inxRest * objToTopLeftPos.x () + inx * objToTopRightPos.x ()); float hor1y = (inxRest * objToTopLeftPos.y () + inx * objToTopRightPos.y ()); float hor1z = (notUsing3dCoords ? 0 : inxRest * objToTopLeftPos.z () + inx * objToTopRightPos.z ()); float hor2x = (inxRest * objToBottomLeftPos.x () + inx * objToBottomRightPos.x ()); float hor2y = (inxRest * objToBottomLeftPos.y () + inx * objToBottomRightPos.y ()); float hor2z = (notUsing3dCoords ? 0 : inxRest * objToBottomLeftPos.z () + inx * objToBottomRightPos.z ()); deformedX = inyRest * hor1x + iny * hor2x; deformedY = inyRest * hor1y + iny * hor2y; deformedZ = inyRest * hor1z + iny * hor2z; // Texture coordinates (s, t, r, q) if (mUseQTexCoord) { if (jx == 1) rowCellWidth = deformedX - v[-3]; // do only once per row for all rows except row 0 if (jy > 0 && jx == 1) { rowTexCoordQ = (rowCellWidth / prevRowCellWidth); for (unsigned int it = 0; it < nMatrix; it++, v += 4) { // update first column // (since we didn't know rowTexCoordQ before) v[-vSize] *= rowTexCoordQ; // multiply s & t by q v[-vSize + 1] *= rowTexCoordQ; v[-vSize + 3] = rowTexCoordQ; // copy q } v -= nMatrix * 4; } } // Loop for each texture element // (4 texture coordinates for each one) for (unsigned int it = 0; it < nMatrix; it++, v += 4) { float offsetY = 0; if (rect) { if (applyOffsets && y < y2) offsetY = objToTopLeft->mOffsetTexCoordForQuadAfter.y (); v[0] = COMP_TEX_COORD_X (matrix[it], x); // s v[1] = COMP_TEX_COORD_Y (matrix[it], y + offsetY); // t } else { if (applyOffsets && y < y2) // FIXME: // The correct y offset below produces wrong // texture coordinates for some reason. offsetY = 0; // offsetY = objToTopLeft->offsetTexCoordForQuadAfter.y; v[0] = COMP_TEX_COORD_XY (matrix[it], x, y + offsetY); // s v[1] = COMP_TEX_COORD_YX (matrix[it], x, y + offsetY); // t } v[2] = 0; // r if (0 < jy && jy < nVertY - 1) { // copy s, t, r to duplicate row memcpy (v + clipRowSize, v, 3 * sizeof (GLfloat)); v[3 + clipRowSize] = 1; // q } if (applyOffsets && objToTopLeft->mOffsetTexCoordForQuadBefore.y () != 0) { // After copying to next row, update texture y coord // by following object's offset offsetY = objToTopLeft->mOffsetTexCoordForQuadBefore.y (); if (rect) { v[1] = COMP_TEX_COORD_Y (matrix[it], y + offsetY); } else { v[0] = COMP_TEX_COORD_XY (matrix[it], x, y + offsetY); v[1] = COMP_TEX_COORD_YX (matrix[it], x, y + offsetY); } } if (mUseQTexCoord) { v[3] = rowTexCoordQ; // q if (jx > 0) // since column 0 is updated when jx == 1 { // multiply s & t by q v[0] *= rowTexCoordQ; v[1] *= rowTexCoordQ; } } else { v[3] = 1; // q } } v[0] = deformedX; v[1] = deformedY; v[2] = deformedZ; // Copy vertex coordinates to duplicate row if (0 < jy && jy < nVertY - 1) memcpy (v + clipRowSize, v, 3 * sizeof (GLfloat)); nVertices++; // increment x properly (so that coordinates fall on grid intersections) x = rightix * gridW + ox; v += 3; // move on to next vertex } if (mUseQTexCoord) prevRowCellWidth = rowCellWidth; if (0 < jy && jy < nVertY - 1) { v += clipRowSize; // skip the duplicate row nVertices += nVertX; } // increment y properly (so that coordinates fall on grid intersections) if (mCurWindowEvent == WindowEventShade || mCurWindowEvent == WindowEventUnshade) { y += gridH; } else { y = bottomiy * gridH + oy; } } } geometry.vCount = nVertices; geometry.indexCount = nIndices; }
void BurnAnim::step () { CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); float timestep = mIntenseTimeStep; float old = 1 - (mRemainingTime) / (mTotalTime - timestep); float stepSize; mRemainingTime -= timestep; if (mRemainingTime <= 0) mRemainingTime = 0; // avoid sub-zero values float newProgress = 1 - (mRemainingTime) / (mTotalTime - timestep); stepSize = newProgress - old; if (mCurWindowEvent == WindowEventOpen || mCurWindowEvent == WindowEventUnminimize || mCurWindowEvent == WindowEventUnshade) { newProgress = 1 - newProgress; } if (mRemainingTime > 0) { CompRect rect; switch (mDirection) { case AnimDirectionUp: rect = CompRect (0, 0, outRect.width (), outRect.height () - (newProgress * outRect.height ())); break; case AnimDirectionRight: rect = CompRect (newProgress * outRect.width (), 0, outRect.width () - (newProgress * outRect.width ()), outRect.height ()); break; case AnimDirectionLeft: rect = CompRect (0, 0, outRect.width () - (newProgress * outRect.width ()), outRect.height ()); break; case AnimDirectionDown: default: rect = CompRect (0, newProgress * outRect.height (), outRect.width (), outRect.height () - (newProgress * outRect.height ())); break; } rect.setX (rect.x () + outRect.x ()); rect.setY (rect.y () + outRect.y ()); mDrawRegion = CompRegion (rect); } else { mDrawRegion = emptyRegion; } mUseDrawRegion = (fabs (newProgress) > 1e-5); if (mRemainingTime > 0) { switch (mDirection) { case AnimDirectionUp: if (mHasSmoke) genNewSmoke (outRect.x (), outRect.y () + ((1 - newProgress) * outRect.height ()), outRect.width (), 1, outRect.width () / 40.0, mTimeSinceLastPaint); genNewFire (outRect.x (), outRect.y () + ((1 - newProgress) * outRect.height ()), outRect.width (), (stepSize) * outRect.height (), outRect.width () / 40.0, mTimeSinceLastPaint); break; case AnimDirectionLeft: if (mHasSmoke) genNewSmoke (outRect.x () + ((1 - newProgress) * outRect.width ()), outRect.y (), (stepSize) * outRect.width (), outRect.height (), outRect.height () / 40.0, mTimeSinceLastPaint); genNewFire (outRect.x () + ((1 - newProgress) * outRect.width ()), outRect.y (), (stepSize) * outRect.width (), outRect.height (), outRect.height () / 40.0, mTimeSinceLastPaint); break; case AnimDirectionRight: if (mHasSmoke) genNewSmoke (outRect.x () + (newProgress * outRect.width ()), outRect.y (), (stepSize) * outRect.width (), outRect.height (), outRect.height () / 40.0, mTimeSinceLastPaint); genNewFire (outRect.x () + (newProgress * outRect.width ()), outRect.y (), (stepSize) * outRect.width (), outRect.height (), outRect.height () / 40.0, mTimeSinceLastPaint); break; case AnimDirectionDown: default: if (mHasSmoke) genNewSmoke (outRect.x (), outRect.y () + (newProgress * outRect.height ()), outRect.width (), 1, outRect.width () / 40.0, mTimeSinceLastPaint); genNewFire (outRect.x (), outRect.y () + (newProgress * outRect.height ()), outRect.width (), (stepSize) * outRect.height (), outRect.width () / 40.0, mTimeSinceLastPaint); break; } } if (mRemainingTime <= 0 && (mParticleSystems[0].active () || (mHasSmoke && mParticleSystems[1].active ()))) // force animation to continue until particle systems are done mRemainingTime = timestep; Particle *part; if (mRemainingTime > 0) { int nParticles; if (mHasSmoke) { float partxg = outRect.width () / 40.0; float partxgNeg = -partxg; vector<Particle> &particles = mParticleSystems[mSmokePSId].particles (); nParticles = particles.size (); part = &particles[0]; for (int i = 0; i < nParticles; i++, part++) part->xg = (part->x < part->xo) ? partxg : partxgNeg; mParticleSystems[mSmokePSId].setOrigin (outRect.x (), outRect.y ()); } vector<Particle> &particles = mParticleSystems[mFirePSId].particles (); nParticles = particles.size (); part = &particles[0]; for (int i = 0; i < nParticles; i++, part++) part->xg = (part->x < part->xo) ? 1.0 : -1.0; } mParticleSystems[mFirePSId].setOrigin (outRect.x (), outRect.y ()); }
void BeamUpAnim::step () { CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); float timestep = mIntenseTimeStep; mRemainingTime -= timestep; if (mRemainingTime <= 0) mRemainingTime = 0; // avoid sub-zero values float newProgress = 1 - mRemainingTime / (mTotalTime - timestep); bool creating = (mCurWindowEvent == WindowEventOpen || mCurWindowEvent == WindowEventUnminimize || mCurWindowEvent == WindowEventUnshade); if (creating) newProgress = 1 - newProgress; if (mRemainingTime > 0) { CompRect rect (((newProgress / 2) * outRect.width ()), ((newProgress / 2) * outRect.height ()), (1 - newProgress) * outRect.width (), (1 - newProgress) * outRect.height ()); rect.setX (rect.x () + outRect.x ()); rect.setY (rect.y () + outRect.y ()); mDrawRegion = CompRegion (rect); } else { mDrawRegion = emptyRegion; } mUseDrawRegion = (fabs (newProgress) > 1e-5); if (mRemainingTime > 0) { genNewBeam (outRect.x (), outRect.y () + (outRect.height () / 2), outRect.width (), creating ? (1 - newProgress / 2) * outRect.height () : (1 - newProgress) * outRect.height (), outRect.width () / 40.0, mTimeSinceLastPaint); } if (mRemainingTime <= 0 && mParticleSystems[0].active ()) // force animation to continue until particle systems are done mRemainingTime = 0.001f; if (mRemainingTime > 0) { vector<Particle> &particles = mParticleSystems[0].particles (); int nParticles = particles.size (); Particle *part = &particles[0]; for (int i = 0; i < nParticles; i++, part++) part->xg = (part->x < part->xo) ? 1.0 : -1.0; } mParticleSystems[0].setOrigin (outRect.x (), outRect.y ()); }